aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad Davis <[email protected]>2014-04-14 21:25:09 -0700
committerBrad Davis <[email protected]>2014-04-14 21:25:09 -0700
commit07d0f4d0bbf3477ac6a9584f726e8ec6ab285707 (patch)
tree1854d0c690eff32e77b137567c88a52d56d8b660
parentf28388ff2af14b56ef2d973b2f4f9da021716d4c (diff)
Adding windows 0.3.1 SDK
-rw-r--r--3rdParty/glext/GL/glext.h11081
-rw-r--r--3rdParty/glext/GL/wglext.h929
-rwxr-xr-xConfigurePermissionsAndPackages.sh47
-rw-r--r--LICENSE.TXT258
-rw-r--r--LibOVR/90-oculus.rules2
-rw-r--r--LibOVR/CMakeLists.txt136
-rw-r--r--LibOVR/Include/OVR.h11
-rw-r--r--LibOVR/Include/OVRVersion.h14
-rw-r--r--LibOVR/Lib/Linux/Debug/i386/readme2
-rw-r--r--LibOVR/Lib/Linux/Debug/x86_64/readme2
-rw-r--r--LibOVR/Lib/Linux/Release/i386/readme2
-rw-r--r--LibOVR/Lib/Linux/Release/x86_64/readme2
-rw-r--r--LibOVR/Makefile211
-rw-r--r--LibOVR/Obj/Linux/Debug/i386/readme2
-rw-r--r--LibOVR/Obj/Linux/Debug/x86_64/readme2
-rw-r--r--LibOVR/Obj/Linux/Release/i386/readme2
-rw-r--r--LibOVR/Obj/Linux/Release/x86_64/readme2
-rw-r--r--LibOVR/Projects/Win32/LibOVR_Msvc2010.sln20
-rw-r--r--LibOVR/Projects/Win32/LibOVR_Msvc2010.vcxproj279
-rw-r--r--LibOVR/Projects/Win32/LibOVR_Msvc2010.vcxproj.filters184
-rw-r--r--LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj433
-rw-r--r--LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters332
-rw-r--r--LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj439
-rw-r--r--LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters332
-rw-r--r--LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj439
-rw-r--r--LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters332
-rw-r--r--LibOVR/Projects/libovr.txt83
-rw-r--r--LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp63
-rw-r--r--LibOVR/Src/CAPI/CAPI_DistortionRenderer.h100
-rw-r--r--LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp674
-rw-r--r--LibOVR/Src/CAPI/CAPI_FrameTimeManager.h264
-rw-r--r--LibOVR/Src/CAPI/CAPI_GlobalState.cpp142
-rw-r--r--LibOVR/Src/CAPI/CAPI_GlobalState.h84
-rw-r--r--LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp147
-rw-r--r--LibOVR/Src/CAPI/CAPI_HMDRenderState.h93
-rw-r--r--LibOVR/Src/CAPI/CAPI_HMDState.cpp774
-rw-r--r--LibOVR/Src/CAPI/CAPI_HMDState.h334
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.cpp29
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h34
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.cpp30
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h34
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp773
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h131
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp416
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h505
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp251
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h120
-rw-r--r--LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp317
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp1006
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h125
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp516
-rw-r--r--LibOVR/Src/CAPI/GL/CAPI_GL_Util.h522
-rw-r--r--LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh12
-rw-r--r--LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.vsh24
-rw-r--r--LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.vsh40
-rw-r--r--LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.vsh36
-rw-r--r--LibOVR/Src/CAPI/Shaders/Distortion_ps.psh9
-rw-r--r--LibOVR/Src/CAPI/Shaders/Distortion_vs.vsh14
-rw-r--r--LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.psh6
-rw-r--r--LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.vsh8
-rw-r--r--LibOVR/Src/CAPI/Shaders/genPixelShaderHeader.bat15
-rw-r--r--LibOVR/Src/CAPI/Shaders/genVertexShaderHeader.bat15
-rw-r--r--LibOVR/Src/Kernel/OVR_Alg.cpp8
-rw-r--r--LibOVR/Src/Kernel/OVR_Alg.h122
-rw-r--r--LibOVR/Src/Kernel/OVR_Allocator.cpp8
-rw-r--r--LibOVR/Src/Kernel/OVR_Allocator.h10
-rw-r--r--LibOVR/Src/Kernel/OVR_Array.h53
-rw-r--r--LibOVR/Src/Kernel/OVR_Atomic.cpp77
-rw-r--r--LibOVR/Src/Kernel/OVR_Atomic.h27
-rw-r--r--LibOVR/Src/Kernel/OVR_Color.h8
-rw-r--r--LibOVR/Src/Kernel/OVR_ContainerAllocator.h8
-rw-r--r--LibOVR/Src/Kernel/OVR_Deque.h310
-rw-r--r--LibOVR/Src/Kernel/OVR_File.cpp8
-rw-r--r--LibOVR/Src/Kernel/OVR_File.h8
-rw-r--r--LibOVR/Src/Kernel/OVR_FileFILE.cpp13
-rw-r--r--LibOVR/Src/Kernel/OVR_Hash.h8
-rw-r--r--LibOVR/Src/Kernel/OVR_KeyCodes.h10
-rw-r--r--LibOVR/Src/Kernel/OVR_List.h8
-rw-r--r--LibOVR/Src/Kernel/OVR_Lockless.cpp231
-rw-r--r--LibOVR/Src/Kernel/OVR_Lockless.h107
-rw-r--r--LibOVR/Src/Kernel/OVR_Log.cpp8
-rw-r--r--LibOVR/Src/Kernel/OVR_Log.h10
-rw-r--r--LibOVR/Src/Kernel/OVR_Math.cpp99
-rw-r--r--LibOVR/Src/Kernel/OVR_Math.h1918
-rw-r--r--LibOVR/Src/Kernel/OVR_RefCount.cpp8
-rw-r--r--LibOVR/Src/Kernel/OVR_RefCount.h47
-rw-r--r--LibOVR/Src/Kernel/OVR_Std.cpp8
-rw-r--r--LibOVR/Src/Kernel/OVR_Std.h14
-rw-r--r--LibOVR/Src/Kernel/OVR_String.cpp8
-rw-r--r--LibOVR/Src/Kernel/OVR_String.h16
-rw-r--r--LibOVR/Src/Kernel/OVR_StringHash.h8
-rw-r--r--LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp8
-rw-r--r--LibOVR/Src/Kernel/OVR_String_PathUtil.cpp8
-rw-r--r--LibOVR/Src/Kernel/OVR_SysFile.cpp12
-rw-r--r--LibOVR/Src/Kernel/OVR_SysFile.h8
-rw-r--r--LibOVR/Src/Kernel/OVR_System.cpp8
-rw-r--r--LibOVR/Src/Kernel/OVR_System.h8
-rw-r--r--LibOVR/Src/Kernel/OVR_Threads.h8
-rw-r--r--LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp821
-rw-r--r--LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp8
-rw-r--r--LibOVR/Src/Kernel/OVR_Timer.cpp256
-rw-r--r--LibOVR/Src/Kernel/OVR_Timer.h85
-rw-r--r--LibOVR/Src/Kernel/OVR_Types.h19
-rw-r--r--LibOVR/Src/Kernel/OVR_UTF8Util.cpp8
-rw-r--r--LibOVR/Src/Kernel/OVR_UTF8Util.h9
-rw-r--r--LibOVR/Src/OVR_CAPI.cpp911
-rw-r--r--LibOVR/Src/OVR_CAPI.h762
-rw-r--r--LibOVR/Src/OVR_CAPI_D3D.h156
-rw-r--r--LibOVR/Src/OVR_CAPI_GL.h59
-rw-r--r--LibOVR/Src/OVR_Common_HMDDevice.cpp383
-rw-r--r--LibOVR/Src/OVR_Device.h585
-rw-r--r--LibOVR/Src/OVR_DeviceConstants.h100
-rw-r--r--LibOVR/Src/OVR_DeviceHandle.cpp8
-rw-r--r--LibOVR/Src/OVR_DeviceHandle.h8
-rw-r--r--LibOVR/Src/OVR_DeviceImpl.cpp203
-rw-r--r--LibOVR/Src/OVR_DeviceImpl.h72
-rw-r--r--LibOVR/Src/OVR_DeviceMessages.h115
-rw-r--r--LibOVR/Src/OVR_HIDDevice.h12
-rw-r--r--LibOVR/Src/OVR_HIDDeviceBase.h8
-rw-r--r--LibOVR/Src/OVR_HIDDeviceImpl.h61
-rw-r--r--LibOVR/Src/OVR_JSON.cpp63
-rw-r--r--LibOVR/Src/OVR_JSON.h13
-rw-r--r--LibOVR/Src/OVR_LatencyTestImpl.cpp64
-rw-r--r--LibOVR/Src/OVR_LatencyTestImpl.h8
-rw-r--r--LibOVR/Src/OVR_Linux_DeviceManager.cpp330
-rw-r--r--LibOVR/Src/OVR_Linux_DeviceManager.h122
-rw-r--r--LibOVR/Src/OVR_Linux_HIDDevice.cpp815
-rw-r--r--LibOVR/Src/OVR_Linux_HIDDevice.h135
-rw-r--r--LibOVR/Src/OVR_Linux_HMDDevice.cpp408
-rw-r--r--LibOVR/Src/OVR_Linux_HMDDevice.h170
-rw-r--r--LibOVR/Src/OVR_Linux_SensorDevice.cpp56
-rw-r--r--LibOVR/Src/OVR_OSX_DeviceManager.cpp360
-rw-r--r--LibOVR/Src/OVR_OSX_DeviceManager.h130
-rw-r--r--LibOVR/Src/OVR_OSX_HIDDevice.cpp923
-rw-r--r--LibOVR/Src/OVR_OSX_HIDDevice.h160
-rw-r--r--LibOVR/Src/OVR_OSX_HMDDevice.cpp417
-rw-r--r--LibOVR/Src/OVR_OSX_HMDDevice.h174
-rw-r--r--LibOVR/Src/OVR_OSX_SensorDevice.cpp56
-rw-r--r--LibOVR/Src/OVR_Profile.cpp1572
-rw-r--r--LibOVR/Src/OVR_Profile.h255
-rw-r--r--LibOVR/Src/OVR_Sensor2Impl.cpp1128
-rw-r--r--LibOVR/Src/OVR_Sensor2Impl.h157
-rw-r--r--LibOVR/Src/OVR_Sensor2ImplUtil.h676
-rw-r--r--LibOVR/Src/OVR_SensorCalibration.cpp276
-rw-r--r--LibOVR/Src/OVR_SensorCalibration.h77
-rw-r--r--LibOVR/Src/OVR_SensorFilter.cpp109
-rw-r--r--LibOVR/Src/OVR_SensorFilter.h312
-rw-r--r--LibOVR/Src/OVR_SensorFusion.cpp1156
-rw-r--r--LibOVR/Src/OVR_SensorFusion.h616
-rw-r--r--LibOVR/Src/OVR_SensorImpl.cpp894
-rw-r--r--LibOVR/Src/OVR_SensorImpl.h90
-rw-r--r--LibOVR/Src/OVR_SensorImpl_Common.cpp245
-rw-r--r--LibOVR/Src/OVR_SensorImpl_Common.h150
-rw-r--r--LibOVR/Src/OVR_SensorTimeFilter.cpp385
-rw-r--r--LibOVR/Src/OVR_SensorTimeFilter.h226
-rw-r--r--LibOVR/Src/OVR_Stereo.cpp1794
-rw-r--r--LibOVR/Src/OVR_Stereo.h460
-rw-r--r--LibOVR/Src/OVR_ThreadCommandQueue.cpp8
-rw-r--r--LibOVR/Src/OVR_ThreadCommandQueue.h8
-rw-r--r--LibOVR/Src/OVR_Win32_DeviceManager.cpp22
-rw-r--r--LibOVR/Src/OVR_Win32_DeviceManager.h22
-rw-r--r--LibOVR/Src/OVR_Win32_DeviceStatus.cpp16
-rw-r--r--LibOVR/Src/OVR_Win32_DeviceStatus.h8
-rw-r--r--LibOVR/Src/OVR_Win32_HIDDevice.cpp33
-rw-r--r--LibOVR/Src/OVR_Win32_HIDDevice.h10
-rw-r--r--LibOVR/Src/OVR_Win32_HMDDevice.cpp264
-rw-r--r--LibOVR/Src/OVR_Win32_HMDDevice.h76
-rw-r--r--LibOVR/Src/OVR_Win32_SensorDevice.cpp24
-rw-r--r--LibOVR/Src/OVR_Win32_SensorDevice.h8
-rw-r--r--LibOVR/Src/Recording/Recorder.h273
-rw-r--r--LibOVR/Src/Util/Util_ImageWindow.cpp473
-rw-r--r--LibOVR/Src/Util/Util_ImageWindow.h122
-rw-r--r--LibOVR/Src/Util/Util_Interface.cpp34
-rw-r--r--LibOVR/Src/Util/Util_Interface.h37
-rw-r--r--LibOVR/Src/Util/Util_LatencyTest.cpp32
-rw-r--r--LibOVR/Src/Util/Util_LatencyTest.h18
-rw-r--r--LibOVR/Src/Util/Util_LatencyTest2.cpp194
-rw-r--r--LibOVR/Src/Util/Util_LatencyTest2.h238
-rw-r--r--LibOVR/Src/Util/Util_MagCalibration.cpp227
-rw-r--r--LibOVR/Src/Util/Util_MagCalibration.h138
-rw-r--r--LibOVR/Src/Util/Util_Render_Stereo.cpp1367
-rw-r--r--LibOVR/Src/Util/Util_Render_Stereo.h579
-rw-r--r--Mac_OculusWorldDemo.app/Contents/Info.plist50
-rw-r--r--Mac_OculusWorldDemo.app/Contents/MacOS/OculusWorldDemobin881004 -> 0 bytes
-rw-r--r--Mac_OculusWorldDemo.app/Contents/PkgInfo1
-rw-r--r--Makefile82
-rw-r--r--Oculus World Demo.lnkbin2349 -> 2287 bytes
-rwxr-xr-xOculusConfigurationUtility.sh28
-rwxr-xr-xOculusWorldDemo.sh25
-rw-r--r--README.md49
-rw-r--r--Samples/CommonSrc/Makefile7
-rw-r--r--Samples/CommonSrc/Platform/Gamepad.h4
-rw-r--r--Samples/CommonSrc/Platform/Linux_Gamepad.cpp453
-rw-r--r--Samples/CommonSrc/Platform/Linux_Gamepad.h83
-rw-r--r--Samples/CommonSrc/Platform/Linux_Platform.cpp563
-rw-r--r--Samples/CommonSrc/Platform/Linux_Platform.h120
-rw-r--r--Samples/CommonSrc/Platform/OSX_Gamepad.cpp424
-rw-r--r--Samples/CommonSrc/Platform/OSX_Gamepad.h66
-rw-r--r--Samples/CommonSrc/Platform/OSX_Platform.h80
-rw-r--r--Samples/CommonSrc/Platform/OSX_Platform.mm514
-rw-r--r--Samples/CommonSrc/Platform/OSX_PlatformObjc.h31
-rw-r--r--Samples/CommonSrc/Platform/OSX_WavPlayer.cpp242
-rw-r--r--Samples/CommonSrc/Platform/OSX_WavPlayer.h64
-rw-r--r--Samples/CommonSrc/Platform/Platform.cpp4
-rw-r--r--Samples/CommonSrc/Platform/Platform.h2
-rw-r--r--Samples/CommonSrc/Platform/Platform_Default.h11
-rw-r--r--Samples/CommonSrc/Platform/Win32_Gamepad.cpp2
-rw-r--r--Samples/CommonSrc/Platform/Win32_Gamepad.h2
-rw-r--r--Samples/CommonSrc/Platform/Win32_Platform.cpp7
-rw-r--r--Samples/CommonSrc/Platform/Win32_Platform.h10
-rw-r--r--Samples/CommonSrc/Render/Render_D3D1X_Device.cpp710
-rw-r--r--Samples/CommonSrc/Render/Render_D3D1X_Device.h41
-rw-r--r--Samples/CommonSrc/Render/Render_Device.cpp2306
-rw-r--r--Samples/CommonSrc/Render/Render_Device.h326
-rw-r--r--Samples/CommonSrc/Render/Render_GL_Device.cpp639
-rw-r--r--Samples/CommonSrc/Render/Render_GL_Device.h113
-rw-r--r--Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp248
-rw-r--r--Samples/CommonSrc/Render/Render_GL_Win32_Device.h24
-rw-r--r--Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp6
-rw-r--r--Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp13
-rw-r--r--Samples/CommonSrc/Render/Render_XmlSceneLoader.h2
-rw-r--r--Samples/LibOVR_Samples_Msvc2010.sln43
-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.xcodeproj/OculusRoomTiny-Info.plist34
-rw-r--r--Samples/LibOVR_With_Samples.xcodeproj/OculusWorldDemo-Info.plist34
-rw-r--r--Samples/LibOVR_With_Samples.xcodeproj/SensorBoxTest-Info.plist34
-rw-r--r--Samples/LibOVR_With_Samples.xcodeproj/project.pbxproj1131
-rw-r--r--Samples/LibOVR_With_Samples.xcodeproj/project.xcworkspace/contents.xcworkspacedata7
-rw-r--r--Samples/LibOVR_With_Samples.xcodeproj/project.xcworkspace/xcuserdata/Nate.xcuserdatad/UserInterfaceState.xcuserstatebin15669 -> 0 bytes
-rw-r--r--Samples/LibOVR_With_Samples.xcodeproj/project.xcworkspace/xcuserdata/Nate.xcuserdatad/WorkspaceSettings.xcsettings20
-rw-r--r--Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/OculusRoomTiny.xcscheme86
-rw-r--r--Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/OculusWorldDemo.xcscheme86
-rw-r--r--Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/SensorBoxTest.xcscheme86
-rw-r--r--Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/ovr.xcscheme59
-rw-r--r--Samples/LibOVR_With_Samples.xcodeproj/xcuserdata/Nate.xcuserdatad/xcschemes/xcschememanagement.plist29
-rw-r--r--Samples/LibOVR_With_Samples_Msvc2010.sln67
-rw-r--r--Samples/LibOVR_With_Samples_VS2010.sln51
-rw-r--r--Samples/LibOVR_With_Samples_VS2012.sln63
-rw-r--r--Samples/LibOVR_With_Samples_VS2013.sln53
-rw-r--r--Samples/OculusRoomTiny/OSX_OculusRoomTiny.mm861
-rw-r--r--Samples/OculusRoomTiny/OSX_OculusRoomTiny2.h (renamed from Samples/OculusRoomTiny/OSX_OculusRoomTiny.h)2
-rw-r--r--Samples/OculusRoomTiny/OculusRoomModel.cpp8
-rw-r--r--Samples/OculusRoomTiny/OculusRoomTiny2.rc (renamed from Samples/OculusRoomTiny/OculusRoomTiny.rc)bin144 -> 144 bytes
-rw-r--r--Samples/OculusRoomTiny/OculusRoomTiny_Msvc2010.vcxproj.filters17
-rw-r--r--Samples/OculusRoomTiny/Projects/Win/VS2010/OculusRoomTiny.vcxproj (renamed from Samples/OculusRoomTiny/OculusRoomTiny_Msvc2010.vcxproj)64
-rw-r--r--Samples/OculusRoomTiny/Projects/Win/VS2010/OculusRoomTiny.vcxproj.filters26
-rw-r--r--Samples/OculusRoomTiny/Projects/Win/VS2012/OculusRoomTiny.vcxproj (renamed from Samples/OculusWorldDemo/OculusWorldDemo_Msvc2010.vcxproj)100
-rw-r--r--Samples/OculusRoomTiny/Projects/Win/VS2012/OculusRoomTiny.vcxproj.filters26
-rw-r--r--Samples/OculusRoomTiny/Projects/Win/VS2013/OculusRoomTiny.vcxproj208
-rw-r--r--Samples/OculusRoomTiny/Projects/Win/VS2013/OculusRoomTiny.vcxproj.filters29
-rw-r--r--Samples/OculusRoomTiny/RenderTiny_D3D11_Device.cpp (renamed from Samples/OculusRoomTiny/RenderTiny_D3D1X_Device.cpp)727
-rw-r--r--Samples/OculusRoomTiny/RenderTiny_D3D11_Device.h (renamed from Samples/OculusRoomTiny/RenderTiny_Device.h)484
-rw-r--r--Samples/OculusRoomTiny/RenderTiny_D3D1X_Device.h273
-rw-r--r--Samples/OculusRoomTiny/RenderTiny_Device.cpp442
-rw-r--r--Samples/OculusRoomTiny/RenderTiny_GL_Device.cpp784
-rw-r--r--Samples/OculusRoomTiny/RenderTiny_GL_Device.h228
-rw-r--r--Samples/OculusRoomTiny/Win32_DistortionMesh.cpp244
-rw-r--r--Samples/OculusRoomTiny/Win32_OculusRoomTiny.cpp876
-rw-r--r--Samples/OculusRoomTiny/Win32_OculusRoomTiny.h189
-rw-r--r--Samples/OculusRoomTiny/Win32_OculusRoomTiny_Util.cpp254
-rw-r--r--Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_OculusCube.tgabin0 -> 2699618 bytes
-rw-r--r--Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_blueCube.tgabin0 -> 270018 bytes
-rw-r--r--Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_redCube.tgabin0 -> 270018 bytes
-rw-r--r--Samples/OculusWorldDemo/Makefile135
-rw-r--r--Samples/OculusWorldDemo/Obj/Linux/Debug/i386/readme2
-rw-r--r--Samples/OculusWorldDemo/Obj/Linux/Debug/x86_64/readme2
-rw-r--r--Samples/OculusWorldDemo/Obj/Linux/Release/i386/readme2
-rw-r--r--Samples/OculusWorldDemo/Obj/Linux/Release/x86_64/readme2
-rw-r--r--Samples/OculusWorldDemo/OculusWorldDemo.cpp2390
-rw-r--r--Samples/OculusWorldDemo/OculusWorldDemo.h339
-rw-r--r--Samples/OculusWorldDemo/OculusWorldDemo_Msvc2010.vcxproj.filters89
-rw-r--r--Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp399
-rw-r--r--Samples/OculusWorldDemo/OptionMenu.cpp896
-rw-r--r--Samples/OculusWorldDemo/OptionMenu.h442
-rw-r--r--Samples/OculusWorldDemo/Player.cpp226
-rw-r--r--Samples/OculusWorldDemo/Player.h48
-rw-r--r--Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj227
-rw-r--r--Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj.filters107
-rw-r--r--Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj232
-rw-r--r--Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj.filters106
-rw-r--r--Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj232
-rw-r--r--Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj.filters106
-rw-r--r--Samples/OculusWorldDemo/Release/readme2
-rw-r--r--Samples/OculusWorldDemo/RenderProfiler.cpp99
-rw-r--r--Samples/OculusWorldDemo/RenderProfiler.h71
-rw-r--r--Samples/SensorBox/SensorBoxTest.cpp506
-rw-r--r--Samples/SensorBox/SensorBoxTest.rcbin144 -> 0 bytes
-rw-r--r--Samples/SensorBox/SensorBoxTest_Msvc2010.vcxproj126
-rw-r--r--Samples/SensorBox/SensorBoxTest_Msvc2010.vcxproj.filters73
-rw-r--r--Win_OculusWorldDemo.lnkbin2349 -> 0 bytes
-rw-r--r--readme.txt2
293 files changed, 49614 insertions, 22771 deletions
diff --git a/3rdParty/glext/GL/glext.h b/3rdParty/glext/GL/glext.h
new file mode 100644
index 0000000..0645c35
--- /dev/null
+++ b/3rdParty/glext/GL/glext.h
@@ -0,0 +1,11081 @@
+#ifndef __glext_h_
+#define __glext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2010 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Header file version number, required by OpenGL ABI for Linux */
+/* glext.h last updated $Date: 2011-04-05 23:08:32 -0700 (Tue, 05 Apr 2011) $ */
+/* Current version at http://www.opengl.org/registry/ */
+#define GL_GLEXT_VERSION 68
+/* Function declaration macros - to move into glplatform.h */
+
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+/*************************************************************/
+
+#ifndef GL_VERSION_1_2
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_BGR 0x80E0
+#define GL_BGRA 0x80E1
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#endif
+
+#ifndef GL_VERSION_1_2_DEPRECATED
+#define GL_RESCALE_NORMAL 0x803A
+#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
+#define GL_SINGLE_COLOR 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#endif
+
+#ifndef GL_ARB_imaging
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+#define GL_FUNC_ADD 0x8006
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_BLEND_EQUATION 0x8009
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#endif
+
+#ifndef GL_ARB_imaging_DEPRECATED
+#define GL_CONVOLUTION_1D 0x8010
+#define GL_CONVOLUTION_2D 0x8011
+#define GL_SEPARABLE_2D 0x8012
+#define GL_CONVOLUTION_BORDER_MODE 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS 0x8015
+#define GL_REDUCE 0x8016
+#define GL_CONVOLUTION_FORMAT 0x8017
+#define GL_CONVOLUTION_WIDTH 0x8018
+#define GL_CONVOLUTION_HEIGHT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023
+#define GL_HISTOGRAM 0x8024
+#define GL_PROXY_HISTOGRAM 0x8025
+#define GL_HISTOGRAM_WIDTH 0x8026
+#define GL_HISTOGRAM_FORMAT 0x8027
+#define GL_HISTOGRAM_RED_SIZE 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C
+#define GL_HISTOGRAM_SINK 0x802D
+#define GL_MINMAX 0x802E
+#define GL_MINMAX_FORMAT 0x802F
+#define GL_MINMAX_SINK 0x8030
+#define GL_TABLE_TOO_LARGE 0x8031
+#define GL_COLOR_MATRIX 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB
+#define GL_COLOR_TABLE 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2
+#define GL_PROXY_COLOR_TABLE 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5
+#define GL_COLOR_TABLE_SCALE 0x80D6
+#define GL_COLOR_TABLE_BIAS 0x80D7
+#define GL_COLOR_TABLE_FORMAT 0x80D8
+#define GL_COLOR_TABLE_WIDTH 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF
+#define GL_CONSTANT_BORDER 0x8151
+#define GL_REPLICATE_BORDER 0x8153
+#define GL_CONVOLUTION_BORDER_COLOR 0x8154
+#endif
+
+#ifndef GL_VERSION_1_3
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_MULTISAMPLE 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_COMPRESSED_RGB 0x84ED
+#define GL_COMPRESSED_RGBA 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_CLAMP_TO_BORDER 0x812D
+#endif
+
+#ifndef GL_VERSION_1_3_DEPRECATED
+#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1
+#define GL_MAX_TEXTURE_UNITS 0x84E2
+#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6
+#define GL_MULTISAMPLE_BIT 0x20000000
+#define GL_NORMAL_MAP 0x8511
+#define GL_REFLECTION_MAP 0x8512
+#define GL_COMPRESSED_ALPHA 0x84E9
+#define GL_COMPRESSED_LUMINANCE 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
+#define GL_COMPRESSED_INTENSITY 0x84EC
+#define GL_COMBINE 0x8570
+#define GL_COMBINE_RGB 0x8571
+#define GL_COMBINE_ALPHA 0x8572
+#define GL_SOURCE0_RGB 0x8580
+#define GL_SOURCE1_RGB 0x8581
+#define GL_SOURCE2_RGB 0x8582
+#define GL_SOURCE0_ALPHA 0x8588
+#define GL_SOURCE1_ALPHA 0x8589
+#define GL_SOURCE2_ALPHA 0x858A
+#define GL_OPERAND0_RGB 0x8590
+#define GL_OPERAND1_RGB 0x8591
+#define GL_OPERAND2_RGB 0x8592
+#define GL_OPERAND0_ALPHA 0x8598
+#define GL_OPERAND1_ALPHA 0x8599
+#define GL_OPERAND2_ALPHA 0x859A
+#define GL_RGB_SCALE 0x8573
+#define GL_ADD_SIGNED 0x8574
+#define GL_INTERPOLATE 0x8575
+#define GL_SUBTRACT 0x84E7
+#define GL_CONSTANT 0x8576
+#define GL_PRIMARY_COLOR 0x8577
+#define GL_PREVIOUS 0x8578
+#define GL_DOT3_RGB 0x86AE
+#define GL_DOT3_RGBA 0x86AF
+#endif
+
+#ifndef GL_VERSION_1_4
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_DEPTH_COMPONENT32 0x81A7
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_LOD_BIAS 0x8501
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#endif
+
+#ifndef GL_VERSION_1_4_DEPRECATED
+#define GL_POINT_SIZE_MIN 0x8126
+#define GL_POINT_SIZE_MAX 0x8127
+#define GL_POINT_DISTANCE_ATTENUATION 0x8129
+#define GL_GENERATE_MIPMAP 0x8191
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_FOG_COORDINATE_SOURCE 0x8450
+#define GL_FOG_COORDINATE 0x8451
+#define GL_FRAGMENT_DEPTH 0x8452
+#define GL_CURRENT_FOG_COORDINATE 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456
+#define GL_FOG_COORDINATE_ARRAY 0x8457
+#define GL_COLOR_SUM 0x8458
+#define GL_CURRENT_SECONDARY_COLOR 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D
+#define GL_SECONDARY_COLOR_ARRAY 0x845E
+#define GL_TEXTURE_FILTER_CONTROL 0x8500
+#define GL_DEPTH_TEXTURE_MODE 0x884B
+#define GL_COMPARE_R_TO_TEXTURE 0x884E
+#endif
+
+#ifndef GL_VERSION_1_5
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_QUERY_COUNTER_BITS 0x8864
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_READ_ONLY 0x88B8
+#define GL_WRITE_ONLY 0x88B9
+#define GL_READ_WRITE 0x88BA
+#define GL_BUFFER_ACCESS 0x88BB
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_DRAW 0x88E4
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_SAMPLES_PASSED 0x8914
+#endif
+
+#ifndef GL_VERSION_1_5_DEPRECATED
+#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E
+#define GL_FOG_COORD_SRC 0x8450
+#define GL_FOG_COORD 0x8451
+#define GL_CURRENT_FOG_COORD 0x8453
+#define GL_FOG_COORD_ARRAY_TYPE 0x8454
+#define GL_FOG_COORD_ARRAY_STRIDE 0x8455
+#define GL_FOG_COORD_ARRAY_POINTER 0x8456
+#define GL_FOG_COORD_ARRAY 0x8457
+#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D
+#define GL_SRC0_RGB 0x8580
+#define GL_SRC1_RGB 0x8581
+#define GL_SRC2_RGB 0x8582
+#define GL_SRC0_ALPHA 0x8588
+#define GL_SRC1_ALPHA 0x8589
+#define GL_SRC2_ALPHA 0x858A
+#endif
+
+#ifndef GL_VERSION_2_0
+#define GL_BLEND_EQUATION_RGB 0x8009
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_MAX_VARYING_FLOATS 0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_1D 0x8B5D
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_SAMPLER_1D_SHADOW 0x8B61
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_DELETE_STATUS 0x8B80
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
+#define GL_LOWER_LEFT 0x8CA1
+#define GL_UPPER_LEFT 0x8CA2
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#endif
+
+#ifndef GL_VERSION_2_0_DEPRECATED
+#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643
+#define GL_POINT_SPRITE 0x8861
+#define GL_COORD_REPLACE 0x8862
+#define GL_MAX_TEXTURE_COORDS 0x8871
+#endif
+
+#ifndef GL_VERSION_2_1
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB_ALPHA 0x8C42
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_COMPRESSED_SRGB 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
+#endif
+
+#ifndef GL_VERSION_2_1_DEPRECATED
+#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F
+#define GL_SLUMINANCE_ALPHA 0x8C44
+#define GL_SLUMINANCE8_ALPHA8 0x8C45
+#define GL_SLUMINANCE 0x8C46
+#define GL_SLUMINANCE8 0x8C47
+#define GL_COMPRESSED_SLUMINANCE 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B
+#endif
+
+#ifndef GL_VERSION_3_0
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_CLIP_DISTANCE0 0x3000
+#define GL_CLIP_DISTANCE1 0x3001
+#define GL_CLIP_DISTANCE2 0x3002
+#define GL_CLIP_DISTANCE3 0x3003
+#define GL_CLIP_DISTANCE4 0x3004
+#define GL_CLIP_DISTANCE5 0x3005
+#define GL_CLIP_DISTANCE6 0x3006
+#define GL_CLIP_DISTANCE7 0x3007
+#define GL_MAX_CLIP_DISTANCES 0x0D32
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_CONTEXT_FLAGS 0x821E
+#define GL_DEPTH_BUFFER 0x8223
+#define GL_STENCIL_BUFFER 0x8224
+#define GL_COMPRESSED_RED 0x8225
+#define GL_COMPRESSED_RG 0x8226
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
+#define GL_RGBA32F 0x8814
+#define GL_RGB32F 0x8815
+#define GL_RGBA16F 0x881A
+#define GL_RGB16F 0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_CLAMP_READ_COLOR 0x891C
+#define GL_FIXED_ONLY 0x891D
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_TEXTURE_1D_ARRAY 0x8C18
+#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B
+#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_RGB9_E5 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_TEXTURE_SHARED_SIZE 0x8C3F
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_PRIMITIVES_GENERATED 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_RGBA32UI 0x8D70
+#define GL_RGB32UI 0x8D71
+#define GL_RGBA16UI 0x8D76
+#define GL_RGB16UI 0x8D77
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGB8UI 0x8D7D
+#define GL_RGBA32I 0x8D82
+#define GL_RGB32I 0x8D83
+#define GL_RGBA16I 0x8D88
+#define GL_RGB16I 0x8D89
+#define GL_RGBA8I 0x8D8E
+#define GL_RGB8I 0x8D8F
+#define GL_RED_INTEGER 0x8D94
+#define GL_GREEN_INTEGER 0x8D95
+#define GL_BLUE_INTEGER 0x8D96
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_BGR_INTEGER 0x8D9A
+#define GL_BGRA_INTEGER 0x8D9B
+#define GL_SAMPLER_1D_ARRAY 0x8DC0
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_INT_SAMPLER_1D 0x8DC9
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_QUERY_WAIT 0x8E13
+#define GL_QUERY_NO_WAIT 0x8E14
+#define GL_QUERY_BY_REGION_WAIT 0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+/* Reuse tokens from ARB_depth_buffer_float */
+/* reuse GL_DEPTH_COMPONENT32F */
+/* reuse GL_DEPTH32F_STENCIL8 */
+/* reuse GL_FLOAT_32_UNSIGNED_INT_24_8_REV */
+/* Reuse tokens from ARB_framebuffer_object */
+/* reuse GL_INVALID_FRAMEBUFFER_OPERATION */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
+/* reuse GL_FRAMEBUFFER_DEFAULT */
+/* reuse GL_FRAMEBUFFER_UNDEFINED */
+/* reuse GL_DEPTH_STENCIL_ATTACHMENT */
+/* reuse GL_INDEX */
+/* reuse GL_MAX_RENDERBUFFER_SIZE */
+/* reuse GL_DEPTH_STENCIL */
+/* reuse GL_UNSIGNED_INT_24_8 */
+/* reuse GL_DEPTH24_STENCIL8 */
+/* reuse GL_TEXTURE_STENCIL_SIZE */
+/* reuse GL_TEXTURE_RED_TYPE */
+/* reuse GL_TEXTURE_GREEN_TYPE */
+/* reuse GL_TEXTURE_BLUE_TYPE */
+/* reuse GL_TEXTURE_ALPHA_TYPE */
+/* reuse GL_TEXTURE_DEPTH_TYPE */
+/* reuse GL_UNSIGNED_NORMALIZED */
+/* reuse GL_FRAMEBUFFER_BINDING */
+/* reuse GL_DRAW_FRAMEBUFFER_BINDING */
+/* reuse GL_RENDERBUFFER_BINDING */
+/* reuse GL_READ_FRAMEBUFFER */
+/* reuse GL_DRAW_FRAMEBUFFER */
+/* reuse GL_READ_FRAMEBUFFER_BINDING */
+/* reuse GL_RENDERBUFFER_SAMPLES */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+/* reuse GL_FRAMEBUFFER_COMPLETE */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */
+/* reuse GL_FRAMEBUFFER_UNSUPPORTED */
+/* reuse GL_MAX_COLOR_ATTACHMENTS */
+/* reuse GL_COLOR_ATTACHMENT0 */
+/* reuse GL_COLOR_ATTACHMENT1 */
+/* reuse GL_COLOR_ATTACHMENT2 */
+/* reuse GL_COLOR_ATTACHMENT3 */
+/* reuse GL_COLOR_ATTACHMENT4 */
+/* reuse GL_COLOR_ATTACHMENT5 */
+/* reuse GL_COLOR_ATTACHMENT6 */
+/* reuse GL_COLOR_ATTACHMENT7 */
+/* reuse GL_COLOR_ATTACHMENT8 */
+/* reuse GL_COLOR_ATTACHMENT9 */
+/* reuse GL_COLOR_ATTACHMENT10 */
+/* reuse GL_COLOR_ATTACHMENT11 */
+/* reuse GL_COLOR_ATTACHMENT12 */
+/* reuse GL_COLOR_ATTACHMENT13 */
+/* reuse GL_COLOR_ATTACHMENT14 */
+/* reuse GL_COLOR_ATTACHMENT15 */
+/* reuse GL_DEPTH_ATTACHMENT */
+/* reuse GL_STENCIL_ATTACHMENT */
+/* reuse GL_FRAMEBUFFER */
+/* reuse GL_RENDERBUFFER */
+/* reuse GL_RENDERBUFFER_WIDTH */
+/* reuse GL_RENDERBUFFER_HEIGHT */
+/* reuse GL_RENDERBUFFER_INTERNAL_FORMAT */
+/* reuse GL_STENCIL_INDEX1 */
+/* reuse GL_STENCIL_INDEX4 */
+/* reuse GL_STENCIL_INDEX8 */
+/* reuse GL_STENCIL_INDEX16 */
+/* reuse GL_RENDERBUFFER_RED_SIZE */
+/* reuse GL_RENDERBUFFER_GREEN_SIZE */
+/* reuse GL_RENDERBUFFER_BLUE_SIZE */
+/* reuse GL_RENDERBUFFER_ALPHA_SIZE */
+/* reuse GL_RENDERBUFFER_DEPTH_SIZE */
+/* reuse GL_RENDERBUFFER_STENCIL_SIZE */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
+/* reuse GL_MAX_SAMPLES */
+/* Reuse tokens from ARB_framebuffer_sRGB */
+/* reuse GL_FRAMEBUFFER_SRGB */
+/* Reuse tokens from ARB_half_float_vertex */
+/* reuse GL_HALF_FLOAT */
+/* Reuse tokens from ARB_map_buffer_range */
+/* reuse GL_MAP_READ_BIT */
+/* reuse GL_MAP_WRITE_BIT */
+/* reuse GL_MAP_INVALIDATE_RANGE_BIT */
+/* reuse GL_MAP_INVALIDATE_BUFFER_BIT */
+/* reuse GL_MAP_FLUSH_EXPLICIT_BIT */
+/* reuse GL_MAP_UNSYNCHRONIZED_BIT */
+/* Reuse tokens from ARB_texture_compression_rgtc */
+/* reuse GL_COMPRESSED_RED_RGTC1 */
+/* reuse GL_COMPRESSED_SIGNED_RED_RGTC1 */
+/* reuse GL_COMPRESSED_RG_RGTC2 */
+/* reuse GL_COMPRESSED_SIGNED_RG_RGTC2 */
+/* Reuse tokens from ARB_texture_rg */
+/* reuse GL_RG */
+/* reuse GL_RG_INTEGER */
+/* reuse GL_R8 */
+/* reuse GL_R16 */
+/* reuse GL_RG8 */
+/* reuse GL_RG16 */
+/* reuse GL_R16F */
+/* reuse GL_R32F */
+/* reuse GL_RG16F */
+/* reuse GL_RG32F */
+/* reuse GL_R8I */
+/* reuse GL_R8UI */
+/* reuse GL_R16I */
+/* reuse GL_R16UI */
+/* reuse GL_R32I */
+/* reuse GL_R32UI */
+/* reuse GL_RG8I */
+/* reuse GL_RG8UI */
+/* reuse GL_RG16I */
+/* reuse GL_RG16UI */
+/* reuse GL_RG32I */
+/* reuse GL_RG32UI */
+/* Reuse tokens from ARB_vertex_array_object */
+/* reuse GL_VERTEX_ARRAY_BINDING */
+#endif
+
+#ifndef GL_VERSION_3_0_DEPRECATED
+#define GL_CLAMP_VERTEX_COLOR 0x891A
+#define GL_CLAMP_FRAGMENT_COLOR 0x891B
+#define GL_ALPHA_INTEGER 0x8D97
+/* Reuse tokens from ARB_framebuffer_object */
+/* reuse GL_TEXTURE_LUMINANCE_TYPE */
+/* reuse GL_TEXTURE_INTENSITY_TYPE */
+#endif
+
+#ifndef GL_VERSION_3_1
+#define GL_SAMPLER_2D_RECT 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
+#define GL_SAMPLER_BUFFER 0x8DC2
+#define GL_INT_SAMPLER_2D_RECT 0x8DCD
+#define GL_INT_SAMPLER_BUFFER 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
+#define GL_TEXTURE_BUFFER 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
+#define GL_RED_SNORM 0x8F90
+#define GL_RG_SNORM 0x8F91
+#define GL_RGB_SNORM 0x8F92
+#define GL_RGBA_SNORM 0x8F93
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_R16_SNORM 0x8F98
+#define GL_RG16_SNORM 0x8F99
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_PRIMITIVE_RESTART 0x8F9D
+#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E
+/* Reuse tokens from ARB_copy_buffer */
+/* reuse GL_COPY_READ_BUFFER */
+/* reuse GL_COPY_WRITE_BUFFER */
+/* Reuse tokens from ARB_draw_instanced (none) */
+/* Reuse tokens from ARB_uniform_buffer_object */
+/* reuse GL_UNIFORM_BUFFER */
+/* reuse GL_UNIFORM_BUFFER_BINDING */
+/* reuse GL_UNIFORM_BUFFER_START */
+/* reuse GL_UNIFORM_BUFFER_SIZE */
+/* reuse GL_MAX_VERTEX_UNIFORM_BLOCKS */
+/* reuse GL_MAX_FRAGMENT_UNIFORM_BLOCKS */
+/* reuse GL_MAX_COMBINED_UNIFORM_BLOCKS */
+/* reuse GL_MAX_UNIFORM_BUFFER_BINDINGS */
+/* reuse GL_MAX_UNIFORM_BLOCK_SIZE */
+/* reuse GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS */
+/* reuse GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT */
+/* reuse GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */
+/* reuse GL_ACTIVE_UNIFORM_BLOCKS */
+/* reuse GL_UNIFORM_TYPE */
+/* reuse GL_UNIFORM_SIZE */
+/* reuse GL_UNIFORM_NAME_LENGTH */
+/* reuse GL_UNIFORM_BLOCK_INDEX */
+/* reuse GL_UNIFORM_OFFSET */
+/* reuse GL_UNIFORM_ARRAY_STRIDE */
+/* reuse GL_UNIFORM_MATRIX_STRIDE */
+/* reuse GL_UNIFORM_IS_ROW_MAJOR */
+/* reuse GL_UNIFORM_BLOCK_BINDING */
+/* reuse GL_UNIFORM_BLOCK_DATA_SIZE */
+/* reuse GL_UNIFORM_BLOCK_NAME_LENGTH */
+/* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS */
+/* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES */
+/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER */
+/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER */
+/* reuse GL_INVALID_INDEX */
+#endif
+
+#ifndef GL_VERSION_3_2
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_LINES_ADJACENCY 0x000A
+#define GL_LINE_STRIP_ADJACENCY 0x000B
+#define GL_TRIANGLES_ADJACENCY 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define GL_PROGRAM_POINT_SIZE 0x8642
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_GEOMETRY_SHADER 0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT 0x8916
+#define GL_GEOMETRY_INPUT_TYPE 0x8917
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+/* reuse GL_MAX_VARYING_COMPONENTS */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+/* Reuse tokens from ARB_depth_clamp */
+/* reuse GL_DEPTH_CLAMP */
+/* Reuse tokens from ARB_draw_elements_base_vertex (none) */
+/* Reuse tokens from ARB_fragment_coord_conventions (none) */
+/* Reuse tokens from ARB_provoking_vertex */
+/* reuse GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
+/* reuse GL_FIRST_VERTEX_CONVENTION */
+/* reuse GL_LAST_VERTEX_CONVENTION */
+/* reuse GL_PROVOKING_VERTEX */
+/* Reuse tokens from ARB_seamless_cube_map */
+/* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS */
+/* Reuse tokens from ARB_sync */
+/* reuse GL_MAX_SERVER_WAIT_TIMEOUT */
+/* reuse GL_OBJECT_TYPE */
+/* reuse GL_SYNC_CONDITION */
+/* reuse GL_SYNC_STATUS */
+/* reuse GL_SYNC_FLAGS */
+/* reuse GL_SYNC_FENCE */
+/* reuse GL_SYNC_GPU_COMMANDS_COMPLETE */
+/* reuse GL_UNSIGNALED */
+/* reuse GL_SIGNALED */
+/* reuse GL_ALREADY_SIGNALED */
+/* reuse GL_TIMEOUT_EXPIRED */
+/* reuse GL_CONDITION_SATISFIED */
+/* reuse GL_WAIT_FAILED */
+/* reuse GL_TIMEOUT_IGNORED */
+/* reuse GL_SYNC_FLUSH_COMMANDS_BIT */
+/* reuse GL_TIMEOUT_IGNORED */
+/* Reuse tokens from ARB_texture_multisample */
+/* reuse GL_SAMPLE_POSITION */
+/* reuse GL_SAMPLE_MASK */
+/* reuse GL_SAMPLE_MASK_VALUE */
+/* reuse GL_MAX_SAMPLE_MASK_WORDS */
+/* reuse GL_TEXTURE_2D_MULTISAMPLE */
+/* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE */
+/* reuse GL_TEXTURE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE */
+/* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_TEXTURE_SAMPLES */
+/* reuse GL_TEXTURE_FIXED_SAMPLE_LOCATIONS */
+/* reuse GL_SAMPLER_2D_MULTISAMPLE */
+/* reuse GL_INT_SAMPLER_2D_MULTISAMPLE */
+/* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE */
+/* reuse GL_SAMPLER_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_MAX_COLOR_TEXTURE_SAMPLES */
+/* reuse GL_MAX_DEPTH_TEXTURE_SAMPLES */
+/* reuse GL_MAX_INTEGER_SAMPLES */
+/* Don't need to reuse tokens from ARB_vertex_array_bgra since they're already in 1.2 core */
+#endif
+
+#ifndef GL_VERSION_3_3
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+/* Reuse tokens from ARB_blend_func_extended */
+/* reuse GL_SRC1_COLOR */
+/* reuse GL_ONE_MINUS_SRC1_COLOR */
+/* reuse GL_ONE_MINUS_SRC1_ALPHA */
+/* reuse GL_MAX_DUAL_SOURCE_DRAW_BUFFERS */
+/* Reuse tokens from ARB_explicit_attrib_location (none) */
+/* Reuse tokens from ARB_occlusion_query2 */
+/* reuse GL_ANY_SAMPLES_PASSED */
+/* Reuse tokens from ARB_sampler_objects */
+/* reuse GL_SAMPLER_BINDING */
+/* Reuse tokens from ARB_shader_bit_encoding (none) */
+/* Reuse tokens from ARB_texture_rgb10_a2ui */
+/* reuse GL_RGB10_A2UI */
+/* Reuse tokens from ARB_texture_swizzle */
+/* reuse GL_TEXTURE_SWIZZLE_R */
+/* reuse GL_TEXTURE_SWIZZLE_G */
+/* reuse GL_TEXTURE_SWIZZLE_B */
+/* reuse GL_TEXTURE_SWIZZLE_A */
+/* reuse GL_TEXTURE_SWIZZLE_RGBA */
+/* Reuse tokens from ARB_timer_query */
+/* reuse GL_TIME_ELAPSED */
+/* reuse GL_TIMESTAMP */
+/* Reuse tokens from ARB_vertex_type_2_10_10_10_rev */
+/* reuse GL_INT_2_10_10_10_REV */
+#endif
+
+#ifndef GL_VERSION_4_0
+#define GL_SAMPLE_SHADING 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+/* Reuse tokens from ARB_texture_query_lod (none) */
+/* Reuse tokens from ARB_draw_buffers_blend (none) */
+/* Reuse tokens from ARB_draw_indirect */
+/* reuse GL_DRAW_INDIRECT_BUFFER */
+/* reuse GL_DRAW_INDIRECT_BUFFER_BINDING */
+/* Reuse tokens from ARB_gpu_shader5 */
+/* reuse GL_GEOMETRY_SHADER_INVOCATIONS */
+/* reuse GL_MAX_GEOMETRY_SHADER_INVOCATIONS */
+/* reuse GL_MIN_FRAGMENT_INTERPOLATION_OFFSET */
+/* reuse GL_MAX_FRAGMENT_INTERPOLATION_OFFSET */
+/* reuse GL_FRAGMENT_INTERPOLATION_OFFSET_BITS */
+/* reuse GL_MAX_VERTEX_STREAMS */
+/* Reuse tokens from ARB_gpu_shader_fp64 */
+/* reuse GL_DOUBLE_VEC2 */
+/* reuse GL_DOUBLE_VEC3 */
+/* reuse GL_DOUBLE_VEC4 */
+/* reuse GL_DOUBLE_MAT2 */
+/* reuse GL_DOUBLE_MAT3 */
+/* reuse GL_DOUBLE_MAT4 */
+/* reuse GL_DOUBLE_MAT2x3 */
+/* reuse GL_DOUBLE_MAT2x4 */
+/* reuse GL_DOUBLE_MAT3x2 */
+/* reuse GL_DOUBLE_MAT3x4 */
+/* reuse GL_DOUBLE_MAT4x2 */
+/* reuse GL_DOUBLE_MAT4x3 */
+/* Reuse tokens from ARB_shader_subroutine */
+/* reuse GL_ACTIVE_SUBROUTINES */
+/* reuse GL_ACTIVE_SUBROUTINE_UNIFORMS */
+/* reuse GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS */
+/* reuse GL_ACTIVE_SUBROUTINE_MAX_LENGTH */
+/* reuse GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH */
+/* reuse GL_MAX_SUBROUTINES */
+/* reuse GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS */
+/* reuse GL_NUM_COMPATIBLE_SUBROUTINES */
+/* reuse GL_COMPATIBLE_SUBROUTINES */
+/* Reuse tokens from ARB_tessellation_shader */
+/* reuse GL_PATCHES */
+/* reuse GL_PATCH_VERTICES */
+/* reuse GL_PATCH_DEFAULT_INNER_LEVEL */
+/* reuse GL_PATCH_DEFAULT_OUTER_LEVEL */
+/* reuse GL_TESS_CONTROL_OUTPUT_VERTICES */
+/* reuse GL_TESS_GEN_MODE */
+/* reuse GL_TESS_GEN_SPACING */
+/* reuse GL_TESS_GEN_VERTEX_ORDER */
+/* reuse GL_TESS_GEN_POINT_MODE */
+/* reuse GL_ISOLINES */
+/* reuse GL_FRACTIONAL_ODD */
+/* reuse GL_FRACTIONAL_EVEN */
+/* reuse GL_MAX_PATCH_VERTICES */
+/* reuse GL_MAX_TESS_GEN_LEVEL */
+/* reuse GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS */
+/* reuse GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS */
+/* reuse GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS */
+/* reuse GL_MAX_TESS_PATCH_COMPONENTS */
+/* reuse GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS */
+/* reuse GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS */
+/* reuse GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS */
+/* reuse GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS */
+/* reuse GL_MAX_TESS_CONTROL_INPUT_COMPONENTS */
+/* reuse GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS */
+/* reuse GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS */
+/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER */
+/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER */
+/* reuse GL_TESS_EVALUATION_SHADER */
+/* reuse GL_TESS_CONTROL_SHADER */
+/* Reuse tokens from ARB_texture_buffer_object_rgb32 (none) */
+/* Reuse tokens from ARB_transform_feedback2 */
+/* reuse GL_TRANSFORM_FEEDBACK */
+/* reuse GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED */
+/* reuse GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE */
+/* reuse GL_TRANSFORM_FEEDBACK_BINDING */
+/* Reuse tokens from ARB_transform_feedback3 */
+/* reuse GL_MAX_TRANSFORM_FEEDBACK_BUFFERS */
+/* reuse GL_MAX_VERTEX_STREAMS */
+#endif
+
+#ifndef GL_VERSION_4_1
+/* Reuse tokens from ARB_ES2_compatibility */
+/* reuse GL_FIXED */
+/* reuse GL_IMPLEMENTATION_COLOR_READ_TYPE */
+/* reuse GL_IMPLEMENTATION_COLOR_READ_FORMAT */
+/* reuse GL_LOW_FLOAT */
+/* reuse GL_MEDIUM_FLOAT */
+/* reuse GL_HIGH_FLOAT */
+/* reuse GL_LOW_INT */
+/* reuse GL_MEDIUM_INT */
+/* reuse GL_HIGH_INT */
+/* reuse GL_SHADER_COMPILER */
+/* reuse GL_NUM_SHADER_BINARY_FORMATS */
+/* reuse GL_MAX_VERTEX_UNIFORM_VECTORS */
+/* reuse GL_MAX_VARYING_VECTORS */
+/* reuse GL_MAX_FRAGMENT_UNIFORM_VECTORS */
+/* Reuse tokens from ARB_get_program_binary */
+/* reuse GL_PROGRAM_BINARY_RETRIEVABLE_HINT */
+/* reuse GL_PROGRAM_BINARY_LENGTH */
+/* reuse GL_NUM_PROGRAM_BINARY_FORMATS */
+/* reuse GL_PROGRAM_BINARY_FORMATS */
+/* Reuse tokens from ARB_separate_shader_objects */
+/* reuse GL_VERTEX_SHADER_BIT */
+/* reuse GL_FRAGMENT_SHADER_BIT */
+/* reuse GL_GEOMETRY_SHADER_BIT */
+/* reuse GL_TESS_CONTROL_SHADER_BIT */
+/* reuse GL_TESS_EVALUATION_SHADER_BIT */
+/* reuse GL_ALL_SHADER_BITS */
+/* reuse GL_PROGRAM_SEPARABLE */
+/* reuse GL_ACTIVE_PROGRAM */
+/* reuse GL_PROGRAM_PIPELINE_BINDING */
+/* Reuse tokens from ARB_shader_precision (none) */
+/* Reuse tokens from ARB_vertex_attrib_64bit - all are in GL 3.0 and 4.0 already */
+/* Reuse tokens from ARB_viewport_array - some are in GL 1.1 and ARB_provoking_vertex already */
+/* reuse GL_MAX_VIEWPORTS */
+/* reuse GL_VIEWPORT_SUBPIXEL_BITS */
+/* reuse GL_VIEWPORT_BOUNDS_RANGE */
+/* reuse GL_LAYER_PROVOKING_VERTEX */
+/* reuse GL_VIEWPORT_INDEX_PROVOKING_VERTEX */
+/* reuse GL_UNDEFINED_VERTEX */
+#endif
+
+#ifndef GL_ARB_multitexture
+#define GL_TEXTURE0_ARB 0x84C0
+#define GL_TEXTURE1_ARB 0x84C1
+#define GL_TEXTURE2_ARB 0x84C2
+#define GL_TEXTURE3_ARB 0x84C3
+#define GL_TEXTURE4_ARB 0x84C4
+#define GL_TEXTURE5_ARB 0x84C5
+#define GL_TEXTURE6_ARB 0x84C6
+#define GL_TEXTURE7_ARB 0x84C7
+#define GL_TEXTURE8_ARB 0x84C8
+#define GL_TEXTURE9_ARB 0x84C9
+#define GL_TEXTURE10_ARB 0x84CA
+#define GL_TEXTURE11_ARB 0x84CB
+#define GL_TEXTURE12_ARB 0x84CC
+#define GL_TEXTURE13_ARB 0x84CD
+#define GL_TEXTURE14_ARB 0x84CE
+#define GL_TEXTURE15_ARB 0x84CF
+#define GL_TEXTURE16_ARB 0x84D0
+#define GL_TEXTURE17_ARB 0x84D1
+#define GL_TEXTURE18_ARB 0x84D2
+#define GL_TEXTURE19_ARB 0x84D3
+#define GL_TEXTURE20_ARB 0x84D4
+#define GL_TEXTURE21_ARB 0x84D5
+#define GL_TEXTURE22_ARB 0x84D6
+#define GL_TEXTURE23_ARB 0x84D7
+#define GL_TEXTURE24_ARB 0x84D8
+#define GL_TEXTURE25_ARB 0x84D9
+#define GL_TEXTURE26_ARB 0x84DA
+#define GL_TEXTURE27_ARB 0x84DB
+#define GL_TEXTURE28_ARB 0x84DC
+#define GL_TEXTURE29_ARB 0x84DD
+#define GL_TEXTURE30_ARB 0x84DE
+#define GL_TEXTURE31_ARB 0x84DF
+#define GL_ACTIVE_TEXTURE_ARB 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
+#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
+#endif
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6
+#endif
+
+#ifndef GL_ARB_multisample
+#define GL_MULTISAMPLE_ARB 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F
+#define GL_SAMPLE_COVERAGE_ARB 0x80A0
+#define GL_SAMPLE_BUFFERS_ARB 0x80A8
+#define GL_SAMPLES_ARB 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB
+#define GL_MULTISAMPLE_BIT_ARB 0x20000000
+#endif
+
+#ifndef GL_ARB_texture_env_add
+#endif
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_NORMAL_MAP_ARB 0x8511
+#define GL_REFLECTION_MAP_ARB 0x8512
+#define GL_TEXTURE_CUBE_MAP_ARB 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C
+#endif
+
+#ifndef GL_ARB_texture_compression
+#define GL_COMPRESSED_ALPHA_ARB 0x84E9
+#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
+#define GL_COMPRESSED_INTENSITY_ARB 0x84EC
+#define GL_COMPRESSED_RGB_ARB 0x84ED
+#define GL_COMPRESSED_RGBA_ARB 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0
+#define GL_TEXTURE_COMPRESSED_ARB 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
+#endif
+
+#ifndef GL_ARB_texture_border_clamp
+#define GL_CLAMP_TO_BORDER_ARB 0x812D
+#endif
+
+#ifndef GL_ARB_point_parameters
+#define GL_POINT_SIZE_MIN_ARB 0x8126
+#define GL_POINT_SIZE_MAX_ARB 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128
+#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129
+#endif
+
+#ifndef GL_ARB_vertex_blend
+#define GL_MAX_VERTEX_UNITS_ARB 0x86A4
+#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5
+#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6
+#define GL_VERTEX_BLEND_ARB 0x86A7
+#define GL_CURRENT_WEIGHT_ARB 0x86A8
+#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9
+#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA
+#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB
+#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC
+#define GL_WEIGHT_ARRAY_ARB 0x86AD
+#define GL_MODELVIEW0_ARB 0x1700
+#define GL_MODELVIEW1_ARB 0x850A
+#define GL_MODELVIEW2_ARB 0x8722
+#define GL_MODELVIEW3_ARB 0x8723
+#define GL_MODELVIEW4_ARB 0x8724
+#define GL_MODELVIEW5_ARB 0x8725
+#define GL_MODELVIEW6_ARB 0x8726
+#define GL_MODELVIEW7_ARB 0x8727
+#define GL_MODELVIEW8_ARB 0x8728
+#define GL_MODELVIEW9_ARB 0x8729
+#define GL_MODELVIEW10_ARB 0x872A
+#define GL_MODELVIEW11_ARB 0x872B
+#define GL_MODELVIEW12_ARB 0x872C
+#define GL_MODELVIEW13_ARB 0x872D
+#define GL_MODELVIEW14_ARB 0x872E
+#define GL_MODELVIEW15_ARB 0x872F
+#define GL_MODELVIEW16_ARB 0x8730
+#define GL_MODELVIEW17_ARB 0x8731
+#define GL_MODELVIEW18_ARB 0x8732
+#define GL_MODELVIEW19_ARB 0x8733
+#define GL_MODELVIEW20_ARB 0x8734
+#define GL_MODELVIEW21_ARB 0x8735
+#define GL_MODELVIEW22_ARB 0x8736
+#define GL_MODELVIEW23_ARB 0x8737
+#define GL_MODELVIEW24_ARB 0x8738
+#define GL_MODELVIEW25_ARB 0x8739
+#define GL_MODELVIEW26_ARB 0x873A
+#define GL_MODELVIEW27_ARB 0x873B
+#define GL_MODELVIEW28_ARB 0x873C
+#define GL_MODELVIEW29_ARB 0x873D
+#define GL_MODELVIEW30_ARB 0x873E
+#define GL_MODELVIEW31_ARB 0x873F
+#endif
+
+#ifndef GL_ARB_matrix_palette
+#define GL_MATRIX_PALETTE_ARB 0x8840
+#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841
+#define GL_MAX_PALETTE_MATRICES_ARB 0x8842
+#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843
+#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844
+#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845
+#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846
+#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847
+#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848
+#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849
+#endif
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_COMBINE_ARB 0x8570
+#define GL_COMBINE_RGB_ARB 0x8571
+#define GL_COMBINE_ALPHA_ARB 0x8572
+#define GL_SOURCE0_RGB_ARB 0x8580
+#define GL_SOURCE1_RGB_ARB 0x8581
+#define GL_SOURCE2_RGB_ARB 0x8582
+#define GL_SOURCE0_ALPHA_ARB 0x8588
+#define GL_SOURCE1_ALPHA_ARB 0x8589
+#define GL_SOURCE2_ALPHA_ARB 0x858A
+#define GL_OPERAND0_RGB_ARB 0x8590
+#define GL_OPERAND1_RGB_ARB 0x8591
+#define GL_OPERAND2_RGB_ARB 0x8592
+#define GL_OPERAND0_ALPHA_ARB 0x8598
+#define GL_OPERAND1_ALPHA_ARB 0x8599
+#define GL_OPERAND2_ALPHA_ARB 0x859A
+#define GL_RGB_SCALE_ARB 0x8573
+#define GL_ADD_SIGNED_ARB 0x8574
+#define GL_INTERPOLATE_ARB 0x8575
+#define GL_SUBTRACT_ARB 0x84E7
+#define GL_CONSTANT_ARB 0x8576
+#define GL_PRIMARY_COLOR_ARB 0x8577
+#define GL_PREVIOUS_ARB 0x8578
+#endif
+
+#ifndef GL_ARB_texture_env_crossbar
+#endif
+
+#ifndef GL_ARB_texture_env_dot3
+#define GL_DOT3_RGB_ARB 0x86AE
+#define GL_DOT3_RGBA_ARB 0x86AF
+#endif
+
+#ifndef GL_ARB_texture_mirrored_repeat
+#define GL_MIRRORED_REPEAT_ARB 0x8370
+#endif
+
+#ifndef GL_ARB_depth_texture
+#define GL_DEPTH_COMPONENT16_ARB 0x81A5
+#define GL_DEPTH_COMPONENT24_ARB 0x81A6
+#define GL_DEPTH_COMPONENT32_ARB 0x81A7
+#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A
+#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B
+#endif
+
+#ifndef GL_ARB_shadow
+#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C
+#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D
+#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E
+#endif
+
+#ifndef GL_ARB_shadow_ambient
+#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF
+#endif
+
+#ifndef GL_ARB_window_pos
+#endif
+
+#ifndef GL_ARB_vertex_program
+#define GL_COLOR_SUM_ARB 0x8458
+#define GL_VERTEX_PROGRAM_ARB 0x8620
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625
+#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626
+#define GL_PROGRAM_LENGTH_ARB 0x8627
+#define GL_PROGRAM_STRING_ARB 0x8628
+#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E
+#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F
+#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640
+#define GL_CURRENT_MATRIX_ARB 0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645
+#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B
+#define GL_PROGRAM_BINDING_ARB 0x8677
+#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A
+#define GL_PROGRAM_ERROR_STRING_ARB 0x8874
+#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875
+#define GL_PROGRAM_FORMAT_ARB 0x8876
+#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0
+#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1
+#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2
+#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3
+#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4
+#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5
+#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6
+#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7
+#define GL_PROGRAM_PARAMETERS_ARB 0x88A8
+#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9
+#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA
+#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB
+#define GL_PROGRAM_ATTRIBS_ARB 0x88AC
+#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD
+#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE
+#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF
+#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0
+#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1
+#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2
+#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3
+#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4
+#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5
+#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6
+#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7
+#define GL_MATRIX0_ARB 0x88C0
+#define GL_MATRIX1_ARB 0x88C1
+#define GL_MATRIX2_ARB 0x88C2
+#define GL_MATRIX3_ARB 0x88C3
+#define GL_MATRIX4_ARB 0x88C4
+#define GL_MATRIX5_ARB 0x88C5
+#define GL_MATRIX6_ARB 0x88C6
+#define GL_MATRIX7_ARB 0x88C7
+#define GL_MATRIX8_ARB 0x88C8
+#define GL_MATRIX9_ARB 0x88C9
+#define GL_MATRIX10_ARB 0x88CA
+#define GL_MATRIX11_ARB 0x88CB
+#define GL_MATRIX12_ARB 0x88CC
+#define GL_MATRIX13_ARB 0x88CD
+#define GL_MATRIX14_ARB 0x88CE
+#define GL_MATRIX15_ARB 0x88CF
+#define GL_MATRIX16_ARB 0x88D0
+#define GL_MATRIX17_ARB 0x88D1
+#define GL_MATRIX18_ARB 0x88D2
+#define GL_MATRIX19_ARB 0x88D3
+#define GL_MATRIX20_ARB 0x88D4
+#define GL_MATRIX21_ARB 0x88D5
+#define GL_MATRIX22_ARB 0x88D6
+#define GL_MATRIX23_ARB 0x88D7
+#define GL_MATRIX24_ARB 0x88D8
+#define GL_MATRIX25_ARB 0x88D9
+#define GL_MATRIX26_ARB 0x88DA
+#define GL_MATRIX27_ARB 0x88DB
+#define GL_MATRIX28_ARB 0x88DC
+#define GL_MATRIX29_ARB 0x88DD
+#define GL_MATRIX30_ARB 0x88DE
+#define GL_MATRIX31_ARB 0x88DF
+#endif
+
+#ifndef GL_ARB_fragment_program
+#define GL_FRAGMENT_PROGRAM_ARB 0x8804
+#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805
+#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806
+#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807
+#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808
+#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809
+#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A
+#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B
+#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C
+#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D
+#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E
+#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F
+#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810
+#define GL_MAX_TEXTURE_COORDS_ARB 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+#define GL_BUFFER_SIZE_ARB 0x8764
+#define GL_BUFFER_USAGE_ARB 0x8765
+#define GL_ARRAY_BUFFER_ARB 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
+#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
+#define GL_READ_ONLY_ARB 0x88B8
+#define GL_WRITE_ONLY_ARB 0x88B9
+#define GL_READ_WRITE_ARB 0x88BA
+#define GL_BUFFER_ACCESS_ARB 0x88BB
+#define GL_BUFFER_MAPPED_ARB 0x88BC
+#define GL_BUFFER_MAP_POINTER_ARB 0x88BD
+#define GL_STREAM_DRAW_ARB 0x88E0
+#define GL_STREAM_READ_ARB 0x88E1
+#define GL_STREAM_COPY_ARB 0x88E2
+#define GL_STATIC_DRAW_ARB 0x88E4
+#define GL_STATIC_READ_ARB 0x88E5
+#define GL_STATIC_COPY_ARB 0x88E6
+#define GL_DYNAMIC_DRAW_ARB 0x88E8
+#define GL_DYNAMIC_READ_ARB 0x88E9
+#define GL_DYNAMIC_COPY_ARB 0x88EA
+#endif
+
+#ifndef GL_ARB_occlusion_query
+#define GL_QUERY_COUNTER_BITS_ARB 0x8864
+#define GL_CURRENT_QUERY_ARB 0x8865
+#define GL_QUERY_RESULT_ARB 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
+#define GL_SAMPLES_PASSED_ARB 0x8914
+#endif
+
+#ifndef GL_ARB_shader_objects
+#define GL_PROGRAM_OBJECT_ARB 0x8B40
+#define GL_SHADER_OBJECT_ARB 0x8B48
+#define GL_OBJECT_TYPE_ARB 0x8B4E
+#define GL_OBJECT_SUBTYPE_ARB 0x8B4F
+#define GL_FLOAT_VEC2_ARB 0x8B50
+#define GL_FLOAT_VEC3_ARB 0x8B51
+#define GL_FLOAT_VEC4_ARB 0x8B52
+#define GL_INT_VEC2_ARB 0x8B53
+#define GL_INT_VEC3_ARB 0x8B54
+#define GL_INT_VEC4_ARB 0x8B55
+#define GL_BOOL_ARB 0x8B56
+#define GL_BOOL_VEC2_ARB 0x8B57
+#define GL_BOOL_VEC3_ARB 0x8B58
+#define GL_BOOL_VEC4_ARB 0x8B59
+#define GL_FLOAT_MAT2_ARB 0x8B5A
+#define GL_FLOAT_MAT3_ARB 0x8B5B
+#define GL_FLOAT_MAT4_ARB 0x8B5C
+#define GL_SAMPLER_1D_ARB 0x8B5D
+#define GL_SAMPLER_2D_ARB 0x8B5E
+#define GL_SAMPLER_3D_ARB 0x8B5F
+#define GL_SAMPLER_CUBE_ARB 0x8B60
+#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61
+#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62
+#define GL_SAMPLER_2D_RECT_ARB 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64
+#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80
+#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81
+#define GL_OBJECT_LINK_STATUS_ARB 0x8B82
+#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83
+#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84
+#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85
+#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86
+#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87
+#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88
+#endif
+
+#ifndef GL_ARB_vertex_shader
+#define GL_VERTEX_SHADER_ARB 0x8B31
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A
+#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D
+#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89
+#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A
+#endif
+
+#ifndef GL_ARB_fragment_shader
+#define GL_FRAGMENT_SHADER_ARB 0x8B30
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B
+#endif
+
+#ifndef GL_ARB_shading_language_100
+#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
+#endif
+
+#ifndef GL_ARB_texture_non_power_of_two
+#endif
+
+#ifndef GL_ARB_point_sprite
+#define GL_POINT_SPRITE_ARB 0x8861
+#define GL_COORD_REPLACE_ARB 0x8862
+#endif
+
+#ifndef GL_ARB_fragment_program_shadow
+#endif
+
+#ifndef GL_ARB_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_ARB 0x8824
+#define GL_DRAW_BUFFER0_ARB 0x8825
+#define GL_DRAW_BUFFER1_ARB 0x8826
+#define GL_DRAW_BUFFER2_ARB 0x8827
+#define GL_DRAW_BUFFER3_ARB 0x8828
+#define GL_DRAW_BUFFER4_ARB 0x8829
+#define GL_DRAW_BUFFER5_ARB 0x882A
+#define GL_DRAW_BUFFER6_ARB 0x882B
+#define GL_DRAW_BUFFER7_ARB 0x882C
+#define GL_DRAW_BUFFER8_ARB 0x882D
+#define GL_DRAW_BUFFER9_ARB 0x882E
+#define GL_DRAW_BUFFER10_ARB 0x882F
+#define GL_DRAW_BUFFER11_ARB 0x8830
+#define GL_DRAW_BUFFER12_ARB 0x8831
+#define GL_DRAW_BUFFER13_ARB 0x8832
+#define GL_DRAW_BUFFER14_ARB 0x8833
+#define GL_DRAW_BUFFER15_ARB 0x8834
+#endif
+
+#ifndef GL_ARB_texture_rectangle
+#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
+#endif
+
+#ifndef GL_ARB_color_buffer_float
+#define GL_RGBA_FLOAT_MODE_ARB 0x8820
+#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A
+#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B
+#define GL_CLAMP_READ_COLOR_ARB 0x891C
+#define GL_FIXED_ONLY_ARB 0x891D
+#endif
+
+#ifndef GL_ARB_half_float_pixel
+#define GL_HALF_FLOAT_ARB 0x140B
+#endif
+
+#ifndef GL_ARB_texture_float
+#define GL_TEXTURE_RED_TYPE_ARB 0x8C10
+#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11
+#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12
+#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13
+#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14
+#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15
+#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16
+#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17
+#define GL_RGBA32F_ARB 0x8814
+#define GL_RGB32F_ARB 0x8815
+#define GL_ALPHA32F_ARB 0x8816
+#define GL_INTENSITY32F_ARB 0x8817
+#define GL_LUMINANCE32F_ARB 0x8818
+#define GL_LUMINANCE_ALPHA32F_ARB 0x8819
+#define GL_RGBA16F_ARB 0x881A
+#define GL_RGB16F_ARB 0x881B
+#define GL_ALPHA16F_ARB 0x881C
+#define GL_INTENSITY16F_ARB 0x881D
+#define GL_LUMINANCE16F_ARB 0x881E
+#define GL_LUMINANCE_ALPHA16F_ARB 0x881F
+#endif
+
+#ifndef GL_ARB_pixel_buffer_object
+#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
+#endif
+
+#ifndef GL_ARB_depth_buffer_float
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#endif
+
+#ifndef GL_ARB_draw_instanced
+#endif
+
+#ifndef GL_ARB_framebuffer_object
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_TEXTURE_STENCIL_SIZE 0x88F1
+#define GL_TEXTURE_RED_TYPE 0x8C10
+#define GL_TEXTURE_GREEN_TYPE 0x8C11
+#define GL_TEXTURE_BLUE_TYPE 0x8C12
+#define GL_TEXTURE_ALPHA_TYPE 0x8C13
+#define GL_TEXTURE_DEPTH_TYPE 0x8C16
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_STENCIL_INDEX1 0x8D46
+#define GL_STENCIL_INDEX4 0x8D47
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_STENCIL_INDEX16 0x8D49
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_MAX_SAMPLES 0x8D57
+#endif
+
+#ifndef GL_ARB_framebuffer_object_DEPRECATED
+#define GL_INDEX 0x8222
+#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14
+#define GL_TEXTURE_INTENSITY_TYPE 0x8C15
+#endif
+
+#ifndef GL_ARB_framebuffer_sRGB
+#define GL_FRAMEBUFFER_SRGB 0x8DB9
+#endif
+
+#ifndef GL_ARB_geometry_shader4
+#define GL_LINES_ADJACENCY_ARB 0x000A
+#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B
+#define GL_TRIANGLES_ADJACENCY_ARB 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D
+#define GL_PROGRAM_POINT_SIZE_ARB 0x8642
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9
+#define GL_GEOMETRY_SHADER_ARB 0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA
+#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1
+/* reuse GL_MAX_VARYING_COMPONENTS */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+#endif
+
+#ifndef GL_ARB_half_float_vertex
+#define GL_HALF_FLOAT 0x140B
+#endif
+
+#ifndef GL_ARB_instanced_arrays
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE
+#endif
+
+#ifndef GL_ARB_map_buffer_range
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#endif
+
+#ifndef GL_ARB_texture_buffer_object
+#define GL_TEXTURE_BUFFER_ARB 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E
+#endif
+
+#ifndef GL_ARB_texture_compression_rgtc
+#define GL_COMPRESSED_RED_RGTC1 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
+#define GL_COMPRESSED_RG_RGTC2 0x8DBD
+#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
+#endif
+
+#ifndef GL_ARB_texture_rg
+#define GL_RG 0x8227
+#define GL_RG_INTEGER 0x8228
+#define GL_R8 0x8229
+#define GL_R16 0x822A
+#define GL_RG8 0x822B
+#define GL_RG16 0x822C
+#define GL_R16F 0x822D
+#define GL_R32F 0x822E
+#define GL_RG16F 0x822F
+#define GL_RG32F 0x8230
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#endif
+
+#ifndef GL_ARB_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#endif
+
+#ifndef GL_ARB_uniform_buffer_object
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+#endif
+
+#ifndef GL_ARB_compatibility
+/* ARB_compatibility just defines tokens from core 3.0 */
+#endif
+
+#ifndef GL_ARB_copy_buffer
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#endif
+
+#ifndef GL_ARB_shader_texture_lod
+#endif
+
+#ifndef GL_ARB_depth_clamp
+#define GL_DEPTH_CLAMP 0x864F
+#endif
+
+#ifndef GL_ARB_draw_elements_base_vertex
+#endif
+
+#ifndef GL_ARB_fragment_coord_conventions
+#endif
+
+#ifndef GL_ARB_provoking_vertex
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_PROVOKING_VERTEX 0x8E4F
+#endif
+
+#ifndef GL_ARB_seamless_cube_map
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+#endif
+
+#ifndef GL_ARB_sync
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#endif
+
+#ifndef GL_ARB_texture_multisample
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+#endif
+
+#ifndef GL_ARB_vertex_array_bgra
+/* reuse GL_BGRA */
+#endif
+
+#ifndef GL_ARB_draw_buffers_blend
+#endif
+
+#ifndef GL_ARB_sample_shading
+#define GL_SAMPLE_SHADING_ARB 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37
+#endif
+
+#ifndef GL_ARB_texture_cube_map_array
+#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F
+#endif
+
+#ifndef GL_ARB_texture_gather
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F
+#endif
+
+#ifndef GL_ARB_texture_query_lod
+#endif
+
+#ifndef GL_ARB_shading_language_include
+#define GL_SHADER_INCLUDE_ARB 0x8DAE
+#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9
+#define GL_NAMED_STRING_TYPE_ARB 0x8DEA
+#endif
+
+#ifndef GL_ARB_texture_compression_bptc
+#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
+#endif
+
+#ifndef GL_ARB_blend_func_extended
+#define GL_SRC1_COLOR 0x88F9
+/* reuse GL_SRC1_ALPHA */
+#define GL_ONE_MINUS_SRC1_COLOR 0x88FA
+#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC
+#endif
+
+#ifndef GL_ARB_explicit_attrib_location
+#endif
+
+#ifndef GL_ARB_occlusion_query2
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#endif
+
+#ifndef GL_ARB_sampler_objects
+#define GL_SAMPLER_BINDING 0x8919
+#endif
+
+#ifndef GL_ARB_shader_bit_encoding
+#endif
+
+#ifndef GL_ARB_texture_rgb10_a2ui
+#define GL_RGB10_A2UI 0x906F
+#endif
+
+#ifndef GL_ARB_texture_swizzle
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+#endif
+
+#ifndef GL_ARB_timer_query
+#define GL_TIME_ELAPSED 0x88BF
+#define GL_TIMESTAMP 0x8E28
+#endif
+
+#ifndef GL_ARB_vertex_type_2_10_10_10_rev
+/* reuse GL_UNSIGNED_INT_2_10_10_10_REV */
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#endif
+
+#ifndef GL_ARB_draw_indirect
+#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
+#endif
+
+#ifndef GL_ARB_gpu_shader5
+#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D
+/* reuse GL_MAX_VERTEX_STREAMS */
+#endif
+
+#ifndef GL_ARB_gpu_shader_fp64
+/* reuse GL_DOUBLE */
+#define GL_DOUBLE_VEC2 0x8FFC
+#define GL_DOUBLE_VEC3 0x8FFD
+#define GL_DOUBLE_VEC4 0x8FFE
+#define GL_DOUBLE_MAT2 0x8F46
+#define GL_DOUBLE_MAT3 0x8F47
+#define GL_DOUBLE_MAT4 0x8F48
+#define GL_DOUBLE_MAT2x3 0x8F49
+#define GL_DOUBLE_MAT2x4 0x8F4A
+#define GL_DOUBLE_MAT3x2 0x8F4B
+#define GL_DOUBLE_MAT3x4 0x8F4C
+#define GL_DOUBLE_MAT4x2 0x8F4D
+#define GL_DOUBLE_MAT4x3 0x8F4E
+#endif
+
+#ifndef GL_ARB_shader_subroutine
+#define GL_ACTIVE_SUBROUTINES 0x8DE5
+#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47
+#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49
+#define GL_MAX_SUBROUTINES 0x8DE7
+#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8
+#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A
+#define GL_COMPATIBLE_SUBROUTINES 0x8E4B
+/* reuse GL_UNIFORM_SIZE */
+/* reuse GL_UNIFORM_NAME_LENGTH */
+#endif
+
+#ifndef GL_ARB_tessellation_shader
+#define GL_PATCHES 0x000E
+#define GL_PATCH_VERTICES 0x8E72
+#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73
+#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74
+#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75
+#define GL_TESS_GEN_MODE 0x8E76
+#define GL_TESS_GEN_SPACING 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER 0x8E78
+#define GL_TESS_GEN_POINT_MODE 0x8E79
+/* reuse GL_TRIANGLES */
+/* reuse GL_QUADS */
+#define GL_ISOLINES 0x8E7A
+/* reuse GL_EQUAL */
+#define GL_FRACTIONAL_ODD 0x8E7B
+#define GL_FRACTIONAL_EVEN 0x8E7C
+/* reuse GL_CCW */
+/* reuse GL_CW */
+#define GL_MAX_PATCH_VERTICES 0x8E7D
+#define GL_MAX_TESS_GEN_LEVEL 0x8E7E
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83
+#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1
+#define GL_TESS_EVALUATION_SHADER 0x8E87
+#define GL_TESS_CONTROL_SHADER 0x8E88
+#endif
+
+#ifndef GL_ARB_texture_buffer_object_rgb32
+/* reuse GL_RGB32F */
+/* reuse GL_RGB32UI */
+/* reuse GL_RGB32I */
+#endif
+
+#ifndef GL_ARB_transform_feedback2
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#endif
+
+#ifndef GL_ARB_transform_feedback3
+#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
+#define GL_MAX_VERTEX_STREAMS 0x8E71
+#endif
+
+#ifndef GL_ARB_ES2_compatibility
+#define GL_FIXED 0x140C
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_LOW_INT 0x8DF3
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_HIGH_INT 0x8DF5
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#endif
+
+#ifndef GL_ARB_get_program_binary
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#endif
+
+#ifndef GL_ARB_separate_shader_objects
+#define GL_VERTEX_SHADER_BIT 0x00000001
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#define GL_GEOMETRY_SHADER_BIT 0x00000004
+#define GL_TESS_CONTROL_SHADER_BIT 0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010
+#define GL_ALL_SHADER_BITS 0xFFFFFFFF
+#define GL_PROGRAM_SEPARABLE 0x8258
+#define GL_ACTIVE_PROGRAM 0x8259
+#define GL_PROGRAM_PIPELINE_BINDING 0x825A
+#endif
+
+#ifndef GL_ARB_shader_precision
+#endif
+
+#ifndef GL_ARB_vertex_attrib_64bit
+/* reuse GL_RGB32I */
+/* reuse GL_DOUBLE_VEC2 */
+/* reuse GL_DOUBLE_VEC3 */
+/* reuse GL_DOUBLE_VEC4 */
+/* reuse GL_DOUBLE_MAT2 */
+/* reuse GL_DOUBLE_MAT3 */
+/* reuse GL_DOUBLE_MAT4 */
+/* reuse GL_DOUBLE_MAT2x3 */
+/* reuse GL_DOUBLE_MAT2x4 */
+/* reuse GL_DOUBLE_MAT3x2 */
+/* reuse GL_DOUBLE_MAT3x4 */
+/* reuse GL_DOUBLE_MAT4x2 */
+/* reuse GL_DOUBLE_MAT4x3 */
+#endif
+
+#ifndef GL_ARB_viewport_array
+/* reuse GL_SCISSOR_BOX */
+/* reuse GL_VIEWPORT */
+/* reuse GL_DEPTH_RANGE */
+/* reuse GL_SCISSOR_TEST */
+#define GL_MAX_VIEWPORTS 0x825B
+#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C
+#define GL_VIEWPORT_BOUNDS_RANGE 0x825D
+#define GL_LAYER_PROVOKING_VERTEX 0x825E
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F
+#define GL_UNDEFINED_VERTEX 0x8260
+/* reuse GL_FIRST_VERTEX_CONVENTION */
+/* reuse GL_LAST_VERTEX_CONVENTION */
+/* reuse GL_PROVOKING_VERTEX */
+#endif
+
+#ifndef GL_ARB_cl_event
+#define GL_SYNC_CL_EVENT_ARB 0x8240
+#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241
+#endif
+
+#ifndef GL_ARB_debug_output
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245
+#define GL_DEBUG_SOURCE_API_ARB 0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249
+#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A
+#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B
+#define GL_DEBUG_TYPE_ERROR_ARB 0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250
+#define GL_DEBUG_TYPE_OTHER_ARB 0x8251
+#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145
+#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147
+#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148
+#endif
+
+#ifndef GL_ARB_robustness
+/* reuse GL_NO_ERROR */
+#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
+#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
+#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
+#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define GL_NO_RESET_NOTIFICATION_ARB 0x8261
+#endif
+
+#ifndef GL_ARB_shader_stencil_export
+#endif
+
+#ifndef GL_EXT_abgr
+#define GL_ABGR_EXT 0x8000
+#endif
+
+#ifndef GL_EXT_blend_color
+#define GL_CONSTANT_COLOR_EXT 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002
+#define GL_CONSTANT_ALPHA_EXT 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004
+#define GL_BLEND_COLOR_EXT 0x8005
+#endif
+
+#ifndef GL_EXT_polygon_offset
+#define GL_POLYGON_OFFSET_EXT 0x8037
+#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038
+#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039
+#endif
+
+#ifndef GL_EXT_texture
+#define GL_ALPHA4_EXT 0x803B
+#define GL_ALPHA8_EXT 0x803C
+#define GL_ALPHA12_EXT 0x803D
+#define GL_ALPHA16_EXT 0x803E
+#define GL_LUMINANCE4_EXT 0x803F
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE12_EXT 0x8041
+#define GL_LUMINANCE16_EXT 0x8042
+#define GL_LUMINANCE4_ALPHA4_EXT 0x8043
+#define GL_LUMINANCE6_ALPHA2_EXT 0x8044
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_LUMINANCE12_ALPHA4_EXT 0x8046
+#define GL_LUMINANCE12_ALPHA12_EXT 0x8047
+#define GL_LUMINANCE16_ALPHA16_EXT 0x8048
+#define GL_INTENSITY_EXT 0x8049
+#define GL_INTENSITY4_EXT 0x804A
+#define GL_INTENSITY8_EXT 0x804B
+#define GL_INTENSITY12_EXT 0x804C
+#define GL_INTENSITY16_EXT 0x804D
+#define GL_RGB2_EXT 0x804E
+#define GL_RGB4_EXT 0x804F
+#define GL_RGB5_EXT 0x8050
+#define GL_RGB8_EXT 0x8051
+#define GL_RGB10_EXT 0x8052
+#define GL_RGB12_EXT 0x8053
+#define GL_RGB16_EXT 0x8054
+#define GL_RGBA2_EXT 0x8055
+#define GL_RGBA4_EXT 0x8056
+#define GL_RGB5_A1_EXT 0x8057
+#define GL_RGBA8_EXT 0x8058
+#define GL_RGB10_A2_EXT 0x8059
+#define GL_RGBA12_EXT 0x805A
+#define GL_RGBA16_EXT 0x805B
+#define GL_TEXTURE_RED_SIZE_EXT 0x805C
+#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D
+#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E
+#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F
+#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060
+#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061
+#define GL_REPLACE_EXT 0x8062
+#define GL_PROXY_TEXTURE_1D_EXT 0x8063
+#define GL_PROXY_TEXTURE_2D_EXT 0x8064
+#define GL_TEXTURE_TOO_LARGE_EXT 0x8065
+#endif
+
+#ifndef GL_EXT_texture3D
+#define GL_PACK_SKIP_IMAGES_EXT 0x806B
+#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C
+#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E
+#define GL_TEXTURE_3D_EXT 0x806F
+#define GL_PROXY_TEXTURE_3D_EXT 0x8070
+#define GL_TEXTURE_DEPTH_EXT 0x8071
+#define GL_TEXTURE_WRAP_R_EXT 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073
+#endif
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_FILTER4_SGIS 0x8146
+#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147
+#endif
+
+#ifndef GL_EXT_subtexture
+#endif
+
+#ifndef GL_EXT_copy_texture
+#endif
+
+#ifndef GL_EXT_histogram
+#define GL_HISTOGRAM_EXT 0x8024
+#define GL_PROXY_HISTOGRAM_EXT 0x8025
+#define GL_HISTOGRAM_WIDTH_EXT 0x8026
+#define GL_HISTOGRAM_FORMAT_EXT 0x8027
+#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C
+#define GL_HISTOGRAM_SINK_EXT 0x802D
+#define GL_MINMAX_EXT 0x802E
+#define GL_MINMAX_FORMAT_EXT 0x802F
+#define GL_MINMAX_SINK_EXT 0x8030
+#define GL_TABLE_TOO_LARGE_EXT 0x8031
+#endif
+
+#ifndef GL_EXT_convolution
+#define GL_CONVOLUTION_1D_EXT 0x8010
+#define GL_CONVOLUTION_2D_EXT 0x8011
+#define GL_SEPARABLE_2D_EXT 0x8012
+#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015
+#define GL_REDUCE_EXT 0x8016
+#define GL_CONVOLUTION_FORMAT_EXT 0x8017
+#define GL_CONVOLUTION_WIDTH_EXT 0x8018
+#define GL_CONVOLUTION_HEIGHT_EXT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023
+#endif
+
+#ifndef GL_SGI_color_matrix
+#define GL_COLOR_MATRIX_SGI 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB
+#endif
+
+#ifndef GL_SGI_color_table
+#define GL_COLOR_TABLE_SGI 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2
+#define GL_PROXY_COLOR_TABLE_SGI 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5
+#define GL_COLOR_TABLE_SCALE_SGI 0x80D6
+#define GL_COLOR_TABLE_BIAS_SGI 0x80D7
+#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8
+#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF
+#endif
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_PIXEL_TEXTURE_SGIS 0x8353
+#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354
+#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355
+#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356
+#endif
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_PIXEL_TEX_GEN_SGIX 0x8139
+#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B
+#endif
+
+#ifndef GL_SGIS_texture4D
+#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130
+#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131
+#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132
+#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133
+#define GL_TEXTURE_4D_SGIS 0x8134
+#define GL_PROXY_TEXTURE_4D_SGIS 0x8135
+#define GL_TEXTURE_4DSIZE_SGIS 0x8136
+#define GL_TEXTURE_WRAP_Q_SGIS 0x8137
+#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138
+#define GL_TEXTURE_4D_BINDING_SGIS 0x814F
+#endif
+
+#ifndef GL_SGI_texture_color_table
+#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC
+#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD
+#endif
+
+#ifndef GL_EXT_cmyka
+#define GL_CMYK_EXT 0x800C
+#define GL_CMYKA_EXT 0x800D
+#define GL_PACK_CMYK_HINT_EXT 0x800E
+#define GL_UNPACK_CMYK_HINT_EXT 0x800F
+#endif
+
+#ifndef GL_EXT_texture_object
+#define GL_TEXTURE_PRIORITY_EXT 0x8066
+#define GL_TEXTURE_RESIDENT_EXT 0x8067
+#define GL_TEXTURE_1D_BINDING_EXT 0x8068
+#define GL_TEXTURE_2D_BINDING_EXT 0x8069
+#define GL_TEXTURE_3D_BINDING_EXT 0x806A
+#endif
+
+#ifndef GL_SGIS_detail_texture
+#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095
+#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096
+#define GL_LINEAR_DETAIL_SGIS 0x8097
+#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098
+#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099
+#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A
+#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B
+#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C
+#endif
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_LINEAR_SHARPEN_SGIS 0x80AD
+#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE
+#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF
+#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0
+#endif
+
+#ifndef GL_EXT_packed_pixels
+#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036
+#endif
+
+#ifndef GL_SGIS_texture_lod
+#define GL_TEXTURE_MIN_LOD_SGIS 0x813A
+#define GL_TEXTURE_MAX_LOD_SGIS 0x813B
+#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C
+#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D
+#endif
+
+#ifndef GL_SGIS_multisample
+#define GL_MULTISAMPLE_SGIS 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F
+#define GL_SAMPLE_MASK_SGIS 0x80A0
+#define GL_1PASS_SGIS 0x80A1
+#define GL_2PASS_0_SGIS 0x80A2
+#define GL_2PASS_1_SGIS 0x80A3
+#define GL_4PASS_0_SGIS 0x80A4
+#define GL_4PASS_1_SGIS 0x80A5
+#define GL_4PASS_2_SGIS 0x80A6
+#define GL_4PASS_3_SGIS 0x80A7
+#define GL_SAMPLE_BUFFERS_SGIS 0x80A8
+#define GL_SAMPLES_SGIS 0x80A9
+#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA
+#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB
+#define GL_SAMPLE_PATTERN_SGIS 0x80AC
+#endif
+
+#ifndef GL_EXT_rescale_normal
+#define GL_RESCALE_NORMAL_EXT 0x803A
+#endif
+
+#ifndef GL_EXT_vertex_array
+#define GL_VERTEX_ARRAY_EXT 0x8074
+#define GL_NORMAL_ARRAY_EXT 0x8075
+#define GL_COLOR_ARRAY_EXT 0x8076
+#define GL_INDEX_ARRAY_EXT 0x8077
+#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078
+#define GL_EDGE_FLAG_ARRAY_EXT 0x8079
+#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A
+#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B
+#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C
+#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D
+#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E
+#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F
+#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080
+#define GL_COLOR_ARRAY_SIZE_EXT 0x8081
+#define GL_COLOR_ARRAY_TYPE_EXT 0x8082
+#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083
+#define GL_COLOR_ARRAY_COUNT_EXT 0x8084
+#define GL_INDEX_ARRAY_TYPE_EXT 0x8085
+#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086
+#define GL_INDEX_ARRAY_COUNT_EXT 0x8087
+#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A
+#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B
+#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C
+#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D
+#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E
+#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F
+#define GL_COLOR_ARRAY_POINTER_EXT 0x8090
+#define GL_INDEX_ARRAY_POINTER_EXT 0x8091
+#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092
+#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093
+#endif
+
+#ifndef GL_EXT_misc_attribute
+#endif
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_GENERATE_MIPMAP_SGIS 0x8191
+#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
+#endif
+
+#ifndef GL_SGIX_clipmap
+#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170
+#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171
+#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172
+#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173
+#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174
+#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175
+#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176
+#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177
+#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178
+#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D
+#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E
+#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F
+#endif
+
+#ifndef GL_SGIX_shadow
+#define GL_TEXTURE_COMPARE_SGIX 0x819A
+#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B
+#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C
+#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D
+#endif
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_CLAMP_TO_EDGE_SGIS 0x812F
+#endif
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_CLAMP_TO_BORDER_SGIS 0x812D
+#endif
+
+#ifndef GL_EXT_blend_minmax
+#define GL_FUNC_ADD_EXT 0x8006
+#define GL_MIN_EXT 0x8007
+#define GL_MAX_EXT 0x8008
+#define GL_BLEND_EQUATION_EXT 0x8009
+#endif
+
+#ifndef GL_EXT_blend_subtract
+#define GL_FUNC_SUBTRACT_EXT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B
+#endif
+
+#ifndef GL_EXT_blend_logic_op
+#endif
+
+#ifndef GL_SGIX_interlace
+#define GL_INTERLACE_SGIX 0x8094
+#endif
+
+#ifndef GL_SGIX_pixel_tiles
+#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E
+#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F
+#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140
+#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141
+#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142
+#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143
+#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144
+#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145
+#endif
+
+#ifndef GL_SGIS_texture_select
+#define GL_DUAL_ALPHA4_SGIS 0x8110
+#define GL_DUAL_ALPHA8_SGIS 0x8111
+#define GL_DUAL_ALPHA12_SGIS 0x8112
+#define GL_DUAL_ALPHA16_SGIS 0x8113
+#define GL_DUAL_LUMINANCE4_SGIS 0x8114
+#define GL_DUAL_LUMINANCE8_SGIS 0x8115
+#define GL_DUAL_LUMINANCE12_SGIS 0x8116
+#define GL_DUAL_LUMINANCE16_SGIS 0x8117
+#define GL_DUAL_INTENSITY4_SGIS 0x8118
+#define GL_DUAL_INTENSITY8_SGIS 0x8119
+#define GL_DUAL_INTENSITY12_SGIS 0x811A
+#define GL_DUAL_INTENSITY16_SGIS 0x811B
+#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C
+#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D
+#define GL_QUAD_ALPHA4_SGIS 0x811E
+#define GL_QUAD_ALPHA8_SGIS 0x811F
+#define GL_QUAD_LUMINANCE4_SGIS 0x8120
+#define GL_QUAD_LUMINANCE8_SGIS 0x8121
+#define GL_QUAD_INTENSITY4_SGIS 0x8122
+#define GL_QUAD_INTENSITY8_SGIS 0x8123
+#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124
+#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125
+#endif
+
+#ifndef GL_SGIX_sprite
+#define GL_SPRITE_SGIX 0x8148
+#define GL_SPRITE_MODE_SGIX 0x8149
+#define GL_SPRITE_AXIS_SGIX 0x814A
+#define GL_SPRITE_TRANSLATION_SGIX 0x814B
+#define GL_SPRITE_AXIAL_SGIX 0x814C
+#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D
+#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E
+#endif
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E
+#endif
+
+#ifndef GL_EXT_point_parameters
+#define GL_POINT_SIZE_MIN_EXT 0x8126
+#define GL_POINT_SIZE_MAX_EXT 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128
+#define GL_DISTANCE_ATTENUATION_EXT 0x8129
+#endif
+
+#ifndef GL_SGIS_point_parameters
+#define GL_POINT_SIZE_MIN_SGIS 0x8126
+#define GL_POINT_SIZE_MAX_SGIS 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128
+#define GL_DISTANCE_ATTENUATION_SGIS 0x8129
+#endif
+
+#ifndef GL_SGIX_instruments
+#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180
+#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181
+#endif
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179
+#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A
+#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B
+#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C
+#endif
+
+#ifndef GL_SGIX_framezoom
+#define GL_FRAMEZOOM_SGIX 0x818B
+#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C
+#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D
+#endif
+
+#ifndef GL_SGIX_tag_sample_buffer
+#endif
+
+#ifndef GL_FfdMaskSGIX
+#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001
+#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002
+#endif
+
+#ifndef GL_SGIX_polynomial_ffd
+#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194
+#define GL_TEXTURE_DEFORMATION_SGIX 0x8195
+#define GL_DEFORMATIONS_MASK_SGIX 0x8196
+#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197
+#endif
+
+#ifndef GL_SGIX_reference_plane
+#define GL_REFERENCE_PLANE_SGIX 0x817D
+#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E
+#endif
+
+#ifndef GL_SGIX_flush_raster
+#endif
+
+#ifndef GL_SGIX_depth_texture
+#define GL_DEPTH_COMPONENT16_SGIX 0x81A5
+#define GL_DEPTH_COMPONENT24_SGIX 0x81A6
+#define GL_DEPTH_COMPONENT32_SGIX 0x81A7
+#endif
+
+#ifndef GL_SGIS_fog_function
+#define GL_FOG_FUNC_SGIS 0x812A
+#define GL_FOG_FUNC_POINTS_SGIS 0x812B
+#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C
+#endif
+
+#ifndef GL_SGIX_fog_offset
+#define GL_FOG_OFFSET_SGIX 0x8198
+#define GL_FOG_OFFSET_VALUE_SGIX 0x8199
+#endif
+
+#ifndef GL_HP_image_transform
+#define GL_IMAGE_SCALE_X_HP 0x8155
+#define GL_IMAGE_SCALE_Y_HP 0x8156
+#define GL_IMAGE_TRANSLATE_X_HP 0x8157
+#define GL_IMAGE_TRANSLATE_Y_HP 0x8158
+#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159
+#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A
+#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B
+#define GL_IMAGE_MAG_FILTER_HP 0x815C
+#define GL_IMAGE_MIN_FILTER_HP 0x815D
+#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E
+#define GL_CUBIC_HP 0x815F
+#define GL_AVERAGE_HP 0x8160
+#define GL_IMAGE_TRANSFORM_2D_HP 0x8161
+#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162
+#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163
+#endif
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_IGNORE_BORDER_HP 0x8150
+#define GL_CONSTANT_BORDER_HP 0x8151
+#define GL_REPLICATE_BORDER_HP 0x8153
+#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154
+#endif
+
+#ifndef GL_INGR_palette_buffer
+#endif
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE
+#endif
+
+#ifndef GL_EXT_color_subtable
+#endif
+
+#ifndef GL_PGI_vertex_hints
+#define GL_VERTEX_DATA_HINT_PGI 0x1A22A
+#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B
+#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C
+#define GL_MAX_VERTEX_HINT_PGI 0x1A22D
+#define GL_COLOR3_BIT_PGI 0x00010000
+#define GL_COLOR4_BIT_PGI 0x00020000
+#define GL_EDGEFLAG_BIT_PGI 0x00040000
+#define GL_INDEX_BIT_PGI 0x00080000
+#define GL_MAT_AMBIENT_BIT_PGI 0x00100000
+#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000
+#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000
+#define GL_MAT_EMISSION_BIT_PGI 0x00800000
+#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000
+#define GL_MAT_SHININESS_BIT_PGI 0x02000000
+#define GL_MAT_SPECULAR_BIT_PGI 0x04000000
+#define GL_NORMAL_BIT_PGI 0x08000000
+#define GL_TEXCOORD1_BIT_PGI 0x10000000
+#define GL_TEXCOORD2_BIT_PGI 0x20000000
+#define GL_TEXCOORD3_BIT_PGI 0x40000000
+#define GL_TEXCOORD4_BIT_PGI 0x80000000
+#define GL_VERTEX23_BIT_PGI 0x00000004
+#define GL_VERTEX4_BIT_PGI 0x00000008
+#endif
+
+#ifndef GL_PGI_misc_hints
+#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8
+#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD
+#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE
+#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202
+#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203
+#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204
+#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C
+#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D
+#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E
+#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F
+#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210
+#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211
+#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216
+#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217
+#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218
+#define GL_FULL_STIPPLE_HINT_PGI 0x1A219
+#define GL_CLIP_NEAR_HINT_PGI 0x1A220
+#define GL_CLIP_FAR_HINT_PGI 0x1A221
+#define GL_WIDE_LINE_HINT_PGI 0x1A222
+#define GL_BACK_NORMALS_HINT_PGI 0x1A223
+#endif
+
+#ifndef GL_EXT_paletted_texture
+#define GL_COLOR_INDEX1_EXT 0x80E2
+#define GL_COLOR_INDEX2_EXT 0x80E3
+#define GL_COLOR_INDEX4_EXT 0x80E4
+#define GL_COLOR_INDEX8_EXT 0x80E5
+#define GL_COLOR_INDEX12_EXT 0x80E6
+#define GL_COLOR_INDEX16_EXT 0x80E7
+#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED
+#endif
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0
+#endif
+
+#ifndef GL_SGIX_list_priority
+#define GL_LIST_PRIORITY_SGIX 0x8182
+#endif
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_IR_INSTRUMENT1_SGIX 0x817F
+#endif
+
+#ifndef GL_SGIX_calligraphic_fragment
+#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183
+#endif
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E
+#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F
+#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190
+#endif
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SHADOW_AMBIENT_SGIX 0x80BF
+#endif
+
+#ifndef GL_EXT_index_texture
+#endif
+
+#ifndef GL_EXT_index_material
+#define GL_INDEX_MATERIAL_EXT 0x81B8
+#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9
+#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA
+#endif
+
+#ifndef GL_EXT_index_func
+#define GL_INDEX_TEST_EXT 0x81B5
+#define GL_INDEX_TEST_FUNC_EXT 0x81B6
+#define GL_INDEX_TEST_REF_EXT 0x81B7
+#endif
+
+#ifndef GL_EXT_index_array_formats
+#define GL_IUI_V2F_EXT 0x81AD
+#define GL_IUI_V3F_EXT 0x81AE
+#define GL_IUI_N3F_V2F_EXT 0x81AF
+#define GL_IUI_N3F_V3F_EXT 0x81B0
+#define GL_T2F_IUI_V2F_EXT 0x81B1
+#define GL_T2F_IUI_V3F_EXT 0x81B2
+#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3
+#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4
+#endif
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8
+#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9
+#endif
+
+#ifndef GL_EXT_cull_vertex
+#define GL_CULL_VERTEX_EXT 0x81AA
+#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB
+#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC
+#endif
+
+#ifndef GL_SGIX_ycrcb
+#define GL_YCRCB_422_SGIX 0x81BB
+#define GL_YCRCB_444_SGIX 0x81BC
+#endif
+
+#ifndef GL_SGIX_fragment_lighting
+#define GL_FRAGMENT_LIGHTING_SGIX 0x8400
+#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401
+#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402
+#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403
+#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404
+#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405
+#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406
+#define GL_LIGHT_ENV_MODE_SGIX 0x8407
+#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408
+#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409
+#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A
+#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B
+#define GL_FRAGMENT_LIGHT0_SGIX 0x840C
+#define GL_FRAGMENT_LIGHT1_SGIX 0x840D
+#define GL_FRAGMENT_LIGHT2_SGIX 0x840E
+#define GL_FRAGMENT_LIGHT3_SGIX 0x840F
+#define GL_FRAGMENT_LIGHT4_SGIX 0x8410
+#define GL_FRAGMENT_LIGHT5_SGIX 0x8411
+#define GL_FRAGMENT_LIGHT6_SGIX 0x8412
+#define GL_FRAGMENT_LIGHT7_SGIX 0x8413
+#endif
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262
+#endif
+
+#ifndef GL_HP_texture_lighting
+#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167
+#define GL_TEXTURE_POST_SPECULAR_HP 0x8168
+#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169
+#endif
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8
+#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9
+#endif
+
+#ifndef GL_WIN_phong_shading
+#define GL_PHONG_WIN 0x80EA
+#define GL_PHONG_HINT_WIN 0x80EB
+#endif
+
+#ifndef GL_WIN_specular_fog
+#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC
+#endif
+
+#ifndef GL_EXT_light_texture
+#define GL_FRAGMENT_MATERIAL_EXT 0x8349
+#define GL_FRAGMENT_NORMAL_EXT 0x834A
+#define GL_FRAGMENT_COLOR_EXT 0x834C
+#define GL_ATTENUATION_EXT 0x834D
+#define GL_SHADOW_ATTENUATION_EXT 0x834E
+#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F
+#define GL_TEXTURE_LIGHT_EXT 0x8350
+#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351
+#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352
+/* reuse GL_FRAGMENT_DEPTH_EXT */
+#endif
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_ALPHA_MIN_SGIX 0x8320
+#define GL_ALPHA_MAX_SGIX 0x8321
+#endif
+
+#ifndef GL_SGIX_impact_pixel_texture
+#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184
+#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185
+#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186
+#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187
+#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188
+#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189
+#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A
+#endif
+
+#ifndef GL_EXT_bgra
+#define GL_BGR_EXT 0x80E0
+#define GL_BGRA_EXT 0x80E1
+#endif
+
+#ifndef GL_SGIX_async
+#define GL_ASYNC_MARKER_SGIX 0x8329
+#endif
+
+#ifndef GL_SGIX_async_pixel
+#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C
+#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D
+#define GL_ASYNC_READ_PIXELS_SGIX 0x835E
+#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F
+#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360
+#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361
+#endif
+
+#ifndef GL_SGIX_async_histogram
+#define GL_ASYNC_HISTOGRAM_SGIX 0x832C
+#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D
+#endif
+
+#ifndef GL_INTEL_texture_scissor
+#endif
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_PARALLEL_ARRAYS_INTEL 0x83F4
+#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5
+#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6
+#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7
+#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8
+#endif
+
+#ifndef GL_HP_occlusion_test
+#define GL_OCCLUSION_TEST_HP 0x8165
+#define GL_OCCLUSION_TEST_RESULT_HP 0x8166
+#endif
+
+#ifndef GL_EXT_pixel_transform
+#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330
+#define GL_PIXEL_MAG_FILTER_EXT 0x8331
+#define GL_PIXEL_MIN_FILTER_EXT 0x8332
+#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333
+#define GL_CUBIC_EXT 0x8334
+#define GL_AVERAGE_EXT 0x8335
+#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336
+#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337
+#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338
+#endif
+
+#ifndef GL_EXT_pixel_transform_color_table
+#endif
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB
+#endif
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8
+#define GL_SINGLE_COLOR_EXT 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA
+#endif
+
+#ifndef GL_EXT_secondary_color
+#define GL_COLOR_SUM_EXT 0x8458
+#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D
+#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E
+#endif
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_PERTURB_EXT 0x85AE
+#define GL_TEXTURE_NORMAL_EXT 0x85AF
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#endif
+
+#ifndef GL_EXT_fog_coord
+#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450
+#define GL_FOG_COORDINATE_EXT 0x8451
+#define GL_FRAGMENT_DEPTH_EXT 0x8452
+#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456
+#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457
+#endif
+
+#ifndef GL_REND_screen_coordinates
+#define GL_SCREEN_COORDINATES_REND 0x8490
+#define GL_INVERTED_SCREEN_W_REND 0x8491
+#endif
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_TANGENT_ARRAY_EXT 0x8439
+#define GL_BINORMAL_ARRAY_EXT 0x843A
+#define GL_CURRENT_TANGENT_EXT 0x843B
+#define GL_CURRENT_BINORMAL_EXT 0x843C
+#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E
+#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F
+#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440
+#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441
+#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442
+#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443
+#define GL_MAP1_TANGENT_EXT 0x8444
+#define GL_MAP2_TANGENT_EXT 0x8445
+#define GL_MAP1_BINORMAL_EXT 0x8446
+#define GL_MAP2_BINORMAL_EXT 0x8447
+#endif
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_COMBINE_EXT 0x8570
+#define GL_COMBINE_RGB_EXT 0x8571
+#define GL_COMBINE_ALPHA_EXT 0x8572
+#define GL_RGB_SCALE_EXT 0x8573
+#define GL_ADD_SIGNED_EXT 0x8574
+#define GL_INTERPOLATE_EXT 0x8575
+#define GL_CONSTANT_EXT 0x8576
+#define GL_PRIMARY_COLOR_EXT 0x8577
+#define GL_PREVIOUS_EXT 0x8578
+#define GL_SOURCE0_RGB_EXT 0x8580
+#define GL_SOURCE1_RGB_EXT 0x8581
+#define GL_SOURCE2_RGB_EXT 0x8582
+#define GL_SOURCE0_ALPHA_EXT 0x8588
+#define GL_SOURCE1_ALPHA_EXT 0x8589
+#define GL_SOURCE2_ALPHA_EXT 0x858A
+#define GL_OPERAND0_RGB_EXT 0x8590
+#define GL_OPERAND1_RGB_EXT 0x8591
+#define GL_OPERAND2_RGB_EXT 0x8592
+#define GL_OPERAND0_ALPHA_EXT 0x8598
+#define GL_OPERAND1_ALPHA_EXT 0x8599
+#define GL_OPERAND2_ALPHA_EXT 0x859A
+#endif
+
+#ifndef GL_APPLE_specular_vector
+#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0
+#endif
+
+#ifndef GL_APPLE_transform_hint
+#define GL_TRANSFORM_HINT_APPLE 0x85B1
+#endif
+
+#ifndef GL_SGIX_fog_scale
+#define GL_FOG_SCALE_SGIX 0x81FC
+#define GL_FOG_SCALE_VALUE_SGIX 0x81FD
+#endif
+
+#ifndef GL_SUNX_constant_data
+#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5
+#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6
+#endif
+
+#ifndef GL_SUN_global_alpha
+#define GL_GLOBAL_ALPHA_SUN 0x81D9
+#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA
+#endif
+
+#ifndef GL_SUN_triangle_list
+#define GL_RESTART_SUN 0x0001
+#define GL_REPLACE_MIDDLE_SUN 0x0002
+#define GL_REPLACE_OLDEST_SUN 0x0003
+#define GL_TRIANGLE_LIST_SUN 0x81D7
+#define GL_REPLACEMENT_CODE_SUN 0x81D8
+#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0
+#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1
+#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2
+#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3
+#define GL_R1UI_V3F_SUN 0x85C4
+#define GL_R1UI_C4UB_V3F_SUN 0x85C5
+#define GL_R1UI_C3F_V3F_SUN 0x85C6
+#define GL_R1UI_N3F_V3F_SUN 0x85C7
+#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8
+#define GL_R1UI_T2F_V3F_SUN 0x85C9
+#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA
+#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB
+#endif
+
+#ifndef GL_SUN_vertex
+#endif
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_BLEND_DST_RGB_EXT 0x80C8
+#define GL_BLEND_SRC_RGB_EXT 0x80C9
+#define GL_BLEND_DST_ALPHA_EXT 0x80CA
+#define GL_BLEND_SRC_ALPHA_EXT 0x80CB
+#endif
+
+#ifndef GL_INGR_color_clamp
+#define GL_RED_MIN_CLAMP_INGR 0x8560
+#define GL_GREEN_MIN_CLAMP_INGR 0x8561
+#define GL_BLUE_MIN_CLAMP_INGR 0x8562
+#define GL_ALPHA_MIN_CLAMP_INGR 0x8563
+#define GL_RED_MAX_CLAMP_INGR 0x8564
+#define GL_GREEN_MAX_CLAMP_INGR 0x8565
+#define GL_BLUE_MAX_CLAMP_INGR 0x8566
+#define GL_ALPHA_MAX_CLAMP_INGR 0x8567
+#endif
+
+#ifndef GL_INGR_interlace_read
+#define GL_INTERLACE_READ_INGR 0x8568
+#endif
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_INCR_WRAP_EXT 0x8507
+#define GL_DECR_WRAP_EXT 0x8508
+#endif
+
+#ifndef GL_EXT_422_pixels
+#define GL_422_EXT 0x80CC
+#define GL_422_REV_EXT 0x80CD
+#define GL_422_AVERAGE_EXT 0x80CE
+#define GL_422_REV_AVERAGE_EXT 0x80CF
+#endif
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NORMAL_MAP_NV 0x8511
+#define GL_REFLECTION_MAP_NV 0x8512
+#endif
+
+#ifndef GL_EXT_texture_cube_map
+#define GL_NORMAL_MAP_EXT 0x8511
+#define GL_REFLECTION_MAP_EXT 0x8512
+#define GL_TEXTURE_CUBE_MAP_EXT 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C
+#endif
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_WRAP_BORDER_SUN 0x81D4
+#endif
+
+#ifndef GL_EXT_texture_env_add
+#endif
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD
+#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500
+#define GL_TEXTURE_LOD_BIAS_EXT 0x8501
+#endif
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+#endif
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH
+#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502
+#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX
+#define GL_MODELVIEW1_MATRIX_EXT 0x8506
+#define GL_VERTEX_WEIGHTING_EXT 0x8509
+#define GL_MODELVIEW0_EXT GL_MODELVIEW
+#define GL_MODELVIEW1_EXT 0x850A
+#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B
+#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C
+#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D
+#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E
+#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F
+#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510
+#endif
+
+#ifndef GL_NV_light_max_exponent
+#define GL_MAX_SHININESS_NV 0x8504
+#define GL_MAX_SPOT_EXPONENT_NV 0x8505
+#endif
+
+#ifndef GL_NV_vertex_array_range
+#define GL_VERTEX_ARRAY_RANGE_NV 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E
+#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F
+#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520
+#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521
+#endif
+
+#ifndef GL_NV_register_combiners
+#define GL_REGISTER_COMBINERS_NV 0x8522
+#define GL_VARIABLE_A_NV 0x8523
+#define GL_VARIABLE_B_NV 0x8524
+#define GL_VARIABLE_C_NV 0x8525
+#define GL_VARIABLE_D_NV 0x8526
+#define GL_VARIABLE_E_NV 0x8527
+#define GL_VARIABLE_F_NV 0x8528
+#define GL_VARIABLE_G_NV 0x8529
+#define GL_CONSTANT_COLOR0_NV 0x852A
+#define GL_CONSTANT_COLOR1_NV 0x852B
+#define GL_PRIMARY_COLOR_NV 0x852C
+#define GL_SECONDARY_COLOR_NV 0x852D
+#define GL_SPARE0_NV 0x852E
+#define GL_SPARE1_NV 0x852F
+#define GL_DISCARD_NV 0x8530
+#define GL_E_TIMES_F_NV 0x8531
+#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532
+#define GL_UNSIGNED_IDENTITY_NV 0x8536
+#define GL_UNSIGNED_INVERT_NV 0x8537
+#define GL_EXPAND_NORMAL_NV 0x8538
+#define GL_EXPAND_NEGATE_NV 0x8539
+#define GL_HALF_BIAS_NORMAL_NV 0x853A
+#define GL_HALF_BIAS_NEGATE_NV 0x853B
+#define GL_SIGNED_IDENTITY_NV 0x853C
+#define GL_SIGNED_NEGATE_NV 0x853D
+#define GL_SCALE_BY_TWO_NV 0x853E
+#define GL_SCALE_BY_FOUR_NV 0x853F
+#define GL_SCALE_BY_ONE_HALF_NV 0x8540
+#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541
+#define GL_COMBINER_INPUT_NV 0x8542
+#define GL_COMBINER_MAPPING_NV 0x8543
+#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544
+#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545
+#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546
+#define GL_COMBINER_MUX_SUM_NV 0x8547
+#define GL_COMBINER_SCALE_NV 0x8548
+#define GL_COMBINER_BIAS_NV 0x8549
+#define GL_COMBINER_AB_OUTPUT_NV 0x854A
+#define GL_COMBINER_CD_OUTPUT_NV 0x854B
+#define GL_COMBINER_SUM_OUTPUT_NV 0x854C
+#define GL_MAX_GENERAL_COMBINERS_NV 0x854D
+#define GL_NUM_GENERAL_COMBINERS_NV 0x854E
+#define GL_COLOR_SUM_CLAMP_NV 0x854F
+#define GL_COMBINER0_NV 0x8550
+#define GL_COMBINER1_NV 0x8551
+#define GL_COMBINER2_NV 0x8552
+#define GL_COMBINER3_NV 0x8553
+#define GL_COMBINER4_NV 0x8554
+#define GL_COMBINER5_NV 0x8555
+#define GL_COMBINER6_NV 0x8556
+#define GL_COMBINER7_NV 0x8557
+/* reuse GL_TEXTURE0_ARB */
+/* reuse GL_TEXTURE1_ARB */
+/* reuse GL_ZERO */
+/* reuse GL_NONE */
+/* reuse GL_FOG */
+#endif
+
+#ifndef GL_NV_fog_distance
+#define GL_FOG_DISTANCE_MODE_NV 0x855A
+#define GL_EYE_RADIAL_NV 0x855B
+#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C
+/* reuse GL_EYE_PLANE */
+#endif
+
+#ifndef GL_NV_texgen_emboss
+#define GL_EMBOSS_LIGHT_NV 0x855D
+#define GL_EMBOSS_CONSTANT_NV 0x855E
+#define GL_EMBOSS_MAP_NV 0x855F
+#endif
+
+#ifndef GL_NV_blend_square
+#endif
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_COMBINE4_NV 0x8503
+#define GL_SOURCE3_RGB_NV 0x8583
+#define GL_SOURCE3_ALPHA_NV 0x858B
+#define GL_OPERAND3_RGB_NV 0x8593
+#define GL_OPERAND3_ALPHA_NV 0x859B
+#endif
+
+#ifndef GL_MESA_resize_buffers
+#endif
+
+#ifndef GL_MESA_window_pos
+#endif
+
+#ifndef GL_EXT_texture_compression_s3tc
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+#endif
+
+#ifndef GL_IBM_cull_vertex
+#define GL_CULL_VERTEX_IBM 103050
+#endif
+
+#ifndef GL_IBM_multimode_draw_arrays
+#endif
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_VERTEX_ARRAY_LIST_IBM 103070
+#define GL_NORMAL_ARRAY_LIST_IBM 103071
+#define GL_COLOR_ARRAY_LIST_IBM 103072
+#define GL_INDEX_ARRAY_LIST_IBM 103073
+#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074
+#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075
+#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076
+#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077
+#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080
+#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081
+#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082
+#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083
+#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084
+#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085
+#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086
+#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087
+#endif
+
+#ifndef GL_SGIX_subsample
+#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0
+#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1
+#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2
+#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3
+#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4
+#endif
+
+#ifndef GL_SGIX_ycrcb_subsample
+#endif
+
+#ifndef GL_SGIX_ycrcba
+#define GL_YCRCB_SGIX 0x8318
+#define GL_YCRCBA_SGIX 0x8319
+#endif
+
+#ifndef GL_SGI_depth_pass_instrument
+#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310
+#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311
+#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312
+#endif
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0
+#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1
+#endif
+
+#ifndef GL_3DFX_multisample
+#define GL_MULTISAMPLE_3DFX 0x86B2
+#define GL_SAMPLE_BUFFERS_3DFX 0x86B3
+#define GL_SAMPLES_3DFX 0x86B4
+#define GL_MULTISAMPLE_BIT_3DFX 0x20000000
+#endif
+
+#ifndef GL_3DFX_tbuffer
+#endif
+
+#ifndef GL_EXT_multisample
+#define GL_MULTISAMPLE_EXT 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F
+#define GL_SAMPLE_MASK_EXT 0x80A0
+#define GL_1PASS_EXT 0x80A1
+#define GL_2PASS_0_EXT 0x80A2
+#define GL_2PASS_1_EXT 0x80A3
+#define GL_4PASS_0_EXT 0x80A4
+#define GL_4PASS_1_EXT 0x80A5
+#define GL_4PASS_2_EXT 0x80A6
+#define GL_4PASS_3_EXT 0x80A7
+#define GL_SAMPLE_BUFFERS_EXT 0x80A8
+#define GL_SAMPLES_EXT 0x80A9
+#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA
+#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB
+#define GL_SAMPLE_PATTERN_EXT 0x80AC
+#define GL_MULTISAMPLE_BIT_EXT 0x20000000
+#endif
+
+#ifndef GL_SGIX_vertex_preclip
+#define GL_VERTEX_PRECLIP_SGIX 0x83EE
+#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF
+#endif
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_CONVOLUTION_HINT_SGIX 0x8316
+#endif
+
+#ifndef GL_SGIX_resample
+#define GL_PACK_RESAMPLE_SGIX 0x842C
+#define GL_UNPACK_RESAMPLE_SGIX 0x842D
+#define GL_RESAMPLE_REPLICATE_SGIX 0x842E
+#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F
+#define GL_RESAMPLE_DECIMATE_SGIX 0x8430
+#endif
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0
+#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1
+#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2
+#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3
+#define GL_EYE_POINT_SGIS 0x81F4
+#define GL_OBJECT_POINT_SGIS 0x81F5
+#define GL_EYE_LINE_SGIS 0x81F6
+#define GL_OBJECT_LINE_SGIS 0x81F7
+#endif
+
+#ifndef GL_SGIS_texture_color_mask
+#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF
+#endif
+
+#ifndef GL_EXT_texture_env_dot3
+#define GL_DOT3_RGB_EXT 0x8740
+#define GL_DOT3_RGBA_EXT 0x8741
+#endif
+
+#ifndef GL_ATI_texture_mirror_once
+#define GL_MIRROR_CLAMP_ATI 0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743
+#endif
+
+#ifndef GL_NV_fence
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FENCE_CONDITION_NV 0x84F4
+#endif
+
+#ifndef GL_IBM_texture_mirrored_repeat
+#define GL_MIRRORED_REPEAT_IBM 0x8370
+#endif
+
+#ifndef GL_NV_evaluators
+#define GL_EVAL_2D_NV 0x86C0
+#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1
+#define GL_MAP_TESSELLATION_NV 0x86C2
+#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3
+#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4
+#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5
+#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6
+#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7
+#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8
+#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9
+#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA
+#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB
+#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC
+#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD
+#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE
+#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF
+#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0
+#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1
+#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2
+#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3
+#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4
+#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5
+#define GL_MAX_MAP_TESSELLATION_NV 0x86D6
+#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7
+#endif
+
+#ifndef GL_NV_packed_depth_stencil
+#define GL_DEPTH_STENCIL_NV 0x84F9
+#define GL_UNSIGNED_INT_24_8_NV 0x84FA
+#endif
+
+#ifndef GL_NV_register_combiners2
+#define GL_PER_STAGE_CONSTANTS_NV 0x8535
+#endif
+
+#ifndef GL_NV_texture_compression_vtc
+#endif
+
+#ifndef GL_NV_texture_rectangle
+#define GL_TEXTURE_RECTANGLE_NV 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8
+#endif
+
+#ifndef GL_NV_texture_shader
+#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C
+#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D
+#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E
+#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9
+#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA
+#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB
+#define GL_DSDT_MAG_INTENSITY_NV 0x86DC
+#define GL_SHADER_CONSISTENT_NV 0x86DD
+#define GL_TEXTURE_SHADER_NV 0x86DE
+#define GL_SHADER_OPERATION_NV 0x86DF
+#define GL_CULL_MODES_NV 0x86E0
+#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1
+#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2
+#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3
+#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV
+#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV
+#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV
+#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4
+#define GL_CONST_EYE_NV 0x86E5
+#define GL_PASS_THROUGH_NV 0x86E6
+#define GL_CULL_FRAGMENT_NV 0x86E7
+#define GL_OFFSET_TEXTURE_2D_NV 0x86E8
+#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9
+#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA
+#define GL_DOT_PRODUCT_NV 0x86EC
+#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED
+#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE
+#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0
+#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1
+#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2
+#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3
+#define GL_HILO_NV 0x86F4
+#define GL_DSDT_NV 0x86F5
+#define GL_DSDT_MAG_NV 0x86F6
+#define GL_DSDT_MAG_VIB_NV 0x86F7
+#define GL_HILO16_NV 0x86F8
+#define GL_SIGNED_HILO_NV 0x86F9
+#define GL_SIGNED_HILO16_NV 0x86FA
+#define GL_SIGNED_RGBA_NV 0x86FB
+#define GL_SIGNED_RGBA8_NV 0x86FC
+#define GL_SIGNED_RGB_NV 0x86FE
+#define GL_SIGNED_RGB8_NV 0x86FF
+#define GL_SIGNED_LUMINANCE_NV 0x8701
+#define GL_SIGNED_LUMINANCE8_NV 0x8702
+#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703
+#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704
+#define GL_SIGNED_ALPHA_NV 0x8705
+#define GL_SIGNED_ALPHA8_NV 0x8706
+#define GL_SIGNED_INTENSITY_NV 0x8707
+#define GL_SIGNED_INTENSITY8_NV 0x8708
+#define GL_DSDT8_NV 0x8709
+#define GL_DSDT8_MAG8_NV 0x870A
+#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B
+#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C
+#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D
+#define GL_HI_SCALE_NV 0x870E
+#define GL_LO_SCALE_NV 0x870F
+#define GL_DS_SCALE_NV 0x8710
+#define GL_DT_SCALE_NV 0x8711
+#define GL_MAGNITUDE_SCALE_NV 0x8712
+#define GL_VIBRANCE_SCALE_NV 0x8713
+#define GL_HI_BIAS_NV 0x8714
+#define GL_LO_BIAS_NV 0x8715
+#define GL_DS_BIAS_NV 0x8716
+#define GL_DT_BIAS_NV 0x8717
+#define GL_MAGNITUDE_BIAS_NV 0x8718
+#define GL_VIBRANCE_BIAS_NV 0x8719
+#define GL_TEXTURE_BORDER_VALUES_NV 0x871A
+#define GL_TEXTURE_HI_SIZE_NV 0x871B
+#define GL_TEXTURE_LO_SIZE_NV 0x871C
+#define GL_TEXTURE_DS_SIZE_NV 0x871D
+#define GL_TEXTURE_DT_SIZE_NV 0x871E
+#define GL_TEXTURE_MAG_SIZE_NV 0x871F
+#endif
+
+#ifndef GL_NV_texture_shader2
+#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF
+#endif
+
+#ifndef GL_NV_vertex_array_range2
+#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533
+#endif
+
+#ifndef GL_NV_vertex_program
+#define GL_VERTEX_PROGRAM_NV 0x8620
+#define GL_VERTEX_STATE_PROGRAM_NV 0x8621
+#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623
+#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624
+#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625
+#define GL_CURRENT_ATTRIB_NV 0x8626
+#define GL_PROGRAM_LENGTH_NV 0x8627
+#define GL_PROGRAM_STRING_NV 0x8628
+#define GL_MODELVIEW_PROJECTION_NV 0x8629
+#define GL_IDENTITY_NV 0x862A
+#define GL_INVERSE_NV 0x862B
+#define GL_TRANSPOSE_NV 0x862C
+#define GL_INVERSE_TRANSPOSE_NV 0x862D
+#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E
+#define GL_MAX_TRACK_MATRICES_NV 0x862F
+#define GL_MATRIX0_NV 0x8630
+#define GL_MATRIX1_NV 0x8631
+#define GL_MATRIX2_NV 0x8632
+#define GL_MATRIX3_NV 0x8633
+#define GL_MATRIX4_NV 0x8634
+#define GL_MATRIX5_NV 0x8635
+#define GL_MATRIX6_NV 0x8636
+#define GL_MATRIX7_NV 0x8637
+#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640
+#define GL_CURRENT_MATRIX_NV 0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643
+#define GL_PROGRAM_PARAMETER_NV 0x8644
+#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645
+#define GL_PROGRAM_TARGET_NV 0x8646
+#define GL_PROGRAM_RESIDENT_NV 0x8647
+#define GL_TRACK_MATRIX_NV 0x8648
+#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649
+#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A
+#define GL_PROGRAM_ERROR_POSITION_NV 0x864B
+#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650
+#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651
+#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652
+#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653
+#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654
+#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655
+#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656
+#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657
+#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658
+#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659
+#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A
+#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B
+#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C
+#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D
+#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E
+#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F
+#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660
+#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661
+#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662
+#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663
+#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664
+#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665
+#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666
+#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667
+#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668
+#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669
+#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A
+#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B
+#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C
+#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D
+#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E
+#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F
+#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670
+#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671
+#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672
+#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673
+#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674
+#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675
+#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676
+#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677
+#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678
+#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679
+#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A
+#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B
+#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C
+#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D
+#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E
+#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F
+#endif
+
+#ifndef GL_SGIX_texture_coordinate_clamp
+#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369
+#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A
+#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B
+#endif
+
+#ifndef GL_SGIX_scalebias_hint
+#define GL_SCALEBIAS_HINT_SGIX 0x8322
+#endif
+
+#ifndef GL_OML_interlace
+#define GL_INTERLACE_OML 0x8980
+#define GL_INTERLACE_READ_OML 0x8981
+#endif
+
+#ifndef GL_OML_subsample
+#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982
+#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983
+#endif
+
+#ifndef GL_OML_resample
+#define GL_PACK_RESAMPLE_OML 0x8984
+#define GL_UNPACK_RESAMPLE_OML 0x8985
+#define GL_RESAMPLE_REPLICATE_OML 0x8986
+#define GL_RESAMPLE_ZERO_FILL_OML 0x8987
+#define GL_RESAMPLE_AVERAGE_OML 0x8988
+#define GL_RESAMPLE_DECIMATE_OML 0x8989
+#endif
+
+#ifndef GL_NV_copy_depth_to_color
+#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E
+#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F
+#endif
+
+#ifndef GL_ATI_envmap_bumpmap
+#define GL_BUMP_ROT_MATRIX_ATI 0x8775
+#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776
+#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777
+#define GL_BUMP_TEX_UNITS_ATI 0x8778
+#define GL_DUDV_ATI 0x8779
+#define GL_DU8DV8_ATI 0x877A
+#define GL_BUMP_ENVMAP_ATI 0x877B
+#define GL_BUMP_TARGET_ATI 0x877C
+#endif
+
+#ifndef GL_ATI_fragment_shader
+#define GL_FRAGMENT_SHADER_ATI 0x8920
+#define GL_REG_0_ATI 0x8921
+#define GL_REG_1_ATI 0x8922
+#define GL_REG_2_ATI 0x8923
+#define GL_REG_3_ATI 0x8924
+#define GL_REG_4_ATI 0x8925
+#define GL_REG_5_ATI 0x8926
+#define GL_REG_6_ATI 0x8927
+#define GL_REG_7_ATI 0x8928
+#define GL_REG_8_ATI 0x8929
+#define GL_REG_9_ATI 0x892A
+#define GL_REG_10_ATI 0x892B
+#define GL_REG_11_ATI 0x892C
+#define GL_REG_12_ATI 0x892D
+#define GL_REG_13_ATI 0x892E
+#define GL_REG_14_ATI 0x892F
+#define GL_REG_15_ATI 0x8930
+#define GL_REG_16_ATI 0x8931
+#define GL_REG_17_ATI 0x8932
+#define GL_REG_18_ATI 0x8933
+#define GL_REG_19_ATI 0x8934
+#define GL_REG_20_ATI 0x8935
+#define GL_REG_21_ATI 0x8936
+#define GL_REG_22_ATI 0x8937
+#define GL_REG_23_ATI 0x8938
+#define GL_REG_24_ATI 0x8939
+#define GL_REG_25_ATI 0x893A
+#define GL_REG_26_ATI 0x893B
+#define GL_REG_27_ATI 0x893C
+#define GL_REG_28_ATI 0x893D
+#define GL_REG_29_ATI 0x893E
+#define GL_REG_30_ATI 0x893F
+#define GL_REG_31_ATI 0x8940
+#define GL_CON_0_ATI 0x8941
+#define GL_CON_1_ATI 0x8942
+#define GL_CON_2_ATI 0x8943
+#define GL_CON_3_ATI 0x8944
+#define GL_CON_4_ATI 0x8945
+#define GL_CON_5_ATI 0x8946
+#define GL_CON_6_ATI 0x8947
+#define GL_CON_7_ATI 0x8948
+#define GL_CON_8_ATI 0x8949
+#define GL_CON_9_ATI 0x894A
+#define GL_CON_10_ATI 0x894B
+#define GL_CON_11_ATI 0x894C
+#define GL_CON_12_ATI 0x894D
+#define GL_CON_13_ATI 0x894E
+#define GL_CON_14_ATI 0x894F
+#define GL_CON_15_ATI 0x8950
+#define GL_CON_16_ATI 0x8951
+#define GL_CON_17_ATI 0x8952
+#define GL_CON_18_ATI 0x8953
+#define GL_CON_19_ATI 0x8954
+#define GL_CON_20_ATI 0x8955
+#define GL_CON_21_ATI 0x8956
+#define GL_CON_22_ATI 0x8957
+#define GL_CON_23_ATI 0x8958
+#define GL_CON_24_ATI 0x8959
+#define GL_CON_25_ATI 0x895A
+#define GL_CON_26_ATI 0x895B
+#define GL_CON_27_ATI 0x895C
+#define GL_CON_28_ATI 0x895D
+#define GL_CON_29_ATI 0x895E
+#define GL_CON_30_ATI 0x895F
+#define GL_CON_31_ATI 0x8960
+#define GL_MOV_ATI 0x8961
+#define GL_ADD_ATI 0x8963
+#define GL_MUL_ATI 0x8964
+#define GL_SUB_ATI 0x8965
+#define GL_DOT3_ATI 0x8966
+#define GL_DOT4_ATI 0x8967
+#define GL_MAD_ATI 0x8968
+#define GL_LERP_ATI 0x8969
+#define GL_CND_ATI 0x896A
+#define GL_CND0_ATI 0x896B
+#define GL_DOT2_ADD_ATI 0x896C
+#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D
+#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E
+#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F
+#define GL_NUM_PASSES_ATI 0x8970
+#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971
+#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972
+#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973
+#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974
+#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975
+#define GL_SWIZZLE_STR_ATI 0x8976
+#define GL_SWIZZLE_STQ_ATI 0x8977
+#define GL_SWIZZLE_STR_DR_ATI 0x8978
+#define GL_SWIZZLE_STQ_DQ_ATI 0x8979
+#define GL_SWIZZLE_STRQ_ATI 0x897A
+#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B
+#define GL_RED_BIT_ATI 0x00000001
+#define GL_GREEN_BIT_ATI 0x00000002
+#define GL_BLUE_BIT_ATI 0x00000004
+#define GL_2X_BIT_ATI 0x00000001
+#define GL_4X_BIT_ATI 0x00000002
+#define GL_8X_BIT_ATI 0x00000004
+#define GL_HALF_BIT_ATI 0x00000008
+#define GL_QUARTER_BIT_ATI 0x00000010
+#define GL_EIGHTH_BIT_ATI 0x00000020
+#define GL_SATURATE_BIT_ATI 0x00000040
+#define GL_COMP_BIT_ATI 0x00000002
+#define GL_NEGATE_BIT_ATI 0x00000004
+#define GL_BIAS_BIT_ATI 0x00000008
+#endif
+
+#ifndef GL_ATI_pn_triangles
+#define GL_PN_TRIANGLES_ATI 0x87F0
+#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1
+#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2
+#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3
+#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4
+#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5
+#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6
+#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
+#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
+#endif
+
+#ifndef GL_ATI_vertex_array_object
+#define GL_STATIC_ATI 0x8760
+#define GL_DYNAMIC_ATI 0x8761
+#define GL_PRESERVE_ATI 0x8762
+#define GL_DISCARD_ATI 0x8763
+#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764
+#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765
+#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766
+#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767
+#endif
+
+#ifndef GL_EXT_vertex_shader
+#define GL_VERTEX_SHADER_EXT 0x8780
+#define GL_VERTEX_SHADER_BINDING_EXT 0x8781
+#define GL_OP_INDEX_EXT 0x8782
+#define GL_OP_NEGATE_EXT 0x8783
+#define GL_OP_DOT3_EXT 0x8784
+#define GL_OP_DOT4_EXT 0x8785
+#define GL_OP_MUL_EXT 0x8786
+#define GL_OP_ADD_EXT 0x8787
+#define GL_OP_MADD_EXT 0x8788
+#define GL_OP_FRAC_EXT 0x8789
+#define GL_OP_MAX_EXT 0x878A
+#define GL_OP_MIN_EXT 0x878B
+#define GL_OP_SET_GE_EXT 0x878C
+#define GL_OP_SET_LT_EXT 0x878D
+#define GL_OP_CLAMP_EXT 0x878E
+#define GL_OP_FLOOR_EXT 0x878F
+#define GL_OP_ROUND_EXT 0x8790
+#define GL_OP_EXP_BASE_2_EXT 0x8791
+#define GL_OP_LOG_BASE_2_EXT 0x8792
+#define GL_OP_POWER_EXT 0x8793
+#define GL_OP_RECIP_EXT 0x8794
+#define GL_OP_RECIP_SQRT_EXT 0x8795
+#define GL_OP_SUB_EXT 0x8796
+#define GL_OP_CROSS_PRODUCT_EXT 0x8797
+#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798
+#define GL_OP_MOV_EXT 0x8799
+#define GL_OUTPUT_VERTEX_EXT 0x879A
+#define GL_OUTPUT_COLOR0_EXT 0x879B
+#define GL_OUTPUT_COLOR1_EXT 0x879C
+#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D
+#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E
+#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F
+#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0
+#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1
+#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2
+#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3
+#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4
+#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5
+#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6
+#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7
+#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8
+#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9
+#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA
+#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB
+#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC
+#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD
+#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE
+#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF
+#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0
+#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1
+#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2
+#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3
+#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4
+#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5
+#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6
+#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7
+#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8
+#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9
+#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA
+#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB
+#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC
+#define GL_OUTPUT_FOG_EXT 0x87BD
+#define GL_SCALAR_EXT 0x87BE
+#define GL_VECTOR_EXT 0x87BF
+#define GL_MATRIX_EXT 0x87C0
+#define GL_VARIANT_EXT 0x87C1
+#define GL_INVARIANT_EXT 0x87C2
+#define GL_LOCAL_CONSTANT_EXT 0x87C3
+#define GL_LOCAL_EXT 0x87C4
+#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5
+#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6
+#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7
+#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8
+#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE
+#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF
+#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0
+#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1
+#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2
+#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3
+#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4
+#define GL_X_EXT 0x87D5
+#define GL_Y_EXT 0x87D6
+#define GL_Z_EXT 0x87D7
+#define GL_W_EXT 0x87D8
+#define GL_NEGATIVE_X_EXT 0x87D9
+#define GL_NEGATIVE_Y_EXT 0x87DA
+#define GL_NEGATIVE_Z_EXT 0x87DB
+#define GL_NEGATIVE_W_EXT 0x87DC
+#define GL_ZERO_EXT 0x87DD
+#define GL_ONE_EXT 0x87DE
+#define GL_NEGATIVE_ONE_EXT 0x87DF
+#define GL_NORMALIZED_RANGE_EXT 0x87E0
+#define GL_FULL_RANGE_EXT 0x87E1
+#define GL_CURRENT_VERTEX_EXT 0x87E2
+#define GL_MVP_MATRIX_EXT 0x87E3
+#define GL_VARIANT_VALUE_EXT 0x87E4
+#define GL_VARIANT_DATATYPE_EXT 0x87E5
+#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6
+#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7
+#define GL_VARIANT_ARRAY_EXT 0x87E8
+#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9
+#define GL_INVARIANT_VALUE_EXT 0x87EA
+#define GL_INVARIANT_DATATYPE_EXT 0x87EB
+#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC
+#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED
+#endif
+
+#ifndef GL_ATI_vertex_streams
+#define GL_MAX_VERTEX_STREAMS_ATI 0x876B
+#define GL_VERTEX_STREAM0_ATI 0x876C
+#define GL_VERTEX_STREAM1_ATI 0x876D
+#define GL_VERTEX_STREAM2_ATI 0x876E
+#define GL_VERTEX_STREAM3_ATI 0x876F
+#define GL_VERTEX_STREAM4_ATI 0x8770
+#define GL_VERTEX_STREAM5_ATI 0x8771
+#define GL_VERTEX_STREAM6_ATI 0x8772
+#define GL_VERTEX_STREAM7_ATI 0x8773
+#define GL_VERTEX_SOURCE_ATI 0x8774
+#endif
+
+#ifndef GL_ATI_element_array
+#define GL_ELEMENT_ARRAY_ATI 0x8768
+#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769
+#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A
+#endif
+
+#ifndef GL_SUN_mesh_array
+#define GL_QUAD_MESH_SUN 0x8614
+#define GL_TRIANGLE_MESH_SUN 0x8615
+#endif
+
+#ifndef GL_SUN_slice_accum
+#define GL_SLICE_ACCUM_SUN 0x85CC
+#endif
+
+#ifndef GL_NV_multisample_filter_hint
+#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534
+#endif
+
+#ifndef GL_NV_depth_clamp
+#define GL_DEPTH_CLAMP_NV 0x864F
+#endif
+
+#ifndef GL_NV_occlusion_query
+#define GL_PIXEL_COUNTER_BITS_NV 0x8864
+#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865
+#define GL_PIXEL_COUNT_NV 0x8866
+#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867
+#endif
+
+#ifndef GL_NV_point_sprite
+#define GL_POINT_SPRITE_NV 0x8861
+#define GL_COORD_REPLACE_NV 0x8862
+#define GL_POINT_SPRITE_R_MODE_NV 0x8863
+#endif
+
+#ifndef GL_NV_texture_shader3
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853
+#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854
+#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857
+#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858
+#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859
+#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A
+#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B
+#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C
+#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D
+#define GL_HILO8_NV 0x885E
+#define GL_SIGNED_HILO8_NV 0x885F
+#define GL_FORCE_BLUE_TO_ONE_NV 0x8860
+#endif
+
+#ifndef GL_NV_vertex_program1_1
+#endif
+
+#ifndef GL_EXT_shadow_funcs
+#endif
+
+#ifndef GL_EXT_stencil_two_side
+#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910
+#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911
+#endif
+
+#ifndef GL_ATI_text_fragment_shader
+#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200
+#endif
+
+#ifndef GL_APPLE_client_storage
+#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2
+#endif
+
+#ifndef GL_APPLE_element_array
+#define GL_ELEMENT_ARRAY_APPLE 0x8A0C
+#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D
+#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E
+#endif
+
+#ifndef GL_APPLE_fence
+#define GL_DRAW_PIXELS_APPLE 0x8A0A
+#define GL_FENCE_APPLE 0x8A0B
+#endif
+
+#ifndef GL_APPLE_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5
+#endif
+
+#ifndef GL_APPLE_vertex_array_range
+#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E
+#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F
+#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521
+#define GL_STORAGE_CLIENT_APPLE 0x85B4
+#define GL_STORAGE_CACHED_APPLE 0x85BE
+#define GL_STORAGE_SHARED_APPLE 0x85BF
+#endif
+
+#ifndef GL_APPLE_ycbcr_422
+#define GL_YCBCR_422_APPLE 0x85B9
+#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
+#endif
+
+#ifndef GL_S3_s3tc
+#define GL_RGB_S3TC 0x83A0
+#define GL_RGB4_S3TC 0x83A1
+#define GL_RGBA_S3TC 0x83A2
+#define GL_RGBA4_S3TC 0x83A3
+#endif
+
+#ifndef GL_ATI_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_ATI 0x8824
+#define GL_DRAW_BUFFER0_ATI 0x8825
+#define GL_DRAW_BUFFER1_ATI 0x8826
+#define GL_DRAW_BUFFER2_ATI 0x8827
+#define GL_DRAW_BUFFER3_ATI 0x8828
+#define GL_DRAW_BUFFER4_ATI 0x8829
+#define GL_DRAW_BUFFER5_ATI 0x882A
+#define GL_DRAW_BUFFER6_ATI 0x882B
+#define GL_DRAW_BUFFER7_ATI 0x882C
+#define GL_DRAW_BUFFER8_ATI 0x882D
+#define GL_DRAW_BUFFER9_ATI 0x882E
+#define GL_DRAW_BUFFER10_ATI 0x882F
+#define GL_DRAW_BUFFER11_ATI 0x8830
+#define GL_DRAW_BUFFER12_ATI 0x8831
+#define GL_DRAW_BUFFER13_ATI 0x8832
+#define GL_DRAW_BUFFER14_ATI 0x8833
+#define GL_DRAW_BUFFER15_ATI 0x8834
+#endif
+
+#ifndef GL_ATI_pixel_format_float
+#define GL_TYPE_RGBA_FLOAT_ATI 0x8820
+#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835
+#endif
+
+#ifndef GL_ATI_texture_env_combine3
+#define GL_MODULATE_ADD_ATI 0x8744
+#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
+#define GL_MODULATE_SUBTRACT_ATI 0x8746
+#endif
+
+#ifndef GL_ATI_texture_float
+#define GL_RGBA_FLOAT32_ATI 0x8814
+#define GL_RGB_FLOAT32_ATI 0x8815
+#define GL_ALPHA_FLOAT32_ATI 0x8816
+#define GL_INTENSITY_FLOAT32_ATI 0x8817
+#define GL_LUMINANCE_FLOAT32_ATI 0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819
+#define GL_RGBA_FLOAT16_ATI 0x881A
+#define GL_RGB_FLOAT16_ATI 0x881B
+#define GL_ALPHA_FLOAT16_ATI 0x881C
+#define GL_INTENSITY_FLOAT16_ATI 0x881D
+#define GL_LUMINANCE_FLOAT16_ATI 0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F
+#endif
+
+#ifndef GL_NV_float_buffer
+#define GL_FLOAT_R_NV 0x8880
+#define GL_FLOAT_RG_NV 0x8881
+#define GL_FLOAT_RGB_NV 0x8882
+#define GL_FLOAT_RGBA_NV 0x8883
+#define GL_FLOAT_R16_NV 0x8884
+#define GL_FLOAT_R32_NV 0x8885
+#define GL_FLOAT_RG16_NV 0x8886
+#define GL_FLOAT_RG32_NV 0x8887
+#define GL_FLOAT_RGB16_NV 0x8888
+#define GL_FLOAT_RGB32_NV 0x8889
+#define GL_FLOAT_RGBA16_NV 0x888A
+#define GL_FLOAT_RGBA32_NV 0x888B
+#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C
+#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D
+#define GL_FLOAT_RGBA_MODE_NV 0x888E
+#endif
+
+#ifndef GL_NV_fragment_program
+#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868
+#define GL_FRAGMENT_PROGRAM_NV 0x8870
+#define GL_MAX_TEXTURE_COORDS_NV 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872
+#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873
+#define GL_PROGRAM_ERROR_STRING_NV 0x8874
+#endif
+
+#ifndef GL_NV_half_float
+#define GL_HALF_FLOAT_NV 0x140B
+#endif
+
+#ifndef GL_NV_pixel_data_range
+#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878
+#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879
+#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A
+#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B
+#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C
+#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D
+#endif
+
+#ifndef GL_NV_primitive_restart
+#define GL_PRIMITIVE_RESTART_NV 0x8558
+#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559
+#endif
+
+#ifndef GL_NV_texture_expand_normal
+#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F
+#endif
+
+#ifndef GL_NV_vertex_program2
+#endif
+
+#ifndef GL_ATI_map_object_buffer
+#endif
+
+#ifndef GL_ATI_separate_stencil
+#define GL_STENCIL_BACK_FUNC_ATI 0x8800
+#define GL_STENCIL_BACK_FAIL_ATI 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803
+#endif
+
+#ifndef GL_ATI_vertex_attrib_array_object
+#endif
+
+#ifndef GL_OES_read_format
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B
+#endif
+
+#ifndef GL_EXT_depth_bounds_test
+#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890
+#define GL_DEPTH_BOUNDS_EXT 0x8891
+#endif
+
+#ifndef GL_EXT_texture_mirror_clamp
+#define GL_MIRROR_CLAMP_EXT 0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743
+#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912
+#endif
+
+#ifndef GL_EXT_blend_equation_separate
+#define GL_BLEND_EQUATION_RGB_EXT 0x8009
+#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D
+#endif
+
+#ifndef GL_MESA_pack_invert
+#define GL_PACK_INVERT_MESA 0x8758
+#endif
+
+#ifndef GL_MESA_ycbcr_texture
+#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB
+#define GL_YCBCR_MESA 0x8757
+#endif
+
+#ifndef GL_EXT_pixel_buffer_object
+#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF
+#endif
+
+#ifndef GL_NV_fragment_program_option
+#endif
+
+#ifndef GL_NV_fragment_program2
+#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4
+#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5
+#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6
+#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7
+#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8
+#endif
+
+#ifndef GL_NV_vertex_program2_option
+/* reuse GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
+/* reuse GL_MAX_PROGRAM_CALL_DEPTH_NV */
+#endif
+
+#ifndef GL_NV_vertex_program3
+/* reuse GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */
+#endif
+
+#ifndef GL_EXT_framebuffer_object
+#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
+#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
+#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
+#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
+#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
+#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
+#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
+#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
+#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
+#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
+#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
+#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
+#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
+#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
+#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
+#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
+#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
+#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
+#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
+#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
+#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
+#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
+#define GL_STENCIL_ATTACHMENT_EXT 0x8D20
+#define GL_FRAMEBUFFER_EXT 0x8D40
+#define GL_RENDERBUFFER_EXT 0x8D41
+#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
+#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
+#define GL_STENCIL_INDEX1_EXT 0x8D46
+#define GL_STENCIL_INDEX4_EXT 0x8D47
+#define GL_STENCIL_INDEX8_EXT 0x8D48
+#define GL_STENCIL_INDEX16_EXT 0x8D49
+#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
+#endif
+
+#ifndef GL_GREMEDY_string_marker
+#endif
+
+#ifndef GL_EXT_packed_depth_stencil
+#define GL_DEPTH_STENCIL_EXT 0x84F9
+#define GL_UNSIGNED_INT_24_8_EXT 0x84FA
+#define GL_DEPTH24_STENCIL8_EXT 0x88F0
+#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
+#endif
+
+#ifndef GL_EXT_stencil_clear_tag
+#define GL_STENCIL_TAG_BITS_EXT 0x88F2
+#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3
+#endif
+
+#ifndef GL_EXT_texture_sRGB
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB8_EXT 0x8C41
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_SLUMINANCE_ALPHA_EXT 0x8C44
+#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
+#define GL_SLUMINANCE_EXT 0x8C46
+#define GL_SLUMINANCE8_EXT 0x8C47
+#define GL_COMPRESSED_SRGB_EXT 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
+#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+#endif
+
+#ifndef GL_EXT_framebuffer_blit
+#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT
+#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT 0x8D57
+#endif
+
+#ifndef GL_MESAX_texture_stack
+#define GL_TEXTURE_1D_STACK_MESAX 0x8759
+#define GL_TEXTURE_2D_STACK_MESAX 0x875A
+#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B
+#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C
+#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D
+#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E
+#endif
+
+#ifndef GL_EXT_timer_query
+#define GL_TIME_ELAPSED_EXT 0x88BF
+#endif
+
+#ifndef GL_EXT_gpu_program_parameters
+#endif
+
+#ifndef GL_APPLE_flush_buffer_range
+#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12
+#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13
+#endif
+
+#ifndef GL_NV_gpu_program4
+#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905
+#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906
+#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907
+#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908
+#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909
+#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5
+#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6
+#endif
+
+#ifndef GL_NV_geometry_program4
+#define GL_LINES_ADJACENCY_EXT 0x000A
+#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B
+#define GL_TRIANGLES_ADJACENCY_EXT 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D
+#define GL_GEOMETRY_PROGRAM_NV 0x8C26
+#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27
+#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28
+#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA
+#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
+#define GL_PROGRAM_POINT_SIZE_EXT 0x8642
+#endif
+
+#ifndef GL_EXT_geometry_shader4
+#define GL_GEOMETRY_SHADER_EXT 0x8DD9
+/* reuse GL_GEOMETRY_VERTICES_OUT_EXT */
+/* reuse GL_GEOMETRY_INPUT_TYPE_EXT */
+/* reuse GL_GEOMETRY_OUTPUT_TYPE_EXT */
+/* reuse GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE
+#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+/* reuse GL_LINES_ADJACENCY_EXT */
+/* reuse GL_LINE_STRIP_ADJACENCY_EXT */
+/* reuse GL_TRIANGLES_ADJACENCY_EXT */
+/* reuse GL_TRIANGLE_STRIP_ADJACENCY_EXT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
+/* reuse GL_PROGRAM_POINT_SIZE_EXT */
+#endif
+
+#ifndef GL_NV_vertex_program4
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD
+#endif
+
+#ifndef GL_EXT_gpu_shader4
+#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0
+#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1
+#define GL_SAMPLER_BUFFER_EXT 0x8DC2
+#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3
+#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5
+#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6
+#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7
+#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8
+#define GL_INT_SAMPLER_1D_EXT 0x8DC9
+#define GL_INT_SAMPLER_2D_EXT 0x8DCA
+#define GL_INT_SAMPLER_3D_EXT 0x8DCB
+#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC
+#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD
+#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE
+#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF
+#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8
+#endif
+
+#ifndef GL_EXT_draw_instanced
+#endif
+
+#ifndef GL_EXT_packed_float
+#define GL_R11F_G11F_B10F_EXT 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B
+#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C
+#endif
+
+#ifndef GL_EXT_texture_array
+#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18
+#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19
+#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A
+#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B
+#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D
+#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF
+#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
+#endif
+
+#ifndef GL_EXT_texture_buffer_object
+#define GL_TEXTURE_BUFFER_EXT 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E
+#endif
+
+#ifndef GL_EXT_texture_compression_latc
+#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
+#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71
+#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
+#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
+#endif
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
+#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
+#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
+#endif
+
+#ifndef GL_EXT_texture_shared_exponent
+#define GL_RGB9_E5_EXT 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E
+#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F
+#endif
+
+#ifndef GL_NV_depth_buffer_float
+#define GL_DEPTH_COMPONENT32F_NV 0x8DAB
+#define GL_DEPTH32F_STENCIL8_NV 0x8DAC
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD
+#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF
+#endif
+
+#ifndef GL_NV_fragment_program4
+#endif
+
+#ifndef GL_NV_framebuffer_multisample_coverage
+#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB
+#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10
+#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11
+#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12
+#endif
+
+#ifndef GL_EXT_framebuffer_sRGB
+#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
+#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA
+#endif
+
+#ifndef GL_NV_geometry_shader4
+#endif
+
+#ifndef GL_NV_parameter_buffer_object
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1
+#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2
+#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3
+#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4
+#endif
+
+#ifndef GL_EXT_draw_buffers2
+#endif
+
+#ifndef GL_NV_transform_feedback
+#define GL_BACK_PRIMARY_COLOR_NV 0x8C77
+#define GL_BACK_SECONDARY_COLOR_NV 0x8C78
+#define GL_TEXTURE_COORD_NV 0x8C79
+#define GL_CLIP_DISTANCE_NV 0x8C7A
+#define GL_VERTEX_ID_NV 0x8C7B
+#define GL_PRIMITIVE_ID_NV 0x8C7C
+#define GL_GENERIC_ATTRIB_NV 0x8C7D
+#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80
+#define GL_ACTIVE_VARYINGS_NV 0x8C81
+#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85
+#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86
+#define GL_PRIMITIVES_GENERATED_NV 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88
+#define GL_RASTERIZER_DISCARD_NV 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C
+#define GL_SEPARATE_ATTRIBS_NV 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F
+#define GL_LAYER_NV 0x8DAA
+#define GL_NEXT_BUFFER_NV -2
+#define GL_SKIP_COMPONENTS4_NV -3
+#define GL_SKIP_COMPONENTS3_NV -4
+#define GL_SKIP_COMPONENTS2_NV -5
+#define GL_SKIP_COMPONENTS1_NV -6
+#endif
+
+#ifndef GL_EXT_bindable_uniform
+#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2
+#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3
+#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4
+#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED
+#define GL_UNIFORM_BUFFER_EXT 0x8DEE
+#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF
+#endif
+
+#ifndef GL_EXT_texture_integer
+#define GL_RGBA32UI_EXT 0x8D70
+#define GL_RGB32UI_EXT 0x8D71
+#define GL_ALPHA32UI_EXT 0x8D72
+#define GL_INTENSITY32UI_EXT 0x8D73
+#define GL_LUMINANCE32UI_EXT 0x8D74
+#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75
+#define GL_RGBA16UI_EXT 0x8D76
+#define GL_RGB16UI_EXT 0x8D77
+#define GL_ALPHA16UI_EXT 0x8D78
+#define GL_INTENSITY16UI_EXT 0x8D79
+#define GL_LUMINANCE16UI_EXT 0x8D7A
+#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B
+#define GL_RGBA8UI_EXT 0x8D7C
+#define GL_RGB8UI_EXT 0x8D7D
+#define GL_ALPHA8UI_EXT 0x8D7E
+#define GL_INTENSITY8UI_EXT 0x8D7F
+#define GL_LUMINANCE8UI_EXT 0x8D80
+#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81
+#define GL_RGBA32I_EXT 0x8D82
+#define GL_RGB32I_EXT 0x8D83
+#define GL_ALPHA32I_EXT 0x8D84
+#define GL_INTENSITY32I_EXT 0x8D85
+#define GL_LUMINANCE32I_EXT 0x8D86
+#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87
+#define GL_RGBA16I_EXT 0x8D88
+#define GL_RGB16I_EXT 0x8D89
+#define GL_ALPHA16I_EXT 0x8D8A
+#define GL_INTENSITY16I_EXT 0x8D8B
+#define GL_LUMINANCE16I_EXT 0x8D8C
+#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D
+#define GL_RGBA8I_EXT 0x8D8E
+#define GL_RGB8I_EXT 0x8D8F
+#define GL_ALPHA8I_EXT 0x8D90
+#define GL_INTENSITY8I_EXT 0x8D91
+#define GL_LUMINANCE8I_EXT 0x8D92
+#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93
+#define GL_RED_INTEGER_EXT 0x8D94
+#define GL_GREEN_INTEGER_EXT 0x8D95
+#define GL_BLUE_INTEGER_EXT 0x8D96
+#define GL_ALPHA_INTEGER_EXT 0x8D97
+#define GL_RGB_INTEGER_EXT 0x8D98
+#define GL_RGBA_INTEGER_EXT 0x8D99
+#define GL_BGR_INTEGER_EXT 0x8D9A
+#define GL_BGRA_INTEGER_EXT 0x8D9B
+#define GL_LUMINANCE_INTEGER_EXT 0x8D9C
+#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D
+#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E
+#endif
+
+#ifndef GL_GREMEDY_frame_terminator
+#endif
+
+#ifndef GL_NV_conditional_render
+#define GL_QUERY_WAIT_NV 0x8E13
+#define GL_QUERY_NO_WAIT_NV 0x8E14
+#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15
+#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16
+#endif
+
+#ifndef GL_NV_present_video
+#define GL_FRAME_NV 0x8E26
+#define GL_FIELDS_NV 0x8E27
+#define GL_CURRENT_TIME_NV 0x8E28
+#define GL_NUM_FILL_STREAMS_NV 0x8E29
+#define GL_PRESENT_TIME_NV 0x8E2A
+#define GL_PRESENT_DURATION_NV 0x8E2B
+#endif
+
+#ifndef GL_EXT_transform_feedback
+#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F
+#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C
+#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D
+#define GL_PRIMITIVES_GENERATED_EXT 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88
+#define GL_RASTERIZER_DISCARD_EXT 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76
+#endif
+
+#ifndef GL_EXT_direct_state_access
+#define GL_PROGRAM_MATRIX_EXT 0x8E2D
+#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E
+#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F
+#endif
+
+#ifndef GL_EXT_vertex_array_bgra
+/* reuse GL_BGRA */
+#endif
+
+#ifndef GL_EXT_texture_swizzle
+#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42
+#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43
+#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44
+#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45
+#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46
+#endif
+
+#ifndef GL_NV_explicit_multisample
+#define GL_SAMPLE_POSITION_NV 0x8E50
+#define GL_SAMPLE_MASK_NV 0x8E51
+#define GL_SAMPLE_MASK_VALUE_NV 0x8E52
+#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53
+#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54
+#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55
+#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56
+#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57
+#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58
+#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59
+#endif
+
+#ifndef GL_NV_transform_feedback2
+#define GL_TRANSFORM_FEEDBACK_NV 0x8E22
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25
+#endif
+
+#ifndef GL_ATI_meminfo
+#define GL_VBO_FREE_MEMORY_ATI 0x87FB
+#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
+#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
+#endif
+
+#ifndef GL_AMD_performance_monitor
+#define GL_COUNTER_TYPE_AMD 0x8BC0
+#define GL_COUNTER_RANGE_AMD 0x8BC1
+#define GL_UNSIGNED_INT64_AMD 0x8BC2
+#define GL_PERCENTAGE_AMD 0x8BC3
+#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4
+#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5
+#define GL_PERFMON_RESULT_AMD 0x8BC6
+#endif
+
+#ifndef GL_AMD_texture_texture4
+#endif
+
+#ifndef GL_AMD_vertex_shader_tesselator
+#define GL_SAMPLER_BUFFER_AMD 0x9001
+#define GL_INT_SAMPLER_BUFFER_AMD 0x9002
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003
+#define GL_TESSELLATION_MODE_AMD 0x9004
+#define GL_TESSELLATION_FACTOR_AMD 0x9005
+#define GL_DISCRETE_AMD 0x9006
+#define GL_CONTINUOUS_AMD 0x9007
+#endif
+
+#ifndef GL_EXT_provoking_vertex
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E
+#define GL_PROVOKING_VERTEX_EXT 0x8E4F
+#endif
+
+#ifndef GL_EXT_texture_snorm
+#define GL_ALPHA_SNORM 0x9010
+#define GL_LUMINANCE_SNORM 0x9011
+#define GL_LUMINANCE_ALPHA_SNORM 0x9012
+#define GL_INTENSITY_SNORM 0x9013
+#define GL_ALPHA8_SNORM 0x9014
+#define GL_LUMINANCE8_SNORM 0x9015
+#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016
+#define GL_INTENSITY8_SNORM 0x9017
+#define GL_ALPHA16_SNORM 0x9018
+#define GL_LUMINANCE16_SNORM 0x9019
+#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A
+#define GL_INTENSITY16_SNORM 0x901B
+/* reuse GL_RED_SNORM */
+/* reuse GL_RG_SNORM */
+/* reuse GL_RGB_SNORM */
+/* reuse GL_RGBA_SNORM */
+/* reuse GL_R8_SNORM */
+/* reuse GL_RG8_SNORM */
+/* reuse GL_RGB8_SNORM */
+/* reuse GL_RGBA8_SNORM */
+/* reuse GL_R16_SNORM */
+/* reuse GL_RG16_SNORM */
+/* reuse GL_RGB16_SNORM */
+/* reuse GL_RGBA16_SNORM */
+/* reuse GL_SIGNED_NORMALIZED */
+#endif
+
+#ifndef GL_AMD_draw_buffers_blend
+#endif
+
+#ifndef GL_APPLE_texture_range
+#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7
+#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8
+#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
+#define GL_STORAGE_PRIVATE_APPLE 0x85BD
+/* reuse GL_STORAGE_CACHED_APPLE */
+/* reuse GL_STORAGE_SHARED_APPLE */
+#endif
+
+#ifndef GL_APPLE_float_pixels
+#define GL_HALF_APPLE 0x140B
+#define GL_RGBA_FLOAT32_APPLE 0x8814
+#define GL_RGB_FLOAT32_APPLE 0x8815
+#define GL_ALPHA_FLOAT32_APPLE 0x8816
+#define GL_INTENSITY_FLOAT32_APPLE 0x8817
+#define GL_LUMINANCE_FLOAT32_APPLE 0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819
+#define GL_RGBA_FLOAT16_APPLE 0x881A
+#define GL_RGB_FLOAT16_APPLE 0x881B
+#define GL_ALPHA_FLOAT16_APPLE 0x881C
+#define GL_INTENSITY_FLOAT16_APPLE 0x881D
+#define GL_LUMINANCE_FLOAT16_APPLE 0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F
+#define GL_COLOR_FLOAT_APPLE 0x8A0F
+#endif
+
+#ifndef GL_APPLE_vertex_program_evaluators
+#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00
+#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01
+#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02
+#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03
+#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04
+#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05
+#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06
+#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07
+#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08
+#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09
+#endif
+
+#ifndef GL_APPLE_aux_depth_stencil
+#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14
+#endif
+
+#ifndef GL_APPLE_object_purgeable
+#define GL_BUFFER_OBJECT_APPLE 0x85B3
+#define GL_RELEASED_APPLE 0x8A19
+#define GL_VOLATILE_APPLE 0x8A1A
+#define GL_RETAINED_APPLE 0x8A1B
+#define GL_UNDEFINED_APPLE 0x8A1C
+#define GL_PURGEABLE_APPLE 0x8A1D
+#endif
+
+#ifndef GL_APPLE_row_bytes
+#define GL_PACK_ROW_BYTES_APPLE 0x8A15
+#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16
+#endif
+
+#ifndef GL_APPLE_rgb_422
+#define GL_RGB_422_APPLE 0x8A1F
+/* reuse GL_UNSIGNED_SHORT_8_8_APPLE */
+/* reuse GL_UNSIGNED_SHORT_8_8_REV_APPLE */
+#endif
+
+#ifndef GL_NV_video_capture
+#define GL_VIDEO_BUFFER_NV 0x9020
+#define GL_VIDEO_BUFFER_BINDING_NV 0x9021
+#define GL_FIELD_UPPER_NV 0x9022
+#define GL_FIELD_LOWER_NV 0x9023
+#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024
+#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025
+#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026
+#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027
+#define GL_VIDEO_BUFFER_PITCH_NV 0x9028
+#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029
+#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A
+#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B
+#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C
+#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D
+#define GL_PARTIAL_SUCCESS_NV 0x902E
+#define GL_SUCCESS_NV 0x902F
+#define GL_FAILURE_NV 0x9030
+#define GL_YCBYCR8_422_NV 0x9031
+#define GL_YCBAYCR8A_4224_NV 0x9032
+#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033
+#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034
+#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035
+#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036
+#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037
+#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038
+#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039
+#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A
+#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B
+#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C
+#endif
+
+#ifndef GL_NV_copy_image
+#endif
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_ACTIVE_PROGRAM_EXT 0x8B8D
+#endif
+
+#ifndef GL_NV_parameter_buffer_object2
+#endif
+
+#ifndef GL_NV_shader_buffer_load
+#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D
+#define GL_GPU_ADDRESS_NV 0x8F34
+#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35
+#endif
+
+#ifndef GL_NV_vertex_buffer_unified_memory
+#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E
+#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F
+#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20
+#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21
+#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22
+#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23
+#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24
+#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25
+#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26
+#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27
+#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28
+#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29
+#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A
+#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B
+#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C
+#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D
+#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E
+#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F
+#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30
+#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31
+#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32
+#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33
+#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40
+#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41
+#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42
+#endif
+
+#ifndef GL_NV_texture_barrier
+#endif
+
+#ifndef GL_AMD_shader_stencil_export
+#endif
+
+#ifndef GL_AMD_seamless_cubemap_per_texture
+/* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS */
+#endif
+
+#ifndef GL_AMD_conservative_depth
+#endif
+
+#ifndef GL_EXT_shader_image_load_store
+#define GL_MAX_IMAGE_UNITS_EXT 0x8F38
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39
+#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A
+#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B
+#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C
+#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D
+#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E
+#define GL_IMAGE_1D_EXT 0x904C
+#define GL_IMAGE_2D_EXT 0x904D
+#define GL_IMAGE_3D_EXT 0x904E
+#define GL_IMAGE_2D_RECT_EXT 0x904F
+#define GL_IMAGE_CUBE_EXT 0x9050
+#define GL_IMAGE_BUFFER_EXT 0x9051
+#define GL_IMAGE_1D_ARRAY_EXT 0x9052
+#define GL_IMAGE_2D_ARRAY_EXT 0x9053
+#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054
+#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056
+#define GL_INT_IMAGE_1D_EXT 0x9057
+#define GL_INT_IMAGE_2D_EXT 0x9058
+#define GL_INT_IMAGE_3D_EXT 0x9059
+#define GL_INT_IMAGE_2D_RECT_EXT 0x905A
+#define GL_INT_IMAGE_CUBE_EXT 0x905B
+#define GL_INT_IMAGE_BUFFER_EXT 0x905C
+#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D
+#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F
+#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061
+#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062
+#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063
+#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066
+#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C
+#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D
+#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001
+#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002
+#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004
+#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020
+#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040
+#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080
+#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100
+#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200
+#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800
+#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000
+#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF
+#endif
+
+#ifndef GL_EXT_vertex_attrib_64bit
+/* reuse GL_DOUBLE */
+#define GL_DOUBLE_VEC2_EXT 0x8FFC
+#define GL_DOUBLE_VEC3_EXT 0x8FFD
+#define GL_DOUBLE_VEC4_EXT 0x8FFE
+#define GL_DOUBLE_MAT2_EXT 0x8F46
+#define GL_DOUBLE_MAT3_EXT 0x8F47
+#define GL_DOUBLE_MAT4_EXT 0x8F48
+#define GL_DOUBLE_MAT2x3_EXT 0x8F49
+#define GL_DOUBLE_MAT2x4_EXT 0x8F4A
+#define GL_DOUBLE_MAT3x2_EXT 0x8F4B
+#define GL_DOUBLE_MAT3x4_EXT 0x8F4C
+#define GL_DOUBLE_MAT4x2_EXT 0x8F4D
+#define GL_DOUBLE_MAT4x3_EXT 0x8F4E
+#endif
+
+#ifndef GL_NV_gpu_program5
+#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C
+#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F
+#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44
+#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45
+#endif
+
+#ifndef GL_NV_gpu_shader5
+#define GL_INT64_NV 0x140E
+#define GL_UNSIGNED_INT64_NV 0x140F
+#define GL_INT8_NV 0x8FE0
+#define GL_INT8_VEC2_NV 0x8FE1
+#define GL_INT8_VEC3_NV 0x8FE2
+#define GL_INT8_VEC4_NV 0x8FE3
+#define GL_INT16_NV 0x8FE4
+#define GL_INT16_VEC2_NV 0x8FE5
+#define GL_INT16_VEC3_NV 0x8FE6
+#define GL_INT16_VEC4_NV 0x8FE7
+#define GL_INT64_VEC2_NV 0x8FE9
+#define GL_INT64_VEC3_NV 0x8FEA
+#define GL_INT64_VEC4_NV 0x8FEB
+#define GL_UNSIGNED_INT8_NV 0x8FEC
+#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED
+#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE
+#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF
+#define GL_UNSIGNED_INT16_NV 0x8FF0
+#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1
+#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2
+#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3
+#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5
+#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6
+#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7
+#define GL_FLOAT16_NV 0x8FF8
+#define GL_FLOAT16_VEC2_NV 0x8FF9
+#define GL_FLOAT16_VEC3_NV 0x8FFA
+#define GL_FLOAT16_VEC4_NV 0x8FFB
+/* reuse GL_PATCHES */
+#endif
+
+#ifndef GL_NV_shader_buffer_store
+#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010
+/* reuse GL_READ_WRITE */
+/* reuse GL_WRITE_ONLY */
+#endif
+
+#ifndef GL_NV_tessellation_program5
+#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8
+#define GL_TESS_CONTROL_PROGRAM_NV 0x891E
+#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F
+#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74
+#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75
+#endif
+
+#ifndef GL_NV_vertex_attrib_integer_64bit
+/* reuse GL_INT64_NV */
+/* reuse GL_UNSIGNED_INT64_NV */
+#endif
+
+#ifndef GL_NV_multisample_coverage
+#define GL_COVERAGE_SAMPLES_NV 0x80A9
+#define GL_COLOR_SAMPLES_NV 0x8E20
+#endif
+
+#ifndef GL_AMD_name_gen_delete
+#define GL_DATA_BUFFER_AMD 0x9151
+#define GL_PERFORMANCE_MONITOR_AMD 0x9152
+#define GL_QUERY_OBJECT_AMD 0x9153
+#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154
+#define GL_SAMPLER_OBJECT_AMD 0x9155
+#endif
+
+#ifndef GL_AMD_debug_output
+#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145
+#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147
+#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148
+#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149
+#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A
+#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B
+#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C
+#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D
+#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E
+#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F
+#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150
+#endif
+
+#ifndef GL_NV_vdpau_interop
+#define GL_SURFACE_STATE_NV 0x86EB
+#define GL_SURFACE_REGISTERED_NV 0x86FD
+#define GL_SURFACE_MAPPED_NV 0x8700
+#define GL_WRITE_DISCARD_NV 0x88BE
+#endif
+
+#ifndef GL_AMD_transform_feedback3_lines_triangles
+#endif
+
+#ifndef GL_AMD_depth_clamp_separate
+#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E
+#define GL_DEPTH_CLAMP_FAR_AMD 0x901F
+#endif
+
+#ifndef GL_EXT_texture_sRGB_decode
+#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
+#define GL_DECODE_EXT 0x8A49
+#define GL_SKIP_DECODE_EXT 0x8A4A
+#endif
+
+#ifndef GL_NV_texture_multisample
+#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045
+#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046
+#endif
+
+#ifndef GL_AMD_blend_minmax_factor
+#define GL_FACTOR_MIN_AMD 0x901C
+#define GL_FACTOR_MAX_AMD 0x901D
+#endif
+
+
+/*************************************************************/
+
+#include <stddef.h>
+#ifndef GL_VERSION_2_0
+/* GL type for program/shader text */
+typedef char GLchar;
+#endif
+
+#ifndef GL_VERSION_1_5
+/* GL types for handling large vertex buffer objects */
+typedef ptrdiff_t GLintptr;
+typedef ptrdiff_t GLsizeiptr;
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+/* GL types for handling large vertex buffer objects */
+typedef ptrdiff_t GLintptrARB;
+typedef ptrdiff_t GLsizeiptrARB;
+#endif
+
+#ifndef GL_ARB_shader_objects
+/* GL types for program/shader text and shader object handles */
+typedef char GLcharARB;
+typedef unsigned int GLhandleARB;
+#endif
+
+/* GL type for "half" precision (s10e5) float data in host memory */
+#ifndef GL_ARB_half_float_pixel
+typedef unsigned short GLhalfARB;
+#endif
+
+#ifndef GL_NV_half_float
+typedef unsigned short GLhalfNV;
+#endif
+
+#ifndef GLEXT_64_TYPES_DEFINED
+/* This code block is duplicated in glxext.h, so must be protected */
+#define GLEXT_64_TYPES_DEFINED
+/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
+/* (as used in the GL_EXT_timer_query extension). */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+#elif defined(__sun__) || defined(__digital__)
+#include <inttypes.h>
+#if defined(__STDC__)
+#if defined(__arch64__) || defined(_LP64)
+typedef long int int64_t;
+typedef unsigned long int uint64_t;
+#else
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#endif /* __arch64__ */
+#endif /* __STDC__ */
+#elif defined( __VMS ) || defined(__sgi)
+#include <inttypes.h>
+#elif defined(__SCO__) || defined(__USLC__)
+#include <stdint.h>
+#elif defined(__UNIXOS2__) || defined(__SOL64__)
+typedef long int int32_t;
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#elif defined(_WIN32) && defined(__GNUC__)
+#include <stdint.h>
+#elif defined(_WIN32)
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+/* Fallback if nothing above works */
+#include <inttypes.h>
+#endif
+#endif
+
+#ifndef GL_EXT_timer_query
+typedef int64_t GLint64EXT;
+typedef uint64_t GLuint64EXT;
+#endif
+
+#ifndef GL_ARB_sync
+typedef int64_t GLint64;
+typedef uint64_t GLuint64;
+typedef struct __GLsync *GLsync;
+#endif
+
+#ifndef GL_ARB_cl_event
+/* These incomplete types let us declare types compatible with OpenCL's cl_context and cl_event */
+struct _cl_context;
+struct _cl_event;
+#endif
+
+#ifndef GL_ARB_debug_output
+typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+#endif
+
+#ifndef GL_AMD_debug_output
+typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+#endif
+
+#ifndef GL_NV_vdpau_interop
+typedef GLintptr GLvdpauSurfaceNV;
+#endif
+
+#ifndef GL_VERSION_1_2
+#define GL_VERSION_1_2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+GLAPI void APIENTRY glBlendEquation (GLenum mode);
+GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_VERSION_1_2_DEPRECATED
+#define GL_VERSION_1_2_DEPRECATED 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+GLAPI void APIENTRY glColorTableParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glColorTableParameteriv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyColorTable (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glGetColorTable (GLenum target, GLenum format, GLenum type, GLvoid *table);
+GLAPI void APIENTRY glGetColorTableParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetColorTableParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+GLAPI void APIENTRY glCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionParameterf (GLenum target, GLenum pname, GLfloat params);
+GLAPI void APIENTRY glConvolutionParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glConvolutionParameteri (GLenum target, GLenum pname, GLint params);
+GLAPI void APIENTRY glConvolutionParameteriv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetConvolutionFilter (GLenum target, GLenum format, GLenum type, GLvoid *image);
+GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSeparableFilter (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+GLAPI void APIENTRY glSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+GLAPI void APIENTRY glGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetHistogramParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetHistogramParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glHistogram (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glMinmax (GLenum target, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glResetHistogram (GLenum target);
+GLAPI void APIENTRY glResetMinmax (GLenum target);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target);
+#endif
+
+#ifndef GL_VERSION_1_3
+#define GL_VERSION_1_3 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveTexture (GLenum texture);
+GLAPI void APIENTRY glSampleCoverage (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, GLvoid *img);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img);
+#endif
+
+#ifndef GL_VERSION_1_3_DEPRECATED
+#define GL_VERSION_1_3_DEPRECATED 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClientActiveTexture (GLenum texture);
+GLAPI void APIENTRY glMultiTexCoord1d (GLenum target, GLdouble s);
+GLAPI void APIENTRY glMultiTexCoord1dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord1f (GLenum target, GLfloat s);
+GLAPI void APIENTRY glMultiTexCoord1fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord1i (GLenum target, GLint s);
+GLAPI void APIENTRY glMultiTexCoord1iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord1s (GLenum target, GLshort s);
+GLAPI void APIENTRY glMultiTexCoord1sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord2d (GLenum target, GLdouble s, GLdouble t);
+GLAPI void APIENTRY glMultiTexCoord2dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord2f (GLenum target, GLfloat s, GLfloat t);
+GLAPI void APIENTRY glMultiTexCoord2fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord2i (GLenum target, GLint s, GLint t);
+GLAPI void APIENTRY glMultiTexCoord2iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord2s (GLenum target, GLshort s, GLshort t);
+GLAPI void APIENTRY glMultiTexCoord2sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord3d (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+GLAPI void APIENTRY glMultiTexCoord3dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord3f (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+GLAPI void APIENTRY glMultiTexCoord3fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord3i (GLenum target, GLint s, GLint t, GLint r);
+GLAPI void APIENTRY glMultiTexCoord3iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord3s (GLenum target, GLshort s, GLshort t, GLshort r);
+GLAPI void APIENTRY glMultiTexCoord3sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord4d (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+GLAPI void APIENTRY glMultiTexCoord4dv (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GLAPI void APIENTRY glMultiTexCoord4fv (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord4i (GLenum target, GLint s, GLint t, GLint r, GLint q);
+GLAPI void APIENTRY glMultiTexCoord4iv (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord4s (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+GLAPI void APIENTRY glMultiTexCoord4sv (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *m);
+GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *m);
+GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *m);
+GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m);
+#endif
+
+#ifndef GL_VERSION_1_4
+#define GL_VERSION_1_4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param);
+GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_VERSION_1_4_DEPRECATED
+#define GL_VERSION_1_4_DEPRECATED 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogCoordf (GLfloat coord);
+GLAPI void APIENTRY glFogCoordfv (const GLfloat *coord);
+GLAPI void APIENTRY glFogCoordd (GLdouble coord);
+GLAPI void APIENTRY glFogCoorddv (const GLdouble *coord);
+GLAPI void APIENTRY glFogCoordPointer (GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glSecondaryColor3b (GLbyte red, GLbyte green, GLbyte blue);
+GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *v);
+GLAPI void APIENTRY glSecondaryColor3d (GLdouble red, GLdouble green, GLdouble blue);
+GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *v);
+GLAPI void APIENTRY glSecondaryColor3f (GLfloat red, GLfloat green, GLfloat blue);
+GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *v);
+GLAPI void APIENTRY glSecondaryColor3i (GLint red, GLint green, GLint blue);
+GLAPI void APIENTRY glSecondaryColor3iv (const GLint *v);
+GLAPI void APIENTRY glSecondaryColor3s (GLshort red, GLshort green, GLshort blue);
+GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *v);
+GLAPI void APIENTRY glSecondaryColor3ub (GLubyte red, GLubyte green, GLubyte blue);
+GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *v);
+GLAPI void APIENTRY glSecondaryColor3ui (GLuint red, GLuint green, GLuint blue);
+GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *v);
+GLAPI void APIENTRY glSecondaryColor3us (GLushort red, GLushort green, GLushort blue);
+GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *v);
+GLAPI void APIENTRY glSecondaryColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glWindowPos2d (GLdouble x, GLdouble y);
+GLAPI void APIENTRY glWindowPos2dv (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos2f (GLfloat x, GLfloat y);
+GLAPI void APIENTRY glWindowPos2fv (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos2i (GLint x, GLint y);
+GLAPI void APIENTRY glWindowPos2iv (const GLint *v);
+GLAPI void APIENTRY glWindowPos2s (GLshort x, GLshort y);
+GLAPI void APIENTRY glWindowPos2sv (const GLshort *v);
+GLAPI void APIENTRY glWindowPos3d (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glWindowPos3dv (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos3f (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glWindowPos3fv (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos3i (GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glWindowPos3iv (const GLint *v);
+GLAPI void APIENTRY glWindowPos3s (GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glWindowPos3sv (const GLshort *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord);
+typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_VERSION_1_5
+#define GL_VERSION_1_5 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids);
+GLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids);
+GLAPI GLboolean APIENTRY glIsQuery (GLuint id);
+GLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id);
+GLAPI void APIENTRY glEndQuery (GLenum target);
+GLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
+GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
+GLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer);
+GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
+GLAPI GLvoid* APIENTRY glMapBuffer (GLenum target, GLenum access);
+GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target);
+GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
+typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_VERSION_2_0
+#define GL_VERSION_2_0 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
+GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs);
+GLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+GLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
+GLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
+GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader);
+GLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name);
+GLAPI void APIENTRY glCompileShader (GLuint shader);
+GLAPI GLuint APIENTRY glCreateProgram (void);
+GLAPI GLuint APIENTRY glCreateShader (GLenum type);
+GLAPI void APIENTRY glDeleteProgram (GLuint program);
+GLAPI void APIENTRY glDeleteShader (GLuint shader);
+GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader);
+GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index);
+GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index);
+GLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj);
+GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+GLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params);
+GLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid* *pointer);
+GLAPI GLboolean APIENTRY glIsProgram (GLuint program);
+GLAPI GLboolean APIENTRY glIsShader (GLuint shader);
+GLAPI void APIENTRY glLinkProgram (GLuint program);
+GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
+GLAPI void APIENTRY glUseProgram (GLuint program);
+GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0);
+GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glUniform1i (GLint location, GLint v0);
+GLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glValidateProgram (GLuint program);
+GLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x);
+GLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x);
+GLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs);
+typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask);
+typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);
+typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);
+typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
+typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
+typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj);
+typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
+typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader);
+typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
+typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_VERSION_2_1
+#define GL_VERSION_2_1 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#endif
+
+#ifndef GL_VERSION_3_0
+#define GL_VERSION_3_0 1
+/* OpenGL 3.0 also reuses entry points from these extensions: */
+/* ARB_framebuffer_object */
+/* ARB_map_buffer_range */
+/* ARB_vertex_array_object */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data);
+GLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data);
+GLAPI void APIENTRY glEnablei (GLenum target, GLuint index);
+GLAPI void APIENTRY glDisablei (GLenum target, GLuint index);
+GLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index);
+GLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode);
+GLAPI void APIENTRY glEndTransformFeedback (void);
+GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer);
+GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp);
+GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode);
+GLAPI void APIENTRY glEndConditionalRender (void);
+GLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x);
+GLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y);
+GLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x);
+GLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y);
+GLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z);
+GLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params);
+GLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name);
+GLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0);
+GLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value);
+GLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value);
+GLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+GLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+GLAPI const GLubyte * APIENTRY glGetStringi (GLenum name, GLuint index);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data);
+typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index);
+typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode);
+typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void);
+typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp);
+typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode);
+typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
+#endif
+
+#ifndef GL_VERSION_3_1
+#define GL_VERSION_3_1 1
+/* OpenGL 3.1 also reuses entry points from these extensions: */
+/* ARB_copy_buffer */
+/* ARB_uniform_buffer_object */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer);
+GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index);
+#endif
+
+#ifndef GL_VERSION_3_2
+#define GL_VERSION_3_2 1
+/* OpenGL 3.2 also reuses entry points from these extensions: */
+/* ARB_draw_elements_base_vertex */
+/* ARB_provoking_vertex */
+/* ARB_sync */
+/* ARB_texture_multisample */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data);
+GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params);
+GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+#endif
+
+#ifndef GL_VERSION_3_3
+#define GL_VERSION_3_3 1
+/* OpenGL 3.3 also reuses entry points from these extensions: */
+/* ARB_blend_func_extended */
+/* ARB_sampler_objects */
+/* ARB_explicit_attrib_location, but it has none */
+/* ARB_occlusion_query2 (no entry points) */
+/* ARB_shader_bit_encoding (no entry points) */
+/* ARB_texture_rgb10_a2ui (no entry points) */
+/* ARB_texture_swizzle (no entry points) */
+/* ARB_timer_query */
+/* ARB_vertex_type_2_10_10_10_rev */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor);
+#endif
+
+#ifndef GL_VERSION_4_0
+#define GL_VERSION_4_0 1
+/* OpenGL 4.0 also reuses entry points from these extensions: */
+/* ARB_texture_query_lod (no entry points) */
+/* ARB_draw_indirect */
+/* ARB_gpu_shader5 (no entry points) */
+/* ARB_gpu_shader_fp64 */
+/* ARB_shader_subroutine */
+/* ARB_tessellation_shader */
+/* ARB_texture_buffer_object_rgb32 (no entry points) */
+/* ARB_texture_cube_map_array (no entry points) */
+/* ARB_texture_gather (no entry points) */
+/* ARB_transform_feedback2 */
+/* ARB_transform_feedback3 */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMinSampleShading (GLclampf value);
+GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode);
+GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst);
+GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLclampf value);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+
+#ifndef GL_VERSION_4_1
+#define GL_VERSION_4_1 1
+/* OpenGL 4.1 also reuses entry points from these extensions: */
+/* ARB_ES2_compatibility */
+/* ARB_get_program_binary */
+/* ARB_separate_shader_objects */
+/* ARB_shader_precision (no entry points) */
+/* ARB_vertex_attrib_64bit */
+/* ARB_viewport_array */
+#endif
+
+#ifndef GL_ARB_multitexture
+#define GL_ARB_multitexture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveTextureARB (GLenum texture);
+GLAPI void APIENTRY glClientActiveTextureARB (GLenum texture);
+GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum target, GLdouble s);
+GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum target, GLfloat s);
+GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum target, GLint s);
+GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum target, GLshort s);
+GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum target, GLdouble s, GLdouble t);
+GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum target, GLfloat s, GLfloat t);
+GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum target, GLint s, GLint t);
+GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum target, GLshort s, GLshort t);
+GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum target, GLint s, GLint t, GLint r);
+GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum target, GLshort s, GLshort t, GLshort r);
+GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum target, const GLshort *v);
+GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum target, const GLdouble *v);
+GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum target, const GLfloat *v);
+GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum target, GLint s, GLint t, GLint r, GLint q);
+GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum target, const GLint *v);
+GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum target, const GLshort *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v);
+#endif
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_ARB_transpose_matrix 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *m);
+GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *m);
+GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *m);
+GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *m);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+#endif
+
+#ifndef GL_ARB_multisample
+#define GL_ARB_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleCoverageARB (GLclampf value, GLboolean invert);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert);
+#endif
+
+#ifndef GL_ARB_texture_env_add
+#define GL_ARB_texture_env_add 1
+#endif
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_ARB_texture_cube_map 1
+#endif
+
+#ifndef GL_ARB_texture_compression
+#define GL_ARB_texture_compression 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, GLvoid *img);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img);
+#endif
+
+#ifndef GL_ARB_texture_border_clamp
+#define GL_ARB_texture_border_clamp 1
+#endif
+
+#ifndef GL_ARB_point_parameters
+#define GL_ARB_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfARB (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_ARB_vertex_blend
+#define GL_ARB_vertex_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWeightbvARB (GLint size, const GLbyte *weights);
+GLAPI void APIENTRY glWeightsvARB (GLint size, const GLshort *weights);
+GLAPI void APIENTRY glWeightivARB (GLint size, const GLint *weights);
+GLAPI void APIENTRY glWeightfvARB (GLint size, const GLfloat *weights);
+GLAPI void APIENTRY glWeightdvARB (GLint size, const GLdouble *weights);
+GLAPI void APIENTRY glWeightubvARB (GLint size, const GLubyte *weights);
+GLAPI void APIENTRY glWeightusvARB (GLint size, const GLushort *weights);
+GLAPI void APIENTRY glWeightuivARB (GLint size, const GLuint *weights);
+GLAPI void APIENTRY glWeightPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glVertexBlendARB (GLint count);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights);
+typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights);
+typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights);
+typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights);
+typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights);
+typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count);
+#endif
+
+#ifndef GL_ARB_matrix_palette
+#define GL_ARB_matrix_palette 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint index);
+GLAPI void APIENTRY glMatrixIndexubvARB (GLint size, const GLubyte *indices);
+GLAPI void APIENTRY glMatrixIndexusvARB (GLint size, const GLushort *indices);
+GLAPI void APIENTRY glMatrixIndexuivARB (GLint size, const GLuint *indices);
+GLAPI void APIENTRY glMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_ARB_texture_env_combine 1
+#endif
+
+#ifndef GL_ARB_texture_env_crossbar
+#define GL_ARB_texture_env_crossbar 1
+#endif
+
+#ifndef GL_ARB_texture_env_dot3
+#define GL_ARB_texture_env_dot3 1
+#endif
+
+#ifndef GL_ARB_texture_mirrored_repeat
+#define GL_ARB_texture_mirrored_repeat 1
+#endif
+
+#ifndef GL_ARB_depth_texture
+#define GL_ARB_depth_texture 1
+#endif
+
+#ifndef GL_ARB_shadow
+#define GL_ARB_shadow 1
+#endif
+
+#ifndef GL_ARB_shadow_ambient
+#define GL_ARB_shadow_ambient 1
+#endif
+
+#ifndef GL_ARB_window_pos
+#define GL_ARB_window_pos 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWindowPos2dARB (GLdouble x, GLdouble y);
+GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos2fARB (GLfloat x, GLfloat y);
+GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos2iARB (GLint x, GLint y);
+GLAPI void APIENTRY glWindowPos2ivARB (const GLint *v);
+GLAPI void APIENTRY glWindowPos2sARB (GLshort x, GLshort y);
+GLAPI void APIENTRY glWindowPos2svARB (const GLshort *v);
+GLAPI void APIENTRY glWindowPos3dARB (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos3fARB (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos3iARB (GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glWindowPos3ivARB (const GLint *v);
+GLAPI void APIENTRY glWindowPos3sARB (GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_ARB_vertex_program
+#define GL_ARB_vertex_program 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttrib1dARB (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib1fARB (GLuint index, GLfloat x);
+GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib1sARB (GLuint index, GLshort x);
+GLAPI void APIENTRY glVertexAttrib1svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib2dARB (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib2fARB (GLuint index, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib2sARB (GLuint index, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexAttrib2svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib3dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib3fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib3sARB (GLuint index, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexAttrib3svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttrib4dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib4fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttrib4sARB (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexAttrib4svARB (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttribPointerARB (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint index);
+GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint index);
+GLAPI void APIENTRY glProgramStringARB (GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+GLAPI void APIENTRY glBindProgramARB (GLenum target, GLuint program);
+GLAPI void APIENTRY glDeleteProgramsARB (GLsizei n, const GLuint *programs);
+GLAPI void APIENTRY glGenProgramsARB (GLsizei n, GLuint *programs);
+GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum target, GLuint index, const GLdouble *params);
+GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum target, GLuint index, const GLfloat *params);
+GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum target, GLuint index, const GLdouble *params);
+GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum target, GLuint index, const GLfloat *params);
+GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum target, GLuint index, GLdouble *params);
+GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum target, GLuint index, GLfloat *params);
+GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum target, GLuint index, GLdouble *params);
+GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum target, GLuint index, GLfloat *params);
+GLAPI void APIENTRY glGetProgramivARB (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetProgramStringARB (GLenum target, GLenum pname, GLvoid *string);
+GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribivARB (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint index, GLenum pname, GLvoid* *pointer);
+GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program);
+#endif
+
+#ifndef GL_ARB_fragment_program
+#define GL_ARB_fragment_program 1
+/* All ARB_fragment_program entry points are shared with ARB_vertex_program. */
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+#define GL_ARB_vertex_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindBufferARB (GLenum target, GLuint buffer);
+GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint *buffers);
+GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint *buffers);
+GLAPI GLboolean APIENTRY glIsBufferARB (GLuint buffer);
+GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
+GLAPI void APIENTRY glBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
+GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
+GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum target, GLenum access);
+GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum target);
+GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetBufferPointervARB (GLenum target, GLenum pname, GLvoid* *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
+typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
+typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_ARB_occlusion_query
+#define GL_ARB_occlusion_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenQueriesARB (GLsizei n, GLuint *ids);
+GLAPI void APIENTRY glDeleteQueriesARB (GLsizei n, const GLuint *ids);
+GLAPI GLboolean APIENTRY glIsQueryARB (GLuint id);
+GLAPI void APIENTRY glBeginQueryARB (GLenum target, GLuint id);
+GLAPI void APIENTRY glEndQueryARB (GLenum target);
+GLAPI void APIENTRY glGetQueryivARB (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectivARB (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_ARB_shader_objects
+#define GL_ARB_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB obj);
+GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum pname);
+GLAPI void APIENTRY glDetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj);
+GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum shaderType);
+GLAPI void APIENTRY glShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
+GLAPI void APIENTRY glCompileShaderARB (GLhandleARB shaderObj);
+GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void);
+GLAPI void APIENTRY glAttachObjectARB (GLhandleARB containerObj, GLhandleARB obj);
+GLAPI void APIENTRY glLinkProgramARB (GLhandleARB programObj);
+GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB programObj);
+GLAPI void APIENTRY glValidateProgramARB (GLhandleARB programObj);
+GLAPI void APIENTRY glUniform1fARB (GLint location, GLfloat v0);
+GLAPI void APIENTRY glUniform2fARB (GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glUniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glUniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glUniform1iARB (GLint location, GLint v0);
+GLAPI void APIENTRY glUniform2iARB (GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glUniform3iARB (GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glUniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glUniform1fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform2fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform3fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform4fvARB (GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glUniform1ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform2ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform3ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniform4ivARB (GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glUniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glUniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
+GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj);
+GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name);
+GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params);
+GLAPI void APIENTRY glGetUniformivARB (GLhandleARB programObj, GLint location, GLint *params);
+GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj);
+typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname);
+typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj);
+typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
+typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
+typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj);
+typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void);
+typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj);
+typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
+typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params);
+typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source);
+#endif
+
+#ifndef GL_ARB_vertex_shader
+#define GL_ARB_vertex_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name);
+GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
+#endif
+
+#ifndef GL_ARB_fragment_shader
+#define GL_ARB_fragment_shader 1
+#endif
+
+#ifndef GL_ARB_shading_language_100
+#define GL_ARB_shading_language_100 1
+#endif
+
+#ifndef GL_ARB_texture_non_power_of_two
+#define GL_ARB_texture_non_power_of_two 1
+#endif
+
+#ifndef GL_ARB_point_sprite
+#define GL_ARB_point_sprite 1
+#endif
+
+#ifndef GL_ARB_fragment_program_shadow
+#define GL_ARB_fragment_program_shadow 1
+#endif
+
+#ifndef GL_ARB_draw_buffers
+#define GL_ARB_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawBuffersARB (GLsizei n, const GLenum *bufs);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+#ifndef GL_ARB_texture_rectangle
+#define GL_ARB_texture_rectangle 1
+#endif
+
+#ifndef GL_ARB_color_buffer_float
+#define GL_ARB_color_buffer_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClampColorARB (GLenum target, GLenum clamp);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp);
+#endif
+
+#ifndef GL_ARB_half_float_pixel
+#define GL_ARB_half_float_pixel 1
+#endif
+
+#ifndef GL_ARB_texture_float
+#define GL_ARB_texture_float 1
+#endif
+
+#ifndef GL_ARB_pixel_buffer_object
+#define GL_ARB_pixel_buffer_object 1
+#endif
+
+#ifndef GL_ARB_depth_buffer_float
+#define GL_ARB_depth_buffer_float 1
+#endif
+
+#ifndef GL_ARB_draw_instanced
+#define GL_ARB_draw_instanced 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+GLAPI void APIENTRY glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_ARB_framebuffer_object
+#define GL_ARB_framebuffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer);
+GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers);
+GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers);
+GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer);
+GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
+GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);
+GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
+GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target);
+GLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGenerateMipmap (GLenum target);
+GLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer);
+typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
+typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);
+typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+#endif
+
+#ifndef GL_ARB_framebuffer_sRGB
+#define GL_ARB_framebuffer_sRGB 1
+#endif
+
+#ifndef GL_ARB_geometry_shader4
+#define GL_ARB_geometry_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramParameteriARB (GLuint program, GLenum pname, GLint value);
+GLAPI void APIENTRY glFramebufferTextureARB (GLenum target, GLenum attachment, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif
+
+#ifndef GL_ARB_half_float_vertex
+#define GL_ARB_half_float_vertex 1
+#endif
+
+#ifndef GL_ARB_instanced_arrays
+#define GL_ARB_instanced_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor);
+#endif
+
+#ifndef GL_ARB_map_buffer_range
+#define GL_ARB_map_buffer_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLvoid* APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length);
+#endif
+
+#ifndef GL_ARB_texture_buffer_object
+#define GL_ARB_texture_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBufferARB (GLenum target, GLenum internalformat, GLuint buffer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+#endif
+
+#ifndef GL_ARB_texture_compression_rgtc
+#define GL_ARB_texture_compression_rgtc 1
+#endif
+
+#ifndef GL_ARB_texture_rg
+#define GL_ARB_texture_rg 1
+#endif
+
+#ifndef GL_ARB_vertex_array_object
+#define GL_ARB_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindVertexArray (GLuint array);
+GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
+GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);
+GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
+typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
+typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array);
+#endif
+
+#ifndef GL_ARB_uniform_buffer_object
+#define GL_ARB_uniform_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* *uniformNames, GLuint *uniformIndices);
+GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);
+GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName);
+GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* *uniformNames, GLuint *uniformIndices);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);
+typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
+typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+#endif
+
+#ifndef GL_ARB_compatibility
+#define GL_ARB_compatibility 1
+#endif
+
+#ifndef GL_ARB_copy_buffer
+#define GL_ARB_copy_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+#endif
+
+#ifndef GL_ARB_shader_texture_lod
+#define GL_ARB_shader_texture_lod 1
+#endif
+
+#ifndef GL_ARB_depth_clamp
+#define GL_ARB_depth_clamp 1
+#endif
+
+#ifndef GL_ARB_draw_elements_base_vertex
+#define GL_ARB_draw_elements_base_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex);
+GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex);
+#endif
+
+#ifndef GL_ARB_fragment_coord_conventions
+#define GL_ARB_fragment_coord_conventions 1
+#endif
+
+#ifndef GL_ARB_provoking_vertex
+#define GL_ARB_provoking_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProvokingVertex (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode);
+#endif
+
+#ifndef GL_ARB_seamless_cube_map
+#define GL_ARB_seamless_cube_map 1
+#endif
+
+#ifndef GL_ARB_sync
+#define GL_ARB_sync 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags);
+GLAPI GLboolean APIENTRY glIsSync (GLsync sync);
+GLAPI void APIENTRY glDeleteSync (GLsync sync);
+GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *params);
+GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags);
+typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync);
+typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync);
+typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#endif
+
+#ifndef GL_ARB_texture_multisample
+#define GL_ARB_texture_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+GLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+GLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val);
+GLAPI void APIENTRY glSampleMaski (GLuint index, GLbitfield mask);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val);
+typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask);
+#endif
+
+#ifndef GL_ARB_vertex_array_bgra
+#define GL_ARB_vertex_array_bgra 1
+#endif
+
+#ifndef GL_ARB_draw_buffers_blend
+#define GL_ARB_draw_buffers_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode);
+GLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+GLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst);
+GLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+
+#ifndef GL_ARB_sample_shading
+#define GL_ARB_sample_shading 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMinSampleShadingARB (GLclampf value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value);
+#endif
+
+#ifndef GL_ARB_texture_cube_map_array
+#define GL_ARB_texture_cube_map_array 1
+#endif
+
+#ifndef GL_ARB_texture_gather
+#define GL_ARB_texture_gather 1
+#endif
+
+#ifndef GL_ARB_texture_query_lod
+#define GL_ARB_texture_query_lod 1
+#endif
+
+#ifndef GL_ARB_shading_language_include
+#define GL_ARB_shading_language_include 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string);
+GLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name);
+GLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length);
+GLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name);
+GLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string);
+GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string);
+typedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name);
+typedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length);
+typedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string);
+typedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_ARB_texture_compression_bptc
+#define GL_ARB_texture_compression_bptc 1
+#endif
+
+#ifndef GL_ARB_blend_func_extended
+#define GL_ARB_blend_func_extended 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+GLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name);
+#endif
+
+#ifndef GL_ARB_explicit_attrib_location
+#define GL_ARB_explicit_attrib_location 1
+#endif
+
+#ifndef GL_ARB_occlusion_query2
+#define GL_ARB_occlusion_query2 1
+#endif
+
+#ifndef GL_ARB_sampler_objects
+#define GL_ARB_sampler_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers);
+GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers);
+GLAPI GLboolean APIENTRY glIsSampler (GLuint sampler);
+GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler);
+GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param);
+GLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param);
+GLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param);
+GLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param);
+GLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param);
+GLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers);
+typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers);
+typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler);
+typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param);
+typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_ARB_texture_rgb10_a2ui
+#define GL_ARB_texture_rgb10_a2ui 1
+#endif
+
+#ifndef GL_ARB_texture_swizzle
+#define GL_ARB_texture_swizzle 1
+#endif
+
+#ifndef GL_ARB_timer_query
+#define GL_ARB_timer_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target);
+GLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params);
+GLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params);
+#endif
+
+#ifndef GL_ARB_vertex_type_2_10_10_10_rev
+#define GL_ARB_vertex_type_2_10_10_10_rev 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexP2ui (GLenum type, GLuint value);
+GLAPI void APIENTRY glVertexP2uiv (GLenum type, const GLuint *value);
+GLAPI void APIENTRY glVertexP3ui (GLenum type, GLuint value);
+GLAPI void APIENTRY glVertexP3uiv (GLenum type, const GLuint *value);
+GLAPI void APIENTRY glVertexP4ui (GLenum type, GLuint value);
+GLAPI void APIENTRY glVertexP4uiv (GLenum type, const GLuint *value);
+GLAPI void APIENTRY glTexCoordP1ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP1uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glTexCoordP2ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP2uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glTexCoordP3ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP3uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glTexCoordP4ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glTexCoordP4uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP1ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP1uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP2ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP2uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP3ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP3uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glMultiTexCoordP4ui (GLenum texture, GLenum type, GLuint coords);
+GLAPI void APIENTRY glMultiTexCoordP4uiv (GLenum texture, GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glNormalP3ui (GLenum type, GLuint coords);
+GLAPI void APIENTRY glNormalP3uiv (GLenum type, const GLuint *coords);
+GLAPI void APIENTRY glColorP3ui (GLenum type, GLuint color);
+GLAPI void APIENTRY glColorP3uiv (GLenum type, const GLuint *color);
+GLAPI void APIENTRY glColorP4ui (GLenum type, GLuint color);
+GLAPI void APIENTRY glColorP4uiv (GLenum type, const GLuint *color);
+GLAPI void APIENTRY glSecondaryColorP3ui (GLenum type, GLuint color);
+GLAPI void APIENTRY glSecondaryColorP3uiv (GLenum type, const GLuint *color);
+GLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+GLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+GLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+GLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+GLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint *value);
+typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords);
+typedef void (APIENTRYP PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint *coords);
+typedef void (APIENTRYP PFNGLCOLORP3UIPROC) (GLenum type, GLuint color);
+typedef void (APIENTRYP PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint *color);
+typedef void (APIENTRYP PFNGLCOLORP4UIPROC) (GLenum type, GLuint color);
+typedef void (APIENTRYP PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint *color);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint *color);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value);
+#endif
+
+#ifndef GL_ARB_draw_indirect
+#define GL_ARB_draw_indirect 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const GLvoid *indirect);
+GLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const GLvoid *indirect);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const GLvoid *indirect);
+#endif
+
+#ifndef GL_ARB_gpu_shader5
+#define GL_ARB_gpu_shader5 1
+#endif
+
+#ifndef GL_ARB_gpu_shader_fp64
+#define GL_ARB_gpu_shader_fp64 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniform1d (GLint location, GLdouble x);
+GLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x);
+typedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params);
+#endif
+
+#ifndef GL_ARB_shader_subroutine
+#define GL_ARB_shader_subroutine 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name);
+GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name);
+GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);
+GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices);
+GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params);
+GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name);
+typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values);
+typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices);
+typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values);
+#endif
+
+#ifndef GL_ARB_tessellation_shader
+#define GL_ARB_tessellation_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value);
+GLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value);
+typedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values);
+#endif
+
+#ifndef GL_ARB_texture_buffer_object_rgb32
+#define GL_ARB_texture_buffer_object_rgb32 1
+#endif
+
+#ifndef GL_ARB_transform_feedback2
+#define GL_ARB_transform_feedback2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id);
+GLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids);
+GLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids);
+GLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id);
+GLAPI void APIENTRY glPauseTransformFeedback (void);
+GLAPI void APIENTRY glResumeTransformFeedback (void);
+GLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids);
+typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void);
+typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void);
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id);
+#endif
+
+#ifndef GL_ARB_transform_feedback3
+#define GL_ARB_transform_feedback3 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream);
+GLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id);
+GLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index);
+GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream);
+typedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_ARB_ES2_compatibility
+#define GL_ARB_ES2_compatibility 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReleaseShaderCompiler (void);
+GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length);
+GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+GLAPI void APIENTRY glDepthRangef (GLclampf n, GLclampf f);
+GLAPI void APIENTRY glClearDepthf (GLclampf d);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);
+typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length);
+typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
+typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f);
+typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLclampf d);
+#endif
+
+#ifndef GL_ARB_get_program_binary
+#define GL_ARB_get_program_binary 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+GLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length);
+GLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);
+#endif
+
+#ifndef GL_ARB_separate_shader_objects
+#define GL_ARB_separate_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program);
+GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program);
+GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar* *strings);
+GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline);
+GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines);
+GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines);
+GLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline);
+GLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params);
+GLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0);
+GLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0);
+GLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0);
+GLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0);
+GLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1);
+GLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);
+GLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);
+GLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline);
+GLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program);
+typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar* *strings);
+typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines);
+typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline);
+typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+#endif
+
+#ifndef GL_ARB_vertex_attrib_64bit
+#define GL_ARB_vertex_attrib_64bit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params);
+#endif
+
+#ifndef GL_ARB_viewport_array
+#define GL_ARB_viewport_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+GLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v);
+GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v);
+GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLclampd *v);
+GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLclampd n, GLclampd f);
+GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data);
+GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v);
+typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLclampd *v);
+typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLclampd n, GLclampd f);
+typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data);
+#endif
+
+#ifndef GL_ARB_cl_event
+#define GL_ARB_cl_event 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context * context, struct _cl_event * event, GLbitfield flags);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context * context, struct _cl_event * event, GLbitfield flags);
+#endif
+
+#ifndef GL_ARB_debug_output
+#define GL_ARB_debug_output 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+GLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+GLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const GLvoid *userParam);
+GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const GLvoid *userParam);
+typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+#endif
+
+#ifndef GL_ARB_robustness
+#define GL_ARB_robustness 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void);
+GLAPI void APIENTRY glGetnMapdvARB (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v);
+GLAPI void APIENTRY glGetnMapfvARB (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v);
+GLAPI void APIENTRY glGetnMapivARB (GLenum target, GLenum query, GLsizei bufSize, GLint *v);
+GLAPI void APIENTRY glGetnPixelMapfvARB (GLenum map, GLsizei bufSize, GLfloat *values);
+GLAPI void APIENTRY glGetnPixelMapuivARB (GLenum map, GLsizei bufSize, GLuint *values);
+GLAPI void APIENTRY glGetnPixelMapusvARB (GLenum map, GLsizei bufSize, GLushort *values);
+GLAPI void APIENTRY glGetnPolygonStippleARB (GLsizei bufSize, GLubyte *pattern);
+GLAPI void APIENTRY glGetnColorTableARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table);
+GLAPI void APIENTRY glGetnConvolutionFilterARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image);
+GLAPI void APIENTRY glGetnSeparableFilterARB (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span);
+GLAPI void APIENTRY glGetnHistogramARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+GLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img);
+GLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
+GLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img);
+GLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+GLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+GLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+GLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void);
+typedef void (APIENTRYP PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v);
+typedef void (APIENTRYP PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v);
+typedef void (APIENTRYP PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v);
+typedef void (APIENTRYP PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat *values);
+typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint *values);
+typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort *values);
+typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte *pattern);
+typedef void (APIENTRYP PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img);
+typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data);
+typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img);
+typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params);
+typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params);
+typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params);
+#endif
+
+#ifndef GL_ARB_shader_stencil_export
+#define GL_ARB_shader_stencil_export 1
+#endif
+
+#ifndef GL_EXT_abgr
+#define GL_EXT_abgr 1
+#endif
+
+#ifndef GL_EXT_blend_color
+#define GL_EXT_blend_color 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendColorEXT (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+#endif
+
+#ifndef GL_EXT_polygon_offset
+#define GL_EXT_polygon_offset 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat factor, GLfloat bias);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias);
+#endif
+
+#ifndef GL_EXT_texture
+#define GL_EXT_texture 1
+#endif
+
+#ifndef GL_EXT_texture3D
+#define GL_EXT_texture3D 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_SGIS_texture_filter4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum target, GLenum filter, GLfloat *weights);
+GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights);
+typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights);
+#endif
+
+#ifndef GL_EXT_subtexture
+#define GL_EXT_subtexture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_EXT_copy_texture
+#define GL_EXT_copy_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_EXT_histogram
+#define GL_EXT_histogram 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetHistogramEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMinmaxEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glHistogramEXT (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glMinmaxEXT (GLenum target, GLenum internalformat, GLboolean sink);
+GLAPI void APIENTRY glResetHistogramEXT (GLenum target);
+GLAPI void APIENTRY glResetMinmaxEXT (GLenum target);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target);
+#endif
+
+#ifndef GL_EXT_convolution
+#define GL_EXT_convolution 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum target, GLenum pname, GLfloat params);
+GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum target, GLenum pname, GLint params);
+GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *image);
+GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+#endif
+
+#ifndef GL_SGI_color_matrix
+#define GL_SGI_color_matrix 1
+#endif
+
+#ifndef GL_SGI_color_table
+#define GL_SGI_color_table 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTableSGI (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glColorTableParameterivSGI (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCopyColorTableSGI (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glGetColorTableSGI (GLenum target, GLenum format, GLenum type, GLvoid *table);
+GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum target, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_SGIX_pixel_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTexGenSGIX (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode);
+#endif
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_SGIS_pixel_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum pname, GLint param);
+GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum pname, const GLint *params);
+GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_SGIS_texture4D
+#define GL_SGIS_texture4D 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_SGI_texture_color_table
+#define GL_SGI_texture_color_table 1
+#endif
+
+#ifndef GL_EXT_cmyka
+#define GL_EXT_cmyka 1
+#endif
+
+#ifndef GL_EXT_texture_object
+#define GL_EXT_texture_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei n, const GLuint *textures, GLboolean *residences);
+GLAPI void APIENTRY glBindTextureEXT (GLenum target, GLuint texture);
+GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei n, const GLuint *textures);
+GLAPI void APIENTRY glGenTexturesEXT (GLsizei n, GLuint *textures);
+GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint texture);
+GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei n, const GLuint *textures, const GLclampf *priorities);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences);
+typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures);
+typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures);
+typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture);
+typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities);
+#endif
+
+#ifndef GL_SGIS_detail_texture
+#define GL_SGIS_detail_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points);
+GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum target, GLfloat *points);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points);
+#endif
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_SGIS_sharpen_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points);
+GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum target, GLfloat *points);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points);
+#endif
+
+#ifndef GL_EXT_packed_pixels
+#define GL_EXT_packed_pixels 1
+#endif
+
+#ifndef GL_SGIS_texture_lod
+#define GL_SGIS_texture_lod 1
+#endif
+
+#ifndef GL_SGIS_multisample
+#define GL_SGIS_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleMaskSGIS (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glSamplePatternSGIS (GLenum pattern);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern);
+#endif
+
+#ifndef GL_EXT_rescale_normal
+#define GL_EXT_rescale_normal 1
+#endif
+
+#ifndef GL_EXT_vertex_array
+#define GL_EXT_vertex_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glArrayElementEXT (GLint i);
+GLAPI void APIENTRY glColorPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glDrawArraysEXT (GLenum mode, GLint first, GLsizei count);
+GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei stride, GLsizei count, const GLboolean *pointer);
+GLAPI void APIENTRY glGetPointervEXT (GLenum pname, GLvoid* *params);
+GLAPI void APIENTRY glIndexPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glNormalPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glTexCoordPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+GLAPI void APIENTRY glVertexPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i);
+typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer);
+typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params);
+typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_misc_attribute
+#define GL_EXT_misc_attribute 1
+#endif
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_SGIS_generate_mipmap 1
+#endif
+
+#ifndef GL_SGIX_clipmap
+#define GL_SGIX_clipmap 1
+#endif
+
+#ifndef GL_SGIX_shadow
+#define GL_SGIX_shadow 1
+#endif
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_SGIS_texture_edge_clamp 1
+#endif
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_SGIS_texture_border_clamp 1
+#endif
+
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationEXT (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_blend_subtract
+#define GL_EXT_blend_subtract 1
+#endif
+
+#ifndef GL_EXT_blend_logic_op
+#define GL_EXT_blend_logic_op 1
+#endif
+
+#ifndef GL_SGIX_interlace
+#define GL_SGIX_interlace 1
+#endif
+
+#ifndef GL_SGIX_pixel_tiles
+#define GL_SGIX_pixel_tiles 1
+#endif
+
+#ifndef GL_SGIX_texture_select
+#define GL_SGIX_texture_select 1
+#endif
+
+#ifndef GL_SGIX_sprite
+#define GL_SGIX_sprite 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum pname, GLint param);
+GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum pname, const GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_SGIX_texture_multi_buffer 1
+#endif
+
+#ifndef GL_EXT_point_parameters
+#define GL_EXT_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfEXT (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfvEXT (GLenum pname, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_SGIS_point_parameters
+#define GL_SGIS_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfSGIS (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPointParameterfvSGIS (GLenum pname, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_SGIX_instruments
+#define GL_SGIX_instruments 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLint APIENTRY glGetInstrumentsSGIX (void);
+GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei size, GLint *buffer);
+GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *marker_p);
+GLAPI void APIENTRY glReadInstrumentsSGIX (GLint marker);
+GLAPI void APIENTRY glStartInstrumentsSGIX (void);
+GLAPI void APIENTRY glStopInstrumentsSGIX (GLint marker);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void);
+typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer);
+typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p);
+typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker);
+typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void);
+typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker);
+#endif
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_SGIX_texture_scale_bias 1
+#endif
+
+#ifndef GL_SGIX_framezoom
+#define GL_SGIX_framezoom 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFrameZoomSGIX (GLint factor);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor);
+#endif
+
+#ifndef GL_SGIX_tag_sample_buffer
+#define GL_SGIX_tag_sample_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTagSampleBufferSGIX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void);
+#endif
+
+#ifndef GL_SGIX_polynomial_ffd
+#define GL_SGIX_polynomial_ffd 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points);
+GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points);
+GLAPI void APIENTRY glDeformSGIX (GLbitfield mask);
+GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield mask);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points);
+typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points);
+typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask);
+typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask);
+#endif
+
+#ifndef GL_SGIX_reference_plane
+#define GL_SGIX_reference_plane 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *equation);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation);
+#endif
+
+#ifndef GL_SGIX_flush_raster
+#define GL_SGIX_flush_raster 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFlushRasterSGIX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void);
+#endif
+
+#ifndef GL_SGIX_depth_texture
+#define GL_SGIX_depth_texture 1
+#endif
+
+#ifndef GL_SGIS_fog_function
+#define GL_SGIS_fog_function 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogFuncSGIS (GLsizei n, const GLfloat *points);
+GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *points);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points);
+#endif
+
+#ifndef GL_SGIX_fog_offset
+#define GL_SGIX_fog_offset 1
+#endif
+
+#ifndef GL_HP_image_transform
+#define GL_HP_image_transform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glImageTransformParameteriHP (GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glImageTransformParameterfHP (GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glImageTransformParameterivHP (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum target, GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_HP_convolution_border_modes 1
+#endif
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_SGIX_texture_add_env 1
+#endif
+
+#ifndef GL_EXT_color_subtable
+#define GL_EXT_color_subtable 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorSubTableEXT (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+#endif
+
+#ifndef GL_PGI_vertex_hints
+#define GL_PGI_vertex_hints 1
+#endif
+
+#ifndef GL_PGI_misc_hints
+#define GL_PGI_misc_hints 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glHintPGI (GLenum target, GLint mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode);
+#endif
+
+#ifndef GL_EXT_paletted_texture
+#define GL_EXT_paletted_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTableEXT (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+GLAPI void APIENTRY glGetColorTableEXT (GLenum target, GLenum format, GLenum type, GLvoid *data);
+GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum target, GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_EXT_clip_volume_hint 1
+#endif
+
+#ifndef GL_SGIX_list_priority
+#define GL_SGIX_list_priority 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint list, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetListParameterivSGIX (GLuint list, GLenum pname, GLint *params);
+GLAPI void APIENTRY glListParameterfSGIX (GLuint list, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glListParameterfvSGIX (GLuint list, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glListParameteriSGIX (GLuint list, GLenum pname, GLint param);
+GLAPI void APIENTRY glListParameterivSGIX (GLuint list, GLenum pname, const GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_SGIX_ir_instrument1 1
+#endif
+
+#ifndef GL_SGIX_calligraphic_fragment
+#define GL_SGIX_calligraphic_fragment 1
+#endif
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_SGIX_texture_lod_bias 1
+#endif
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SGIX_shadow_ambient 1
+#endif
+
+#ifndef GL_EXT_index_texture
+#define GL_EXT_index_texture 1
+#endif
+
+#ifndef GL_EXT_index_material
+#define GL_EXT_index_material 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIndexMaterialEXT (GLenum face, GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode);
+#endif
+
+#ifndef GL_EXT_index_func
+#define GL_EXT_index_func 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIndexFuncEXT (GLenum func, GLclampf ref);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref);
+#endif
+
+#ifndef GL_EXT_index_array_formats
+#define GL_EXT_index_array_formats 1
+#endif
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_EXT_compiled_vertex_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count);
+GLAPI void APIENTRY glUnlockArraysEXT (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void);
+#endif
+
+#ifndef GL_EXT_cull_vertex
+#define GL_EXT_cull_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCullParameterdvEXT (GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glCullParameterfvEXT (GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_SGIX_ycrcb
+#define GL_SGIX_ycrcb 1
+#endif
+
+#ifndef GL_SGIX_fragment_lighting
+#define GL_SGIX_fragment_lighting 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum face, GLenum mode);
+GLAPI void APIENTRY glFragmentLightfSGIX (GLenum light, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum light, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glFragmentLightiSGIX (GLenum light, GLenum pname, GLint param);
+GLAPI void APIENTRY glFragmentLightivSGIX (GLenum light, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum pname, GLint param);
+GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum pname, const GLint *params);
+GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum face, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum face, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum face, GLenum pname, GLint param);
+GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum face, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum light, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum light, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum face, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum face, GLenum pname, GLint *params);
+GLAPI void APIENTRY glLightEnviSGIX (GLenum pname, GLint param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param);
+#endif
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_IBM_rasterpos_clip 1
+#endif
+
+#ifndef GL_HP_texture_lighting
+#define GL_HP_texture_lighting 1
+#endif
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_EXT_draw_range_elements 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+#endif
+
+#ifndef GL_WIN_phong_shading
+#define GL_WIN_phong_shading 1
+#endif
+
+#ifndef GL_WIN_specular_fog
+#define GL_WIN_specular_fog 1
+#endif
+
+#ifndef GL_EXT_light_texture
+#define GL_EXT_light_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glApplyTextureEXT (GLenum mode);
+GLAPI void APIENTRY glTextureLightEXT (GLenum pname);
+GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname);
+typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode);
+#endif
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_SGIX_blend_alpha_minmax 1
+#endif
+
+#ifndef GL_EXT_bgra
+#define GL_EXT_bgra 1
+#endif
+
+#ifndef GL_SGIX_async
+#define GL_SGIX_async 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint marker);
+GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *markerp);
+GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *markerp);
+GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei range);
+GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint marker, GLsizei range);
+GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint marker);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker);
+typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp);
+typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp);
+typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range);
+typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range);
+typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker);
+#endif
+
+#ifndef GL_SGIX_async_pixel
+#define GL_SGIX_async_pixel 1
+#endif
+
+#ifndef GL_SGIX_async_histogram
+#define GL_SGIX_async_histogram 1
+#endif
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_INTEL_parallel_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer);
+GLAPI void APIENTRY glNormalPointervINTEL (GLenum type, const GLvoid* *pointer);
+GLAPI void APIENTRY glColorPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer);
+GLAPI void APIENTRY glTexCoordPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+#endif
+
+#ifndef GL_HP_occlusion_test
+#define GL_HP_occlusion_test 1
+#endif
+
+#ifndef GL_EXT_pixel_transform
+#define GL_EXT_pixel_transform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_EXT_pixel_transform_color_table
+#define GL_EXT_pixel_transform_color_table 1
+#endif
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_EXT_shared_texture_palette 1
+#endif
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_EXT_separate_specular_color 1
+#endif
+
+#ifndef GL_EXT_secondary_color
+#define GL_EXT_secondary_color 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte red, GLbyte green, GLbyte blue);
+GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *v);
+GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble red, GLdouble green, GLdouble blue);
+GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *v);
+GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat red, GLfloat green, GLfloat blue);
+GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *v);
+GLAPI void APIENTRY glSecondaryColor3iEXT (GLint red, GLint green, GLint blue);
+GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *v);
+GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort red, GLshort green, GLshort blue);
+GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *v);
+GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte red, GLubyte green, GLubyte blue);
+GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *v);
+GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint red, GLuint green, GLuint blue);
+GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *v);
+GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort red, GLushort green, GLushort blue);
+GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *v);
+GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_EXT_texture_perturb_normal 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureNormalEXT (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_EXT_fog_coord
+#define GL_EXT_fog_coord 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogCoordfEXT (GLfloat coord);
+GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *coord);
+GLAPI void APIENTRY glFogCoorddEXT (GLdouble coord);
+GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *coord);
+GLAPI void APIENTRY glFogCoordPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord);
+typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_REND_screen_coordinates
+#define GL_REND_screen_coordinates 1
+#endif
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_EXT_coordinate_frame 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTangent3bEXT (GLbyte tx, GLbyte ty, GLbyte tz);
+GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *v);
+GLAPI void APIENTRY glTangent3dEXT (GLdouble tx, GLdouble ty, GLdouble tz);
+GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *v);
+GLAPI void APIENTRY glTangent3fEXT (GLfloat tx, GLfloat ty, GLfloat tz);
+GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *v);
+GLAPI void APIENTRY glTangent3iEXT (GLint tx, GLint ty, GLint tz);
+GLAPI void APIENTRY glTangent3ivEXT (const GLint *v);
+GLAPI void APIENTRY glTangent3sEXT (GLshort tx, GLshort ty, GLshort tz);
+GLAPI void APIENTRY glTangent3svEXT (const GLshort *v);
+GLAPI void APIENTRY glBinormal3bEXT (GLbyte bx, GLbyte by, GLbyte bz);
+GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *v);
+GLAPI void APIENTRY glBinormal3dEXT (GLdouble bx, GLdouble by, GLdouble bz);
+GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *v);
+GLAPI void APIENTRY glBinormal3fEXT (GLfloat bx, GLfloat by, GLfloat bz);
+GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *v);
+GLAPI void APIENTRY glBinormal3iEXT (GLint bx, GLint by, GLint bz);
+GLAPI void APIENTRY glBinormal3ivEXT (const GLint *v);
+GLAPI void APIENTRY glBinormal3sEXT (GLshort bx, GLshort by, GLshort bz);
+GLAPI void APIENTRY glBinormal3svEXT (const GLshort *v);
+GLAPI void APIENTRY glTangentPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glBinormalPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz);
+typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz);
+typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz);
+typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz);
+typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz);
+typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz);
+typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz);
+typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz);
+typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz);
+typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz);
+typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_EXT_texture_env_combine 1
+#endif
+
+#ifndef GL_APPLE_specular_vector
+#define GL_APPLE_specular_vector 1
+#endif
+
+#ifndef GL_APPLE_transform_hint
+#define GL_APPLE_transform_hint 1
+#endif
+
+#ifndef GL_SGIX_fog_scale
+#define GL_SGIX_fog_scale 1
+#endif
+
+#ifndef GL_SUNX_constant_data
+#define GL_SUNX_constant_data 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFinishTextureSUNX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void);
+#endif
+
+#ifndef GL_SUN_global_alpha
+#define GL_SUN_global_alpha 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte factor);
+GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort factor);
+GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint factor);
+GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat factor);
+GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble factor);
+GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte factor);
+GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort factor);
+GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint factor);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor);
+#endif
+
+#ifndef GL_SUN_triangle_list
+#define GL_SUN_triangle_list 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint code);
+GLAPI void APIENTRY glReplacementCodeusSUN (GLushort code);
+GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte code);
+GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *code);
+GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *code);
+GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *code);
+GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum type, GLsizei stride, const GLvoid* *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer);
+#endif
+
+#ifndef GL_SUN_vertex
+#define GL_SUN_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *c, const GLfloat *v);
+GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *tc, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *tc, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *tc, const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint rc, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *rc, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *rc, const GLubyte *c, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+#endif
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_EXT_blend_func_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+
+#ifndef GL_INGR_blend_func_separate
+#define GL_INGR_blend_func_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+
+#ifndef GL_INGR_color_clamp
+#define GL_INGR_color_clamp 1
+#endif
+
+#ifndef GL_INGR_interlace_read
+#define GL_INGR_interlace_read 1
+#endif
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_EXT_stencil_wrap 1
+#endif
+
+#ifndef GL_EXT_422_pixels
+#define GL_EXT_422_pixels 1
+#endif
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NV_texgen_reflection 1
+#endif
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_SUN_convolution_border_modes 1
+#endif
+
+#ifndef GL_EXT_texture_env_add
+#define GL_EXT_texture_env_add 1
+#endif
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_EXT_texture_lod_bias 1
+#endif
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+#endif
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_EXT_vertex_weighting 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexWeightfEXT (GLfloat weight);
+GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *weight);
+GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_NV_light_max_exponent
+#define GL_NV_light_max_exponent 1
+#endif
+
+#ifndef GL_NV_vertex_array_range
+#define GL_NV_vertex_array_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFlushVertexArrayRangeNV (void);
+GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei length, const GLvoid *pointer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void);
+typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer);
+#endif
+
+#ifndef GL_NV_register_combiners
+#define GL_NV_register_combiners 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCombinerParameterfvNV (GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glCombinerParameterfNV (GLenum pname, GLfloat param);
+GLAPI void APIENTRY glCombinerParameterivNV (GLenum pname, const GLint *params);
+GLAPI void APIENTRY glCombinerParameteriNV (GLenum pname, GLint param);
+GLAPI void APIENTRY glCombinerInputNV (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+GLAPI void APIENTRY glCombinerOutputNV (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum);
+GLAPI void APIENTRY glFinalCombinerInputNV (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum stage, GLenum portion, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum stage, GLenum portion, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum variable, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum variable, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum);
+typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_NV_fog_distance
+#define GL_NV_fog_distance 1
+#endif
+
+#ifndef GL_NV_texgen_emboss
+#define GL_NV_texgen_emboss 1
+#endif
+
+#ifndef GL_NV_blend_square
+#define GL_NV_blend_square 1
+#endif
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_NV_texture_env_combine4 1
+#endif
+
+#ifndef GL_MESA_resize_buffers
+#define GL_MESA_resize_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glResizeBuffersMESA (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void);
+#endif
+
+#ifndef GL_MESA_window_pos
+#define GL_MESA_window_pos 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWindowPos2dMESA (GLdouble x, GLdouble y);
+GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos2fMESA (GLfloat x, GLfloat y);
+GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos2iMESA (GLint x, GLint y);
+GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *v);
+GLAPI void APIENTRY glWindowPos2sMESA (GLshort x, GLshort y);
+GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *v);
+GLAPI void APIENTRY glWindowPos3dMESA (GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos3iMESA (GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *v);
+GLAPI void APIENTRY glWindowPos3sMESA (GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *v);
+GLAPI void APIENTRY glWindowPos4dMESA (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *v);
+GLAPI void APIENTRY glWindowPos4fMESA (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *v);
+GLAPI void APIENTRY glWindowPos4iMESA (GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *v);
+GLAPI void APIENTRY glWindowPos4sMESA (GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_IBM_cull_vertex
+#define GL_IBM_cull_vertex 1
+#endif
+
+#ifndef GL_IBM_multimode_draw_arrays
+#define GL_IBM_multimode_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride);
+GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride);
+typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride);
+#endif
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_IBM_vertex_array_lists 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint stride, const GLboolean* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glIndexPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glNormalPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glTexCoordPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+GLAPI void APIENTRY glVertexPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+#endif
+
+#ifndef GL_SGIX_subsample
+#define GL_SGIX_subsample 1
+#endif
+
+#ifndef GL_SGIX_ycrcba
+#define GL_SGIX_ycrcba 1
+#endif
+
+#ifndef GL_SGIX_ycrcb_subsample
+#define GL_SGIX_ycrcb_subsample 1
+#endif
+
+#ifndef GL_SGIX_depth_pass_instrument
+#define GL_SGIX_depth_pass_instrument 1
+#endif
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_3DFX_texture_compression_FXT1 1
+#endif
+
+#ifndef GL_3DFX_multisample
+#define GL_3DFX_multisample 1
+#endif
+
+#ifndef GL_3DFX_tbuffer
+#define GL_3DFX_tbuffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTbufferMask3DFX (GLuint mask);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask);
+#endif
+
+#ifndef GL_EXT_multisample
+#define GL_EXT_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleMaskEXT (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glSamplePatternEXT (GLenum pattern);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern);
+#endif
+
+#ifndef GL_SGIX_vertex_preclip
+#define GL_SGIX_vertex_preclip 1
+#endif
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_SGIX_convolution_accuracy 1
+#endif
+
+#ifndef GL_SGIX_resample
+#define GL_SGIX_resample 1
+#endif
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_SGIS_point_line_texgen 1
+#endif
+
+#ifndef GL_SGIS_texture_color_mask
+#define GL_SGIS_texture_color_mask 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+#endif
+
+#ifndef GL_SGIX_igloo_interface
+#define GL_SGIX_igloo_interface 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum pname, const GLvoid *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params);
+#endif
+
+#ifndef GL_EXT_texture_env_dot3
+#define GL_EXT_texture_env_dot3 1
+#endif
+
+#ifndef GL_ATI_texture_mirror_once
+#define GL_ATI_texture_mirror_once 1
+#endif
+
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences);
+GLAPI void APIENTRY glGenFencesNV (GLsizei n, GLuint *fences);
+GLAPI GLboolean APIENTRY glIsFenceNV (GLuint fence);
+GLAPI GLboolean APIENTRY glTestFenceNV (GLuint fence);
+GLAPI void APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params);
+GLAPI void APIENTRY glFinishFenceNV (GLuint fence);
+GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences);
+typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences);
+typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
+#endif
+
+#ifndef GL_NV_evaluators
+#define GL_NV_evaluators 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points);
+GLAPI void APIENTRY glMapParameterivNV (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMapParameterfvNV (GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points);
+GLAPI void APIENTRY glGetMapParameterivNV (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMapParameterfvNV (GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum target, GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glEvalMapsNV (GLenum target, GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points);
+typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points);
+typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode);
+#endif
+
+#ifndef GL_NV_packed_depth_stencil
+#define GL_NV_packed_depth_stencil 1
+#endif
+
+#ifndef GL_NV_register_combiners2
+#define GL_NV_register_combiners2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum stage, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_NV_texture_compression_vtc
+#define GL_NV_texture_compression_vtc 1
+#endif
+
+#ifndef GL_NV_texture_rectangle
+#define GL_NV_texture_rectangle 1
+#endif
+
+#ifndef GL_NV_texture_shader
+#define GL_NV_texture_shader 1
+#endif
+
+#ifndef GL_NV_texture_shader2
+#define GL_NV_texture_shader2 1
+#endif
+
+#ifndef GL_NV_vertex_array_range2
+#define GL_NV_vertex_array_range2 1
+#endif
+
+#ifndef GL_NV_vertex_program
+#define GL_NV_vertex_program 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei n, const GLuint *programs, GLboolean *residences);
+GLAPI void APIENTRY glBindProgramNV (GLenum target, GLuint id);
+GLAPI void APIENTRY glDeleteProgramsNV (GLsizei n, const GLuint *programs);
+GLAPI void APIENTRY glExecuteProgramNV (GLenum target, GLuint id, const GLfloat *params);
+GLAPI void APIENTRY glGenProgramsNV (GLsizei n, GLuint *programs);
+GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum target, GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetProgramivNV (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetProgramStringNV (GLuint id, GLenum pname, GLubyte *program);
+GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum target, GLuint address, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribivNV (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint index, GLenum pname, GLvoid* *pointer);
+GLAPI GLboolean APIENTRY glIsProgramNV (GLuint id);
+GLAPI void APIENTRY glLoadProgramNV (GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+GLAPI void APIENTRY glProgramParameter4dNV (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramParameter4dvNV (GLenum target, GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glProgramParameter4fNV (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramParameter4fvNV (GLenum target, GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glProgramParameters4dvNV (GLenum target, GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glProgramParameters4fvNV (GLenum target, GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei n, const GLuint *programs);
+GLAPI void APIENTRY glTrackMatrixNV (GLenum target, GLuint address, GLenum matrix, GLenum transform);
+GLAPI void APIENTRY glVertexAttribPointerNV (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glVertexAttrib1dNV (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib1fNV (GLuint index, GLfloat x);
+GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib1sNV (GLuint index, GLshort x);
+GLAPI void APIENTRY glVertexAttrib1svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib2dNV (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib2fNV (GLuint index, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib2sNV (GLuint index, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexAttrib2svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib3dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib3fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib3sNV (GLuint index, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexAttrib3svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttrib4fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint index, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttrib4sNV (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexAttrib4svNV (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs1svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs2svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs3svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint index, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint index, GLsizei count, const GLfloat *v);
+GLAPI void APIENTRY glVertexAttribs4svNV (GLuint index, GLsizei count, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint index, GLsizei count, const GLubyte *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences);
+typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs);
+typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program);
+typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v);
+#endif
+
+#ifndef GL_SGIX_texture_coordinate_clamp
+#define GL_SGIX_texture_coordinate_clamp 1
+#endif
+
+#ifndef GL_SGIX_scalebias_hint
+#define GL_SGIX_scalebias_hint 1
+#endif
+
+#ifndef GL_OML_interlace
+#define GL_OML_interlace 1
+#endif
+
+#ifndef GL_OML_subsample
+#define GL_OML_subsample 1
+#endif
+
+#ifndef GL_OML_resample
+#define GL_OML_resample 1
+#endif
+
+#ifndef GL_NV_copy_depth_to_color
+#define GL_NV_copy_depth_to_color 1
+#endif
+
+#ifndef GL_ATI_envmap_bumpmap
+#define GL_ATI_envmap_bumpmap 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBumpParameterivATI (GLenum pname, const GLint *param);
+GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum pname, const GLfloat *param);
+GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum pname, GLint *param);
+GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum pname, GLfloat *param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param);
+typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param);
+typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param);
+typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param);
+#endif
+
+#ifndef GL_ATI_fragment_shader
+#define GL_ATI_fragment_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint range);
+GLAPI void APIENTRY glBindFragmentShaderATI (GLuint id);
+GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint id);
+GLAPI void APIENTRY glBeginFragmentShaderATI (void);
+GLAPI void APIENTRY glEndFragmentShaderATI (void);
+GLAPI void APIENTRY glPassTexCoordATI (GLuint dst, GLuint coord, GLenum swizzle);
+GLAPI void APIENTRY glSampleMapATI (GLuint dst, GLuint interp, GLenum swizzle);
+GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint dst, const GLfloat *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range);
+typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void);
+typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void);
+typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle);
+typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value);
+#endif
+
+#ifndef GL_ATI_pn_triangles
+#define GL_ATI_pn_triangles 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPNTrianglesiATI (GLenum pname, GLint param);
+GLAPI void APIENTRY glPNTrianglesfATI (GLenum pname, GLfloat param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param);
+#endif
+
+#ifndef GL_ATI_vertex_array_object
+#define GL_ATI_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei size, const GLvoid *pointer, GLenum usage);
+GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint buffer);
+GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve);
+GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint buffer, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetObjectBufferivATI (GLuint buffer, GLenum pname, GLint *params);
+GLAPI void APIENTRY glFreeObjectBufferATI (GLuint buffer);
+GLAPI void APIENTRY glArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum array, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetArrayObjectivATI (GLenum array, GLenum pname, GLint *params);
+GLAPI void APIENTRY glVariantArrayObjectATI (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint id, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint id, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage);
+typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve);
+typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_EXT_vertex_shader
+#define GL_EXT_vertex_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginVertexShaderEXT (void);
+GLAPI void APIENTRY glEndVertexShaderEXT (void);
+GLAPI void APIENTRY glBindVertexShaderEXT (GLuint id);
+GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint range);
+GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint id);
+GLAPI void APIENTRY glShaderOp1EXT (GLenum op, GLuint res, GLuint arg1);
+GLAPI void APIENTRY glShaderOp2EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2);
+GLAPI void APIENTRY glShaderOp3EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3);
+GLAPI void APIENTRY glSwizzleEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+GLAPI void APIENTRY glWriteMaskEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+GLAPI void APIENTRY glInsertComponentEXT (GLuint res, GLuint src, GLuint num);
+GLAPI void APIENTRY glExtractComponentEXT (GLuint res, GLuint src, GLuint num);
+GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum datatype, GLenum storagetype, GLenum range, GLuint components);
+GLAPI void APIENTRY glSetInvariantEXT (GLuint id, GLenum type, const GLvoid *addr);
+GLAPI void APIENTRY glSetLocalConstantEXT (GLuint id, GLenum type, const GLvoid *addr);
+GLAPI void APIENTRY glVariantbvEXT (GLuint id, const GLbyte *addr);
+GLAPI void APIENTRY glVariantsvEXT (GLuint id, const GLshort *addr);
+GLAPI void APIENTRY glVariantivEXT (GLuint id, const GLint *addr);
+GLAPI void APIENTRY glVariantfvEXT (GLuint id, const GLfloat *addr);
+GLAPI void APIENTRY glVariantdvEXT (GLuint id, const GLdouble *addr);
+GLAPI void APIENTRY glVariantubvEXT (GLuint id, const GLubyte *addr);
+GLAPI void APIENTRY glVariantusvEXT (GLuint id, const GLushort *addr);
+GLAPI void APIENTRY glVariantuivEXT (GLuint id, const GLuint *addr);
+GLAPI void APIENTRY glVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const GLvoid *addr);
+GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint id);
+GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint id);
+GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum light, GLenum value);
+GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum face, GLenum value);
+GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum unit, GLenum coord, GLenum value);
+GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum unit, GLenum value);
+GLAPI GLuint APIENTRY glBindParameterEXT (GLenum value);
+GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint id, GLenum cap);
+GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data);
+GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint id, GLenum value, GLint *data);
+GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint id, GLenum value, GLfloat *data);
+GLAPI void APIENTRY glGetVariantPointervEXT (GLuint id, GLenum value, GLvoid* *data);
+GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data);
+GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint id, GLenum value, GLint *data);
+GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint id, GLenum value, GLfloat *data);
+GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint id, GLenum value, GLboolean *data);
+GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint id, GLenum value, GLint *data);
+GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint id, GLenum value, GLfloat *data);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void);
+typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void);
+typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id);
+typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range);
+typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1);
+typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2);
+typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3);
+typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components);
+typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr);
+typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr);
+typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr);
+typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr);
+typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr);
+typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr);
+typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr);
+typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr);
+typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value);
+typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap);
+typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+#endif
+
+#ifndef GL_ATI_vertex_streams
+#define GL_ATI_vertex_streams 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexStream1sATI (GLenum stream, GLshort x);
+GLAPI void APIENTRY glVertexStream1svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream1iATI (GLenum stream, GLint x);
+GLAPI void APIENTRY glVertexStream1ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream1fATI (GLenum stream, GLfloat x);
+GLAPI void APIENTRY glVertexStream1fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream1dATI (GLenum stream, GLdouble x);
+GLAPI void APIENTRY glVertexStream1dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glVertexStream2sATI (GLenum stream, GLshort x, GLshort y);
+GLAPI void APIENTRY glVertexStream2svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream2iATI (GLenum stream, GLint x, GLint y);
+GLAPI void APIENTRY glVertexStream2ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream2fATI (GLenum stream, GLfloat x, GLfloat y);
+GLAPI void APIENTRY glVertexStream2fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream2dATI (GLenum stream, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexStream2dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glVertexStream3sATI (GLenum stream, GLshort x, GLshort y, GLshort z);
+GLAPI void APIENTRY glVertexStream3svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream3iATI (GLenum stream, GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glVertexStream3ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream3fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glVertexStream3fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream3dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexStream3dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glVertexStream4sATI (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w);
+GLAPI void APIENTRY glVertexStream4svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glVertexStream4iATI (GLenum stream, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glVertexStream4ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glVertexStream4fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glVertexStream4fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glVertexStream4dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexStream4dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glNormalStream3bATI (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz);
+GLAPI void APIENTRY glNormalStream3bvATI (GLenum stream, const GLbyte *coords);
+GLAPI void APIENTRY glNormalStream3sATI (GLenum stream, GLshort nx, GLshort ny, GLshort nz);
+GLAPI void APIENTRY glNormalStream3svATI (GLenum stream, const GLshort *coords);
+GLAPI void APIENTRY glNormalStream3iATI (GLenum stream, GLint nx, GLint ny, GLint nz);
+GLAPI void APIENTRY glNormalStream3ivATI (GLenum stream, const GLint *coords);
+GLAPI void APIENTRY glNormalStream3fATI (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz);
+GLAPI void APIENTRY glNormalStream3fvATI (GLenum stream, const GLfloat *coords);
+GLAPI void APIENTRY glNormalStream3dATI (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz);
+GLAPI void APIENTRY glNormalStream3dvATI (GLenum stream, const GLdouble *coords);
+GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum stream);
+GLAPI void APIENTRY glVertexBlendEnviATI (GLenum pname, GLint param);
+GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream);
+typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param);
+#endif
+
+#ifndef GL_ATI_element_array
+#define GL_ATI_element_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glElementPointerATI (GLenum type, const GLvoid *pointer);
+GLAPI void APIENTRY glDrawElementArrayATI (GLenum mode, GLsizei count);
+GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count);
+#endif
+
+#ifndef GL_SUN_mesh_array
+#define GL_SUN_mesh_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width);
+#endif
+
+#ifndef GL_SUN_slice_accum
+#define GL_SUN_slice_accum 1
+#endif
+
+#ifndef GL_NV_multisample_filter_hint
+#define GL_NV_multisample_filter_hint 1
+#endif
+
+#ifndef GL_NV_depth_clamp
+#define GL_NV_depth_clamp 1
+#endif
+
+#ifndef GL_NV_occlusion_query
+#define GL_NV_occlusion_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei n, GLuint *ids);
+GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei n, const GLuint *ids);
+GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint id);
+GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint id);
+GLAPI void APIENTRY glEndOcclusionQueryNV (void);
+GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint id, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint id, GLenum pname, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void);
+typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_NV_point_sprite
+#define GL_NV_point_sprite 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameteriNV (GLenum pname, GLint param);
+GLAPI void APIENTRY glPointParameterivNV (GLenum pname, const GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_NV_texture_shader3
+#define GL_NV_texture_shader3 1
+#endif
+
+#ifndef GL_NV_vertex_program1_1
+#define GL_NV_vertex_program1_1 1
+#endif
+
+#ifndef GL_EXT_shadow_funcs
+#define GL_EXT_shadow_funcs 1
+#endif
+
+#ifndef GL_EXT_stencil_two_side
+#define GL_EXT_stencil_two_side 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum face);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
+#endif
+
+#ifndef GL_ATI_text_fragment_shader
+#define GL_ATI_text_fragment_shader 1
+#endif
+
+#ifndef GL_APPLE_client_storage
+#define GL_APPLE_client_storage 1
+#endif
+
+#ifndef GL_APPLE_element_array
+#define GL_APPLE_element_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glElementPointerAPPLE (GLenum type, const GLvoid *pointer);
+GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum mode, GLint first, GLsizei count);
+GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count);
+GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount);
+#endif
+
+#ifndef GL_APPLE_fence
+#define GL_APPLE_fence 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenFencesAPPLE (GLsizei n, GLuint *fences);
+GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei n, const GLuint *fences);
+GLAPI void APIENTRY glSetFenceAPPLE (GLuint fence);
+GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint fence);
+GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint fence);
+GLAPI void APIENTRY glFinishFenceAPPLE (GLuint fence);
+GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum object, GLuint name);
+GLAPI void APIENTRY glFinishObjectAPPLE (GLenum object, GLint name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences);
+typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences);
+typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name);
+typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name);
+#endif
+
+#ifndef GL_APPLE_vertex_array_object
+#define GL_APPLE_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint array);
+GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei n, const GLuint *arrays);
+GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei n, GLuint *arrays);
+GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint array);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array);
+typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays);
+typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array);
+#endif
+
+#ifndef GL_APPLE_vertex_array_range
+#define GL_APPLE_vertex_array_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer);
+GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer);
+GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum pname, GLint param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param);
+#endif
+
+#ifndef GL_APPLE_ycbcr_422
+#define GL_APPLE_ycbcr_422 1
+#endif
+
+#ifndef GL_S3_s3tc
+#define GL_S3_s3tc 1
+#endif
+
+#ifndef GL_ATI_draw_buffers
+#define GL_ATI_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawBuffersATI (GLsizei n, const GLenum *bufs);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+#ifndef GL_ATI_pixel_format_float
+#define GL_ATI_pixel_format_float 1
+/* This is really a WGL extension, but defines some associated GL enums.
+ * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string.
+ */
+#endif
+
+#ifndef GL_ATI_texture_env_combine3
+#define GL_ATI_texture_env_combine3 1
+#endif
+
+#ifndef GL_ATI_texture_float
+#define GL_ATI_texture_float 1
+#endif
+
+#ifndef GL_NV_float_buffer
+#define GL_NV_float_buffer 1
+#endif
+
+#ifndef GL_NV_fragment_program
+#define GL_NV_fragment_program 1
+/* Some NV_fragment_program entry points are shared with ARB_vertex_program. */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v);
+GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v);
+GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params);
+GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v);
+typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params);
+#endif
+
+#ifndef GL_NV_half_float
+#define GL_NV_half_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertex2hNV (GLhalfNV x, GLhalfNV y);
+GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glVertex3hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z);
+GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glVertex4hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glNormal3hNV (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz);
+GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glColor4hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha);
+GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV s);
+GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV s, GLhalfNV t);
+GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r);
+GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum target, GLhalfNV s);
+GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum target, GLhalfNV s, GLhalfNV t);
+GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r);
+GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum target, const GLhalfNV *v);
+GLAPI void APIENTRY glFogCoordhNV (GLhalfNV fog);
+GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *fog);
+GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *v);
+GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV weight);
+GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *weight);
+GLAPI void APIENTRY glVertexAttrib1hNV (GLuint index, GLhalfNV x);
+GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttrib2hNV (GLuint index, GLhalfNV x, GLhalfNV y);
+GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttrib3hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z);
+GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttrib4hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint index, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfNV *v);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y);
+typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z);
+typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz);
+typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha);
+typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s);
+typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t);
+typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r);
+typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog);
+typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+#endif
+
+#ifndef GL_NV_pixel_data_range
+#define GL_NV_pixel_data_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, GLvoid *pointer);
+GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum target);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target);
+#endif
+
+#ifndef GL_NV_primitive_restart
+#define GL_NV_primitive_restart 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPrimitiveRestartNV (void);
+GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void);
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index);
+#endif
+
+#ifndef GL_NV_texture_expand_normal
+#define GL_NV_texture_expand_normal 1
+#endif
+
+#ifndef GL_NV_vertex_program2
+#define GL_NV_vertex_program2 1
+#endif
+
+#ifndef GL_ATI_map_object_buffer
+#define GL_ATI_map_object_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint buffer);
+GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint buffer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+#endif
+
+#ifndef GL_ATI_separate_stencil
+#define GL_ATI_separate_stencil 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStencilOpSeparateATI (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+#endif
+
+#ifndef GL_ATI_vertex_attrib_array_object
+#define GL_ATI_vertex_attrib_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset);
+GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint index, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint index, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_OES_read_format
+#define GL_OES_read_format 1
+#endif
+
+#ifndef GL_EXT_depth_bounds_test
+#define GL_EXT_depth_bounds_test 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDepthBoundsEXT (GLclampd zmin, GLclampd zmax);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax);
+#endif
+
+#ifndef GL_EXT_texture_mirror_clamp
+#define GL_EXT_texture_mirror_clamp 1
+#endif
+
+#ifndef GL_EXT_blend_equation_separate
+#define GL_EXT_blend_equation_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum modeRGB, GLenum modeAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha);
+#endif
+
+#ifndef GL_MESA_pack_invert
+#define GL_MESA_pack_invert 1
+#endif
+
+#ifndef GL_MESA_ycbcr_texture
+#define GL_MESA_ycbcr_texture 1
+#endif
+
+#ifndef GL_EXT_pixel_buffer_object
+#define GL_EXT_pixel_buffer_object 1
+#endif
+
+#ifndef GL_NV_fragment_program_option
+#define GL_NV_fragment_program_option 1
+#endif
+
+#ifndef GL_NV_fragment_program2
+#define GL_NV_fragment_program2 1
+#endif
+
+#ifndef GL_NV_vertex_program2_option
+#define GL_NV_vertex_program2_option 1
+#endif
+
+#ifndef GL_NV_vertex_program3
+#define GL_NV_vertex_program3 1
+#endif
+
+#ifndef GL_EXT_framebuffer_object
+#define GL_EXT_framebuffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint renderbuffer);
+GLAPI void APIENTRY glBindRenderbufferEXT (GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei n, const GLuint *renderbuffers);
+GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei n, GLuint *renderbuffers);
+GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint framebuffer);
+GLAPI void APIENTRY glBindFramebufferEXT (GLenum target, GLuint framebuffer);
+GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei n, const GLuint *framebuffers);
+GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei n, GLuint *framebuffers);
+GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum target);
+GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGenerateMipmapEXT (GLenum target);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer);
+typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
+typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
+typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target);
+#endif
+
+#ifndef GL_GREMEDY_string_marker
+#define GL_GREMEDY_string_marker 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei len, const GLvoid *string);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string);
+#endif
+
+#ifndef GL_EXT_packed_depth_stencil
+#define GL_EXT_packed_depth_stencil 1
+#endif
+
+#ifndef GL_EXT_stencil_clear_tag
+#define GL_EXT_stencil_clear_tag 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStencilClearTagEXT (GLsizei stencilTagBits, GLuint stencilClearTag);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag);
+#endif
+
+#ifndef GL_EXT_texture_sRGB
+#define GL_EXT_texture_sRGB 1
+#endif
+
+#ifndef GL_EXT_framebuffer_blit
+#define GL_EXT_framebuffer_blit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample
+#define GL_EXT_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_MESAX_texture_stack
+#define GL_MESAX_texture_stack 1
+#endif
+
+#ifndef GL_EXT_timer_query
+#define GL_EXT_timer_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64EXT *params);
+GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64EXT *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params);
+#endif
+
+#ifndef GL_EXT_gpu_program_parameters
+#define GL_EXT_gpu_program_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+#endif
+
+#ifndef GL_APPLE_flush_buffer_range
+#define GL_APPLE_flush_buffer_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum target, GLintptr offset, GLsizeiptr size);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size);
+#endif
+
+#ifndef GL_NV_gpu_program4
+#define GL_NV_gpu_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum target, GLuint index, const GLint *params);
+GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum target, GLuint index, const GLuint *params);
+GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum target, GLuint index, const GLint *params);
+GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum target, GLuint index, const GLuint *params);
+GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum target, GLuint index, GLint *params);
+GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum target, GLuint index, GLuint *params);
+GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum target, GLuint index, GLint *params);
+GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum target, GLuint index, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params);
+#endif
+
+#ifndef GL_NV_geometry_program4
+#define GL_NV_geometry_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit);
+GLAPI void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level);
+GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif
+
+#ifndef GL_EXT_geometry_shader4
+#define GL_EXT_geometry_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
+#endif
+
+#ifndef GL_NV_vertex_program4
+#define GL_NV_vertex_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x);
+GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y);
+GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z);
+GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x);
+GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y);
+GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z);
+GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v);
+GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v);
+GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v);
+GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v);
+GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v);
+GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v);
+GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_EXT_gpu_shader4
+#define GL_EXT_gpu_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params);
+GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name);
+GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glUniform1uiEXT (GLint location, GLuint v0);
+GLAPI void APIENTRY glUniform2uiEXT (GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glUniform3uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glUniform4uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+#endif
+
+#ifndef GL_EXT_draw_instanced
+#define GL_EXT_draw_instanced 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_EXT_packed_float
+#define GL_EXT_packed_float 1
+#endif
+
+#ifndef GL_EXT_texture_array
+#define GL_EXT_texture_array 1
+#endif
+
+#ifndef GL_EXT_texture_buffer_object
+#define GL_EXT_texture_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+#endif
+
+#ifndef GL_EXT_texture_compression_latc
+#define GL_EXT_texture_compression_latc 1
+#endif
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_EXT_texture_compression_rgtc 1
+#endif
+
+#ifndef GL_EXT_texture_shared_exponent
+#define GL_EXT_texture_shared_exponent 1
+#endif
+
+#ifndef GL_NV_depth_buffer_float
+#define GL_NV_depth_buffer_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar);
+GLAPI void APIENTRY glClearDepthdNV (GLdouble depth);
+GLAPI void APIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar);
+typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth);
+typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax);
+#endif
+
+#ifndef GL_NV_fragment_program4
+#define GL_NV_fragment_program4 1
+#endif
+
+#ifndef GL_NV_framebuffer_multisample_coverage
+#define GL_NV_framebuffer_multisample_coverage 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_EXT_framebuffer_sRGB
+#define GL_EXT_framebuffer_sRGB 1
+#endif
+
+#ifndef GL_NV_geometry_shader4
+#define GL_NV_geometry_shader4 1
+#endif
+
+#ifndef GL_NV_parameter_buffer_object
+#define GL_NV_parameter_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params);
+GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params);
+#endif
+
+#ifndef GL_EXT_draw_buffers2
+#define GL_EXT_draw_buffers2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data);
+GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data);
+GLAPI void APIENTRY glEnableIndexedEXT (GLenum target, GLuint index);
+GLAPI void APIENTRY glDisableIndexedEXT (GLenum target, GLuint index);
+GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data);
+typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index);
+#endif
+
+#ifndef GL_NV_transform_feedback
+#define GL_NV_transform_feedback 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode);
+GLAPI void APIENTRY glEndTransformFeedbackNV (void);
+GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint count, const GLint *attribs, GLenum bufferMode);
+GLAPI void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GLAPI void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+GLAPI void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer);
+GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
+GLAPI void APIENTRY glActiveVaryingNV (GLuint program, const GLchar *name);
+GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint program, const GLchar *name);
+GLAPI void APIENTRY glGetActiveVaryingNV (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint program, GLuint index, GLint *location);
+GLAPI void APIENTRY glTransformFeedbackStreamAttribsNV (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode);
+typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode);
+#endif
+
+#ifndef GL_EXT_bindable_uniform
+#define GL_EXT_bindable_uniform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniformBufferEXT (GLuint program, GLint location, GLuint buffer);
+GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint program, GLint location);
+GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint program, GLint location);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location);
+typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location);
+#endif
+
+#ifndef GL_EXT_texture_integer
+#define GL_EXT_texture_integer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glClearColorIiEXT (GLint red, GLint green, GLint blue, GLint alpha);
+GLAPI void APIENTRY glClearColorIuiEXT (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha);
+typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+#endif
+
+#ifndef GL_GREMEDY_frame_terminator
+#define GL_GREMEDY_frame_terminator 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFrameTerminatorGREMEDY (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void);
+#endif
+
+#ifndef GL_NV_conditional_render
+#define GL_NV_conditional_render 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode);
+GLAPI void APIENTRY glEndConditionalRenderNV (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode);
+typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void);
+#endif
+
+#ifndef GL_NV_present_video
+#define GL_NV_present_video 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1);
+GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3);
+GLAPI void APIENTRY glGetVideoivNV (GLuint video_slot, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVideouivNV (GLuint video_slot, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glGetVideoi64vNV (GLuint video_slot, GLenum pname, GLint64EXT *params);
+GLAPI void APIENTRY glGetVideoui64vNV (GLuint video_slot, GLenum pname, GLuint64EXT *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1);
+typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3);
+typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params);
+#endif
+
+#ifndef GL_EXT_transform_feedback
+#define GL_EXT_transform_feedback 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginTransformFeedbackEXT (GLenum primitiveMode);
+GLAPI void APIENTRY glEndTransformFeedbackEXT (void);
+GLAPI void APIENTRY glBindBufferRangeEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+GLAPI void APIENTRY glBindBufferBaseEXT (GLenum target, GLuint index, GLuint buffer);
+GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode);
+typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void);
+typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+#endif
+
+#ifndef GL_EXT_direct_state_access
+#define GL_EXT_direct_state_access 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield mask);
+GLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield mask);
+GLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum mode);
+GLAPI void APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+GLAPI void APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLAPI void APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GLAPI void APIENTRY glMatrixPopEXT (GLenum mode);
+GLAPI void APIENTRY glMatrixPushEXT (GLenum mode);
+GLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m);
+GLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m);
+GLAPI void APIENTRY glTextureParameterfEXT (GLuint texture, GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glTextureParameteriEXT (GLuint texture, GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetTextureImageEXT (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+GLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params);
+GLAPI void APIENTRY glTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glMultiTexParameterfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glMultiTexParameteriEXT (GLenum texunit, GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+GLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+GLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+GLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params);
+GLAPI void APIENTRY glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+GLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glBindMultiTextureEXT (GLenum texunit, GLenum target, GLuint texture);
+GLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum array, GLuint index);
+GLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum array, GLuint index);
+GLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glMultiTexEnvfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glMultiTexEnviEXT (GLenum texunit, GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMultiTexGendEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble param);
+GLAPI void APIENTRY glMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params);
+GLAPI void APIENTRY glMultiTexGenfEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat param);
+GLAPI void APIENTRY glMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glMultiTexGeniEXT (GLenum texunit, GLenum coord, GLenum pname, GLint param);
+GLAPI void APIENTRY glMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum target, GLuint index, GLfloat *data);
+GLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum target, GLuint index, GLdouble *data);
+GLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum target, GLuint index, GLvoid* *data);
+GLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint texture, GLenum target, GLint lod, GLvoid *img);
+GLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+GLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, GLint lod, GLvoid *img);
+GLAPI void APIENTRY glNamedProgramStringEXT (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+GLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint program, GLenum target, GLuint index, const GLdouble *params);
+GLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint program, GLenum target, GLuint index, const GLfloat *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint program, GLenum target, GLuint index, GLdouble *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint program, GLenum target, GLuint index, GLfloat *params);
+GLAPI void APIENTRY glGetNamedProgramivEXT (GLuint program, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint program, GLenum target, GLenum pname, GLvoid *string);
+GLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint program, GLenum target, GLuint index, const GLint *params);
+GLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint program, GLenum target, GLuint index, const GLuint *params);
+GLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint program, GLenum target, GLuint index, GLint *params);
+GLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint program, GLenum target, GLuint index, GLuint *params);
+GLAPI void APIENTRY glTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, const GLuint *params);
+GLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, GLuint *params);
+GLAPI void APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0);
+GLAPI void APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+GLAPI void APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+GLAPI void APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+GLAPI void APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0);
+GLAPI void APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1);
+GLAPI void APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+GLAPI void APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+GLAPI void APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value);
+GLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+GLAPI void APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0);
+GLAPI void APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1);
+GLAPI void APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+GLAPI void APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GLAPI void APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value);
+GLAPI void APIENTRY glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage);
+GLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+GLAPI GLvoid* APIENTRY glMapNamedBufferEXT (GLuint buffer, GLenum access);
+GLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint buffer);
+GLAPI GLvoid* APIENTRY glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GLAPI void APIENTRY glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length);
+GLAPI void APIENTRY glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+GLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint buffer, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint buffer, GLenum pname, GLvoid* *params);
+GLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data);
+GLAPI void APIENTRY glTextureBufferEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer);
+GLAPI void APIENTRY glMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);
+GLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint renderbuffer, GLenum pname, GLint *params);
+GLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint framebuffer, GLenum target);
+GLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+GLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint texture, GLenum target);
+GLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum texunit, GLenum target);
+GLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint framebuffer, GLenum mode);
+GLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint framebuffer, GLsizei n, const GLenum *bufs);
+GLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint framebuffer, GLenum mode);
+GLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params);
+GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);
+GLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face);
+GLAPI void APIENTRY glTextureRenderbufferEXT (GLuint texture, GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum texunit, GLenum target, GLuint renderbuffer);
+GLAPI void APIENTRY glProgramUniform1dEXT (GLuint program, GLint location, GLdouble x);
+GLAPI void APIENTRY glProgramUniform2dEXT (GLuint program, GLint location, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glProgramUniform3dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glProgramUniform4dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glProgramUniform1dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform2dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform3dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniform4dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix2x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix3x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+GLAPI void APIENTRY glProgramUniformMatrix4x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);
+typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask);
+typedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index);
+typedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param);
+typedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params);
+typedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data);
+typedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLvoid* *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, GLvoid *img);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, GLvoid *img);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, GLvoid *string);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer);
+typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access);
+typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (APIENTRYP PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, GLvoid* *params);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data);
+typedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer);
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params);
+typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target);
+typedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face);
+typedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DEXTPROC) (GLuint program, GLint location, GLdouble x);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value);
+#endif
+
+#ifndef GL_EXT_vertex_array_bgra
+#define GL_EXT_vertex_array_bgra 1
+#endif
+
+#ifndef GL_EXT_texture_swizzle
+#define GL_EXT_texture_swizzle 1
+#endif
+
+#ifndef GL_NV_explicit_multisample
+#define GL_NV_explicit_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetMultisamplefvNV (GLenum pname, GLuint index, GLfloat *val);
+GLAPI void APIENTRY glSampleMaskIndexedNV (GLuint index, GLbitfield mask);
+GLAPI void APIENTRY glTexRenderbufferNV (GLenum target, GLuint renderbuffer);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat *val);
+typedef void (APIENTRYP PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask);
+typedef void (APIENTRYP PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer);
+#endif
+
+#ifndef GL_NV_transform_feedback2
+#define GL_NV_transform_feedback2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindTransformFeedbackNV (GLenum target, GLuint id);
+GLAPI void APIENTRY glDeleteTransformFeedbacksNV (GLsizei n, const GLuint *ids);
+GLAPI void APIENTRY glGenTransformFeedbacksNV (GLsizei n, GLuint *ids);
+GLAPI GLboolean APIENTRY glIsTransformFeedbackNV (GLuint id);
+GLAPI void APIENTRY glPauseTransformFeedbackNV (void);
+GLAPI void APIENTRY glResumeTransformFeedbackNV (void);
+GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint *ids);
+typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void);
+typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void);
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id);
+#endif
+
+#ifndef GL_ATI_meminfo
+#define GL_ATI_meminfo 1
+#endif
+
+#ifndef GL_AMD_performance_monitor
+#define GL_AMD_performance_monitor 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data);
+GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);
+GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint monitor);
+GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint monitor);
+GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data);
+typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList);
+typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif
+
+#ifndef GL_AMD_texture_texture4
+#define GL_AMD_texture_texture4 1
+#endif
+
+#ifndef GL_AMD_vertex_shader_tesselator
+#define GL_AMD_vertex_shader_tesselator 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTessellationFactorAMD (GLfloat factor);
+GLAPI void APIENTRY glTessellationModeAMD (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor);
+typedef void (APIENTRYP PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_provoking_vertex
+#define GL_EXT_provoking_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProvokingVertexEXT (GLenum mode);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_texture_snorm
+#define GL_EXT_texture_snorm 1
+#endif
+
+#ifndef GL_AMD_draw_buffers_blend
+#define GL_AMD_draw_buffers_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncIndexedAMD (GLuint buf, GLenum src, GLenum dst);
+GLAPI void APIENTRY glBlendFuncSeparateIndexedAMD (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GLAPI void APIENTRY glBlendEquationIndexedAMD (GLuint buf, GLenum mode);
+GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+#endif
+
+#ifndef GL_APPLE_texture_range
+#define GL_APPLE_texture_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureRangeAPPLE (GLenum target, GLsizei length, const GLvoid *pointer);
+GLAPI void APIENTRY glGetTexParameterPointervAPPLE (GLenum target, GLenum pname, GLvoid* *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_APPLE_float_pixels
+#define GL_APPLE_float_pixels 1
+#endif
+
+#ifndef GL_APPLE_vertex_program_evaluators
+#define GL_APPLE_vertex_program_evaluators 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glEnableVertexAttribAPPLE (GLuint index, GLenum pname);
+GLAPI void APIENTRY glDisableVertexAttribAPPLE (GLuint index, GLenum pname);
+GLAPI GLboolean APIENTRY glIsVertexAttribEnabledAPPLE (GLuint index, GLenum pname);
+GLAPI void APIENTRY glMapVertexAttrib1dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+GLAPI void APIENTRY glMapVertexAttrib1fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+GLAPI void APIENTRY glMapVertexAttrib2dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+GLAPI void APIENTRY glMapVertexAttrib2fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+#endif
+
+#ifndef GL_APPLE_aux_depth_stencil
+#define GL_APPLE_aux_depth_stencil 1
+#endif
+
+#ifndef GL_APPLE_object_purgeable
+#define GL_APPLE_object_purgeable 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLenum APIENTRY glObjectPurgeableAPPLE (GLenum objectType, GLuint name, GLenum option);
+GLAPI GLenum APIENTRY glObjectUnpurgeableAPPLE (GLenum objectType, GLuint name, GLenum option);
+GLAPI void APIENTRY glGetObjectParameterivAPPLE (GLenum objectType, GLuint name, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLenum (APIENTRYP PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+typedef GLenum (APIENTRYP PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_APPLE_row_bytes
+#define GL_APPLE_row_bytes 1
+#endif
+
+#ifndef GL_APPLE_rgb_422
+#define GL_APPLE_rgb_422 1
+#endif
+
+#ifndef GL_NV_video_capture
+#define GL_NV_video_capture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint video_capture_slot);
+GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset);
+GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture);
+GLAPI void APIENTRY glEndVideoCaptureNV (GLuint video_capture_slot);
+GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint video_capture_slot, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVideoCaptureStreamivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params);
+GLAPI void APIENTRY glGetVideoCaptureStreamfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params);
+GLAPI void APIENTRY glGetVideoCaptureStreamdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params);
+GLAPI GLenum APIENTRY glVideoCaptureNV (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time);
+GLAPI void APIENTRY glVideoCaptureStreamParameterivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glVideoCaptureStreamParameterfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params);
+GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
+typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset);
+typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params);
+typedef GLenum (APIENTRYP PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time);
+typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params);
+#endif
+
+#ifndef GL_NV_copy_image
+#define GL_NV_copy_image 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyImageSubDataNV (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
+#ifndef GL_EXT_separate_shader_objects
+#define GL_EXT_separate_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUseShaderProgramEXT (GLenum type, GLuint program);
+GLAPI void APIENTRY glActiveProgramEXT (GLuint program);
+GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *string);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program);
+typedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string);
+#endif
+
+#ifndef GL_NV_parameter_buffer_object2
+#define GL_NV_parameter_buffer_object2 1
+#endif
+
+#ifndef GL_NV_shader_buffer_load
+#define GL_NV_shader_buffer_load 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMakeBufferResidentNV (GLenum target, GLenum access);
+GLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum target);
+GLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum target);
+GLAPI void APIENTRY glMakeNamedBufferResidentNV (GLuint buffer, GLenum access);
+GLAPI void APIENTRY glMakeNamedBufferNonResidentNV (GLuint buffer);
+GLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint buffer);
+GLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum target, GLenum pname, GLuint64EXT *params);
+GLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint buffer, GLenum pname, GLuint64EXT *params);
+GLAPI void APIENTRY glGetIntegerui64vNV (GLenum value, GLuint64EXT *result);
+GLAPI void APIENTRY glUniformui64NV (GLint location, GLuint64EXT value);
+GLAPI void APIENTRY glUniformui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glGetUniformui64vNV (GLuint program, GLint location, GLuint64EXT *params);
+GLAPI void APIENTRY glProgramUniformui64NV (GLuint program, GLint location, GLuint64EXT value);
+GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access);
+typedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access);
+typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer);
+typedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result);
+typedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value);
+typedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif
+
+#ifndef GL_NV_vertex_buffer_unified_memory
+#define GL_NV_vertex_buffer_unified_memory 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBufferAddressRangeNV (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);
+GLAPI void APIENTRY glVertexFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glNormalFormatNV (GLenum type, GLsizei stride);
+GLAPI void APIENTRY glColorFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glIndexFormatNV (GLenum type, GLsizei stride);
+GLAPI void APIENTRY glTexCoordFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei stride);
+GLAPI void APIENTRY glSecondaryColorFormatNV (GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glFogCoordFormatNV (GLenum type, GLsizei stride);
+GLAPI void APIENTRY glVertexAttribFormatNV (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);
+GLAPI void APIENTRY glVertexAttribIFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride);
+GLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum value, GLuint index, GLuint64EXT *result);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length);
+typedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
+typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result);
+#endif
+
+#ifndef GL_NV_texture_barrier
+#define GL_NV_texture_barrier 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureBarrierNV (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void);
+#endif
+
+#ifndef GL_AMD_shader_stencil_export
+#define GL_AMD_shader_stencil_export 1
+#endif
+
+#ifndef GL_AMD_seamless_cubemap_per_texture
+#define GL_AMD_seamless_cubemap_per_texture 1
+#endif
+
+#ifndef GL_AMD_conservative_depth
+#define GL_AMD_conservative_depth 1
+#endif
+
+#ifndef GL_EXT_shader_image_load_store
+#define GL_EXT_shader_image_load_store 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindImageTextureEXT (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format);
+GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format);
+typedef void (APIENTRYP PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers);
+#endif
+
+#ifndef GL_EXT_vertex_attrib_64bit
+#define GL_EXT_vertex_attrib_64bit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribL1dEXT (GLuint index, GLdouble x);
+GLAPI void APIENTRY glVertexAttribL2dEXT (GLuint index, GLdouble x, GLdouble y);
+GLAPI void APIENTRY glVertexAttribL3dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+GLAPI void APIENTRY glVertexAttribL4dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+GLAPI void APIENTRY glVertexAttribL1dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL2dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL3dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribL4dvEXT (GLuint index, const GLdouble *v);
+GLAPI void APIENTRY glVertexAttribLPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GLAPI void APIENTRY glGetVertexAttribLdvEXT (GLuint index, GLenum pname, GLdouble *params);
+GLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
+#endif
+
+#ifndef GL_NV_gpu_program5
+#define GL_NV_gpu_program5 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramSubroutineParametersuivNV (GLenum target, GLsizei count, const GLuint *params);
+GLAPI void APIENTRY glGetProgramSubroutineParameteruivNV (GLenum target, GLuint index, GLuint *param);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC) (GLenum target, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC) (GLenum target, GLuint index, GLuint *param);
+#endif
+
+#ifndef GL_NV_gpu_shader5
+#define GL_NV_gpu_shader5 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniform1i64NV (GLint location, GLint64EXT x);
+GLAPI void APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y);
+GLAPI void APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GLAPI void APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GLAPI void APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x);
+GLAPI void APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y);
+GLAPI void APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GLAPI void APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GLAPI void APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params);
+GLAPI void APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x);
+GLAPI void APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+GLAPI void APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GLAPI void APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GLAPI void APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+GLAPI void APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x);
+GLAPI void APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+GLAPI void APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GLAPI void APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GLAPI void APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+GLAPI void APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x);
+typedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x);
+typedef void (APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value);
+#endif
+
+#ifndef GL_NV_shader_buffer_store
+#define GL_NV_shader_buffer_store 1
+#endif
+
+#ifndef GL_NV_tessellation_program5
+#define GL_NV_tessellation_program5 1
+#endif
+
+#ifndef GL_NV_vertex_attrib_integer_64bit
+#define GL_NV_vertex_attrib_integer_64bit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribL1i64NV (GLuint index, GLint64EXT x);
+GLAPI void APIENTRY glVertexAttribL2i64NV (GLuint index, GLint64EXT x, GLint64EXT y);
+GLAPI void APIENTRY glVertexAttribL3i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+GLAPI void APIENTRY glVertexAttribL4i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+GLAPI void APIENTRY glVertexAttribL1i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL2i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL3i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL4i64vNV (GLuint index, const GLint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL1ui64NV (GLuint index, GLuint64EXT x);
+GLAPI void APIENTRY glVertexAttribL2ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y);
+GLAPI void APIENTRY glVertexAttribL3ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+GLAPI void APIENTRY glVertexAttribL4ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+GLAPI void APIENTRY glVertexAttribL1ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL2ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL3ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glVertexAttribL4ui64vNV (GLuint index, const GLuint64EXT *v);
+GLAPI void APIENTRY glGetVertexAttribLi64vNV (GLuint index, GLenum pname, GLint64EXT *params);
+GLAPI void APIENTRY glGetVertexAttribLui64vNV (GLuint index, GLenum pname, GLuint64EXT *params);
+GLAPI void APIENTRY glVertexAttribLFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT *v);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT *params);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride);
+#endif
+
+#ifndef GL_NV_multisample_coverage
+#define GL_NV_multisample_coverage 1
+#endif
+
+#ifndef GL_AMD_name_gen_delete
+#define GL_AMD_name_gen_delete 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenNamesAMD (GLenum identifier, GLuint num, GLuint *names);
+GLAPI void APIENTRY glDeleteNamesAMD (GLenum identifier, GLuint num, const GLuint *names);
+GLAPI GLboolean APIENTRY glIsNameAMD (GLenum identifier, GLuint name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint *names);
+typedef void (APIENTRYP PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint *names);
+typedef GLboolean (APIENTRYP PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name);
+#endif
+
+#ifndef GL_AMD_debug_output
+#define GL_AMD_debug_output 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf);
+GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, GLvoid *userParam);
+GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, GLvoid *userParam);
+typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message);
+#endif
+
+#ifndef GL_NV_vdpau_interop
+#define GL_NV_vdpau_interop 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVDPAUInitNV (const GLvoid *vdpDevice, const GLvoid *getProcAddress);
+GLAPI void APIENTRY glVDPAUFiniNV (void);
+GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceNV (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterOutputSurfaceNV (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+GLAPI void APIENTRY glVDPAUIsSurfaceNV (GLvdpauSurfaceNV surface);
+GLAPI void APIENTRY glVDPAUUnregisterSurfaceNV (GLvdpauSurfaceNV surface);
+GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+GLAPI void APIENTRY glVDPAUSurfaceAccessNV (GLvdpauSurfaceNV surface, GLenum access);
+GLAPI void APIENTRY glVDPAUMapSurfacesNV (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces);
+GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVDPAUINITNVPROC) (const GLvoid *vdpDevice, const GLvoid *getProcAddress);
+typedef void (APIENTRYP PFNGLVDPAUFININVPROC) (void);
+typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames);
+typedef void (APIENTRYP PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface);
+typedef void (APIENTRYP PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface);
+typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+typedef void (APIENTRYP PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access);
+typedef void (APIENTRYP PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces);
+typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces);
+#endif
+
+#ifndef GL_AMD_transform_feedback3_lines_triangles
+#define GL_AMD_transform_feedback3_lines_triangles 1
+#endif
+
+#ifndef GL_AMD_depth_clamp_separate
+#define GL_AMD_depth_clamp_separate 1
+#endif
+
+#ifndef GL_EXT_texture_sRGB_decode
+#define GL_EXT_texture_sRGB_decode 1
+#endif
+
+#ifndef GL_NV_texture_multisample
+#define GL_NV_texture_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage2DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTexImage3DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTextureImage2DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTextureImage3DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTextureImage2DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+#endif
+
+#ifndef GL_AMD_blend_minmax_factor
+#define GL_AMD_blend_minmax_factor 1
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/3rdParty/glext/GL/wglext.h b/3rdParty/glext/GL/wglext.h
new file mode 100644
index 0000000..3fe2e2d
--- /dev/null
+++ b/3rdParty/glext/GL/wglext.h
@@ -0,0 +1,929 @@
+#ifndef __wglext_h_
+#define __wglext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2010 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Function declaration macros - to move into glplatform.h */
+
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+/*************************************************************/
+
+/* Header file version number */
+/* wglext.h last updated 2011/04/13 */
+/* Current version at http://www.opengl.org/registry/ */
+#define WGL_WGLEXT_VERSION 23
+
+#ifndef WGL_ARB_buffer_region
+#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
+#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
+#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
+#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#endif
+
+#ifndef WGL_ARB_extensions_string
+#endif
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NEED_PALETTE_ARB 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define WGL_SWAP_METHOD_ARB 0x2007
+#define WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define WGL_TRANSPARENT_ARB 0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define WGL_SHARE_DEPTH_ARB 0x200C
+#define WGL_SHARE_STENCIL_ARB 0x200D
+#define WGL_SHARE_ACCUM_ARB 0x200E
+#define WGL_SUPPORT_GDI_ARB 0x200F
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201A
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_ALPHA_SHIFT_ARB 0x201C
+#define WGL_ACCUM_BITS_ARB 0x201D
+#define WGL_ACCUM_RED_BITS_ARB 0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_SWAP_EXCHANGE_ARB 0x2028
+#define WGL_SWAP_COPY_ARB 0x2029
+#define WGL_SWAP_UNDEFINED_ARB 0x202A
+#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_TYPE_COLORINDEX_ARB 0x202C
+#endif
+
+#ifndef WGL_ARB_make_current_read
+#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
+#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
+#endif
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
+#define WGL_PBUFFER_LARGEST_ARB 0x2033
+#define WGL_PBUFFER_WIDTH_ARB 0x2034
+#define WGL_PBUFFER_HEIGHT_ARB 0x2035
+#define WGL_PBUFFER_LOST_ARB 0x2036
+#endif
+
+#ifndef WGL_ARB_render_texture
+#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
+#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
+#define WGL_TEXTURE_FORMAT_ARB 0x2072
+#define WGL_TEXTURE_TARGET_ARB 0x2073
+#define WGL_MIPMAP_TEXTURE_ARB 0x2074
+#define WGL_TEXTURE_RGB_ARB 0x2075
+#define WGL_TEXTURE_RGBA_ARB 0x2076
+#define WGL_NO_TEXTURE_ARB 0x2077
+#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
+#define WGL_TEXTURE_1D_ARB 0x2079
+#define WGL_TEXTURE_2D_ARB 0x207A
+#define WGL_MIPMAP_LEVEL_ARB 0x207B
+#define WGL_CUBE_MAP_FACE_ARB 0x207C
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
+#define WGL_FRONT_LEFT_ARB 0x2083
+#define WGL_FRONT_RIGHT_ARB 0x2084
+#define WGL_BACK_LEFT_ARB 0x2085
+#define WGL_BACK_RIGHT_ARB 0x2086
+#define WGL_AUX0_ARB 0x2087
+#define WGL_AUX1_ARB 0x2088
+#define WGL_AUX2_ARB 0x2089
+#define WGL_AUX3_ARB 0x208A
+#define WGL_AUX4_ARB 0x208B
+#define WGL_AUX5_ARB 0x208C
+#define WGL_AUX6_ARB 0x208D
+#define WGL_AUX7_ARB 0x208E
+#define WGL_AUX8_ARB 0x208F
+#define WGL_AUX9_ARB 0x2090
+#endif
+
+#ifndef WGL_ARB_pixel_format_float
+#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
+#endif
+
+#ifndef WGL_ARB_framebuffer_sRGB
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
+#endif
+
+#ifndef WGL_ARB_create_context
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define ERROR_INVALID_VERSION_ARB 0x2095
+#endif
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define ERROR_INVALID_PROFILE_ARB 0x2096
+#endif
+
+#ifndef WGL_ARB_create_context_robustness
+#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
+#endif
+
+#ifndef WGL_EXT_make_current_read
+#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
+#endif
+
+#ifndef WGL_EXT_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
+#define WGL_DRAW_TO_WINDOW_EXT 0x2001
+#define WGL_DRAW_TO_BITMAP_EXT 0x2002
+#define WGL_ACCELERATION_EXT 0x2003
+#define WGL_NEED_PALETTE_EXT 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
+#define WGL_SWAP_METHOD_EXT 0x2007
+#define WGL_NUMBER_OVERLAYS_EXT 0x2008
+#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
+#define WGL_TRANSPARENT_EXT 0x200A
+#define WGL_TRANSPARENT_VALUE_EXT 0x200B
+#define WGL_SHARE_DEPTH_EXT 0x200C
+#define WGL_SHARE_STENCIL_EXT 0x200D
+#define WGL_SHARE_ACCUM_EXT 0x200E
+#define WGL_SUPPORT_GDI_EXT 0x200F
+#define WGL_SUPPORT_OPENGL_EXT 0x2010
+#define WGL_DOUBLE_BUFFER_EXT 0x2011
+#define WGL_STEREO_EXT 0x2012
+#define WGL_PIXEL_TYPE_EXT 0x2013
+#define WGL_COLOR_BITS_EXT 0x2014
+#define WGL_RED_BITS_EXT 0x2015
+#define WGL_RED_SHIFT_EXT 0x2016
+#define WGL_GREEN_BITS_EXT 0x2017
+#define WGL_GREEN_SHIFT_EXT 0x2018
+#define WGL_BLUE_BITS_EXT 0x2019
+#define WGL_BLUE_SHIFT_EXT 0x201A
+#define WGL_ALPHA_BITS_EXT 0x201B
+#define WGL_ALPHA_SHIFT_EXT 0x201C
+#define WGL_ACCUM_BITS_EXT 0x201D
+#define WGL_ACCUM_RED_BITS_EXT 0x201E
+#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
+#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
+#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
+#define WGL_DEPTH_BITS_EXT 0x2022
+#define WGL_STENCIL_BITS_EXT 0x2023
+#define WGL_AUX_BUFFERS_EXT 0x2024
+#define WGL_NO_ACCELERATION_EXT 0x2025
+#define WGL_GENERIC_ACCELERATION_EXT 0x2026
+#define WGL_FULL_ACCELERATION_EXT 0x2027
+#define WGL_SWAP_EXCHANGE_EXT 0x2028
+#define WGL_SWAP_COPY_EXT 0x2029
+#define WGL_SWAP_UNDEFINED_EXT 0x202A
+#define WGL_TYPE_RGBA_EXT 0x202B
+#define WGL_TYPE_COLORINDEX_EXT 0x202C
+#endif
+
+#ifndef WGL_EXT_pbuffer
+#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
+#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
+#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
+#define WGL_PBUFFER_LARGEST_EXT 0x2033
+#define WGL_PBUFFER_WIDTH_EXT 0x2034
+#define WGL_PBUFFER_HEIGHT_EXT 0x2035
+#endif
+
+#ifndef WGL_EXT_depth_float
+#define WGL_DEPTH_FLOAT_EXT 0x2040
+#endif
+
+#ifndef WGL_3DFX_multisample
+#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
+#define WGL_SAMPLES_3DFX 0x2061
+#endif
+
+#ifndef WGL_EXT_multisample
+#define WGL_SAMPLE_BUFFERS_EXT 0x2041
+#define WGL_SAMPLES_EXT 0x2042
+#endif
+
+#ifndef WGL_I3D_digital_video_control
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
+#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
+#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
+#endif
+
+#ifndef WGL_I3D_gamma
+#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
+#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
+#endif
+
+#ifndef WGL_I3D_genlock
+#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
+#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045
+#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046
+#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047
+#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
+#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
+#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
+#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
+#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
+#endif
+
+#ifndef WGL_I3D_image_buffer
+#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
+#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
+#endif
+
+#ifndef WGL_I3D_swap_frame_lock
+#endif
+
+#ifndef WGL_NV_render_depth_texture
+#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
+#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
+#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
+#define WGL_DEPTH_COMPONENT_NV 0x20A7
+#endif
+
+#ifndef WGL_NV_render_texture_rectangle
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
+#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
+#endif
+
+#ifndef WGL_ATI_pixel_format_float
+#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
+#endif
+
+#ifndef WGL_NV_float_buffer
+#define WGL_FLOAT_COMPONENTS_NV 0x20B0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
+#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
+#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
+#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
+#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
+#endif
+
+#ifndef WGL_3DL_stereo_control
+#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
+#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
+#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
+#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
+#endif
+
+#ifndef WGL_EXT_pixel_format_packed_float
+#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
+#endif
+
+#ifndef WGL_EXT_framebuffer_sRGB
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
+#endif
+
+#ifndef WGL_NV_present_video
+#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0
+#endif
+
+#ifndef WGL_NV_video_out
+#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
+#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
+#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
+#define WGL_VIDEO_OUT_COLOR_NV 0x20C3
+#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4
+#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5
+#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
+#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
+#define WGL_VIDEO_OUT_FRAME 0x20C8
+#define WGL_VIDEO_OUT_FIELD_1 0x20C9
+#define WGL_VIDEO_OUT_FIELD_2 0x20CA
+#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
+#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
+#endif
+
+#ifndef WGL_NV_swap_group
+#endif
+
+#ifndef WGL_NV_gpu_affinity
+#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
+#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
+#endif
+
+#ifndef WGL_AMD_gpu_association
+#define WGL_GPU_VENDOR_AMD 0x1F00
+#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
+#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
+#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
+#define WGL_GPU_RAM_AMD 0x21A3
+#define WGL_GPU_CLOCK_AMD 0x21A4
+#define WGL_GPU_NUM_PIPES_AMD 0x21A5
+#define WGL_GPU_NUM_SIMD_AMD 0x21A6
+#define WGL_GPU_NUM_RB_AMD 0x21A7
+#define WGL_GPU_NUM_SPI_AMD 0x21A8
+#endif
+
+#ifndef WGL_NV_video_capture
+#define WGL_UNIQUE_ID_NV 0x20CE
+#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
+#endif
+
+#ifndef WGL_NV_copy_image
+#endif
+
+#ifndef WGL_NV_multisample_coverage
+#define WGL_COVERAGE_SAMPLES_NV 0x2042
+#define WGL_COLOR_SAMPLES_NV 0x20B9
+#endif
+
+#ifndef WGL_EXT_create_context_es2_profile
+#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+#endif
+
+#ifndef WGL_NV_DX_interop
+#define WGL_ACCESS_READ_ONLY_NV 0x00000000
+#define WGL_ACCESS_READ_WRITE_NV 0x00000001
+#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002
+#endif
+
+
+/*************************************************************/
+
+#ifndef WGL_ARB_pbuffer
+DECLARE_HANDLE(HPBUFFERARB);
+#endif
+#ifndef WGL_EXT_pbuffer
+DECLARE_HANDLE(HPBUFFEREXT);
+#endif
+#ifndef WGL_NV_present_video
+DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
+#endif
+#ifndef WGL_NV_video_output
+DECLARE_HANDLE(HPVIDEODEV);
+#endif
+#ifndef WGL_NV_gpu_affinity
+DECLARE_HANDLE(HPGPUNV);
+DECLARE_HANDLE(HGPUNV);
+
+typedef struct _GPU_DEVICE {
+ DWORD cb;
+ CHAR DeviceName[32];
+ CHAR DeviceString[128];
+ DWORD Flags;
+ RECT rcVirtualScreen;
+} GPU_DEVICE, *PGPU_DEVICE;
+#endif
+#ifndef WGL_NV_video_capture
+DECLARE_HANDLE(HVIDEOINPUTDEVICENV);
+#endif
+
+#ifndef WGL_ARB_buffer_region
+#define WGL_ARB_buffer_region 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType);
+extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion);
+extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height);
+extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
+typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
+typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
+typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_ARB_multisample 1
+#endif
+
+#ifndef WGL_ARB_extensions_string
+#define WGL_ARB_extensions_string 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern const char * WINAPI wglGetExtensionsStringARB (HDC hdc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
+#endif
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_ARB_pixel_format 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
+extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
+extern BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif
+
+#ifndef WGL_ARB_make_current_read
+#define WGL_ARB_make_current_read 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+extern HDC WINAPI wglGetCurrentReadDCARB (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void);
+#endif
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_ARB_pbuffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer);
+extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC);
+extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer);
+extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_ARB_render_texture
+#define WGL_ARB_render_texture 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
+extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
+extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList);
+#endif
+
+#ifndef WGL_ARB_pixel_format_float
+#define WGL_ARB_pixel_format_float 1
+#endif
+
+#ifndef WGL_ARB_framebuffer_sRGB
+#define WGL_ARB_framebuffer_sRGB 1
+#endif
+
+#ifndef WGL_ARB_create_context
+#define WGL_ARB_create_context 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
+#endif
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_ARB_create_context_profile 1
+#endif
+
+#ifndef WGL_ARB_create_context_robustness
+#define WGL_ARB_create_context_robustness 1
+#endif
+
+#ifndef WGL_EXT_display_color_table
+#define WGL_EXT_display_color_table 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id);
+extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length);
+extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id);
+extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length);
+typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+#endif
+
+#ifndef WGL_EXT_extensions_string
+#define WGL_EXT_extensions_string 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern const char * WINAPI wglGetExtensionsStringEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_make_current_read
+#define WGL_EXT_make_current_read 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+extern HDC WINAPI wglGetCurrentReadDCEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_pbuffer
+#define WGL_EXT_pbuffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer);
+extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC);
+extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer);
+extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_EXT_pixel_format
+#define WGL_EXT_pixel_format 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
+extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
+extern BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif
+
+#ifndef WGL_EXT_swap_control
+#define WGL_EXT_swap_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglSwapIntervalEXT (int interval);
+extern int WINAPI wglGetSwapIntervalEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
+typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_depth_float
+#define WGL_EXT_depth_float 1
+#endif
+
+#ifndef WGL_NV_vertex_array_range
+#define WGL_NV_vertex_array_range 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern void* WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
+extern void WINAPI wglFreeMemoryNV (void *pointer);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
+typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
+#endif
+
+#ifndef WGL_3DFX_multisample
+#define WGL_3DFX_multisample 1
+#endif
+
+#ifndef WGL_EXT_multisample
+#define WGL_EXT_multisample 1
+#endif
+
+#ifndef WGL_OML_sync_control
+#define WGL_OML_sync_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
+extern BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator);
+extern INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
+extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
+extern BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
+extern BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator);
+typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
+#endif
+
+#ifndef WGL_I3D_digital_video_control
+#define WGL_I3D_digital_video_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue);
+extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
+#endif
+
+#ifndef WGL_I3D_gamma
+#define WGL_I3D_gamma 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue);
+extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue);
+extern BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
+extern BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
+#endif
+
+#ifndef WGL_I3D_genlock
+#define WGL_I3D_genlock 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnableGenlockI3D (HDC hDC);
+extern BOOL WINAPI wglDisableGenlockI3D (HDC hDC);
+extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag);
+extern BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource);
+extern BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource);
+extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge);
+extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge);
+extern BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate);
+extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate);
+extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay);
+extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay);
+extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay);
+typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
+#endif
+
+#ifndef WGL_I3D_image_buffer
+#define WGL_I3D_image_buffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags);
+extern BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress);
+extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
+extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
+typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
+typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
+typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count);
+#endif
+
+#ifndef WGL_I3D_swap_frame_lock
+#define WGL_I3D_swap_frame_lock 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnableFrameLockI3D (void);
+extern BOOL WINAPI wglDisableFrameLockI3D (void);
+extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag);
+extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag);
+#endif
+
+#ifndef WGL_I3D_swap_frame_usage
+#define WGL_I3D_swap_frame_usage 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetFrameUsageI3D (float *pUsage);
+extern BOOL WINAPI wglBeginFrameTrackingI3D (void);
+extern BOOL WINAPI wglEndFrameTrackingI3D (void);
+extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage);
+typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
+#endif
+
+#ifndef WGL_ATI_pixel_format_float
+#define WGL_ATI_pixel_format_float 1
+#endif
+
+#ifndef WGL_NV_float_buffer
+#define WGL_NV_float_buffer 1
+#endif
+
+#ifndef WGL_3DL_stereo_control
+#define WGL_3DL_stereo_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState);
+#endif
+
+#ifndef WGL_EXT_pixel_format_packed_float
+#define WGL_EXT_pixel_format_packed_float 1
+#endif
+
+#ifndef WGL_EXT_framebuffer_sRGB
+#define WGL_EXT_framebuffer_sRGB 1
+#endif
+
+#ifndef WGL_NV_present_video
+#define WGL_NV_present_video 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
+extern BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
+extern BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
+typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
+typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_NV_video_output
+#define WGL_NV_video_output 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
+extern BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice);
+extern BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
+extern BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer);
+extern BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
+extern BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
+typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
+typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
+#endif
+
+#ifndef WGL_NV_swap_group
+#define WGL_NV_swap_group 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group);
+extern BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier);
+extern BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier);
+extern BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
+extern BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count);
+extern BOOL WINAPI wglResetFrameCountNV (HDC hDC);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
+typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
+typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier);
+typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count);
+typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
+#endif
+
+#ifndef WGL_NV_gpu_affinity
+#define WGL_NV_gpu_affinity 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu);
+extern BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
+extern HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList);
+extern BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
+extern BOOL WINAPI wglDeleteDCNV (HDC hdc);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
+typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
+typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
+typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
+typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
+#endif
+
+#ifndef WGL_AMD_gpu_association
+#define WGL_AMD_gpu_association 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids);
+extern INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data);
+extern UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc);
+extern HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id);
+extern HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList);
+extern BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc);
+extern BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc);
+extern HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void);
+extern VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids);
+typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data);
+typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
+typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList);
+typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
+typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
+typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
+typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+
+#ifndef WGL_NV_video_capture
+#define WGL_NV_video_capture 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
+extern UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
+extern BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+extern BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
+extern BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
+typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
+typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
+#endif
+
+#ifndef WGL_NV_copy_image
+#define WGL_NV_copy_image 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+#endif
+
+#ifndef WGL_NV_multisample_coverage
+#define WGL_NV_multisample_coverage 1
+#endif
+
+#ifndef WGL_NV_DX_interop
+#define WGL_NV_DX_interop 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle);
+extern HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice);
+extern BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice);
+extern HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
+extern BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject);
+extern BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access);
+extern BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
+extern BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle);
+typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice);
+typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice);
+typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
+typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject);
+typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access);
+typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
+typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ConfigurePermissionsAndPackages.sh b/ConfigurePermissionsAndPackages.sh
deleted file mode 100755
index ca12a56..0000000
--- a/ConfigurePermissionsAndPackages.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/bash
-
-#############################################################################
-#
-# Filename : ConfigurePermissionsAndPackages.sh
-# Content : Linux file for installing prerequisite libraries and the
-# permissions file for the USB HID device
-# Created : 2013
-# Authors : Simon Hallam and Brant Lewis
-# Copyright : Copyright 2013 OculusVR, Inc. All Rights Reserved
-# Instruction : Ensure that the install.sh has execute permissions.
-# Navigate to a command shell, enter:
-#
-# ./install.sh
-#
-# Enter the administrator password for sudo access.
-#
-# Notes : UBUNTU 13 USERS
-# ---------------
-# The OculusConfigUtil does not currently support Ubuntu 13
-# out of the box. If you see an error similar to this upon
-# launching OculusConfigUtil:
-#
-# "error while loading shared libraries: libudev.so.0"
-#
-# Then please try the following solution, until we officially
-# support Ubuntu 13:
-#
-# cd /lib/x86_64-linux-gnu/
-# sudo ln -sf libudev.so.1 libudev.so.0
-#
-#############################################################################
-
-echo "Installing OculusVR Rift udev rules file..."
-sudo cp ./LibOVR/90-oculus.rules /lib/udev/rules.d
-echo "Installing libudev..."
-sudo apt-get install libudev-dev
-echo "Installing libxext..."
-sudo apt-get install libxext-dev
-echo "Installing mesa-common..."
-sudo apt-get install mesa-common-dev
-echo "Installing freeglut3..."
-sudo apt-get install freeglut3-dev
-echo "Installing Xinerama..."
-sudo apt-get install libxinerama-dev
-echo "Installation complete"
-
diff --git a/LICENSE.TXT b/LICENSE.TXT
index 2836666..fcee98b 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -1,42 +1,264 @@
+Oculus VR Rift SDK Software License
+
Oculus VR, Inc. Software Development Kit License Agreement
-Copyright © 2013 Oculus VR, Inc. All rights reserved.
+Copyright © 2014 Oculus VR, Inc. All rights reserved.
+
+The text of this may be found at: http://www.oculusvr.com/licenses/LICENSE-3.1
Human-Readable Summary*:
You are Free to:
-Use, modify, and distribute the Oculus SDK in source and binary form with your software.
+Use, modify, and distribute the Oculus VR Rift SDK in source and binary
+form with your applications/software.
With the Following Restrictions:
-Source redistributions must include the whole of the Oculus SDK.
-Modifications to the Oculus SDK in source or binary form must be shared with Oculus VR.
-The Oculus SDK may not be used to interface with unapproved commercial virtual reality headsets.
-* - This human-readable Summary is not a license. It is simply a convenient reference for understanding the the full Oculus SDK License Agreement. The Summary is written as a user-friendly interface to the full Oculus SDK License below. This Summary itself has no legal value, and its contents do not appear in the actual license.
+You can only distribute or re-distribute the source code to LibOVR in
+whole, not in part.
+
+Modifications to the Oculus VR Rift SDK in source or binary form must
+be shared with Oculus VR.
+
+If your applications cause health and safety issues, you may lose your
+right to use the Oculus VR Rift SDK, including LibOVR.
+
+The Oculus VR Rift SDK may not be used to interface with unapproved commercial
+virtual reality mobile or non-mobile products or hardware.
+
+* - This human-readable Summary is not a license. It is simply a convenient
+reference for understanding the full Oculus VR Rift SDK License Agreement.
+The Summary is written as a user-friendly interface to the full Oculus VR Rift
+SDK License below. This Summary itself has no legal value, and its contents do
+not appear in the actual license.
Full-length Legal Copy:
-1. Subject to the terms and conditions of this License Agreement (the "License"), Oculus VR, Inc. ("Oculus VR") hereby grants to you a perpetual, worldwide, non-exclusive, no-charge, royalty-free, fully sublicenseable copyright license to use, reproduce, redistribute, modify, and improve the software contained in this Software Development Kit ("SDK"). This license includes the right to prepare derivative works ("Derivative Works"), whether in source, binary, or object form, based on the SDK including third party software unless otherwise noted. Derivative Works are defined as source, binary or object code derived exclusively from the SDK; provided, however, that Derivative Works do not include engines, utilities, applications, content or games which may be developed using the SDK. By way of example a videogame that is developed using the SDK would not be a Derivative Work and a utility or tool set in a pre-existing game engine that is adapted to work with the SDK would not be a Derivative Work. By way of example, but not limitation, a Derivative Work is or would be: either (i) an adaptation of a utility or piece of code from the SDK to improve efficiency; or (ii) an addition of code or improvement to the SDK that adds functionality. When you use the SDK (including Derivative Works) with your engines, utilities, applications, content or games you retain all rights thereto, and you have no obligations to share or license these items to Oculus or any third parties.
+1. Subject to the terms and conditions of this License Agreement (the "License"),
+Oculus VR, Inc. ("Oculus VR") hereby grants to you a perpetual, worldwide,
+non-exclusive, no-charge, royalty-free, sublicenseable copyright license to use,
+reproduce, redistribute (subject to restrictions below), modify, and improve the
+software contained in this Oculus VR Rift Software Development Kit ("RIFT SDK"),
+including, but not limited to, the samples, headers, LibOVR headers, and LibOVR
+source. This license is subject to the following terms and conditions:
+
+1.1. This license includes the non-exclusive license and right to use (i) the RIFT
+SDK to make applications, content, games and demos (collectively and generally
+referred to as “Developer Content”) that run on the Oculus VR approved mobile hardware
+and software products (“Oculus Approved Rift Products”) and which may incorporate
+the RIFT SDK in whole or in part in binary or object code; and (ii) to use the
+RIFT SDK to create derivative works of the RIFT SDK itself ("RIFT SDK Derivatives"),
+whether in source, binary, or object form, in whole or in part, including third
+party software unless otherwise noted.
+
+1.2. RIFT SDK Derivatives are further defined as source, binary or object code
+derived exclusively from the RIFT SDK by you; provided, however, that RIFT SDK
+Derivatives do not include the Developer Content (engines, utilities, applications,
+content, games or demos) which may be developed using the RIFT SDK. By way of example
+a mobile application or game or demo that is developed using the RIFT SDK would not
+be a RIFT SDK Derivative , nor would a utility or tool set in a pre-existing game
+engine that is adapted to work with the RIFT SDK be a RIFT SDK Derivative.
+By way of example, but not limitation, a RIFT SDK Derivative is or would be: either (i)
+an adaptation of a utility or piece of code from the RIFT SDK to improve efficiency;
+or (ii) an addition of code or improvement to the RIFT SDK that adds functionality.
+
+1.3 For the sake of clarification when you use the RIFT SDK (including RIFT SDK
+Derivatives) in or with Developer Content, you retain all rights to your Developer
+Content, and you have no obligations to share or license Developer Content (including
+your source and object code) to Oculus VR or any third parties; provided, however,
+Oculus VR retains all rights to the RIFT SDK and the RIFT SDK Derivatives that may
+be incorporated into your Developer Content.
+
+1.4 You agree to and you will use the Flash Screen Warning and the Health and
+Safety Warnings (collectively the “Oculus Warnings”) and the Oculus VR health and
+safety protocols found in the Oculus Best Practices Guide (“Oculus H&S Protocols”),
+and your use of the Oculus Warnings and the Oculus end user license agreement
+(“Oculus EULA”) with your Developer Content as provided for in the Oculus Developer
+Center, all of which can be found at the following link:
+https://developer.oculusvr.com/?action=doc.
+
+2. You, the recipient and user of the RIFT SDK, hereby agree and accept that that
+Oculus VR shall own all right, title and interest to the intellectual property
+rights, including, but limited to copyright, trademark and patent rights, to any
+RIFT SDK Derivatives that you may create, and you hereby assign any and all such
+rights to such RIFT SDK Derivatives to Oculus VR, subject to the following.
+
+2.1 We hereby grant to you the a fully paid up, no-charge, royalty-free,
+world-wide, in perpetuity, non-exclusive right and license back to use these RIFT
+SDK Derivatives solely in conjunction with the RIFT SDK (or any components of the
+RIFT SDK) and/or Developer Content on Oculus Rift Products as set forth herein.
+
+2.2 Furthermore, for the sake of clarification, Oculus VR and its assignees and
+licensees shall be free to use such RIFT SDK Derivatives without any approval
+from you and without compensation or attribution to you.
+
+2.3 You also agree upon Oculus VR's request to provide the source and binary code
+of any RIFT SDK Derivatives to Oculus VR. FAILURE TO COMPLY WITH THIS REQUEST
+IS THE BASIS FOR AUTOMATIC TERMINATION OF THIS LICENSE BY OCULUS VR.
+
+3. Subject to the terms and conditions of this License, your license to redistribute
+and sublicense the RIFT SDK and RIFT SDK Derivatives is also expressly made
+subject to the following conditions:
+
+3.1. You may sublicense and redistribute the source, binary, or object code of
+the RIFT SDK in whole or in part by itself for no charge or as part of a for charge
+piece of Developer Content; provided, however, you may only license, sublicense
+or redistribute the source, binary or object code of LibOVR in whole, and you may
+not license, sublicense or redistribute any portion or element of LibOVR separately
+or in part (in either source, binary or object form). If you license, sublicense
+or redistribute RIFT SDK Derivatives in and of themselves (not as a part of a
+piece of Developer Content) then you may only do that solely with and in conjunction
+with either the RIFT SDK or LibOVR. The RIFT SDK (including, but not limited to
+LibOVR), any RIFT SDK Derivatives, and any Developer Content may only be used
+with Oculus Approved Rift Products and may not be used, licensed, or sublicensed
+to interface with mobile software or hardware or other commercial headsets,
+mobile tablets or phones that are not authorized and approved by Oculus VR;
+
+3.2. You must include with all such redistributed or sublicensed RIFT SDK
+or RIFT SDK Derivatives code the following copyright notice:
+"Copyright © 2014 Oculus VR, Inc. All rights reserved," and include the
+list of conditions contained in this Section 3, including the full text of
+the disclaimer in Section 3.6 below;
+
+3.3. Neither the name of Oculus VR, Inc. nor the names of Oculus VR, Inc.'s
+contributors, licensors, employees, or contractors, may be used to endorse or promote
+products derived from this RIFT SDK without specific prior written permission
+of Oculus VR, Inc.;
+
+3.4. You must give any other recipients of the RIFT SDK or any elements thereof,
+including LibOVR or RIFT SDK Derivatives, a copy of this License as such recipients,
+licensees or sublicensees may only use the RIFT SDK or any RIFT SDK Derivatives
+or any elements thereof subject to the terms of this Licence and such recipients,
+licensees or sublicensees agreement and acceptance of this License with Oculus VR
+(which will convey all rights to the recipients’ or licensees’ or sublicensees’
+RIFT SDK Derivatives to Oculus VR), and you must cause any modified files to
+carry prominent notices stating that you changed the files;
+
+3.5. If the RIFT SDK or a specific element thereof such as LibOVR includes a
+"LICENSE" text file as part of its distribution (the “License Notice”), then
+any RIFT SDK Derivatives that you distribute with the RIFT SDK in whole or in
+part must include a readable copy of such attribution notices as are contained
+within the applicable License Notice file (excluding those notices that do not
+pertain to any part of the RIFT SDK Derivatives), in at least one of the following
+places: within a License Notice text file distributed as part of the RIFT SDK
+Derivatives; within the source form or documentation, if provided along with
+the RIFT SDK Derivatives; or, within a display generated by the RIFT SDK Derivatives,
+if and wherever such third-party notices normally appear. You must also include
+in the License Notice file for all RIFT SDK Derivatives a copy of all notices
+(including any product liability or health and safety notices). The contents
+of the License Notice file are for informational purposes only and do not modify
+the License. You may add your own attribution notices within RIFT SDK Derivatives
+that you distribute, alongside or as an addendum to the License Notice text from
+the RIFT SDK or any part thereof, provided that such additional attribution notices
+cannot be construed as modifying the License.
-2. You, the recipient and user of the SDK, hereby agree and accept that that Oculus VR shall own all right, title and interest to the intellectual property rights, including, but limited to copyright, trademark and patent rights, to any Derivative Works that you or your licensees may create, and you hereby assign any and all such rights to such Derivative Works to Oculus VR. We hereby grant to you the right to use these Derivative Works solely in conjunction with the SDK on a fully paid up, no-charge, royalty-free, world-wide, in perpetuity, non-exclusive basis. Furthermore, for the sake of clarification, Oculus VR and its assignees and licensees shall be free to use such Derivative Works without any approval from you and without compensation or attribution to you. You also agree upon Oculus VR's request to provide the source and binary code of any Derivative Works to Oculus VR. FAILURE TO COMPLY WITH THIS REQUEST IS THE BASIS FOR AUTOMATIC TERMINATION OF THIS LICENSE BY OCULUS VR.
+3.6. THIS RIFT SDK AND ANY COMPONENT THEREOF IS PROVIDED BY OCULUS VR AND
+ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OCULUS VR AS THE
+COPYRIGHT OWNER OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS RIFT
+SDK OR THE RIFT SDK DERIVATIVES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-3. Subject to the terms and conditions of this License, your license to redistribute and sublicense the SDK and Derivate Works is also expressly made subject to the following conditions:
+4. This License does not grant permission to use the trade names, trademarks,
+service marks, or product names of Oculus VR, except as required for reasonable
+and customary use in describing the origin of the RIFT SDK, LibOVR, or any
+element thereof, and reproducing the content of the License Notice file.
+5. In no event and under no legal theory, whether in tort (including negligence),
+contract, or otherwise, unless required by applicable law (such as
+deliberate and grossly negligent acts) or agreed to in writing, shall Oculus VR
+or any contributor be liable to you or your licensees or sublicensees for
+damages, including any direct, indirect, special, incidental, or consequential
+damages of any character arising as a result of this License or out of the use
+or inability to use the RIFT SDK, LibOVR, any element thereof or any RIFT SDK
+Derivatives (including but not limited to damages for loss of goodwill, work
+stoppage, computer failure or malfunction, or any and all other commercial
+damages or losses), even if you or such contributor has been advised of the
+possibility of such damages.
-3.1. You may only sublicense and redistribute the source, binary, or object code of the SDK as a whole, and may not redistribute or sublicense any portion or element of the SDK separately by itself. You may only redistribute or sublicense Derivative Works solely with and as part of the SDK. The SDK may not be used, licensed, or sublicensed to interface with commercial headsets not authorized and approved by Oculus VR.
+6. Your acceptance of the terms and conditions of this License in and of
+itself and for all Developer Content created as of March 1, 2014, may be
+evidenced by any of the following: your usage of the RIFT SDK or any element
+thereof, acceptance of the click-through agreement, or opening the packaging
+of the CD-ROM containing the RIFT SDK or any element thereof, including LibOVR.
+As this License is updated for future releases of the RIFT SDK and/or LibOVR,
+you agree to abide by and meet all requirements of future updates of this
+License for those future RIFT SDK releases as evidenced by the same usage of
+the RIFT SDK or any element thereof and the future updates of this License
+will apply for that future Developer Content that may developed for or with
+that future RIFT SDK or any element thereof (i.e., you cannot sidestep out
+of the requirements of future updates of the License by developing against
+an older release of the RIFT SDK or License).
+
+7. Oculus VR reserves the right to terminate this License and all your
+rights hereunder in the event you materially breach this License and fail
+to cure such breach within ten (10) business days after notice of breach
+from Oculus VR.
-3.2. You must include with all such redistributed or sublicensed SDK code the following copyright notice: "Copyright © 2013 Oculus VR, Inc. All rights reserved," and include the list of conditions contained in this Section 3, including the full text of the disclaimer in Section 3.6 below;
+8. Furthermore, Oculus VR also reserves the right to cancel or terminate
+this License for any of the following reasons upon notice to you, subject
+to the appeal process set forth in Section 14 for a wrongful termination:
-3.3. Neither the name of Oculus VR, Inc. nor the names of Oculus VR, Inc.'s contributors, licensors, employees, or contractors, may be used to endorse or promote products derived from this SDK without specific prior written permission of Oculus VR, Inc.;
+ a) Intellectual property infringement by you with Developer Content
+ or RIFT SDK Derivatives created by you that is used with or by the
+ RIFT SDK or any part thereof, or any of the RIFT SDK Derivatives;
+
+ b) Developer Content that violates or infringes upon applicable law;
+
+ c) Health and safety issues associated with your Developer Content;
+
+ d) Failure to comply with or use properly the Oculus Warnings,
+ Oculus H&S Protocols, or Oculus EULA;
+
+ e) Use of the RIFT SDK, RIFT SDK Derivatives or LibOVR with a
+ commercial product other than an Oculus Approved Product; and
+
+ f) Failure to provide required notices or deliver source code
+ and/or binary of RIFT SDK Derivatives as set forth above.
+
+If you believe that you have been wrongfully terminated under this Section 8
+with respect to material breach or with respect to these above conditions,
+you have the right to appeal the termination of this License under Section 14.
-3.4. You must give any other recipients of the SDK or Derivative Works a copy of this License and you must cause any modified files to carry prominent notices stating that you changed the files;
+9. This License may be amended by Oculus VR on a prospective basis, and your
+usage of the License after such amendments or changes signifies your consent
+to and acceptance of any such amendments or changes on a going forward basis.
-3.5. If the SDK includes a "NOTICE" text file as part of its distribution, then any Derivative Works that you distribute with the SDK must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add your own attribution notices within Derivative Works that you distribute, alongside or as an addendum to the NOTICE text from the SDK, provided that such additional attribution notices cannot be construed as modifying the License.
+10. In the event any provision of this License is determined to be invalid,
+prohibited or unenforceable by a court or other body of competent jurisdiction,
+this License shall be construed as if such invalid, prohibited or unenforceable
+provision has been more narrowly drawn so as not to be invalid, prohibited or
+unenforceable.
-3.6. THIS SDK IS PROVIDED BY OCULUS VR AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OCULUS VR AS THE COPYRIGHT OWNER OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SDK OR THE DERIVATIVE WORKS, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+11. You may not assign any rights or obligations under this License without
+the advance written consent of Oculus VR, which may be withheld in its sole
+discretion. Oculus VR may assign its rights or obligations under this License
+in its sole discretion.
-4. This License does not grant permission to use the trade names, trademarks, service marks, or product names of Oculus VR, except as required for reasonable and customary use in describing the origin of the SDK and reproducing the content of the NOTICE file.
+12. Failure of either party at any time to enforce any of the provisions of
+this License will not be construed as a waiver of such provisions or in any way
+affect the validity of this License or parts thereof.
-5. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall Oculus VR or any contributor be liable to you or your licensees or sublicensees for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the SDK or any Derivative Works (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if you or such contributor has been advised of the possibility of such damages.
+13. Your remedies under this License shall be limited to the right to collect
+money damages, if any, and you hereby waive your right to injunctive or other
+equitable relief.
-6. Your acceptance of the terms and conditions of this License may be evidenced by any of the following: your usage of the SDK, acceptance of the click-through agreement, or opening the packaging of the CD-ROM containing the SDK. \ No newline at end of file
+14. This License shall be governed by the laws of the State of California,
+without giving effect to choice of law principles. All disputes relating to
+this License shall be resolved by binding non-appearance-based arbitration
+before a neutral arbitrator in Orange County, California. If your License
+has been terminated hereunder by Oculus, you may appeal your termination
+through this arbitration process on an expedited basis with an arbitration
+within thirty days of your giving Oculus VR notice of the appeal. The
+arbitration shall be conducted in accordance with the rules and procedures
+of JAMS then in effect, and the judgment of the arbitrator shall be final
+and capable of entry in any court of competent jurisdiction. You agree
+to submit to the personal jurisdiction of the courts located within Orange
+County, California in connection with any entrance of an arbitrator’s judgment
+or decision or any dispute with respect to the arbitration process or procedure
+or Oculus VR’s exercise of its equitable rights or remedies.
diff --git a/LibOVR/90-oculus.rules b/LibOVR/90-oculus.rules
deleted file mode 100644
index 56bccdb..0000000
--- a/LibOVR/90-oculus.rules
+++ /dev/null
@@ -1,2 +0,0 @@
-# Oculus HID Sensor naming and permissioning
-KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2833", MODE="0666"
diff --git a/LibOVR/CMakeLists.txt b/LibOVR/CMakeLists.txt
deleted file mode 100644
index 560f80c..0000000
--- a/LibOVR/CMakeLists.txt
+++ /dev/null
@@ -1,136 +0,0 @@
-project (CORE_OculusVR)
-
-include_directories(Include Src Src/Kernel Src/Util)
-
-set(SOURCE_FILES
- Src/Kernel/OVR_Alg.cpp
- Src/Kernel/OVR_Allocator.cpp
- Src/Kernel/OVR_Atomic.cpp
- Src/Kernel/OVR_File.cpp
- Src/Kernel/OVR_FileFILE.cpp
- Src/Kernel/OVR_Log.cpp
- Src/Kernel/OVR_Math.cpp
- Src/Kernel/OVR_RefCount.cpp
- Src/Kernel/OVR_Std.cpp
- Src/Kernel/OVR_String.cpp
- Src/Kernel/OVR_String_FormatUtil.cpp
- Src/Kernel/OVR_String_PathUtil.cpp
- Src/Kernel/OVR_SysFile.cpp
- Src/Kernel/OVR_System.cpp
- Src/Kernel/OVR_Timer.cpp
- Src/Kernel/OVR_UTF8Util.cpp
- Src/OVR_DeviceHandle.cpp
- Src/OVR_DeviceImpl.cpp
- Src/OVR_JSON.cpp
- Src/OVR_LatencyTestImpl.cpp
- Src/OVR_Profile.cpp
- Src/OVR_SensorFilter.cpp
- Src/OVR_SensorFusion.cpp
- Src/OVR_SensorImpl.cpp
- Src/OVR_ThreadCommandQueue.cpp
- Src/Util/Util_LatencyTest.cpp
- Src/Util/Util_Render_Stereo.cpp
-)
-
-set(HEADER_FILES
- Include/OVR.h
- Include/OVRVersion.h
- Src/Kernel/OVR_Alg.h
- Src/Kernel/OVR_Allocator.h
- Src/Kernel/OVR_Array.h
- Src/Kernel/OVR_Atomic.h
- Src/Kernel/OVR_Color.h
- Src/Kernel/OVR_ContainerAllocator.h
- Src/Kernel/OVR_File.h
- Src/Kernel/OVR_Hash.h
- Src/Kernel/OVR_KeyCodes.h
- Src/Kernel/OVR_List.h
- Src/Kernel/OVR_Log.h
- Src/Kernel/OVR_Math.h
- Src/Kernel/OVR_RefCount.h
- Src/Kernel/OVR_Std.h
- Src/Kernel/OVR_String.h
- Src/Kernel/OVR_SysFile.h
- Src/Kernel/OVR_System.h
- Src/Kernel/OVR_Timer.h
- Src/Kernel/OVR_Threads.h
- Src/Kernel/OVR_Types.h
- Src/Kernel/OVR_UTF8Util.h
- Src/OVR_Device.h
- Src/OVR_DeviceConstants.h
- Src/OVR_DeviceHandle.h
- Src/OVR_DeviceImpl.h
- Src/OVR_DeviceMessages.h
- Src/OVR_HIDDevice.h
- Src/OVR_HIDDeviceBase.h
- Src/OVR_HIDDeviceImpl.h
- Src/OVR_JSON.h
- Src/OVR_LatencyTestImpl.h
- Src/OVR_Profile.h
- Src/OVR_SensorFilter.h
- Src/OVR_SensorFusion.h
- Src/OVR_SensorImpl.h
- Src/OVR_ThreadCommandQueue.h
- Src/Util/Util_LatencyTest.h
- Src/Util/Util_Render_Stereo.h
-)
-
-if(WIN32)
- list(APPEND SOURCE_FILES
- Src/Kernel/OVR_ThreadsWinAPI.cpp
- Src/OVR_Win32_DeviceManager.cpp
- Src/OVR_Win32_DeviceStatus.cpp
- Src/OVR_Win32_HIDDevice.cpp
- Src/OVR_Win32_HMDDevice.cpp
- Src/OVR_Win32_SensorDevice.cpp
- )
- list(APPEND HEADER_FILES
- Src/OVR_Win32_DeviceManager.h
- Src/OVR_Win32_DeviceStatus.h
- Src/OVR_Win32_HIDDevice.h
- Src/OVR_Win32_HMDDevice.h
- Src/OVR_Win32_SensorDevice.h
- )
-elseif(APPLE)
- list(APPEND SOURCE_FILES
- Src/Kernel/OVR_ThreadsPthread.cpp
- Src/OVR_OSX_DeviceManager.cpp
- Src/OVR_OSX_HIDDevice.cpp
- Src/OVR_OSX_HMDDevice.cpp
- Src/OVR_OSX_SensorDevice.cpp
- )
- list(APPEND HEADER_FILES
- Src/OVR_OSX_DeviceManager.h
- Src/OVR_OSX_HIDDevice.h
- Src/OVR_OSX_HMDDevice.h
- )
-else()
- list(APPEND SOURCE_FILES
- Src/Kernel/OVR_ThreadsPthread.cpp
- Src/OVR_Linux_DeviceManager.cpp
- Src/OVR_Linux_HIDDevice.cpp
- Src/OVR_Linux_HMDDevice.cpp
- Src/OVR_Linux_SensorDevice.cpp
- )
- list(APPEND HEADER_FILES
- Src/OVR_Linux_DeviceManager.h
- Src/OVR_Linux_HIDDevice.h
- Src/OVR_Linux_HMDDevice.h
- )
- list(APPEND EXTRA_LIBS
- EDID
- )
- include_directories(${LIB_EDID_SOURCE_DIR})
-endif()
-
-if(WIN32)
- SET(OculusVR_EXTRA_LIBS setupapi winmm)
-elseif(APPLE)
- # FIXME ???
-else()
- # FIXME switch to pkg-config for this?
- SET(OculusVR_EXTRA_LIBS pthread udev X11 Xinerama)
-endif()
-
-add_library(OculusVR STATIC ${SOURCE_FILES} ${HEADER_FILES})
-target_link_libraries(OculusVR ${OculusVR_EXTRA_LIBS})
diff --git a/LibOVR/Include/OVR.h b/LibOVR/Include/OVR.h
index 1efea08..6b5d416 100644
--- a/LibOVR/Include/OVR.h
+++ b/LibOVR/Include/OVR.h
@@ -4,16 +4,16 @@ Filename : OVR.h
Content : This contains references to all OVR-specific headers in Src folder.
Should be generated automatically based on PublicHeader tags.
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -26,6 +26,7 @@ limitations under the License.
#ifndef OVR_h
#define OVR_h
+
#include "../Src/Kernel/OVR_Allocator.h"
#include "../Src/Kernel/OVR_Log.h"
#include "../Src/Kernel/OVR_Math.h"
@@ -36,9 +37,11 @@ limitations under the License.
#include "../Src/OVR_DeviceHandle.h"
#include "../Src/OVR_DeviceMessages.h"
#include "../Src/OVR_SensorFusion.h"
+#include "../Src/OVR_Stereo.h"
#include "../Src/OVR_Profile.h"
#include "../Src/Util/Util_LatencyTest.h"
#include "../Src/Util/Util_Render_Stereo.h"
+#include "../Src/Util/Util_Interface.h"
#endif
diff --git a/LibOVR/Include/OVRVersion.h b/LibOVR/Include/OVRVersion.h
index 20f2a88..5c2de3c 100644
--- a/LibOVR/Include/OVRVersion.h
+++ b/LibOVR/Include/OVRVersion.h
@@ -3,16 +3,16 @@
Filename : OVRVersion.h
Content :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -26,8 +26,8 @@ limitations under the License.
#define _OVR_VERSION_H
#define OVR_MAJOR_VERSION 0
-#define OVR_MINOR_VERSION 2
-#define OVR_BUILD_VERSION 5
-#define OVR_VERSION_STRING "0.2.5"
+#define OVR_MINOR_VERSION 3
+#define OVR_BUILD_VERSION 1
+#define OVR_VERSION_STRING "0.3.1"
#endif
diff --git a/LibOVR/Lib/Linux/Debug/i386/readme b/LibOVR/Lib/Linux/Debug/i386/readme
deleted file mode 100644
index c9d0bc0..0000000
--- a/LibOVR/Lib/Linux/Debug/i386/readme
+++ /dev/null
@@ -1,2 +0,0 @@
-This document exits to ensure that the required directory structure gets created correctly.
-
diff --git a/LibOVR/Lib/Linux/Debug/x86_64/readme b/LibOVR/Lib/Linux/Debug/x86_64/readme
deleted file mode 100644
index c9d0bc0..0000000
--- a/LibOVR/Lib/Linux/Debug/x86_64/readme
+++ /dev/null
@@ -1,2 +0,0 @@
-This document exits to ensure that the required directory structure gets created correctly.
-
diff --git a/LibOVR/Lib/Linux/Release/i386/readme b/LibOVR/Lib/Linux/Release/i386/readme
deleted file mode 100644
index c9d0bc0..0000000
--- a/LibOVR/Lib/Linux/Release/i386/readme
+++ /dev/null
@@ -1,2 +0,0 @@
-This document exits to ensure that the required directory structure gets created correctly.
-
diff --git a/LibOVR/Lib/Linux/Release/x86_64/readme b/LibOVR/Lib/Linux/Release/x86_64/readme
deleted file mode 100644
index c9d0bc0..0000000
--- a/LibOVR/Lib/Linux/Release/x86_64/readme
+++ /dev/null
@@ -1,2 +0,0 @@
-This document exits to ensure that the required directory structure gets created correctly.
-
diff --git a/LibOVR/Makefile b/LibOVR/Makefile
deleted file mode 100644
index ff8d399..0000000
--- a/LibOVR/Makefile
+++ /dev/null
@@ -1,211 +0,0 @@
-#############################################################################
-#
-# Filename : Makefile
-# Content : Makefile for building linux version of: libovr
-# Created : 2013
-# Authors : Simon Hallam and Peter Giokaris
-# Copyright : Copyright 2013 OculusVR, Inc. All Rights Reserved
-# Instruction : The g++ compiler and stdndard lib packages need to be
-# installed on the system. Navigate in a shell to the
-# directory where this Makefile is located and enter:
-#
-# make builds the release version for the
-# current architechture
-# make clean delete intermediate release object files
-# and the library file
-# make DEBUG=1 builds the debug version for the current
-# architechture
-# make clean DEBUG=1 deletes intermediate debug object files
-# and the library file
-#
-# Output : Relative to the directory this Makefile lives in, libraries
-# are built at the following locations depending upon the
-# architechture of the system you are running:
-#
-# ./Lib/Linux/Debug/i386/libovr.a
-# ./Lib/Linux/Debug/x86_64/libovr.a
-# ./Lib/Linux/Release/i386/libovr.a
-# ./Lib/Linux/Release/x86_64/libovr.a
-#
-#############################################################################
-
-####### Detect system architecture
-
-SYSARCH = i386
-ifeq ($(shell uname -m),x86_64)
-SYSARCH = x86_64
-endif
-
-####### Compiler, tools and options
-
-CXX = g++
-LINK = ar rvs
-DELETEFILE = rm -f
-
-####### Detect debug or release
-
-DEBUG = 0
-ifeq ($(DEBUG), 1)
- CXXFLAGS = -pipe -fPIC -DDEBUG -g
- RELEASETYPE = Debug
-else
- CXXFLAGS = -pipe -fPIC -O2
- RELEASETYPE = Release
-endif
-
-####### Paths
-
-LIBOVRPATH = .
-3RDPARTYPATH = ../3rdParty
-INCPATH = -I. -I.. -I$(LIBOVRPATH)/Include -I$(LIBOVRPATH)/Src
-OBJPATH = ./Obj/Linux/$(RELEASETYPE)/$(SYSARCH)
-CXXBUILD = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $(OBJPATH)/
-
-####### Files
-
-TARGET = ./Lib/Linux/$(RELEASETYPE)/$(SYSARCH)/libovr.a
-
-OBJECTS = $(OBJPATH)/OVR_DeviceHandle.o \
- $(OBJPATH)/OVR_DeviceImpl.o \
- $(OBJPATH)/OVR_JSON.o \
- $(OBJPATH)/OVR_LatencyTestImpl.o \
- $(OBJPATH)/OVR_Profile.o \
- $(OBJPATH)/OVR_SensorFilter.o\
- $(OBJPATH)/OVR_SensorFusion.o\
- $(OBJPATH)/OVR_SensorImpl.o \
- $(OBJPATH)/OVR_ThreadCommandQueue.o \
- $(OBJPATH)/OVR_Alg.o \
- $(OBJPATH)/OVR_Allocator.o \
- $(OBJPATH)/OVR_Atomic.o \
- $(OBJPATH)/OVR_File.o \
- $(OBJPATH)/OVR_FileFILE.o \
- $(OBJPATH)/OVR_Log.o \
- $(OBJPATH)/OVR_Math.o \
- $(OBJPATH)/OVR_RefCount.o \
- $(OBJPATH)/OVR_Std.o \
- $(OBJPATH)/OVR_String.o \
- $(OBJPATH)/OVR_String_FormatUtil.o \
- $(OBJPATH)/OVR_String_PathUtil.o \
- $(OBJPATH)/OVR_SysFile.o \
- $(OBJPATH)/OVR_System.o \
- $(OBJPATH)/OVR_Timer.o \
- $(OBJPATH)/OVR_UTF8Util.o \
- $(OBJPATH)/Util_LatencyTest.o \
- $(OBJPATH)/Util_Render_Stereo.o \
- $(OBJPATH)/OVR_ThreadsPthread.o \
- $(OBJPATH)/OVR_Linux_HIDDevice.o \
- $(OBJPATH)/OVR_Linux_SensorDevice.o \
- $(OBJPATH)/OVR_Linux_DeviceManager.o \
- $(OBJPATH)/OVR_Linux_HMDDevice.o \
- $(OBJPATH)/tinyxml2.o
-
-####### Rules
-
-all: $(TARGET)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(TARGET) $(OBJECTS)
-
-$(OBJPATH)/OVR_DeviceHandle.o: $(LIBOVRPATH)/Src/OVR_DeviceHandle.cpp
- $(CXXBUILD)OVR_DeviceHandle.o $(LIBOVRPATH)/Src/OVR_DeviceHandle.cpp
-
-$(OBJPATH)/OVR_DeviceImpl.o: $(LIBOVRPATH)/Src/OVR_DeviceImpl.cpp
- $(CXXBUILD)OVR_DeviceImpl.o $(LIBOVRPATH)/Src/OVR_DeviceImpl.cpp
-
-$(OBJPATH)/OVR_JSON.o: $(LIBOVRPATH)/Src/OVR_JSON.cpp
- $(CXXBUILD)OVR_JSON.o $(LIBOVRPATH)/Src/OVR_JSON.cpp
-
-$(OBJPATH)/OVR_LatencyTestImpl.o: $(LIBOVRPATH)/Src/OVR_LatencyTestImpl.cpp
- $(CXXBUILD)OVR_LatencyTestImpl.o $(LIBOVRPATH)/Src/OVR_LatencyTestImpl.cpp
-
-$(OBJPATH)/OVR_Profile.o: $(LIBOVRPATH)/Src/OVR_Profile.cpp
- $(CXXBUILD)OVR_Profile.o $(LIBOVRPATH)/Src/OVR_Profile.cpp
-
-$(OBJPATH)/OVR_SensorFilter.o: $(LIBOVRPATH)/Src/OVR_SensorFilter.cpp
- $(CXXBUILD)OVR_SensorFilter.o $(LIBOVRPATH)/Src/OVR_SensorFilter.cpp
-
-$(OBJPATH)/OVR_SensorFusion.o: $(LIBOVRPATH)/Src/OVR_SensorFusion.cpp
- $(CXXBUILD)OVR_SensorFusion.o $(LIBOVRPATH)/Src/OVR_SensorFusion.cpp
-
-$(OBJPATH)/OVR_SensorImpl.o: $(LIBOVRPATH)/Src/OVR_SensorImpl.cpp
- $(CXXBUILD)OVR_SensorImpl.o $(LIBOVRPATH)/Src/OVR_SensorImpl.cpp
-
-$(OBJPATH)/OVR_ThreadCommandQueue.o: $(LIBOVRPATH)/Src/OVR_ThreadCommandQueue.cpp
- $(CXXBUILD)OVR_ThreadCommandQueue.o $(LIBOVRPATH)/Src/OVR_ThreadCommandQueue.cpp
-
-$(OBJPATH)/OVR_Alg.o: $(LIBOVRPATH)/Src/Kernel/OVR_Alg.cpp
- $(CXXBUILD)OVR_Alg.o $(LIBOVRPATH)/Src/Kernel/OVR_Alg.cpp
-
-$(OBJPATH)/OVR_Allocator.o: $(LIBOVRPATH)/Src/Kernel/OVR_Allocator.cpp
- $(CXXBUILD)OVR_Allocator.o $(LIBOVRPATH)/Src/Kernel/OVR_Allocator.cpp
-
-$(OBJPATH)/OVR_Atomic.o: $(LIBOVRPATH)/Src/Kernel/OVR_Atomic.cpp
- $(CXXBUILD)OVR_Atomic.o $(LIBOVRPATH)/Src/Kernel/OVR_Atomic.cpp
-
-$(OBJPATH)/OVR_File.o: $(LIBOVRPATH)/Src/Kernel/OVR_File.cpp
- $(CXXBUILD)OVR_File.o $(LIBOVRPATH)/Src/Kernel/OVR_File.cpp
-
-$(OBJPATH)/OVR_FileFILE.o: $(LIBOVRPATH)/Src/Kernel/OVR_FileFILE.cpp
- $(CXXBUILD)OVR_FileFILE.o $(LIBOVRPATH)/Src/Kernel/OVR_FileFILE.cpp
-
-$(OBJPATH)/OVR_Log.o: $(LIBOVRPATH)/Src/Kernel/OVR_Log.cpp
- $(CXXBUILD)OVR_Log.o $(LIBOVRPATH)/Src/Kernel/OVR_Log.cpp
-
-$(OBJPATH)/OVR_Math.o: $(LIBOVRPATH)/Src/Kernel/OVR_Math.cpp
- $(CXXBUILD)OVR_Math.o $(LIBOVRPATH)/Src/Kernel/OVR_Math.cpp
-
-$(OBJPATH)/OVR_RefCount.o: $(LIBOVRPATH)/Src/Kernel/OVR_RefCount.cpp
- $(CXXBUILD)OVR_RefCount.o $(LIBOVRPATH)/Src/Kernel/OVR_RefCount.cpp
-
-$(OBJPATH)/OVR_Std.o: $(LIBOVRPATH)/Src/Kernel/OVR_Std.cpp
- $(CXXBUILD)OVR_Std.o $(LIBOVRPATH)/Src/Kernel/OVR_Std.cpp
-
-$(OBJPATH)/OVR_String.o: $(LIBOVRPATH)/Src/Kernel/OVR_String.cpp
- $(CXXBUILD)OVR_String.o $(LIBOVRPATH)/Src/Kernel/OVR_String.cpp
-
-$(OBJPATH)/OVR_String_FormatUtil.o: $(LIBOVRPATH)/Src/Kernel/OVR_String_FormatUtil.cpp
- $(CXXBUILD)OVR_String_FormatUtil.o $(LIBOVRPATH)/Src/Kernel/OVR_String_FormatUtil.cpp
-
-$(OBJPATH)/OVR_String_PathUtil.o: $(LIBOVRPATH)/Src/Kernel/OVR_String_PathUtil.cpp
- $(CXXBUILD)OVR_String_PathUtil.o $(LIBOVRPATH)/Src/Kernel/OVR_String_PathUtil.cpp
-
-$(OBJPATH)/OVR_SysFile.o: $(LIBOVRPATH)/Src/Kernel/OVR_SysFile.cpp
- $(CXXBUILD)OVR_SysFile.o $(LIBOVRPATH)/Src/Kernel/OVR_SysFile.cpp
-
-$(OBJPATH)/OVR_System.o: $(LIBOVRPATH)/Src/Kernel/OVR_System.cpp
- $(CXXBUILD)OVR_System.o $(LIBOVRPATH)/Src/Kernel/OVR_System.cpp
-
-$(OBJPATH)/OVR_Timer.o: $(LIBOVRPATH)/Src/Kernel/OVR_Timer.cpp
- $(CXXBUILD)OVR_Timer.o $(LIBOVRPATH)/Src/Kernel/OVR_Timer.cpp
-
-$(OBJPATH)/OVR_UTF8Util.o: $(LIBOVRPATH)/Src/Kernel/OVR_UTF8Util.cpp
- $(CXXBUILD)OVR_UTF8Util.o $(LIBOVRPATH)/Src/Kernel/OVR_UTF8Util.cpp
-
-$(OBJPATH)/Util_LatencyTest.o: $(LIBOVRPATH)/Src/Util/Util_LatencyTest.cpp
- $(CXXBUILD)Util_LatencyTest.o $(LIBOVRPATH)/Src/Util/Util_LatencyTest.cpp
-
-$(OBJPATH)/Util_Render_Stereo.o: $(LIBOVRPATH)/Src/Util/Util_Render_Stereo.cpp
- $(CXXBUILD)Util_Render_Stereo.o $(LIBOVRPATH)/Src/Util/Util_Render_Stereo.cpp
-
-$(OBJPATH)/OVR_ThreadsPthread.o: $(LIBOVRPATH)/Src/Kernel/OVR_ThreadsPthread.cpp
- $(CXXBUILD)OVR_ThreadsPthread.o $(LIBOVRPATH)/Src/Kernel/OVR_ThreadsPthread.cpp
-
-$(OBJPATH)/OVR_Linux_HIDDevice.o: $(LIBOVRPATH)/Src/OVR_Linux_HIDDevice.cpp
- $(CXXBUILD)OVR_Linux_HIDDevice.o $(LIBOVRPATH)/Src/OVR_Linux_HIDDevice.cpp
-
-$(OBJPATH)/OVR_Linux_SensorDevice.o: $(LIBOVRPATH)/Src/OVR_Linux_SensorDevice.cpp
- $(CXXBUILD)OVR_Linux_SensorDevice.o $(LIBOVRPATH)/Src/OVR_Linux_SensorDevice.cpp
-
-$(OBJPATH)/OVR_Linux_DeviceManager.o: $(LIBOVRPATH)/Src/OVR_Linux_DeviceManager.cpp
- $(CXXBUILD)OVR_Linux_DeviceManager.o $(LIBOVRPATH)/Src/OVR_Linux_DeviceManager.cpp
-
-$(OBJPATH)/OVR_Linux_HMDDevice.o: $(LIBOVRPATH)/Src/OVR_Linux_HMDDevice.cpp
- $(CXXBUILD)OVR_Linux_HMDDevice.o $(LIBOVRPATH)/Src/OVR_Linux_HMDDevice.cpp
-
-$(OBJPATH)/tinyxml2.o: $(3RDPARTYPATH)/TinyXml/tinyxml2.cpp
- $(CXXBUILD)tinyxml2.o $(3RDPARTYPATH)/TinyXml/tinyxml2.cpp
-
-clean:
- -$(DELETEFILE) $(OBJECTS)
- -$(DELETEFILE) $(TARGET)
-
diff --git a/LibOVR/Obj/Linux/Debug/i386/readme b/LibOVR/Obj/Linux/Debug/i386/readme
deleted file mode 100644
index c9d0bc0..0000000
--- a/LibOVR/Obj/Linux/Debug/i386/readme
+++ /dev/null
@@ -1,2 +0,0 @@
-This document exits to ensure that the required directory structure gets created correctly.
-
diff --git a/LibOVR/Obj/Linux/Debug/x86_64/readme b/LibOVR/Obj/Linux/Debug/x86_64/readme
deleted file mode 100644
index c9d0bc0..0000000
--- a/LibOVR/Obj/Linux/Debug/x86_64/readme
+++ /dev/null
@@ -1,2 +0,0 @@
-This document exits to ensure that the required directory structure gets created correctly.
-
diff --git a/LibOVR/Obj/Linux/Release/i386/readme b/LibOVR/Obj/Linux/Release/i386/readme
deleted file mode 100644
index c9d0bc0..0000000
--- a/LibOVR/Obj/Linux/Release/i386/readme
+++ /dev/null
@@ -1,2 +0,0 @@
-This document exits to ensure that the required directory structure gets created correctly.
-
diff --git a/LibOVR/Obj/Linux/Release/x86_64/readme b/LibOVR/Obj/Linux/Release/x86_64/readme
deleted file mode 100644
index c9d0bc0..0000000
--- a/LibOVR/Obj/Linux/Release/x86_64/readme
+++ /dev/null
@@ -1,2 +0,0 @@
-This document exits to ensure that the required directory structure gets created correctly.
-
diff --git a/LibOVR/Projects/Win32/LibOVR_Msvc2010.sln b/LibOVR/Projects/Win32/LibOVR_Msvc2010.sln
deleted file mode 100644
index b062da3..0000000
--- a/LibOVR/Projects/Win32/LibOVR_Msvc2010.sln
+++ /dev/null
@@ -1,20 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibOVR", "LibOVR_Msvc2010.vcxproj", "{934B40C7-F40A-4E4C-97A7-B9659BE0A441}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {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}.Release|Win32.ActiveCfg = Release|Win32
- {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/LibOVR/Projects/Win32/LibOVR_Msvc2010.vcxproj b/LibOVR/Projects/Win32/LibOVR_Msvc2010.vcxproj
deleted file mode 100644
index e16eaf4..0000000
--- a/LibOVR/Projects/Win32/LibOVR_Msvc2010.vcxproj
+++ /dev/null
@@ -1,279 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\..\Include\OVR.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Alg.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Allocator.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Array.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Atomic.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Color.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_ContainerAllocator.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_File.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Hash.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_KeyCodes.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_List.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Log.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Math.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_RefCount.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Std.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_String.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_StringHash.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_SysFile.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_System.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Threads.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Timer.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Types.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_UTF8Util.h" />
- <ClInclude Include="..\..\Src\OVR_Device.h" />
- <ClInclude Include="..\..\Src\OVR_DeviceConstants.h" />
- <ClInclude Include="..\..\Src\OVR_DeviceHandle.h" />
- <ClInclude Include="..\..\Src\OVR_DeviceImpl.h" />
- <ClInclude Include="..\..\Src\OVR_DeviceMessages.h" />
- <ClInclude Include="..\..\Src\OVR_HIDDevice.h" />
- <ClInclude Include="..\..\Src\OVR_HIDDeviceBase.h" />
- <ClInclude Include="..\..\Src\OVR_HIDDeviceImpl.h" />
- <ClInclude Include="..\..\Src\OVR_JSON.h" />
- <ClInclude Include="..\..\Src\OVR_LatencyTestImpl.h" />
- <ClInclude Include="..\..\Src\OVR_Profile.h" />
- <ClInclude Include="..\..\Src\OVR_SensorFilter.h" />
- <ClInclude Include="..\..\Src\Util\Util_LatencyTest.h" />
- <ClInclude Include="..\..\Src\OVR_SensorFusion.h" />
- <ClInclude Include="..\..\Src\OVR_SensorImpl.h" />
- <ClInclude Include="..\..\Src\OVR_ThreadCommandQueue.h" />
- <ClInclude Include="..\..\Src\OVR_Win32_DeviceManager.h" />
- <ClInclude Include="..\..\Src\OVR_Win32_DeviceStatus.h" />
- <ClInclude Include="..\..\Src\OVR_Win32_HIDDevice.h" />
- <ClInclude Include="..\..\Src\OVR_Win32_HMDDevice.h" />
- <ClInclude Include="..\..\Src\OVR_Win32_SensorDevice.h" />
- <ClInclude Include="..\..\Src\Util\Util_Render_Stereo.h" />
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="..\..\Src\Kernel\OVR_Alg.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_Allocator.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_Atomic.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_File.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_FileFILE.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_Log.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_Math.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_RefCount.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_Std.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_String.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_String_FormatUtil.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_String_PathUtil.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_SysFile.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_System.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_ThreadsWinAPI.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_Timer.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_UTF8Util.cpp" />
- <ClCompile Include="..\..\Src\OVR_DeviceHandle.cpp" />
- <ClCompile Include="..\..\Src\OVR_DeviceImpl.cpp" />
- <ClCompile Include="..\..\Src\OVR_JSON.cpp" />
- <ClCompile Include="..\..\Src\OVR_LatencyTestImpl.cpp" />
- <ClCompile Include="..\..\Src\OVR_Profile.cpp" />
- <ClCompile Include="..\..\Src\OVR_SensorFilter.cpp" />
- <ClCompile Include="..\..\Src\OVR_SensorFusion.cpp" />
- <ClCompile Include="..\..\Src\OVR_SensorImpl.cpp" />
- <ClCompile Include="..\..\Src\OVR_ThreadCommandQueue.cpp" />
- <ClCompile Include="..\..\Src\OVR_Win32_DeviceManager.cpp" />
- <ClCompile Include="..\..\Src\OVR_Win32_DeviceStatus.cpp" />
- <ClCompile Include="..\..\Src\OVR_Win32_HIDDevice.cpp" />
- <ClCompile Include="..\..\Src\OVR_Win32_HMDDevice.cpp" />
- <ClCompile Include="..\..\Src\Util\Util_LatencyTest.cpp" />
- <ClCompile Include="..\..\Src\OVR_Win32_SensorDevice.cpp" />
- <ClCompile Include="..\..\Src\Util\Util_Render_Stereo.cpp" />
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{934B40C7-F40A-4E4C-97A7-B9659BE0A441}</ProjectGuid>
- <Keyword>Win32Proj</Keyword>
- <RootNamespace>LibOVR</RootNamespace>
- <ProjectName>LibOVR</ProjectName>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>StaticLibrary</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <OutDir>../../Lib/$(Platform)/</OutDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <OutDir>../../Lib/$(Platform)/</OutDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <IntDir>../../Obj/$(Platform)/$(Configuration)/</IntDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <IntDir>../../Obj/$(Platform)/$(Configuration)/</IntDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <TargetName>libovrd</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <TargetName>libovr64d</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <OutDir>../../Lib/$(Platform)/</OutDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <OutDir>../../Lib/$(Platform)/</OutDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <IntDir>../../Obj/$(Platform)/$(Configuration)/</IntDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <IntDir>../../Obj/$(Platform)/$(Configuration)/</IntDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <TargetName>libovr</TargetName>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <TargetName>libovr64</TargetName>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level4</WarningLevel>
- <Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <DebugInformationFormat>OldStyle</DebugInformationFormat>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- <MinimalRebuild>false</MinimalRebuild>
- <OmitDefaultLibName>true</OmitDefaultLibName>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Windows</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- <Lib>
- <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
- </Lib>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level4</WarningLevel>
- <Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <DebugInformationFormat>OldStyle</DebugInformationFormat>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- <MinimalRebuild>false</MinimalRebuild>
- <OmitDefaultLibName>true</OmitDefaultLibName>
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
- </ClCompile>
- <Link>
- <SubSystem>Windows</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- </Link>
- <Lib>
- <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
- </Lib>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <WarningLevel>Level4</WarningLevel>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- <OmitDefaultLibName>true</OmitDefaultLibName>
- <DebugInformationFormat>OldStyle</DebugInformationFormat>
- <WholeProgramOptimization>false</WholeProgramOptimization>
- </ClCompile>
- <Link>
- <SubSystem>Windows</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- </Link>
- <Lib>
- <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
- </Lib>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <WarningLevel>Level4</WarningLevel>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>WIN32;_WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- <OmitDefaultLibName>true</OmitDefaultLibName>
- <DebugInformationFormat>OldStyle</DebugInformationFormat>
- <WholeProgramOptimization>false</WholeProgramOptimization>
- </ClCompile>
- <Link>
- <SubSystem>Windows</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- </Link>
- <Lib>
- <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
- </Lib>
- </ItemDefinitionGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/LibOVR/Projects/Win32/LibOVR_Msvc2010.vcxproj.filters b/LibOVR/Projects/Win32/LibOVR_Msvc2010.vcxproj.filters
deleted file mode 100644
index e6d1dcf..0000000
--- a/LibOVR/Projects/Win32/LibOVR_Msvc2010.vcxproj.filters
+++ /dev/null
@@ -1,184 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <ClCompile Include="..\..\Src\OVR_SensorFusion.cpp" />
- <ClCompile Include="..\..\Src\OVR_ThreadCommandQueue.cpp" />
- <ClCompile Include="..\..\Src\OVR_Win32_DeviceManager.cpp" />
- <ClCompile Include="..\..\Src\OVR_Win32_HMDDevice.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_Alg.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_Allocator.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_Atomic.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_File.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_FileFILE.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_Log.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_Math.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_RefCount.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_Std.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_String.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_String_PathUtil.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_SysFile.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_System.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_ThreadsWinAPI.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_Timer.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Kernel\OVR_UTF8Util.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\OVR_DeviceImpl.cpp" />
- <ClCompile Include="..\..\Src\OVR_DeviceHandle.cpp" />
- <ClCompile Include="..\..\Src\OVR_Win32_DeviceStatus.cpp" />
- <ClCompile Include="..\..\Src\Kernel\OVR_String_FormatUtil.cpp">
- <Filter>Kernel</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Util\Util_Render_Stereo.cpp">
- <Filter>Util</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\Util\Util_LatencyTest.cpp">
- <Filter>Util</Filter>
- </ClCompile>
- <ClCompile Include="..\..\Src\OVR_Win32_HIDDevice.cpp" />
- <ClCompile Include="..\..\Src\OVR_LatencyTestImpl.cpp" />
- <ClCompile Include="..\..\Src\OVR_SensorImpl.cpp" />
- <ClCompile Include="..\..\Src\OVR_Win32_SensorDevice.cpp" />
- <ClCompile Include="..\..\Src\OVR_SensorFilter.cpp" />
- <ClCompile Include="..\..\Src\OVR_JSON.cpp" />
- <ClCompile Include="..\..\Src\OVR_Profile.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\..\Src\OVR_DeviceImpl.h" />
- <ClInclude Include="..\..\Src\OVR_SensorFusion.h" />
- <ClInclude Include="..\..\Src\OVR_ThreadCommandQueue.h" />
- <ClInclude Include="..\..\Src\OVR_Win32_DeviceManager.h" />
- <ClInclude Include="..\..\Src\OVR_Win32_HMDDevice.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Alg.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_Allocator.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_Array.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_Atomic.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_ContainerAllocator.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_Math.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_File.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_Hash.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_KeyCodes.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_List.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_Log.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_RefCount.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_System.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_Std.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_String.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_StringHash.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_SysFile.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_Threads.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_Timer.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_Types.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Kernel\OVR_UTF8Util.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Include\OVR.h">
- <Filter>Include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\OVR_Device.h" />
- <ClInclude Include="..\..\Src\OVR_DeviceConstants.h" />
- <ClInclude Include="..\..\Src\OVR_DeviceMessages.h" />
- <ClInclude Include="..\..\Src\OVR_DeviceHandle.h" />
- <ClInclude Include="..\..\Src\OVR_Win32_DeviceStatus.h" />
- <ClInclude Include="..\..\Src\Kernel\OVR_Color.h">
- <Filter>Kernel</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Util\Util_Render_Stereo.h">
- <Filter>Util</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\Util\Util_LatencyTest.h">
- <Filter>Util</Filter>
- </ClInclude>
- <ClInclude Include="..\..\Src\OVR_HIDDevice.h" />
- <ClInclude Include="..\..\Src\OVR_Win32_HIDDevice.h" />
- <ClInclude Include="..\..\Src\OVR_HIDDeviceImpl.h" />
- <ClInclude Include="..\..\Src\OVR_LatencyTestImpl.h" />
- <ClInclude Include="..\..\Src\OVR_SensorImpl.h" />
- <ClInclude Include="..\..\Src\OVR_HIDDeviceBase.h" />
- <ClInclude Include="..\..\Src\OVR_Win32_SensorDevice.h" />
- <ClInclude Include="..\..\Src\OVR_SensorFilter.h" />
- <ClInclude Include="..\..\Src\OVR_JSON.h" />
- <ClInclude Include="..\..\Src\OVR_Profile.h" />
- </ItemGroup>
- <ItemGroup>
- <Filter Include="Kernel">
- <UniqueIdentifier>{ccc06f04-d013-483f-8471-bd25332e38bb}</UniqueIdentifier>
- </Filter>
- <Filter Include="Include">
- <UniqueIdentifier>{53c19267-8aec-48ad-a1a3-7ffd9090f075}</UniqueIdentifier>
- </Filter>
- <Filter Include="Util">
- <UniqueIdentifier>{6d4ac63a-dea8-4fdb-ad20-6768c33376d9}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
-</Project> \ No newline at end of file
diff --git a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj
new file mode 100644
index 0000000..f293cb9
--- /dev/null
+++ b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj
@@ -0,0 +1,433 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_FrameTimeManager.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_GlobalState.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_HMDRenderState.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_HMDState.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D10_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D11_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_Util.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Alg.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Allocator.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Array.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Atomic.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Color.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_ContainerAllocator.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_File.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Hash.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_KeyCodes.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_List.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Lockless.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Log.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Math.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Deque.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_RefCount.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Std.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_String.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_StringHash.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_SysFile.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_System.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Threads.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Timer.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Types.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_UTF8Util.h" />
+ <ClInclude Include="..\..\..\Src\OVR_CAPI.h" />
+ <ClInclude Include="..\..\..\Src\OVR_CAPI_D3D.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Device.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceConstants.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceHandle.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceMessages.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDeviceBase.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDeviceImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_JSON.h" />
+ <ClInclude Include="..\..\..\Src\OVR_LatencyTestImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Profile.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Sensor2Impl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Sensor2ImplUtil.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorCalibration.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorFilter.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorFusion.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorImpl_Common.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorTimeFilter.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Stereo.h" />
+ <ClInclude Include="..\..\..\Src\OVR_ThreadCommandQueue.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_DeviceManager.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_DeviceStatus.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_HIDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_HMDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_SensorDevice.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_ImageWindow.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_Interface.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_LatencyTest.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_LatencyTest2.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_Render_Stereo.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_FrameTimeManager.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_GlobalState.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_HMDRenderState.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_HMDState.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D10_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D11_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_DistortionRenderer.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_Util.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_Util.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Alg.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Allocator.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Atomic.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_File.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_FileFILE.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Lockless.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Log.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Math.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_RefCount.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Std.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String_FormatUtil.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String_PathUtil.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_SysFile.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_System.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_ThreadsWinAPI.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Timer.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_UTF8Util.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_CAPI.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_DeviceHandle.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_DeviceImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_JSON.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_LatencyTestImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Profile.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Sensor2Impl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorCalibration.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorFilter.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorFusion.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorImpl_Common.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorTimeFilter.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Stereo.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_ThreadCommandQueue.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_DeviceManager.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_DeviceStatus.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_HIDDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_HMDDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_SensorDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_ImageWindow.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_Interface.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_LatencyTest.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_LatencyTest2.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_Render_Stereo.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionChroma_ps.psh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionChroma_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionTimewarpChroma_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionTimewarp_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\Distortion_ps.psh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\Distortion_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\SimpleQuad_ps.psh">
+ <FileType>Document</FileType>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\SimpleQuad_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ </CustomBuild>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{720F6C5E-6DCF-495A-B25E-10540EA081A2}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>LibOVR</RootNamespace>
+ <ProjectName>LibOVR</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>../../../Lib/$(Platform)/VS2010/</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>../../../Lib/$(Platform)/VS2010/</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <IntDir>../../../Obj/$(Platform)/VS2010/$(Configuration)/</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <IntDir>../../../Obj/$(Platform)/VS2010/$(Configuration)/</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>libovrd</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>libovr64d</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>../../../Lib/$(Platform)/VS2010/</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>../../../Lib/$(Platform)/VS2010/</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <IntDir>../../../Obj/$(Platform)/VS2010/$(Configuration)/</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <IntDir>../../../Obj/$(Platform)/VS2010/$(Configuration)/</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>libovr</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>libovr64</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <OmitDefaultLibName>true</OmitDefaultLibName>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <AdditionalIncludeDirectories>../../../../3rdParty/glext/;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <OmitDefaultLibName>true</OmitDefaultLibName>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <AdditionalIncludeDirectories>../../../../3rdParty/glext/;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <OmitFramePointers>false</OmitFramePointers>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <OmitDefaultLibName>true</OmitDefaultLibName>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <AdditionalIncludeDirectories>../../../../3rdParty/glext/;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>_WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <OmitDefaultLibName>true</OmitDefaultLibName>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <AdditionalIncludeDirectories>../../../../3rdParty/glext/;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters
new file mode 100644
index 0000000..c1a53cd
--- /dev/null
+++ b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters
@@ -0,0 +1,332 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="..\..\..\Src\OVR_DeviceHandle.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_DeviceImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_JSON.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_LatencyTestImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Profile.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Sensor2Impl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorCalibration.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorFilter.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorFusion.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorImpl_Common.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorTimeFilter.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Stereo.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_ThreadCommandQueue.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_DeviceManager.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_DeviceStatus.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_HIDDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_HMDDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_SensorDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_LatencyTest.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Util\Util_Render_Stereo.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Alg.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Allocator.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Atomic.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_File.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_FileFILE.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Lockless.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Log.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Math.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_RefCount.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Std.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String_FormatUtil.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String_PathUtil.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_SysFile.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_System.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_ThreadsWinAPI.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Timer.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_UTF8Util.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_DistortionRenderer.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_GlobalState.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_HMDRenderState.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_HMDState.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_DistortionRenderer.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_Util.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D10_DistortionRenderer.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D11_DistortionRenderer.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\OVR_CAPI.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_FrameTimeManager.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_DistortionRenderer.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_Util.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Util\Util_ImageWindow.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Util\Util_LatencyTest2.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Util\Util_Interface.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_DistortionRenderer.cpp">
+ <Filter>CAPI\GL</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.cpp">
+ <Filter>CAPI\GL</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\Src\OVR_Device.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceConstants.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceHandle.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceMessages.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDeviceBase.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDeviceImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_JSON.h" />
+ <ClInclude Include="..\..\..\Src\OVR_LatencyTestImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Profile.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Sensor2Impl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorCalibration.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorFilter.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorFusion.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorImpl_Common.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorTimeFilter.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Stereo.h" />
+ <ClInclude Include="..\..\..\Src\OVR_ThreadCommandQueue.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_DeviceManager.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_DeviceStatus.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_HIDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_HMDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_SensorDevice.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_Render_Stereo.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Util\Util_LatencyTest.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Alg.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Allocator.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Array.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Atomic.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Color.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_ContainerAllocator.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Deque.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_File.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Hash.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_KeyCodes.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_List.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Lockless.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Log.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Math.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_RefCount.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Std.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_String.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_StringHash.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_SysFile.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_System.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Threads.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Timer.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Types.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_UTF8Util.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\OVR_Sensor2ImplUtil.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_DistortionRenderer.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_GlobalState.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_HMDRenderState.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_HMDState.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_DistortionRenderer.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_Util.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D10_DistortionRenderer.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D11_DistortionRenderer.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\OVR_CAPI.h" />
+ <ClInclude Include="..\..\..\Src\OVR_CAPI_D3D.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_FrameTimeManager.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Util\Util_Interface.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_DistortionRenderer.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Util\Util_ImageWindow.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Util\Util_LatencyTest2.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_DistortionRenderer.h">
+ <Filter>CAPI\GL</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.h">
+ <Filter>CAPI\GL</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Util">
+ <UniqueIdentifier>{aa824f36-4d15-4dca-9894-fef4368ea56a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Kernel">
+ <UniqueIdentifier>{d532b65b-dee5-422f-b723-ce8639eedbe0}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CAPI">
+ <UniqueIdentifier>{7ec9033e-7bc6-49de-93d0-91eecdd9a858}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CAPI\D3D1X">
+ <UniqueIdentifier>{0ee0029b-0b10-4ad6-a10c-7bf4ccefdf54}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CAPI\Shaders">
+ <UniqueIdentifier>{191043aa-7805-44f0-a0a4-02799289365c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CAPI\GL">
+ <UniqueIdentifier>{d1b72f17-b0a8-420d-8625-13c4948df7ed}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionChroma_ps.psh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\Distortion_ps.psh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionTimewarpChroma_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionTimewarp_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionChroma_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\Distortion_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\SimpleQuad_ps.psh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\SimpleQuad_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj b/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj
new file mode 100644
index 0000000..a0718bf
--- /dev/null
+++ b/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj
@@ -0,0 +1,439 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_FrameTimeManager.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_GlobalState.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_HMDRenderState.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_HMDState.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D10_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D11_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_Util.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Alg.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Allocator.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Array.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Atomic.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Color.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_ContainerAllocator.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_File.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Hash.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_KeyCodes.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_List.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Lockless.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Log.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Math.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Deque.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_RefCount.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Std.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_String.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_StringHash.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_SysFile.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_System.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Threads.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Timer.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Types.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_UTF8Util.h" />
+ <ClInclude Include="..\..\..\Src\OVR_CAPI.h" />
+ <ClInclude Include="..\..\..\Src\OVR_CAPI_D3D.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Device.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceConstants.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceHandle.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceMessages.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDeviceBase.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDeviceImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_JSON.h" />
+ <ClInclude Include="..\..\..\Src\OVR_LatencyTestImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Profile.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Sensor2Impl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Sensor2ImplUtil.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorCalibration.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorFilter.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorFusion.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorImpl_Common.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorTimeFilter.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Stereo.h" />
+ <ClInclude Include="..\..\..\Src\OVR_ThreadCommandQueue.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_DeviceManager.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_DeviceStatus.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_HIDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_HMDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_SensorDevice.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_ImageWindow.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_Interface.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_LatencyTest.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_LatencyTest2.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_Render_Stereo.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_FrameTimeManager.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_GlobalState.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_HMDRenderState.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_HMDState.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D10_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D11_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_DistortionRenderer.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_Util.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_Util.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Alg.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Allocator.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Atomic.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_File.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_FileFILE.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Lockless.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Log.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Math.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_RefCount.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Std.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String_FormatUtil.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String_PathUtil.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_SysFile.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_System.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_ThreadsWinAPI.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Timer.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_UTF8Util.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_CAPI.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_DeviceHandle.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_DeviceImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_JSON.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_LatencyTestImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Profile.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Sensor2Impl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorCalibration.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorFilter.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorFusion.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorImpl_Common.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorTimeFilter.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Stereo.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_ThreadCommandQueue.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_DeviceManager.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_DeviceStatus.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_HIDDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_HMDDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_SensorDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_ImageWindow.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_Interface.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_LatencyTest.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_LatencyTest2.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_Render_Stereo.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionChroma_ps.psh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionChroma_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionTimewarpChroma_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionTimewarp_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\Distortion_ps.psh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\Distortion_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\SimpleQuad_ps.psh">
+ <FileType>Document</FileType>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\SimpleQuad_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ </CustomBuild>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>LibOVR</RootNamespace>
+ <ProjectName>LibOVR</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>../../../Lib/$(Platform)/VS2012/</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>../../../Lib/$(Platform)/VS2012/</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <IntDir>../../../Obj/$(Platform)/VS2012/$(Configuration)/</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <IntDir>../../../Obj/$(Platform)/VS2012/$(Configuration)/</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>libovrd</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>libovr64d</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>../../../Lib/$(Platform)/VS2012/</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>../../../Lib/$(Platform)/VS2012/</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <IntDir>../../../Obj/$(Platform)/VS2012/$(Configuration)/</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <IntDir>../../../Obj/$(Platform)/VS2012/$(Configuration)/</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>libovr</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>libovr64</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <OmitDefaultLibName>true</OmitDefaultLibName>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <AdditionalIncludeDirectories>../../../../3rdParty/glext/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <OmitDefaultLibName>true</OmitDefaultLibName>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <AdditionalIncludeDirectories>../../../../3rdParty/glext/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <OmitFramePointers>false</OmitFramePointers>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <OmitDefaultLibName>true</OmitDefaultLibName>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <AdditionalIncludeDirectories>../../../../3rdParty/glext/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>_WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <OmitDefaultLibName>true</OmitDefaultLibName>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <AdditionalIncludeDirectories>../../../../3rdParty/glext/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters b/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters
new file mode 100644
index 0000000..579bddc
--- /dev/null
+++ b/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters
@@ -0,0 +1,332 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="..\..\..\Src\OVR_DeviceHandle.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_DeviceImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_JSON.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_LatencyTestImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Profile.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Sensor2Impl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorCalibration.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorFilter.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorFusion.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorImpl_Common.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorTimeFilter.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Stereo.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_ThreadCommandQueue.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_DeviceManager.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_DeviceStatus.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_HIDDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_HMDDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_SensorDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_LatencyTest.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Util\Util_Render_Stereo.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Alg.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Allocator.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Atomic.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_File.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_FileFILE.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Lockless.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Log.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Math.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_RefCount.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Std.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String_FormatUtil.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String_PathUtil.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_SysFile.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_System.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_ThreadsWinAPI.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Timer.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_UTF8Util.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_DistortionRenderer.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_GlobalState.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_HMDRenderState.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_HMDState.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_DistortionRenderer.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_Util.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D10_DistortionRenderer.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D11_DistortionRenderer.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\OVR_CAPI.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_FrameTimeManager.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_DistortionRenderer.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_Util.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Util\Util_ImageWindow.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Util\Util_LatencyTest2.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Util\Util_Interface.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_DistortionRenderer.cpp">
+ <Filter>CAPI\GL</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.cpp">
+ <Filter>CAPI\GL</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\Src\OVR_Device.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceConstants.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceHandle.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceMessages.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDeviceBase.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDeviceImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_JSON.h" />
+ <ClInclude Include="..\..\..\Src\OVR_LatencyTestImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Profile.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Sensor2Impl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorCalibration.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorFilter.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorFusion.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorImpl_Common.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorTimeFilter.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Stereo.h" />
+ <ClInclude Include="..\..\..\Src\OVR_ThreadCommandQueue.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_DeviceManager.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_DeviceStatus.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_HIDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_HMDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_SensorDevice.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_Render_Stereo.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Util\Util_LatencyTest.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Alg.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Allocator.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Array.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Atomic.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Color.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_ContainerAllocator.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Deque.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_File.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Hash.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_KeyCodes.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_List.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Lockless.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Log.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Math.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_RefCount.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Std.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_String.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_StringHash.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_SysFile.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_System.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Threads.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Timer.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Types.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_UTF8Util.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\OVR_Sensor2ImplUtil.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_DistortionRenderer.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_GlobalState.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_HMDRenderState.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_HMDState.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_DistortionRenderer.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_Util.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D10_DistortionRenderer.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D11_DistortionRenderer.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\OVR_CAPI.h" />
+ <ClInclude Include="..\..\..\Src\OVR_CAPI_D3D.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_FrameTimeManager.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Util\Util_Interface.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_DistortionRenderer.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Util\Util_ImageWindow.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Util\Util_LatencyTest2.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_DistortionRenderer.h">
+ <Filter>CAPI\GL</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.h">
+ <Filter>CAPI\GL</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Util">
+ <UniqueIdentifier>{aa824f36-4d15-4dca-9894-fef4368ea56a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Kernel">
+ <UniqueIdentifier>{d532b65b-dee5-422f-b723-ce8639eedbe0}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CAPI">
+ <UniqueIdentifier>{7ec9033e-7bc6-49de-93d0-91eecdd9a858}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CAPI\D3D1X">
+ <UniqueIdentifier>{0ee0029b-0b10-4ad6-a10c-7bf4ccefdf54}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CAPI\Shaders">
+ <UniqueIdentifier>{191043aa-7805-44f0-a0a4-02799289365c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CAPI\GL">
+ <UniqueIdentifier>{c86c7070-6bf4-4ae4-b9bf-4c21d2ba9516}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionChroma_ps.psh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\Distortion_ps.psh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionTimewarpChroma_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionTimewarp_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionChroma_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\Distortion_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\SimpleQuad_ps.psh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\SimpleQuad_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj b/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj
new file mode 100644
index 0000000..a5f9297
--- /dev/null
+++ b/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj
@@ -0,0 +1,439 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_FrameTimeManager.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_GlobalState.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_HMDRenderState.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_HMDState.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D10_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D11_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_Util.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_DistortionRenderer.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Alg.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Allocator.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Array.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Atomic.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Color.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_ContainerAllocator.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_File.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Hash.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_KeyCodes.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_List.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Lockless.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Log.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Math.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Deque.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_RefCount.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Std.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_String.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_StringHash.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_SysFile.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_System.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Threads.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Timer.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Types.h" />
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_UTF8Util.h" />
+ <ClInclude Include="..\..\..\Src\OVR_CAPI.h" />
+ <ClInclude Include="..\..\..\Src\OVR_CAPI_D3D.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Device.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceConstants.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceHandle.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceMessages.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDeviceBase.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDeviceImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_JSON.h" />
+ <ClInclude Include="..\..\..\Src\OVR_LatencyTestImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Profile.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Sensor2Impl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Sensor2ImplUtil.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorCalibration.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorFilter.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorFusion.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorImpl_Common.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorTimeFilter.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Stereo.h" />
+ <ClInclude Include="..\..\..\Src\OVR_ThreadCommandQueue.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_DeviceManager.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_DeviceStatus.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_HIDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_HMDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_SensorDevice.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_ImageWindow.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_Interface.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_LatencyTest.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_LatencyTest2.h" />
+ <ClInclude Include="..\..\..\Src\Util\Util_Render_Stereo.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_FrameTimeManager.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_GlobalState.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_HMDRenderState.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_HMDState.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D10_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D11_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_DistortionRenderer.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_Util.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_Util.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_DistortionRenderer.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Alg.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Allocator.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Atomic.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_File.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_FileFILE.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Lockless.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Log.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Math.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_RefCount.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Std.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String_FormatUtil.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String_PathUtil.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_SysFile.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_System.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_ThreadsWinAPI.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Timer.cpp" />
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_UTF8Util.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_CAPI.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_DeviceHandle.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_DeviceImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_JSON.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_LatencyTestImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Profile.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Sensor2Impl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorCalibration.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorFilter.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorFusion.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorImpl_Common.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorTimeFilter.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Stereo.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_ThreadCommandQueue.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_DeviceManager.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_DeviceStatus.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_HIDDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_HMDDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_SensorDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_ImageWindow.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_Interface.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_LatencyTest.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_LatencyTest2.cpp" />
+ <ClCompile Include="..\..\..\Src\Util\Util_Render_Stereo.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionChroma_ps.psh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionChroma_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionTimewarpChroma_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionTimewarp_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\Distortion_ps.psh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\Distortion_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\SimpleQuad_ps.psh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\SimpleQuad_vs.vsh">
+ <FileType>Document</FileType>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)"</Command>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(RelativeDir)%(Filename).h</Outputs>
+ </CustomBuild>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{EA50E705-5113-49E5-B105-2512EDC8DDC6}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>LibOVR</RootNamespace>
+ <ProjectName>LibOVR</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>../../../Lib/$(Platform)/VS2013/</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <OutDir>../../../Lib/$(Platform)/VS2013/</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <IntDir>../../../Obj/$(Platform)/VS2013/$(Configuration)/</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <IntDir>../../../Obj/$(Platform)/VS2013/$(Configuration)/</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>libovrd</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>libovr64d</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>../../../Lib/$(Platform)/VS2013/</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <OutDir>../../../Lib/$(Platform)/VS2013/</OutDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <IntDir>../../../Obj/$(Platform)/VS2013/$(Configuration)/</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <IntDir>../../../Obj/$(Platform)/VS2013/$(Configuration)/</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>libovr</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>libovr64</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <OmitDefaultLibName>true</OmitDefaultLibName>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <AdditionalIncludeDirectories>../../../../3rdParty/glext/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <OmitDefaultLibName>true</OmitDefaultLibName>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <AdditionalIncludeDirectories>../../../../3rdParty/glext/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <OmitFramePointers>false</OmitFramePointers>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <OmitDefaultLibName>true</OmitDefaultLibName>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <AdditionalIncludeDirectories>../../../../3rdParty/glext/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>_WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <OmitDefaultLibName>true</OmitDefaultLibName>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <AdditionalIncludeDirectories>../../../../3rdParty/glext/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ <Lib>
+ <AdditionalDependencies>Setupapi.lib</AdditionalDependencies>
+ </Lib>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters b/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters
new file mode 100644
index 0000000..becf605
--- /dev/null
+++ b/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters
@@ -0,0 +1,332 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="..\..\..\Src\OVR_CAPI.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_DeviceHandle.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_DeviceImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_JSON.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_LatencyTestImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Profile.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Sensor2Impl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorCalibration.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorFilter.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorFusion.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorImpl.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorImpl_Common.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_SensorTimeFilter.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Stereo.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_ThreadCommandQueue.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_DeviceManager.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_DeviceStatus.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_HIDDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_HMDDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\OVR_Win32_SensorDevice.cpp" />
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_DistortionRenderer.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_Util.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_DistortionRenderer.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_Util.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D10_DistortionRenderer.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D11_DistortionRenderer.cpp">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_DistortionRenderer.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_FrameTimeManager.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_GlobalState.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_HMDRenderState.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\CAPI_HMDState.cpp">
+ <Filter>CAPI</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Alg.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Allocator.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Atomic.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_File.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_FileFILE.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Lockless.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Log.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Math.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_RefCount.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Std.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String_FormatUtil.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_String_PathUtil.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_SysFile.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_System.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_ThreadsWinAPI.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_Timer.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Kernel\OVR_UTF8Util.cpp">
+ <Filter>Kernel</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Util\Util_LatencyTest.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Util\Util_Render_Stereo.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Util\Util_ImageWindow.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Util\Util_LatencyTest2.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\Util\Util_Interface.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_DistortionRenderer.cpp">
+ <Filter>CAPI\GL</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.cpp">
+ <Filter>CAPI\GL</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\Src\OVR_CAPI.h" />
+ <ClInclude Include="..\..\..\Src\OVR_CAPI_D3D.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Device.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceConstants.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceHandle.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_DeviceMessages.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDeviceBase.h" />
+ <ClInclude Include="..\..\..\Src\OVR_HIDDeviceImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_JSON.h" />
+ <ClInclude Include="..\..\..\Src\OVR_LatencyTestImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Profile.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Sensor2Impl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Sensor2ImplUtil.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorCalibration.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorFilter.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorFusion.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorImpl.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorImpl_Common.h" />
+ <ClInclude Include="..\..\..\Src\OVR_SensorTimeFilter.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Stereo.h" />
+ <ClInclude Include="..\..\..\Src\OVR_ThreadCommandQueue.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_DeviceManager.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_DeviceStatus.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_HIDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_HMDDevice.h" />
+ <ClInclude Include="..\..\..\Src\OVR_Win32_SensorDevice.h" />
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_DistortionRenderer.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D1X_Util.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D9_DistortionRenderer.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D10_DistortionRenderer.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\D3D1X\CAPI_D3D11_DistortionRenderer.h">
+ <Filter>CAPI\D3D1X</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_DistortionRenderer.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_FrameTimeManager.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_GlobalState.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_HMDRenderState.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\CAPI_HMDState.h">
+ <Filter>CAPI</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Alg.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Allocator.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Array.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Atomic.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Color.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_ContainerAllocator.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Deque.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_File.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Hash.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_KeyCodes.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_List.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Lockless.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Log.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Math.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_RefCount.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Std.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_String.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_StringHash.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_SysFile.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_System.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Threads.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Timer.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_Types.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Kernel\OVR_UTF8Util.h">
+ <Filter>Kernel</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Util\Util_Interface.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Util\Util_LatencyTest.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Util\Util_Render_Stereo.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Util\Util_ImageWindow.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\Util\Util_LatencyTest2.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_DistortionRenderer.h">
+ <Filter>CAPI\GL</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\Src\CAPI\GL\CAPI_GL_Util.h">
+ <Filter>CAPI\GL</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionTimewarpChroma_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionTimewarp_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionChroma_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\DistortionChroma_ps.psh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\Distortion_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\Distortion_ps.psh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\SimpleQuad_vs.vsh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ <CustomBuild Include="..\..\..\Src\CAPI\Shaders\SimpleQuad_ps.psh">
+ <Filter>CAPI\Shaders</Filter>
+ </CustomBuild>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="CAPI">
+ <UniqueIdentifier>{42ff86e1-b618-4432-99ce-e6b92c7460eb}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CAPI\Shaders">
+ <UniqueIdentifier>{a65a3889-6d00-4a76-acfe-6db1249f104d}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CAPI\D3D1X">
+ <UniqueIdentifier>{77e1d16e-00a1-4130-8ee6-f81d1e850859}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Kernel">
+ <UniqueIdentifier>{b5206073-e32d-413b-804b-6c4f6984365c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Util">
+ <UniqueIdentifier>{470c25c2-99a2-439b-9f6b-761e8c70f84e}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CAPI\GL">
+ <UniqueIdentifier>{b8c0476b-d36b-4d31-8141-4d42f78b9e51}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/LibOVR/Projects/libovr.txt b/LibOVR/Projects/libovr.txt
deleted file mode 100644
index d81a802..0000000
--- a/LibOVR/Projects/libovr.txt
+++ /dev/null
@@ -1,83 +0,0 @@
-LibOVR/Src/Kernel/OVR_Alg.cpp
-LibOVR/Src/Kernel/OVR_Alg.h
-LibOVR/Src/Kernel/OVR_Allocator.cpp
-LibOVR/Src/Kernel/OVR_Allocator.h
-LibOVR/Src/Kernel/OVR_Array.h
-LibOVR/Src/Kernel/OVR_Atomic.cpp
-LibOVR/Src/Kernel/OVR_Atomic.h
-LibOVR/Src/Kernel/OVR_Color.h
-LibOVR/Src/Kernel/OVR_ContainerAllocator.h
-LibOVR/Src/Kernel/OVR_File.cpp
-LibOVR/Src/Kernel/OVR_File.h
-LibOVR/Src/Kernel/OVR_FileFILE.cpp
-LibOVR/Src/Kernel/OVR_Hash.h
-LibOVR/Src/Kernel/OVR_KeyCodes.h
-LibOVR/Src/Kernel/OVR_List.h
-LibOVR/Src/Kernel/OVR_Log.cpp
-LibOVR/Src/Kernel/OVR_Log.h
-LibOVR/Src/Kernel/OVR_Math.cpp
-LibOVR/Src/Kernel/OVR_Math.h
-LibOVR/Src/Kernel/OVR_RefCount.cpp
-LibOVR/Src/Kernel/OVR_RefCount.h
-LibOVR/Src/Kernel/OVR_Std.cpp
-LibOVR/Src/Kernel/OVR_Std.h
-LibOVR/Src/Kernel/OVR_String.cpp
-LibOVR/Src/Kernel/OVR_String.h
-LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp
-LibOVR/Src/Kernel/OVR_String_PathUtil.cpp
-LibOVR/Src/Kernel/OVR_StringHash.h
-LibOVR/Src/Kernel/OVR_SysFile.cpp
-LibOVR/Src/Kernel/OVR_SysFile.h
-LibOVR/Src/Kernel/OVR_System.cpp
-LibOVR/Src/Kernel/OVR_System.h
-LibOVR/Src/Kernel/OVR_Threads.h
-LibOVR/Src/Kernel/OVR_Timer.cpp
-LibOVR/Src/Kernel/OVR_Timer.h
-LibOVR/Src/Kernel/OVR_Types.h
-LibOVR/Src/Kernel/OVR_UTF8Util.cpp
-LibOVR/Src/Kernel/OVR_UTF8Util.h
-LibOVR/Src/OVR_Device.h
-LibOVR/Src/OVR_DeviceConstants.h
-LibOVR/Src/OVR_DeviceHandle.cpp
-LibOVR/Src/OVR_DeviceHandle.h
-LibOVR/Src/OVR_DeviceImpl.cpp
-LibOVR/Src/OVR_DeviceImpl.h
-LibOVR/Src/OVR_DeviceMessages.h
-LibOVR/Src/OVR_HIDDevice.h
-LibOVR/Src/OVR_HIDDeviceBase.h
-LibOVR/Src/OVR_HIDDeviceImpl.h
-LibOVR/Src/OVR_LatencyTestImpl.cpp
-LibOVR/Src/OVR_LatencyTestImpl.h
-LibOVR/Src/OVR_SensorFusion.cpp
-LibOVR/Src/OVR_SensorFusion.h
-LibOVR/Src/OVR_SensorImpl.cpp
-LibOVR/Src/OVR_SensorImpl.h
-LibOVR/Src/OVR_ThreadCommandQueue.cpp
-LibOVR/Src/OVR_ThreadCommandQueue.h
-LibOVR/Src/Util/Util_LatencyTest.cpp
-LibOVR/Src/Util/Util_LatencyTest.h
-LibOVR/Src/Util/Util_Render_Stereo.cpp
-LibOVR/Src/Util/Util_Render_Stereo.h
-
-[MacOS]
-LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp
-LibOVR/Src/OVR_OSX_DeviceManager.cpp
-LibOVR/Src/OVR_OSX_DeviceManager.h
-LibOVR/Src/OVR_OSX_HIDDevice.cpp
-LibOVR/Src/OVR_OSX_HIDDevice.h
-LibOVR/Src/OVR_OSX_HMDDevice.cpp
-LibOVR/Src/OVR_OSX_HMDDevice.h
-LibOVR/Src/OVR_OSX_SensorDevice.cpp
-
-[Win32]
-LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp
-LibOVR/Src/OVR_Win32_DeviceManager.cpp
-LibOVR/Src/OVR_Win32_DeviceManager.h
-LibOVR/Src/OVR_Win32_DeviceStatus.cpp
-LibOVR/Src/OVR_Win32_DeviceStatus.h
-LibOVR/Src/OVR_Win32_HIDDevice.cpp
-LibOVR/Src/OVR_Win32_HIDDevice.h
-LibOVR/Src/OVR_Win32_HMDDevice.cpp
-LibOVR/Src/OVR_Win32_HMDDevice.h
-LibOVR/Src/OVR_Win32_SensorDevice.cpp
-LibOVR/Src/OVR_Win32_SensorDevice.h
diff --git a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp
new file mode 100644
index 0000000..8c0f8b8
--- /dev/null
+++ b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp
@@ -0,0 +1,63 @@
+/************************************************************************************
+
+Filename : CAPI_DistortionRenderer.cpp
+Content : Combines all of the rendering state associated with the HMD
+Created : February 2, 2014
+Authors : Michael Antonov
+
+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 "CAPI_DistortionRenderer.h"
+
+// TBD: Move to separate config file that handles back-ends.
+#define OVR_D3D_VERSION 11
+#include "D3D1X/CAPI_D3D1X_DistortionRenderer.h"
+#undef OVR_D3D_VERSION
+
+#define OVR_D3D_VERSION 10
+#include "D3D1X/CAPI_D3D1X_DistortionRenderer.h"
+#undef OVR_D3D_VERSION
+
+#define OVR_D3D_VERSION 9
+#include "D3D1X/CAPI_D3D9_DistortionRenderer.h"
+#undef OVR_D3D_VERSION
+
+#include "GL/CAPI_GL_DistortionRenderer.h"
+
+namespace OVR { namespace CAPI {
+
+//-------------------------------------------------------------------------------------
+// ***** DistortionRenderer
+
+// TBD: Move to separate config file that handles back-ends.
+
+DistortionRenderer::CreateFunc DistortionRenderer::APICreateRegistry[ovrRenderAPI_Count] =
+{
+ 0, // None
+ &GL::DistortionRenderer::Create,
+ 0, // Android_GLES
+ &D3D9::DistortionRenderer::Create,
+ &D3D10::DistortionRenderer::Create,
+ &D3D11::DistortionRenderer::Create
+};
+
+
+}} // namespace OVR::CAPI
+
diff --git a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h
new file mode 100644
index 0000000..d1b8011
--- /dev/null
+++ b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h
@@ -0,0 +1,100 @@
+/************************************************************************************
+
+Filename : CAPI_DistortionRenderer.h
+Content : Abstract interface for platform-specific rendering of distortion
+Created : February 2, 2014
+Authors : Michael Antonov
+
+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_CAPI_DistortionRenderer_h
+#define OVR_CAPI_DistortionRenderer_h
+
+#include "CAPI_HMDRenderState.h"
+#include "CAPI_FrameTimeManager.h"
+
+
+namespace OVR { namespace CAPI {
+
+//-------------------------------------------------------------------------------------
+// ***** CAPI::DistortionRenderer
+
+// DistortionRenderer implements rendering of distortion and other overlay elements
+// in platform-independent way.
+// Platform-specific renderer back ends for CAPI are derived from this class.
+
+class DistortionRenderer : public RefCountBase<DistortionRenderer>
+{
+ // Quiet assignment compiler warning.
+ void operator = (const DistortionRenderer&) { }
+public:
+
+ DistortionRenderer(ovrRenderAPIType api, ovrHmd hmd,
+ FrameTimeManager& timeManager,
+ const HMDRenderState& renderState)
+ : RenderAPI(api), HMD(hmd), TimeManager(timeManager), RState(renderState)
+ { }
+ virtual ~DistortionRenderer()
+ { }
+
+
+ // Configures the Renderer based on externally passed API settings. Must be
+ // called before use.
+ // Under D3D, apiConfig includes D3D Device pointer, back buffer and other
+ // needed structures.
+ virtual bool Initialize(const ovrRenderAPIConfig* apiConfig,
+ unsigned hmdCaps, 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
+ // eye can be scanned out before the other.
+ virtual void SubmitEye(int eyeId, ovrTexture* eyeTexture) = 0;
+
+ // Finish the frame, optionally swapping buffers.
+ // Many implementations may actually apply the distortion here.
+ virtual void EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor,
+ unsigned char* latencyTester2DrawColor) = 0;
+
+
+
+ // *** Creation Factory logic
+
+ ovrRenderAPIType GetRenderAPI() const { return RenderAPI; }
+
+ // Creation function for this interface, registered for API.
+ typedef DistortionRenderer* (*CreateFunc)(ovrHmd hmd,
+ FrameTimeManager &timeManager,
+ const HMDRenderState& renderState);
+
+ static CreateFunc APICreateRegistry[ovrRenderAPI_Count];
+
+protected:
+ const ovrRenderAPIType RenderAPI;
+ const ovrHmd HMD;
+ FrameTimeManager& TimeManager;
+ const HMDRenderState& RState;
+};
+
+}} // namespace OVR::CAPI
+
+
+#endif // OVR_CAPI_DistortionRenderer_h
+
+
diff --git a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp
new file mode 100644
index 0000000..de7eeeb
--- /dev/null
+++ b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp
@@ -0,0 +1,674 @@
+/************************************************************************************
+
+Filename : CAPI_FrameTimeManager.cpp
+Content : Manage frame timing and pose prediction for rendering
+Created : November 30, 2013
+Authors : Volga Aksoy, Michael Antonov
+
+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 "CAPI_FrameTimeManager.h"
+
+
+namespace OVR { namespace CAPI {
+
+
+//-------------------------------------------------------------------------------------
+// ***** FrameLatencyTracker
+
+
+FrameLatencyTracker::FrameLatencyTracker()
+{
+ Reset();
+}
+
+void FrameLatencyTracker::Reset()
+{
+ TrackerEnabled = true;
+ WaitMode = SampleWait_Zeroes;
+ FrameIndex = 0;
+ MatchCount = 0;
+ RenderLatencySeconds = 0.0;
+ TimewarpLatencySeconds = 0.0;
+
+ FrameDeltas.Clear();
+}
+
+
+unsigned char FrameLatencyTracker::GetNextDrawColor()
+{
+ if (!TrackerEnabled || (WaitMode == SampleWait_Zeroes) ||
+ (FrameIndex >= FramesTracked))
+ {
+ return (unsigned char)Util::FrameTimeRecord::ReadbackIndexToColor(0);
+ }
+
+ OVR_ASSERT(FrameIndex < FramesTracked);
+ return (unsigned char)Util::FrameTimeRecord::ReadbackIndexToColor(FrameIndex+1);
+}
+
+
+void FrameLatencyTracker::SaveDrawColor(unsigned char drawColor, double endFrameTime,
+ double renderIMUTime, double timewarpIMUTime )
+{
+ if (!TrackerEnabled || (WaitMode == SampleWait_Zeroes))
+ return;
+
+ if (FrameIndex < FramesTracked)
+ {
+ OVR_ASSERT(Util::FrameTimeRecord::ReadbackIndexToColor(FrameIndex+1) == drawColor);
+ OVR_UNUSED(drawColor);
+
+ // saves {color, endFrame time}
+ FrameEndTimes[FrameIndex].ReadbackIndex = FrameIndex + 1;
+ FrameEndTimes[FrameIndex].TimeSeconds = endFrameTime;
+ FrameEndTimes[FrameIndex].RenderIMUTimeSeconds = renderIMUTime;
+ FrameEndTimes[FrameIndex].TimewarpIMUTimeSeconds= timewarpIMUTime;
+ FrameEndTimes[FrameIndex].MatchedRecord = false;
+ FrameIndex++;
+ }
+ else
+ {
+ // If the request was outstanding for too long, switch to zero mode to restart.
+ if (endFrameTime > (FrameEndTimes[FrameIndex-1].TimeSeconds + 0.15))
+ {
+ if (MatchCount == 0)
+ {
+ // If nothing was matched, we have no latency reading.
+ RenderLatencySeconds = 0.0;
+ TimewarpLatencySeconds = 0.0;
+ }
+
+ WaitMode = SampleWait_Zeroes;
+ MatchCount = 0;
+ FrameIndex = 0;
+ }
+ }
+}
+
+
+void FrameLatencyTracker::MatchRecord(const Util::FrameTimeRecordSet &r)
+{
+ if (!TrackerEnabled)
+ return;
+
+ if (WaitMode == SampleWait_Zeroes)
+ {
+ // Do we have all zeros?
+ if (r.IsAllZeroes())
+ {
+ OVR_ASSERT(FrameIndex == 0);
+ WaitMode = SampleWait_Match;
+ MatchCount = 0;
+ }
+ return;
+ }
+
+ // We are in Match Mode. Wait until all colors are matched or timeout,
+ // at which point we go back to zeros.
+
+ for (int i = 0; i < FrameIndex; i++)
+ {
+ int recordIndex = 0;
+ int consecutiveMatch = 0;
+
+ OVR_ASSERT(FrameEndTimes[i].ReadbackIndex != 0);
+
+ if (r.FindReadbackIndex(&recordIndex, FrameEndTimes[i].ReadbackIndex))
+ {
+ // Advance forward to see that we have several more matches.
+ int ri = recordIndex + 1;
+ int j = i + 1;
+
+ consecutiveMatch++;
+
+ for (; (j < FrameIndex) && (ri < Util::FrameTimeRecordSet::RecordCount); j++, ri++)
+ {
+ if (r[ri].ReadbackIndex != FrameEndTimes[j].ReadbackIndex)
+ break;
+ consecutiveMatch++;
+ }
+
+ // Match at least 2 items in the row, to avoid accidentally matching color.
+ if (consecutiveMatch > 1)
+ {
+ // Record latency values for all but last samples. Keep last 2 samples
+ // for the future to simplify matching.
+ for (int q = 0; q < consecutiveMatch; q++)
+ {
+ const Util::FrameTimeRecord &scanoutFrame = r[recordIndex+q];
+ FrameTimeRecordEx &renderFrame = FrameEndTimes[i+q];
+
+ if (!renderFrame.MatchedRecord)
+ {
+ double deltaSeconds = scanoutFrame.TimeSeconds - renderFrame.TimeSeconds;
+ if (deltaSeconds > 0.0)
+ {
+ FrameDeltas.AddTimeDelta(deltaSeconds);
+ LatencyRecordTime = scanoutFrame.TimeSeconds;
+ RenderLatencySeconds = scanoutFrame.TimeSeconds - renderFrame.RenderIMUTimeSeconds;
+ TimewarpLatencySeconds = (renderFrame.TimewarpIMUTimeSeconds == 0.0) ? 0.0 :
+ (scanoutFrame.TimeSeconds - renderFrame.TimewarpIMUTimeSeconds);
+ }
+
+ renderFrame.MatchedRecord = true;
+ MatchCount++;
+ }
+ }
+
+ // Exit for.
+ break;
+ }
+ }
+ } // for ( i => FrameIndex )
+
+
+ // If we matched all frames, start over.
+ if (MatchCount == FramesTracked)
+ {
+ WaitMode = SampleWait_Zeroes;
+ MatchCount = 0;
+ FrameIndex = 0;
+ }
+}
+
+
+void FrameLatencyTracker::GetLatencyTimings(float latencies[3])
+{
+ if (ovr_GetTimeInSeconds() > (LatencyRecordTime + 2.0))
+ {
+ latencies[0] = 0.0f;
+ latencies[1] = 0.0f;
+ latencies[2] = 0.0f;
+ }
+ else
+ {
+ latencies[0] = (float)RenderLatencySeconds;
+ latencies[1] = (float)TimewarpLatencySeconds;
+ latencies[2] = (float)FrameDeltas.GetMedianTimeDelta();
+ }
+}
+
+
+//-------------------------------------------------------------------------------------
+
+FrameTimeManager::FrameTimeManager(bool vsyncEnabled)
+ : VsyncEnabled(vsyncEnabled), DynamicPrediction(true), SdkRender(false),
+ FrameTiming()
+{
+ RenderIMUTimeSeconds = 0.0;
+ TimewarpIMUTimeSeconds = 0.0;
+
+ // HACK: SyncToScanoutDelay observed close to 1 frame in video cards.
+ // Overwritten by dynamic latency measurement on DK2.
+ VSyncToScanoutDelay = 0.013f;
+ NoVSyncToScanoutDelay = 0.004f;
+}
+
+void FrameTimeManager::Init(HmdRenderInfo& renderInfo)
+{
+ // Set up prediction distances.
+ // With-Vsync timings.
+ RenderInfo = renderInfo;
+
+ ScreenSwitchingDelay = RenderInfo.Shutter.PixelSettleTime * 0.5f +
+ RenderInfo.Shutter.PixelPersistence * 0.5f;
+}
+
+void FrameTimeManager::ResetFrameTiming(unsigned frameIndex,
+ bool vsyncEnabled, bool dynamicPrediction,
+ bool sdkRender)
+{
+ VsyncEnabled = vsyncEnabled;
+ DynamicPrediction = dynamicPrediction;
+ SdkRender = sdkRender;
+
+ FrameTimeDeltas.Clear();
+ DistortionRenderTimes.Clear();
+ ScreenLatencyTracker.Reset();
+
+ FrameTiming.FrameIndex = frameIndex;
+ FrameTiming.NextFrameTime = 0.0;
+ FrameTiming.ThisFrameTime = 0.0;
+ FrameTiming.Inputs.FrameDelta = calcFrameDelta();
+ FrameTiming.Inputs.ScreenDelay = calcScreenDelay();
+ FrameTiming.Inputs.TimewarpWaitDelta = 0.0f;
+
+ LocklessTiming.SetState(FrameTiming);
+}
+
+
+double FrameTimeManager::calcFrameDelta() const
+{
+ // Timing difference between frame is tracked by FrameTimeDeltas, or
+ // is a hard-coded value of 1/FrameRate.
+ double frameDelta;
+
+ if (!VsyncEnabled)
+ {
+ frameDelta = 0.0;
+ }
+ else if (FrameTimeDeltas.GetCount() > 3)
+ {
+ frameDelta = FrameTimeDeltas.GetMedianTimeDelta();
+ if (frameDelta > (RenderInfo.Shutter.VsyncToNextVsync + 0.001))
+ frameDelta = RenderInfo.Shutter.VsyncToNextVsync;
+ }
+ else
+ {
+ frameDelta = RenderInfo.Shutter.VsyncToNextVsync;
+ }
+
+ return frameDelta;
+}
+
+
+double FrameTimeManager::calcScreenDelay() const
+{
+ double screenDelay = ScreenSwitchingDelay;
+ double measuredVSyncToScanout;
+
+ // Use real-time DK2 latency tester HW for prediction if its is working.
+ // Do sanity check under 60 ms
+ if (!VsyncEnabled)
+ {
+ screenDelay += NoVSyncToScanoutDelay;
+ }
+ else if ( DynamicPrediction &&
+ (ScreenLatencyTracker.FrameDeltas.GetCount() > 3) &&
+ (measuredVSyncToScanout = ScreenLatencyTracker.FrameDeltas.GetMedianTimeDelta(),
+ (measuredVSyncToScanout > 0.0001) && (measuredVSyncToScanout < 0.06)) )
+ {
+ screenDelay += measuredVSyncToScanout;
+ }
+ else
+ {
+ screenDelay += VSyncToScanoutDelay;
+ }
+
+ return screenDelay;
+}
+
+
+double FrameTimeManager::calcTimewarpWaitDelta() const
+{
+ // If timewarp timing hasn't been calculated, we should wait.
+ if (!VsyncEnabled)
+ return 0.0;
+
+ if (SdkRender)
+ {
+ if (NeedDistortionTimeMeasurement())
+ return 0.0;
+ return -(DistortionRenderTimes.GetMedianTimeDelta() + 0.002);
+ }
+
+ // Just a hard-coded "high" value for game-drawn code.
+ // TBD: Just return 0 and let users calculate this themselves?
+ return -0.003;
+}
+
+
+
+void FrameTimeManager::Timing::InitTimingFromInputs(const FrameTimeManager::TimingInputs& inputs,
+ HmdShutterTypeEnum shutterType,
+ double thisFrameTime, unsigned int frameIndex)
+{
+ // ThisFrameTime comes from the end of last frame, unless it it changed.
+ double nextFrameBase;
+ double frameDelta = inputs.FrameDelta;
+
+ FrameIndex = frameIndex;
+
+ ThisFrameTime = thisFrameTime;
+ NextFrameTime = ThisFrameTime + frameDelta;
+ nextFrameBase = NextFrameTime + inputs.ScreenDelay;
+ MidpointTime = nextFrameBase + frameDelta * 0.5;
+ TimewarpPointTime = (inputs.TimewarpWaitDelta == 0.0) ?
+ 0.0 : (NextFrameTime + inputs.TimewarpWaitDelta);
+
+ // Calculate absolute points in time when eye rendering or corresponding time-warp
+ // screen edges will become visible.
+ // This only matters with VSync.
+ switch(shutterType)
+ {
+ case HmdShutter_RollingTopToBottom:
+ EyeRenderTimes[0] = MidpointTime;
+ EyeRenderTimes[1] = MidpointTime;
+ TimeWarpStartEndTimes[0][0] = nextFrameBase;
+ TimeWarpStartEndTimes[0][1] = nextFrameBase + frameDelta;
+ TimeWarpStartEndTimes[1][0] = nextFrameBase;
+ TimeWarpStartEndTimes[1][1] = nextFrameBase + frameDelta;
+ break;
+ case HmdShutter_RollingLeftToRight:
+ EyeRenderTimes[0] = nextFrameBase + frameDelta * 0.25;
+ EyeRenderTimes[1] = nextFrameBase + frameDelta * 0.75;
+
+ /*
+ // TBD: MA: It is probably better if mesh sets it up per-eye.
+ // Would apply if screen is 0 -> 1 for each eye mesh
+ TimeWarpStartEndTimes[0][0] = nextFrameBase;
+ TimeWarpStartEndTimes[0][1] = MidpointTime;
+ TimeWarpStartEndTimes[1][0] = MidpointTime;
+ TimeWarpStartEndTimes[1][1] = nextFrameBase + frameDelta;
+ */
+
+ // Mesh is set up to vary from Edge of scree 0 -> 1 across both eyes
+ TimeWarpStartEndTimes[0][0] = nextFrameBase;
+ TimeWarpStartEndTimes[0][1] = nextFrameBase + frameDelta;
+ TimeWarpStartEndTimes[1][0] = nextFrameBase;
+ TimeWarpStartEndTimes[1][1] = nextFrameBase + frameDelta;
+
+ break;
+ case HmdShutter_RollingRightToLeft:
+
+ EyeRenderTimes[0] = nextFrameBase + frameDelta * 0.75;
+ EyeRenderTimes[1] = nextFrameBase + frameDelta * 0.25;
+
+ // This is *Correct* with Tom's distortion mesh organization.
+ TimeWarpStartEndTimes[0][0] = nextFrameBase ;
+ TimeWarpStartEndTimes[0][1] = nextFrameBase + frameDelta;
+ TimeWarpStartEndTimes[1][0] = nextFrameBase ;
+ TimeWarpStartEndTimes[1][1] = nextFrameBase + frameDelta;
+ break;
+ case HmdShutter_Global:
+ // TBD
+ EyeRenderTimes[0] = MidpointTime;
+ EyeRenderTimes[1] = MidpointTime;
+ TimeWarpStartEndTimes[0][0] = MidpointTime;
+ TimeWarpStartEndTimes[0][1] = MidpointTime;
+ TimeWarpStartEndTimes[1][0] = MidpointTime;
+ TimeWarpStartEndTimes[1][1] = MidpointTime;
+ break;
+ }
+}
+
+
+double FrameTimeManager::BeginFrame(unsigned frameIndex)
+{
+ RenderIMUTimeSeconds = 0.0;
+ TimewarpIMUTimeSeconds = 0.0;
+
+ // ThisFrameTime comes from the end of last frame, unless it it changed.
+ double thisFrameTime = (FrameTiming.NextFrameTime != 0.0) ?
+ FrameTiming.NextFrameTime : ovr_GetTimeInSeconds();
+
+ // We are starting to process a new frame...
+ FrameTiming.InitTimingFromInputs(FrameTiming.Inputs, RenderInfo.Shutter.Type,
+ thisFrameTime, frameIndex);
+
+ return FrameTiming.ThisFrameTime;
+}
+
+
+void FrameTimeManager::EndFrame()
+{
+ // Record timing since last frame; must be called after Present & sync.
+ FrameTiming.NextFrameTime = ovr_GetTimeInSeconds();
+ if (FrameTiming.ThisFrameTime > 0.0)
+ {
+ FrameTimeDeltas.AddTimeDelta(FrameTiming.NextFrameTime - FrameTiming.ThisFrameTime);
+ FrameTiming.Inputs.FrameDelta = calcFrameDelta();
+ }
+
+ // Write to Lock-less
+ LocklessTiming.SetState(FrameTiming);
+}
+
+
+
+// Thread-safe function to query timing for a future frame
+
+FrameTimeManager::Timing FrameTimeManager::GetFrameTiming(unsigned frameIndex)
+{
+ Timing frameTiming = LocklessTiming.GetState();
+
+ if (frameTiming.ThisFrameTime != 0.0)
+ {
+ // If timing hasn't been initialized, starting based on "now" is the best guess.
+ frameTiming.InitTimingFromInputs(frameTiming.Inputs, RenderInfo.Shutter.Type,
+ ovr_GetTimeInSeconds(), frameIndex);
+ }
+
+ else if (frameIndex > frameTiming.FrameIndex)
+ {
+ unsigned frameDelta = frameIndex - frameTiming.FrameIndex;
+ double thisFrameTime = frameTiming.NextFrameTime +
+ double(frameDelta-1) * frameTiming.Inputs.FrameDelta;
+ // Don't run away too far into the future beyond rendering.
+ OVR_ASSERT(frameDelta < 6);
+
+ frameTiming.InitTimingFromInputs(frameTiming.Inputs, RenderInfo.Shutter.Type,
+ thisFrameTime, frameIndex);
+ }
+
+ return frameTiming;
+}
+
+
+double FrameTimeManager::GetEyePredictionTime(ovrEyeType eye)
+{
+ if (VsyncEnabled)
+ {
+ return FrameTiming.EyeRenderTimes[eye];
+ }
+
+ // No VSync: Best guess for the near future
+ return ovr_GetTimeInSeconds() + ScreenSwitchingDelay + NoVSyncToScanoutDelay;
+}
+
+Posef FrameTimeManager::GetEyePredictionPose(ovrHmd hmd, ovrEyeType eye)
+{
+ double eyeRenderTime = GetEyePredictionTime(eye);
+ ovrSensorState eyeState = ovrHmd_GetSensorState(hmd, eyeRenderTime);
+
+// EyeRenderPoses[eye] = eyeState.Predicted.Pose;
+
+ // Record view pose sampling time for Latency reporting.
+ if (RenderIMUTimeSeconds == 0.0)
+ RenderIMUTimeSeconds = eyeState.Recorded.TimeInSeconds;
+
+ return eyeState.Predicted.Pose;
+}
+
+
+void FrameTimeManager::GetTimewarpPredictions(ovrEyeType eye, double timewarpStartEnd[2])
+{
+ if (VsyncEnabled)
+ {
+ timewarpStartEnd[0] = FrameTiming.TimeWarpStartEndTimes[eye][0];
+ timewarpStartEnd[1] = FrameTiming.TimeWarpStartEndTimes[eye][1];
+ return;
+ }
+
+ // Free-running, so this will be displayed immediately.
+ // Unfortunately we have no idea which bit of the screen is actually going to be displayed.
+ // TODO: guess which bit of the screen is being displayed!
+ // (e.g. use DONOTWAIT on present and see when the return isn't WASSTILLWAITING?)
+
+ // We have no idea where scan-out is currently, so we can't usefully warp the screen spatially.
+ timewarpStartEnd[0] = ovr_GetTimeInSeconds() + ScreenSwitchingDelay + NoVSyncToScanoutDelay;
+ timewarpStartEnd[1] = timewarpStartEnd[0];
+}
+
+
+void FrameTimeManager::GetTimewarpMatrices(ovrHmd hmd, ovrEyeType eyeId,
+ ovrPosef renderPose, ovrMatrix4f twmOut[2])
+{
+ if (!hmd)
+ {
+ return;
+ }
+
+ double timewarpStartEnd[2] = { 0.0, 0.0 };
+ GetTimewarpPredictions(eyeId, timewarpStartEnd);
+
+ ovrSensorState startState = ovrHmd_GetSensorState(hmd, timewarpStartEnd[0]);
+ ovrSensorState endState = ovrHmd_GetSensorState(hmd, timewarpStartEnd[1]);
+
+ if (TimewarpIMUTimeSeconds == 0.0)
+ TimewarpIMUTimeSeconds = startState.Recorded.TimeInSeconds;
+
+ Quatf quatFromStart = startState.Predicted.Pose.Orientation;
+ Quatf quatFromEnd = endState.Predicted.Pose.Orientation;
+ Quatf quatFromEye = renderPose.Orientation; //EyeRenderPoses[eyeId].Orientation;
+ quatFromEye.Invert();
+
+ Quatf timewarpStartQuat = quatFromEye * quatFromStart;
+ Quatf timewarpEndQuat = quatFromEye * quatFromEnd;
+
+ Matrix4f timewarpStart(timewarpStartQuat);
+ Matrix4f timewarpEnd(timewarpEndQuat);
+
+
+ // The real-world 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.
+ // So we need to perform a similarity transform on this delta matrix.
+ // The verbose code would look like this:
+ /*
+ Matrix4f matBasisChange;
+ matBasisChange.SetIdentity();
+ matBasisChange.M[0][0] = 1.0f;
+ matBasisChange.M[1][1] = -1.0f;
+ matBasisChange.M[2][2] = -1.0f;
+ Matrix4f matBasisChangeInv = matBasisChange.Inverted();
+ matRenderFromNow = matBasisChangeInv * matRenderFromNow * matBasisChange;
+ */
+ // ...but of course all the above is a constant transform and much more easily done.
+ // We flip the signs of the Y&Z row, then flip the signs of the Y&Z column,
+ // and of course most of the flips cancel:
+ // +++ +-- +--
+ // +++ -> flip Y&Z columns -> +-- -> flip Y&Z rows -> -++
+ // +++ +-- -++
+ timewarpStart.M[0][1] = -timewarpStart.M[0][1];
+ timewarpStart.M[0][2] = -timewarpStart.M[0][2];
+ timewarpStart.M[1][0] = -timewarpStart.M[1][0];
+ timewarpStart.M[2][0] = -timewarpStart.M[2][0];
+
+ timewarpEnd .M[0][1] = -timewarpEnd .M[0][1];
+ timewarpEnd .M[0][2] = -timewarpEnd .M[0][2];
+ timewarpEnd .M[1][0] = -timewarpEnd .M[1][0];
+ timewarpEnd .M[2][0] = -timewarpEnd .M[2][0];
+
+ twmOut[0] = timewarpStart;
+ twmOut[1] = timewarpEnd;
+}
+
+
+// Used by renderer to determine if it should time distortion rendering.
+bool FrameTimeManager::NeedDistortionTimeMeasurement() const
+{
+ if (!VsyncEnabled)
+ return false;
+ return DistortionRenderTimes.GetCount() < 10;
+}
+
+
+void FrameTimeManager::AddDistortionTimeMeasurement(double distortionTimeSeconds)
+{
+ DistortionRenderTimes.AddTimeDelta(distortionTimeSeconds);
+
+ // If timewarp timing changes based on this sample, update it.
+ double newTimewarpWaitDelta = calcTimewarpWaitDelta();
+ if (newTimewarpWaitDelta != FrameTiming.Inputs.TimewarpWaitDelta)
+ {
+ FrameTiming.Inputs.TimewarpWaitDelta = newTimewarpWaitDelta;
+ LocklessTiming.SetState(FrameTiming);
+ }
+}
+
+
+void FrameTimeManager::UpdateFrameLatencyTrackingAfterEndFrame(
+ unsigned char frameLatencyTestColor,
+ const Util::FrameTimeRecordSet& rs)
+{
+ // FrameTiming.NextFrameTime in this context (after EndFrame) is the end frame time.
+ ScreenLatencyTracker.SaveDrawColor(frameLatencyTestColor,
+ FrameTiming.NextFrameTime,
+ RenderIMUTimeSeconds,
+ TimewarpIMUTimeSeconds);
+
+ ScreenLatencyTracker.MatchRecord(rs);
+
+ // If screen delay changed, update timing.
+ double newScreenDelay = calcScreenDelay();
+ if (newScreenDelay != FrameTiming.Inputs.ScreenDelay)
+ {
+ FrameTiming.Inputs.ScreenDelay = newScreenDelay;
+ LocklessTiming.SetState(FrameTiming);
+ }
+}
+
+
+//-----------------------------------------------------------------------------------
+// ***** TimeDeltaCollector
+
+void TimeDeltaCollector::AddTimeDelta(double timeSeconds)
+{
+ // avoid adding invalid timing values
+ if(timeSeconds < 0.0f)
+ return;
+
+ if (Count == Capacity)
+ {
+ for(int i=0; i< Count-1; i++)
+ TimeBufferSeconds[i] = TimeBufferSeconds[i+1];
+ Count--;
+ }
+ TimeBufferSeconds[Count++] = timeSeconds;
+}
+
+double TimeDeltaCollector::GetMedianTimeDelta() const
+{
+ double SortedList[Capacity];
+ bool used[Capacity];
+
+ memset(used, 0, sizeof(used));
+ SortedList[0] = 0.0; // In case Count was 0...
+
+ // Probably the slowest way to find median...
+ for (int i=0; i<Count; i++)
+ {
+ double smallestDelta = 1000000.0;
+ int index = 0;
+
+ for (int j = 0; j < Count; j++)
+ {
+ if (!used[j])
+ {
+ if (TimeBufferSeconds[j] < smallestDelta)
+ {
+ smallestDelta = TimeBufferSeconds[j];
+ index = j;
+ }
+ }
+ }
+
+ // Mark as used
+ used[index] = true;
+ SortedList[i] = smallestDelta;
+ }
+
+ return SortedList[Count/2];
+}
+
+
+}} // namespace OVR::CAPI
+
diff --git a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h
new file mode 100644
index 0000000..07a2963
--- /dev/null
+++ b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.h
@@ -0,0 +1,264 @@
+/************************************************************************************
+
+Filename : CAPI_FrameTimeManager.h
+Content : Manage frame timing and pose prediction for rendering
+Created : November 30, 2013
+Authors : Volga Aksoy, Michael Antonov
+
+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_CAPI_FrameTimeManager_h
+#define OVR_CAPI_FrameTimeManager_h
+
+#include "../OVR_CAPI.h"
+#include "../Kernel/OVR_Timer.h"
+#include "../Kernel/OVR_Math.h"
+#include "../Util/Util_Render_Stereo.h"
+#include "../Util/Util_LatencyTest2.h"
+
+namespace OVR { namespace CAPI {
+
+//-------------------------------------------------------------------------------------
+
+// Helper class to collect median times between frames, so that we know
+// how long to wait.
+struct TimeDeltaCollector
+{
+ TimeDeltaCollector() : Count(0) { }
+
+ void AddTimeDelta(double timeSeconds);
+ void Clear() { Count = 0; }
+
+ double GetMedianTimeDelta() const;
+
+ double GetCount() const { return Count; }
+
+ enum { Capacity = 12 };
+private:
+ int Count;
+ double TimeBufferSeconds[Capacity];
+};
+
+
+//-------------------------------------------------------------------------------------
+// ***** FrameLatencyTracker
+
+// FrameLatencyTracker tracks frame Present to display Scan-out timing, as reported by
+// the DK2 internal latency tester pixel read-back. The computed value is used in
+// FrameTimeManager for prediction. View Render and TimeWarp to scan-out latencies are
+// also reported for debugging.
+//
+// The class operates by generating color values from GetNextDrawColor() that must
+// be rendered on the back end and then looking for matching values in FrameTimeRecordSet
+// structure as reported by HW.
+
+class FrameLatencyTracker
+{
+public:
+
+ enum { FramesTracked = Util::LT2_IncrementCount-1 };
+
+ FrameLatencyTracker();
+
+ // DrawColor == 0 is special in that it doesn't need saving of timestamp
+ unsigned char GetNextDrawColor();
+
+ void SaveDrawColor(unsigned char drawColor, double endFrameTime,
+ double renderIMUTime, double timewarpIMUTime );
+
+ void MatchRecord(const Util::FrameTimeRecordSet &r);
+
+ void GetLatencyTimings(float latencies[3]);
+
+ void Reset();
+
+public:
+
+ struct FrameTimeRecordEx : public Util::FrameTimeRecord
+ {
+ bool MatchedRecord;
+ double RenderIMUTimeSeconds;
+ double TimewarpIMUTimeSeconds;
+ };
+
+ // True if rendering read-back is enabled.
+ bool TrackerEnabled;
+
+ enum SampleWaitType {
+ SampleWait_Zeroes, // We are waiting for a record with all zeros.
+ SampleWait_Match // We are issuing & matching colors.
+ };
+
+ SampleWaitType WaitMode;
+ int MatchCount;
+ // Records of frame timings that we are trying to measure.
+ FrameTimeRecordEx FrameEndTimes[FramesTracked];
+ int FrameIndex;
+ // Median filter for (ScanoutTimeSeconds - PostPresent frame time)
+ TimeDeltaCollector FrameDeltas;
+ // Latency reporting results
+ double RenderLatencySeconds;
+ double TimewarpLatencySeconds;
+ double LatencyRecordTime;
+};
+
+
+
+//-------------------------------------------------------------------------------------
+// ***** FrameTimeManager
+
+// FrameTimeManager keeps track of rendered frame timing and handles predictions for
+// orientations and time-warp.
+
+class FrameTimeManager
+{
+public:
+ FrameTimeManager(bool vsyncEnabled = true);
+
+ // Data that affects frame timing computation.
+ struct TimingInputs
+ {
+ // Hard-coded value or dynamic as reported by FrameTimeDeltas.GetMedianTimeDelta().
+ double FrameDelta;
+ // Screen delay from present to scan-out, as potentially reported by ScreenLatencyTracker.
+ double ScreenDelay;
+ // Negative value of how many seconds before EndFrame we start timewarp. 0.0 if not used.
+ double TimewarpWaitDelta;
+
+ TimingInputs()
+ : FrameDelta(0), ScreenDelay(0), TimewarpWaitDelta(0)
+ { }
+ };
+
+ // Timing values for a specific frame.
+ struct Timing
+ {
+ TimingInputs Inputs;
+
+ // Index of a frame that started at ThisFrameTime.
+ unsigned int FrameIndex;
+ // Predicted absolute times for when this frame will show up on screen.
+ // Generally, all values will be >= NextFrameTime, since that's the time we expect next
+ // vsync to succeed.
+ double ThisFrameTime;
+ double TimewarpPointTime;
+ double NextFrameTime;
+ double MidpointTime;
+ double EyeRenderTimes[2];
+ double TimeWarpStartEndTimes[2][2];
+
+ Timing()
+ {
+ memset(this, 0, sizeof(Timing));
+ }
+
+ void InitTimingFromInputs(const TimingInputs& inputs, HmdShutterTypeEnum shutterType,
+ double thisFrameTime, unsigned int frameIndex);
+ };
+
+
+ // Called on startup to provided data on HMD timing.
+ void Init(HmdRenderInfo& renderInfo);
+
+ // Called with each new ConfigureRendering.
+ void ResetFrameTiming(unsigned frameIndex,
+ bool vsyncEnabled, bool dynamicPrediction, bool sdkRender);
+
+ void SetVsync(bool enabled) { VsyncEnabled = enabled; }
+
+ // BeginFrame returns time of the call
+ // TBD: Should this be a predicted time value instead ?
+ double BeginFrame(unsigned frameIndex);
+ void EndFrame();
+
+ // Thread-safe function to query timing for a future frame
+ Timing GetFrameTiming(unsigned frameIndex);
+
+ double GetEyePredictionTime(ovrEyeType eye);
+ Posef GetEyePredictionPose(ovrHmd hmd, ovrEyeType eye);
+
+ void GetTimewarpPredictions(ovrEyeType eye, double timewarpStartEnd[2]);
+ void GetTimewarpMatrices(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, ovrMatrix4f twmOut[2]);
+
+ // Used by renderer to determine if it should time distortion rendering.
+ bool NeedDistortionTimeMeasurement() const;
+ void AddDistortionTimeMeasurement(double distortionTimeSeconds);
+
+
+ // DK2 Lateny test interface
+
+ // Get next draw color for DK2 latency tester
+ unsigned char GetFrameLatencyTestDrawColor()
+ { return ScreenLatencyTracker.GetNextDrawColor(); }
+
+ // Must be called after EndFrame() to update latency tester timings.
+ // Must pass color reported by NextFrameColor for this frame.
+ void UpdateFrameLatencyTrackingAfterEndFrame(unsigned char frameLatencyTestColor,
+ const Util::FrameTimeRecordSet& rs);
+
+ void GetLatencyTimings(float latencies[3])
+ { return ScreenLatencyTracker.GetLatencyTimings(latencies); }
+
+
+ const Timing& GetFrameTiming() const { return FrameTiming; }
+
+private:
+
+ double calcFrameDelta() const;
+ double calcScreenDelay() const;
+ double calcTimewarpWaitDelta() const;
+
+
+ HmdRenderInfo RenderInfo;
+ // Timings are collected through a median filter, to avoid outliers.
+ TimeDeltaCollector FrameTimeDeltas;
+ TimeDeltaCollector DistortionRenderTimes;
+ FrameLatencyTracker ScreenLatencyTracker;
+
+ // Timing changes if we have no Vsync (all prediction is reduced to fixed interval).
+ bool VsyncEnabled;
+ // Set if we are rendering via the SDK, so DistortionRenderTimes is valid.
+ bool DynamicPrediction;
+ // Set if SDk is doing teh rendering.
+ bool SdkRender;
+
+ // Total frame delay due to VsyncToFirstScanline, persistence and settle time.
+ // Computed from RenderInfor.Shutter.
+ double VSyncToScanoutDelay;
+ double NoVSyncToScanoutDelay;
+ double ScreenSwitchingDelay;
+
+ // Current (or last) frame timing info. Used as a source for LocklessTiming.
+ Timing FrameTiming;
+ // TBD: Don't we need NextFrame here as well?
+ LocklessUpdater<Timing> LocklessTiming;
+
+
+ // IMU Read timings
+ double RenderIMUTimeSeconds;
+ double TimewarpIMUTimeSeconds;
+};
+
+
+}} // namespace OVR::CAPI
+
+#endif // OVR_CAPI_FrameTimeManager_h
+
+
diff --git a/LibOVR/Src/CAPI/CAPI_GlobalState.cpp b/LibOVR/Src/CAPI/CAPI_GlobalState.cpp
new file mode 100644
index 0000000..2ed1794
--- /dev/null
+++ b/LibOVR/Src/CAPI/CAPI_GlobalState.cpp
@@ -0,0 +1,142 @@
+/************************************************************************************
+
+Filename : CAPI_GlobalState.cpp
+Content : Maintains global state of the CAPI
+Created : January 24, 2014
+Authors : Michael Antonov
+
+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 "CAPI_GlobalState.h"
+
+namespace OVR { namespace CAPI {
+
+
+//-------------------------------------------------------------------------------------
+// Open Questions / Notes
+
+// 2. Detect HMDs.
+// Challenge: If we do everything through polling, it would imply we want all the devices
+// initialized. However, there may be multiple rifts, extra sensors, etc,
+// which shouldn't be allocated.
+//
+
+// How do you reset orientation Quaternion?
+// Can you change IPD?
+
+
+
+//-------------------------------------------------------------------------------------
+// ***** OVRGlobalState
+
+// Global instance
+GlobalState* GlobalState::pInstance = 0;
+
+
+GlobalState::GlobalState()
+{
+ pManager = *DeviceManager::Create();
+ // Handle the DeviceManager's messages
+ pManager->AddMessageHandler( this );
+ EnumerateDevices();
+
+ // PhoneSensors::Init();
+}
+
+GlobalState::~GlobalState()
+{
+ RemoveHandlerFromDevices();
+ OVR_ASSERT(HMDs.IsEmpty());
+}
+
+int GlobalState::EnumerateDevices()
+{
+ // Need to use separate lock for device enumeration, as pManager->GetHandlerLock()
+ // would produce deadlocks here.
+ Lock::Locker lock(&EnumerationLock);
+
+ EnumeratedDevices.Clear();
+
+ DeviceEnumerator<HMDDevice> e = pManager->EnumerateDevices<HMDDevice>();
+ while(e.IsAvailable())
+ {
+ EnumeratedDevices.PushBack(DeviceHandle(e));
+ e.Next();
+ }
+
+ return (int)EnumeratedDevices.GetSize();
+}
+
+
+HMDDevice* GlobalState::CreateDevice(int index)
+{
+ Lock::Locker lock(&EnumerationLock);
+
+ if (index >= (int)EnumeratedDevices.GetSize())
+ return 0;
+ return EnumeratedDevices[index].CreateDeviceTyped<HMDDevice>();
+}
+
+
+void GlobalState::AddHMD(HMDState* hmd)
+{
+ Lock::Locker lock(pManager->GetHandlerLock());
+ HMDs.PushBack(hmd);
+}
+void GlobalState::RemoveHMD(HMDState* hmd)
+{
+ Lock::Locker lock(pManager->GetHandlerLock());
+ hmd->RemoveNode();
+}
+
+void GlobalState::NotifyHMDs_AddDevice(DeviceType deviceType)
+{
+ Lock::Locker lock(pManager->GetHandlerLock());
+ for(HMDState* hmd = HMDs.GetFirst(); !HMDs.IsNull(hmd); hmd = hmd->pNext)
+ hmd->NotifyAddDevice(deviceType);
+}
+
+void GlobalState::OnMessage(const Message& msg)
+{
+ if (msg.Type == Message_DeviceAdded || msg.Type == Message_DeviceRemoved)
+ {
+ if (msg.pDevice == pManager)
+ {
+ const MessageDeviceStatus& statusMsg =
+ static_cast<const MessageDeviceStatus&>(msg);
+
+ if (msg.Type == Message_DeviceAdded)
+ {
+ //LogText("OnMessage DeviceAdded.\n");
+
+ // We may have added a sensor/other device; notify any HMDs that might
+ // need it to check for it later.
+ NotifyHMDs_AddDevice(statusMsg.Handle.GetType());
+ }
+ else
+ {
+ //LogText("OnMessage DeviceRemoved.\n");
+ }
+ }
+ }
+}
+
+
+}} // namespace OVR::CAPI
diff --git a/LibOVR/Src/CAPI/CAPI_GlobalState.h b/LibOVR/Src/CAPI/CAPI_GlobalState.h
new file mode 100644
index 0000000..54ab8cc
--- /dev/null
+++ b/LibOVR/Src/CAPI/CAPI_GlobalState.h
@@ -0,0 +1,84 @@
+/************************************************************************************
+
+Filename : CAPI_GlobalState.h
+Content : Maintains global state of the CAPI
+Created : January 24, 2013
+Authors : Michael Antonov
+
+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_CAPI_GlobalState_h
+#define OVR_CAPI_GlobalState_h
+
+#include "../OVR_CAPI.h"
+#include "../OVR_Device.h"
+#include "../Kernel/OVR_Timer.h"
+#include "../Kernel/OVR_Math.h"
+
+#include "CAPI_HMDState.h"
+
+namespace OVR { namespace CAPI {
+
+//-------------------------------------------------------------------------------------
+// ***** OVRGlobalState
+
+// Global DeviceManager state - singleton instance of this is created
+// by ovr_Initialize().
+class GlobalState : public MessageHandler, public NewOverrideBase
+{
+public:
+ GlobalState();
+ ~GlobalState();
+
+ static GlobalState *pInstance;
+
+ int EnumerateDevices();
+ HMDDevice* CreateDevice(int index);
+
+ // MessageHandler implementation
+ void OnMessage(const Message& msg);
+
+ // Helpers used to keep track of HMDs and notify them of sensor changes.
+ void AddHMD(HMDState* hmd);
+ void RemoveHMD(HMDState* hmd);
+ void NotifyHMDs_AddDevice(DeviceType deviceType);
+
+ const char* GetLastError()
+ {
+ return 0;
+ }
+
+ DeviceManager* GetManager() { return pManager; }
+
+protected:
+
+ Ptr<DeviceManager> pManager;
+ Lock EnumerationLock;
+ Array<DeviceHandle> EnumeratedDevices;
+
+ // Currently created hmds; protected by Manager lock.
+ List<HMDState> HMDs;
+};
+
+}} // namespace OVR::CAPI
+
+#endif
+
+
diff --git a/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp b/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp
new file mode 100644
index 0000000..bdfa0c7
--- /dev/null
+++ b/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp
@@ -0,0 +1,147 @@
+/************************************************************************************
+
+Filename : OVR_CAPI_HMDRenderState.cpp
+Content : Combines all of the rendering state associated with the HMD
+Created : February 2, 2014
+Authors : Michael Antonov
+
+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 "CAPI_HMDRenderState.h"
+
+
+namespace OVR { namespace CAPI {
+
+
+
+//-------------------------------------------------------------------------------------
+// ***** HMDRenderState
+
+
+HMDRenderState::HMDRenderState(ovrHmd hmd, Profile* userProfile, const OVR::HMDInfo& hmdInfo)
+ : HMD(hmd), HMDInfo(hmdInfo)
+{
+ RenderInfo = GenerateHmdRenderInfoFromHmdInfo( HMDInfo, userProfile );
+
+ Distortion[0] = CalculateDistortionRenderDesc(StereoEye_Left, RenderInfo, 0);
+ Distortion[1] = CalculateDistortionRenderDesc(StereoEye_Right, RenderInfo, 0);
+
+ ClearColor[0] = ClearColor[1] = ClearColor[2] = ClearColor[3] =0.0f;
+}
+
+HMDRenderState::~HMDRenderState()
+{
+
+}
+
+
+ovrHmdDesc HMDRenderState::GetDesc()
+{
+ ovrHmdDesc d;
+ memset(&d, 0, sizeof(d));
+
+ d.Type = ovrHmd_Other;
+
+ d.ProductName = HMDInfo.ProductName;
+ d.Manufacturer = HMDInfo.Manufacturer;
+ d.Resolution.w = HMDInfo.ResolutionInPixels.w;
+ d.Resolution.h = HMDInfo.ResolutionInPixels.h;
+ d.WindowsPos.x = HMDInfo.DesktopX;
+ d.WindowsPos.y = HMDInfo.DesktopY;
+ d.DisplayDeviceName = HMDInfo.DisplayDeviceName;
+ d.DisplayId = HMDInfo.DisplayId;
+
+ d.Caps = ovrHmdCap_YawCorrection | ovrHmdCap_Orientation | ovrHmdCap_Present;
+
+ if (strstr(HMDInfo.ProductName, "DK1"))
+ {
+ d.Type = ovrHmd_DK1;
+ }
+ else if (strstr(HMDInfo.ProductName, "DK2"))
+ {
+ d.Type = ovrHmd_DK2;
+ d.Caps |= ovrHmdCap_Position | ovrHmdCap_LowPersistence;
+ }
+
+ DistortionRenderDesc& leftDistortion = Distortion[0];
+ DistortionRenderDesc& rightDistortion = Distortion[1];
+
+ // The suggested FOV (assuming eye rotation)
+ d.DefaultEyeFov[0] = CalculateFovFromHmdInfo(StereoEye_Left, leftDistortion, RenderInfo, OVR_DEFAULT_EXTRA_EYE_ROTATION);
+ d.DefaultEyeFov[1] = CalculateFovFromHmdInfo(StereoEye_Right, rightDistortion, RenderInfo, OVR_DEFAULT_EXTRA_EYE_ROTATION);
+
+ // FOV extended across the entire screen
+ d.MaxEyeFov[0] = GetPhysicalScreenFov(StereoEye_Left, leftDistortion);
+ d.MaxEyeFov[1] = GetPhysicalScreenFov(StereoEye_Right, rightDistortion);
+
+ if (HMDInfo.Shutter.Type == HmdShutter_RollingRightToLeft)
+ {
+ d.EyeRenderOrder[0] = ovrEye_Right;
+ d.EyeRenderOrder[1] = ovrEye_Left;
+ }
+ else
+ {
+ d.EyeRenderOrder[0] = ovrEye_Left;
+ d.EyeRenderOrder[1] = ovrEye_Right;
+ }
+
+ return d;
+}
+
+
+ovrSizei HMDRenderState::GetFOVTextureSize(int eye, ovrFovPort fov, float pixelsPerDisplayPixel)
+{
+ OVR_ASSERT((unsigned)eye < 2);
+ StereoEye seye = (eye == ovrEye_Left) ? StereoEye_Left : StereoEye_Right;
+ return CalculateIdealPixelSize(seye, Distortion[eye], fov, pixelsPerDisplayPixel);
+}
+
+ovrEyeRenderDesc HMDRenderState::calcRenderDesc(const ovrEyeDesc& eyeDesc)
+{
+ HmdRenderInfo& hmdri = RenderInfo;
+ StereoEye eye = (eyeDesc.Eye == ovrEye_Left) ? StereoEye_Left : StereoEye_Right;
+ ovrEyeRenderDesc e0;
+
+ e0.Desc = eyeDesc;
+ 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] )
+{
+ eyeRenderDescOut[0] = EyeRenderDesc[0] = calcRenderDesc(eyeDescIn[0]);
+ eyeRenderDescOut[1] = EyeRenderDesc[1] = calcRenderDesc(eyeDescIn[1]);
+}
+
+
+}} // namespace OVR::CAPI
+
diff --git a/LibOVR/Src/CAPI/CAPI_HMDRenderState.h b/LibOVR/Src/CAPI/CAPI_HMDRenderState.h
new file mode 100644
index 0000000..408af51
--- /dev/null
+++ b/LibOVR/Src/CAPI/CAPI_HMDRenderState.h
@@ -0,0 +1,93 @@
+/************************************************************************************
+
+Filename : CAPI_HMDRenderState.h
+Content : Combines all of the rendering state associated with the HMD
+Created : February 2, 2014
+Authors : Michael Antonov
+
+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_CAPI_HMDRenderState_h
+#define OVR_CAPI_HMDRenderState_h
+
+#include "../OVR_CAPI.h"
+#include "../Kernel/OVR_Math.h"
+#include "../Util/Util_Render_Stereo.h"
+
+
+namespace OVR { namespace CAPI {
+
+using namespace OVR::Util::Render;
+
+//-------------------------------------------------------------------------------------
+// ***** HMDRenderState
+
+// Combines all of the rendering setup information about one HMD.
+
+class HMDRenderState : public NewOverrideBase
+{
+ // Quiet assignment compiler warning.
+ void operator = (const HMDRenderState&) { }
+public:
+
+ HMDRenderState(ovrHmd hmd, Profile* userProfile, const OVR::HMDInfo& hmdInfo);
+ virtual ~HMDRenderState();
+
+
+ // *** Rendering Setup
+
+ // Delegated access APIs
+ ovrHmdDesc GetDesc();
+ ovrSizei GetFOVTextureSize(int eye, ovrFovPort fov, float pixelsPerDisplayPixel);
+
+ ovrEyeRenderDesc calcRenderDesc(const ovrEyeDesc& eyeDesc);
+
+ void setupRenderDesc(ovrEyeRenderDesc eyeRenderDescOut[2],
+ const ovrEyeDesc eyeDescIn[2]);
+public:
+
+ // HMDInfo shouldn't change, as its string pointers are passed out.
+ ovrHmd HMD;
+ const OVR::HMDInfo& HMDInfo;
+
+ //const char* pLastError;
+
+ HmdRenderInfo RenderInfo;
+ DistortionRenderDesc Distortion[2];
+ ovrEyeRenderDesc EyeRenderDesc[2];
+
+ // Clear color used for distortion
+ float ClearColor[4];
+
+ // Pose at which last time the eye was rendered, as submitted by EndEyeRender.
+ ovrPosef EyeRenderPoses[2];
+
+ // Capabilities passed to Configure.
+ unsigned HMDCaps;
+ unsigned DistortionCaps;
+};
+
+
+}} // namespace OVR::CAPI
+
+
+#endif // OVR_CAPI_HMDState_h
+
+
diff --git a/LibOVR/Src/CAPI/CAPI_HMDState.cpp b/LibOVR/Src/CAPI/CAPI_HMDState.cpp
new file mode 100644
index 0000000..156b84a
--- /dev/null
+++ b/LibOVR/Src/CAPI/CAPI_HMDState.cpp
@@ -0,0 +1,774 @@
+/************************************************************************************
+
+Filename : CAPI_HMDState.cpp
+Content : State associated with a single HMD
+Created : January 24, 2014
+Authors : Michael Antonov
+
+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 "CAPI_HMDState.h"
+#include "CAPI_GlobalState.h"
+#include "../OVR_Profile.h"
+
+namespace OVR { namespace CAPI {
+
+//-------------------------------------------------------------------------------------
+// ***** HMDState
+
+
+HMDState::HMDState(HMDDevice* device)
+ : pHMD(device), HMDInfoW(device), HMDInfo(HMDInfoW.h),
+ SensorStarted(0), SensorCreated(0), SensorCaps(0),
+ AddSensorCount(0), AddLatencyTestCount(0), AddLatencyTestDisplayCount(0),
+ RenderState(getThis(), pHMD->GetProfile(), HMDInfoW.h),
+ LastFrameTimeSeconds(0.0f), LastGetFrameTimeSeconds(0.0),
+ LatencyTestActive(false),
+ LatencyTest2Active(false)
+{
+ pLastError = 0;
+ GlobalState::pInstance->AddHMD(this);
+
+ // Should be in renderer?
+ TimeManager.Init(RenderState.RenderInfo);
+
+ EyeRenderActive[0] = false;
+ EyeRenderActive[1] = false;
+
+ LatencyTestDrawColor[0] = 0;
+ LatencyTestDrawColor[1] = 0;
+ LatencyTestDrawColor[2] = 0;
+
+ OVR_CAPI_VISION_CODE( pPoseTracker = 0; )
+
+ RenderingConfigured = false;
+ BeginFrameCalled = false;
+ BeginFrameThreadId = 0;
+ BeginFrameTimingCalled = false;
+}
+
+HMDState::HMDState(ovrHmdType hmdType)
+ : pHMD(0), HMDInfoW(hmdType), HMDInfo(HMDInfoW.h),
+ SensorStarted(0), SensorCreated(0), SensorCaps(0),
+ AddSensorCount(0), AddLatencyTestCount(0), AddLatencyTestDisplayCount(0),
+ RenderState(getThis(), 0, HMDInfoW.h), // No profile.
+ LastFrameTimeSeconds(0.0), LastGetFrameTimeSeconds(0.0)
+{
+ // TBD: We should probably be looking up the default profile for the given
+ // device type + user.
+
+ pLastError = 0;
+ GlobalState::pInstance->AddHMD(this);
+
+ // Should be in renderer?
+ TimeManager.Init(RenderState.RenderInfo);
+
+ EyeRenderActive[0] = false;
+ EyeRenderActive[1] = false;
+
+ OVR_CAPI_VISION_CODE( pPoseTracker = 0; )
+
+ RenderingConfigured = false;
+ BeginFrameCalled = false;
+ BeginFrameThreadId = 0;
+ BeginFrameTimingCalled = false;
+}
+
+
+HMDState::~HMDState()
+{
+ OVR_ASSERT(GlobalState::pInstance);
+
+ StopSensor();
+ ConfigureRendering(0,0,0,0,0);
+
+ OVR_CAPI_VISION_CODE( OVR_ASSERT(pPoseTracker == 0); )
+
+ GlobalState::pInstance->RemoveHMD(this);
+}
+
+
+//-------------------------------------------------------------------------------------
+// *** Sensor
+
+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;
+
+ // 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 (HMDInfo.HmdType != HmdType_CrystalCoveProto && HMDInfo.HmdType != HmdType_DK2)
+ {
+ pLastError = "ovrHmdCap_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;
+ }
+ }
+
+
+ SensorCreated = false;
+ pSensor.Clear();
+ if (pHMD)
+ {
+ // 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();
+ }
+
+ if (!pSensor)
+ {
+ if (requiredCaps & ovrHmdCap_Orientation)
+ {
+ 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)
+ {
+ if (!SFusion.HasMagCalibration())
+ {
+ pLastError = "ovrHmdCap_YawCorrection not available.";
+ SFusion.AttachToSensor(0);
+ SFusion.Reset();
+ pSensor.Clear();
+ 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)
+ {
+ updateLatencyTestForHmd((supportedCaps & ovrHmdCap_LatencyTest) != 0);
+ }
+
+#ifdef OVR_CAPI_VISIONSUPPORT
+ if (supportedCaps & ovrHmdCap_Position)
+ {
+ pPoseTracker = new Vision::PoseTracker(SFusion);
+ if (pPoseTracker)
+ {
+ pPoseTracker->AssociateHMD(pSensor);
+ }
+ LogText("Sensor Pose tracker created.\n");
+ }
+ // TBD: How do we verify that position tracking is actually available
+ // i.e. camera is plugged in?
+
+#endif // OVR_CAPI_VISIONSUPPORT
+
+ SensorCreated = true;
+ }
+
+ SensorCaps = supportedCaps;
+ SensorStarted = true;
+
+ return true;
+}
+
+
+// Stops sensor sampling, shutting down internal resources.
+void HMDState::StopSensor()
+{
+ Lock::Locker lockScope(&DevicesLock);
+
+ if (SensorStarted)
+ {
+#ifdef OVR_CAPI_VISIONSUPPORT
+ if (pPoseTracker)
+ {
+ // TBD: Internals not thread safe - must fix!!
+ delete pPoseTracker;
+ pPoseTracker = 0;
+ LogText("Sensor Pose tracker destroyed.\n");
+ }
+#endif // OVR_CAPI_VISION_CODE
+
+ SFusion.AttachToSensor(0);
+ SFusion.Reset();
+ pSensor.Clear();
+ AddSensorCount = 0;
+ SensorCaps = 0;
+ SensorCreated = false;
+ SensorStarted = false;
+
+ LogText("StopSensor succeeded.\n");
+ }
+}
+
+// Resets sensor orientation.
+void HMDState::ResetSensor()
+{
+ SFusion.Reset();
+}
+
+
+// Returns prediction for time.
+ovrSensorState HMDState::PredictedSensorState(double absTime)
+{
+ SensorState ss;
+
+ // We are trying to keep this path lockless unless we are notified of new device
+ // creation while not having a sensor yet. It's ok to check SensorCreated volatile
+ // flag here, since GetSensorStateAtTime() is internally lockless and safe.
+
+ if (SensorCreated || checkCreateSensor())
+ {
+ ss = SFusion.GetSensorStateAtTime(absTime);
+
+ if (!(ss.StatusFlags & ovrStatus_OrientationTracked))
+ {
+ Lock::Locker lockScope(&DevicesLock);
+
+#ifdef OVR_CAPI_VISIONSUPPORT
+ if (pPoseTracker)
+ {
+ // TBD: Internals not thread safe - must fix!!
+ delete pPoseTracker;
+ pPoseTracker = 0;
+ LogText("Sensor Pose tracker destroyed.\n");
+ }
+#endif // OVR_CAPI_VISION_CODE
+ // Not needed yet; SFusion.AttachToSensor(0);
+ // This seems to reset orientation anyway...
+ pSensor.Clear();
+ SensorCreated = false;
+ }
+ }
+ else
+ {
+ // SensorState() defaults to 0s.
+ // ss.Pose.Orientation = Quatf();
+ // ..
+
+ // John:
+ // We still want valid times so frames will get a delta-time
+ // and allow operation with a joypad when the sensor isn't
+ // connected.
+ ss.Recorded.TimeInSeconds = absTime;
+ ss.Predicted.TimeInSeconds = absTime;
+ }
+
+ ss.StatusFlags |= ovrStatus_HmdConnected;
+ return ss;
+}
+
+
+bool HMDState::checkCreateSensor()
+{
+ if (!(SensorStarted && !SensorCreated && AddSensorCount))
+ return false;
+
+ Lock::Locker lockScope(&DevicesLock);
+
+ // Re-check condition once in the lock, in case the state changed.
+ if (SensorStarted && !SensorCreated && AddSensorCount)
+ {
+ if (pHMD)
+ {
+ AddSensorCount = 0;
+ pSensor = *pHMD->GetSensor();
+ }
+
+ if (pSensor)
+ {
+ pSensor->SetReportRate(500);
+ SFusion.AttachToSensor(pSensor);
+ SFusion.SetYawCorrectionEnabled((SensorCaps & ovrHmdCap_YawCorrection) != 0);
+ applyProfileToSensorFusion();
+
+#ifdef OVR_CAPI_VISIONSUPPORT
+ if (SensorCaps & ovrHmdCap_Position)
+ {
+ pPoseTracker = new Vision::PoseTracker(SFusion);
+ if (pPoseTracker)
+ {
+ pPoseTracker->AssociateHMD(pSensor);
+ }
+ LogText("Sensor Pose tracker created.\n");
+ }
+#endif // OVR_CAPI_VISION_CODE
+
+ LogText("Sensor created.\n");
+
+ SensorCreated = true;
+ return true;
+ }
+ }
+
+ return SensorCreated;
+}
+
+bool HMDState::GetSensorDesc(ovrSensorDesc* descOut)
+{
+ Lock::Locker lockScope(&DevicesLock);
+
+ if (SensorCreated)
+ {
+ OVR_ASSERT(pSensor);
+ OVR::SensorInfo si;
+ pSensor->GetDeviceInfo(&si);
+ descOut->VendorId = si.VendorId;
+ descOut->ProductId = si.ProductId;
+ OVR_ASSERT(si.SerialNumber.GetSize() <= sizeof(descOut->SerialNumber));
+ OVR_strcpy(descOut->SerialNumber, sizeof(descOut->SerialNumber), si.SerialNumber.ToCStr());
+ return true;
+ }
+ return false;
+}
+
+
+void HMDState::applyProfileToSensorFusion()
+{
+ Profile* profile = pHMD ? pHMD->GetProfile() : 0;
+ SFusion.SetUserHeadDimensions ( profile, RenderState.RenderInfo );
+}
+
+void HMDState::updateLowPersistenceMode(bool lowPersistence) const
+{
+ OVR_ASSERT(pSensor);
+ DisplayReport dr;
+ pSensor->GetDisplayReport(&dr);
+
+ dr.Persistence = (UInt16) (dr.TotalRows * (lowPersistence ? 0.18f : 1.0f));
+ dr.Brightness = lowPersistence ? 255 : 0;
+
+ pSensor->SetDisplayReport(dr);
+}
+
+void HMDState::updateLatencyTestForHmd(bool latencyTesting)
+{
+ if (pSensor.GetPtr())
+ {
+ DisplayReport dr;
+ pSensor->GetDisplayReport(&dr);
+
+ dr.ReadPixel = latencyTesting;
+
+ pSensor->SetDisplayReport(dr);
+ }
+
+ if (latencyTesting)
+ {
+ LatencyUtil2.SetSensorDevice(pSensor.GetPtr());
+ }
+ else
+ {
+ LatencyUtil2.SetSensorDevice(NULL);
+ }
+}
+
+//-------------------------------------------------------------------------------------
+// ***** Property Access
+
+// TBD: This all needs to be cleaned up and organized into namespaces.
+
+float HMDState::getFloatValue(const char* propertyName, float defaultVal)
+{
+ if (OVR_strcmp(propertyName, "LensSeparation") == 0)
+ {
+ return HMDInfo.LensSeparationInMeters;
+ }
+ else if (OVR_strcmp(propertyName, "CenterPupilDepth") == 0)
+ {
+ return SFusion.GetCenterPupilDepth();
+ }
+ else if (pHMD)
+ {
+ Profile* p = pHMD->GetProfile();
+ if (p)
+ {
+ return p->GetFloatValue(propertyName, defaultVal);
+ }
+ }
+ return defaultVal;
+}
+
+bool HMDState::setFloatValue(const char* propertyName, float value)
+{
+ if (OVR_strcmp(propertyName, "CenterPupilDepth") == 0)
+ {
+ SFusion.SetCenterPupilDepth(value);
+ return true;
+ }
+ return false;
+}
+
+
+static unsigned CopyFloatArrayWithLimit(float dest[], unsigned destSize,
+ float source[], unsigned sourceSize)
+{
+ unsigned count = Alg::Min(destSize, sourceSize);
+ for (unsigned i = 0; i < count; i++)
+ dest[i] = source[i];
+ return count;
+}
+
+
+unsigned HMDState::getFloatArray(const char* propertyName, float values[], unsigned arraySize)
+{
+ if (arraySize)
+ {
+ if (OVR_strcmp(propertyName, "ScreenSize") == 0)
+ {
+ float data[2] = { HMDInfo.ScreenSizeInMeters.w, HMDInfo.ScreenSizeInMeters.h };
+
+ return CopyFloatArrayWithLimit(values, arraySize, data, 2);
+ }
+ else if (OVR_strcmp(propertyName, "DistortionClearColor") == 0)
+ {
+ return CopyFloatArrayWithLimit(values, arraySize, RenderState.ClearColor, 4);
+ }
+ else if (OVR_strcmp(propertyName, "DK2Latency") == 0)
+ {
+ if (HMDInfo.HmdType != HmdType_DK2)
+ return 0;
+
+ float data[3];
+ TimeManager.GetLatencyTimings(data);
+
+ return CopyFloatArrayWithLimit(values, arraySize, data, 3);
+ }
+
+ /*
+ else if (OVR_strcmp(propertyName, "CenterPupilDepth") == 0)
+ {
+ if (arraySize >= 1)
+ {
+ values[0] = SFusion.GetCenterPupilDepth();
+ return 1;
+ }
+ return 0;
+ } */
+ else if (pHMD)
+ {
+ Profile* p = pHMD->GetProfile();
+
+ // TBD: Not quite right. Should update profile interface, so that
+ // we can return 0 in all conditions if property doesn't exist.
+ if (p)
+ {
+ unsigned count = p->GetFloatValues(propertyName, values, arraySize);
+ return count;
+ }
+ }
+ }
+
+ return 0;
+}
+
+bool HMDState::setFloatArray(const char* propertyName, float values[], unsigned arraySize)
+{
+ if (!arraySize)
+ return false;
+
+ if (OVR_strcmp(propertyName, "DistortionClearColor") == 0)
+ {
+ CopyFloatArrayWithLimit(RenderState.ClearColor, 4, values, arraySize);
+ return true;
+ }
+ return false;
+}
+
+
+const char* HMDState::getString(const char* propertyName, const char* defaultVal)
+{
+ if (pHMD)
+ {
+ // For now, just access the profile.
+ Profile* p = pHMD->GetProfile();
+
+ LastGetStringValue[0] = 0;
+ if (p && p->GetValue(propertyName, LastGetStringValue, sizeof(LastGetStringValue)))
+ {
+ return LastGetStringValue;
+ }
+ }
+
+ return defaultVal;
+}
+
+//-------------------------------------------------------------------------------------
+// *** Latency Test
+
+bool HMDState::ProcessLatencyTest(unsigned char rgbColorOut[3])
+{
+ bool result = false;
+
+ // Check create.
+ if (pLatencyTester)
+ {
+ if (pLatencyTester->IsConnected())
+ {
+ Color colorToDisplay;
+
+ LatencyUtil.ProcessInputs();
+ result = LatencyUtil.DisplayScreenColor(colorToDisplay);
+ rgbColorOut[0] = colorToDisplay.R;
+ rgbColorOut[1] = colorToDisplay.G;
+ rgbColorOut[2] = colorToDisplay.B;
+ }
+ else
+ {
+ // Disconnect.
+ LatencyUtil.SetDevice(NULL);
+ pLatencyTester = 0;
+ LogText("LATENCY SENSOR disconnected.\n");
+ }
+ }
+ else if (AddLatencyTestCount > 0)
+ {
+ // This might have some unlikely race condition issue which could cause us to miss a device...
+ AddLatencyTestCount = 0;
+
+ pLatencyTester = *GlobalState::pInstance->GetManager()->
+ EnumerateDevices<LatencyTestDevice>().CreateDevice();
+ if (pLatencyTester)
+ {
+ LatencyUtil.SetDevice(pLatencyTester);
+ LogText("LATENCY TESTER connected\n");
+ }
+ }
+
+ return result;
+}
+
+void HMDState::ProcessLatencyTest2(unsigned char rgbColorOut[3], double startTime)
+{
+ // Check create.
+ if (!(SensorCaps & ovrHmdCap_LatencyTest))
+ return;
+
+ if (pLatencyTesterDisplay && !LatencyUtil2.HasDisplayDevice())
+ {
+ if (!pLatencyTesterDisplay->IsConnected())
+ {
+ LatencyUtil2.SetDisplayDevice(NULL);
+ }
+ }
+ else if (AddLatencyTestDisplayCount > 0)
+ {
+ // This might have some unlikely race condition issue
+ // which could cause us to miss a device...
+ AddLatencyTestDisplayCount = 0;
+
+ pLatencyTesterDisplay = *GlobalState::pInstance->GetManager()->
+ EnumerateDevices<LatencyTestDevice>().CreateDevice();
+ if (pLatencyTesterDisplay)
+ {
+ LatencyUtil2.SetDisplayDevice(pLatencyTesterDisplay);
+ }
+ }
+
+ if (LatencyUtil2.HasDevice() && pSensor && pSensor->IsConnected())
+ {
+ LatencyUtil2.BeginTest(startTime);
+
+ Color colorToDisplay;
+ LatencyTest2Active = LatencyUtil2.DisplayScreenColor(colorToDisplay);
+ rgbColorOut[0] = colorToDisplay.R;
+ rgbColorOut[1] = colorToDisplay.G;
+ rgbColorOut[2] = colorToDisplay.B;
+ }
+ else
+ {
+ LatencyTest2Active = false;
+ }
+}
+
+//-------------------------------------------------------------------------------------
+// *** Rendering
+
+bool HMDState::ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2],
+ const ovrEyeDesc eyeDescIn[2],
+ const ovrRenderAPIConfig* apiConfig,
+ unsigned hmdCaps,
+ unsigned distortionCaps)
+{
+ ThreadChecker::Scope checkScope(&RenderAPIThreadChecker, "ovrHmd_ConfigureRendering");
+
+ // null -> shut down.
+ if (!apiConfig)
+ {
+ if (pRenderer)
+ pRenderer.Clear();
+ RenderingConfigured = false;
+ return true;
+ }
+
+ if (pRenderer &&
+ (apiConfig->Header.API != pRenderer->GetRenderAPI()))
+ {
+ // Shutdown old renderer.
+ if (pRenderer)
+ pRenderer.Clear();
+ }
+
+
+ // Step 1: do basic setup configuration
+ RenderState.setupRenderDesc(eyeRenderDescOut, eyeDescIn);
+ RenderState.HMDCaps = hmdCaps; // Any cleaner way?
+ RenderState.DistortionCaps = distortionCaps;
+
+ TimeManager.ResetFrameTiming(0,
+ (hmdCaps & ovrHmdCap_NoVSync) ? false : true,
+ (hmdCaps & ovrHmdCap_DynamicPrediction) ? true : false,
+ true);
+
+ LastFrameTimeSeconds = 0.0f;
+
+ // Set RenderingConfigured early to avoid ASSERTs in renderer initialization.
+ RenderingConfigured = true;
+
+ if (!pRenderer)
+ {
+ pRenderer = *DistortionRenderer::APICreateRegistry
+ [apiConfig->Header.API](this, TimeManager, RenderState);
+ }
+
+ if (!pRenderer ||
+ !pRenderer->Initialize(apiConfig, hmdCaps, distortionCaps))
+ {
+ RenderingConfigured = false;
+ return false;
+ }
+
+ return true;
+}
+
+
+
+ovrPosef HMDState::BeginEyeRender(ovrEyeType eye)
+{
+ // Debug checks.
+ checkBeginFrameScope("ovrHmd_BeginEyeRender");
+ ThreadChecker::Scope checkScope(&RenderAPIThreadChecker, "ovrHmd_BeginEyeRender");
+
+ // Unknown eyeId provided in ovrHmd_BeginEyeRender
+ OVR_ASSERT_LOG(eye == ovrEye_Left || eye == ovrEye_Right,
+ ("ovrHmd_BeginEyeRender eyeId out of range."));
+ OVR_ASSERT_LOG(EyeRenderActive[eye] == false,
+ ("Multiple calls to ovrHmd_BeginEyeRender for the same eye."));
+
+ EyeRenderActive[eye] = true;
+
+ // Only process latency tester for drawing the left eye (assumes left eye is drawn first)
+ if (pRenderer && eye == 0)
+ {
+ LatencyTestActive = ProcessLatencyTest(LatencyTestDrawColor);
+ }
+
+ return ovrHmd_GetEyePose(this, eye);
+}
+
+
+void HMDState::EndEyeRender(ovrEyeType eye, ovrPosef renderPose, ovrTexture* eyeTexture)
+{
+ // Debug checks.
+ checkBeginFrameScope("ovrHmd_EndEyeRender");
+ ThreadChecker::Scope checkScope(&RenderAPIThreadChecker, "ovrHmd_EndEyeRender");
+
+ if (!EyeRenderActive[eye])
+ {
+ OVR_ASSERT_LOG(false,
+ ("ovrHmd_EndEyeRender called without ovrHmd_BeginEyeRender."));
+ return;
+ }
+
+ RenderState.EyeRenderPoses[eye] = renderPose;
+
+ if (pRenderer)
+ pRenderer->SubmitEye(eye, eyeTexture);
+
+ EyeRenderActive[eye] = false;
+}
+
+}} // namespace OVR::CAPI
+
diff --git a/LibOVR/Src/CAPI/CAPI_HMDState.h b/LibOVR/Src/CAPI/CAPI_HMDState.h
new file mode 100644
index 0000000..d178042
--- /dev/null
+++ b/LibOVR/Src/CAPI/CAPI_HMDState.h
@@ -0,0 +1,334 @@
+/************************************************************************************
+
+Filename : CAPI_HMDState.h
+Content : State associated with a single HMD
+Created : January 24, 2014
+Authors : Michael Antonov
+
+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_CAPI_HMDState_h
+#define OVR_CAPI_HMDState_h
+
+#include "../Kernel/OVR_Math.h"
+#include "../Kernel/OVR_List.h"
+#include "../Kernel/OVR_Log.h"
+#include "../OVR_CAPI.h"
+#include "../OVR_SensorFusion.h"
+#include "../Util/Util_LatencyTest.h"
+#include "../Util/Util_LatencyTest2.h"
+
+#include "CAPI_FrameTimeManager.h"
+#include "CAPI_HMDRenderState.h"
+#include "CAPI_DistortionRenderer.h"
+
+// Define OVR_CAPI_VISIONSUPPORT to compile in vision support
+#ifdef OVR_CAPI_VISIONSUPPORT
+ #define OVR_CAPI_VISION_CODE(c) c
+ #include "../Vision/Vision_PoseTracker.h"
+#else
+ #define OVR_CAPI_VISION_CODE(c)
+#endif
+
+
+struct ovrHmdStruct { };
+
+namespace OVR { namespace CAPI {
+
+using namespace OVR::Util::Render;
+
+
+//-------------------------------------------------------------------------------------
+// ***** ThreadChecker
+
+// This helper class is used to verify that the API is used according to supported
+// thread safety constraints (is not re-entrant for this and related functions).
+class ThreadChecker
+{
+public:
+
+#ifndef OVR_BUILD_DEBUG
+
+ // In release build, thread checks are disabled.
+ ThreadChecker() { }
+ void Begin(const char* functionName) { OVR_UNUSED1(functionName); }
+ void End() { }
+
+ // Add thread-re-entrancy check for function scope
+ struct Scope
+ {
+ Scope(ThreadChecker*, const char *) { }
+ ~Scope() { }
+ };
+
+
+#else // OVR_BUILD_DEBUG
+ ThreadChecker() : pFunctionName(0), FirstThread(0)
+ { }
+
+ void Begin(const char* functionName)
+ {
+ if (!pFunctionName)
+ {
+ pFunctionName = functionName;
+ FirstThread = GetCurrentThreadId();
+ }
+ else
+ {
+ // 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",
+ functionName, GetCurrentThreadId(), pFunctionName, FirstThread) );
+ }
+ }
+ void End()
+ {
+ pFunctionName = 0;
+ FirstThread = 0;
+ }
+
+ // Add thread-re-entrancy check for function scope.
+ struct Scope
+ {
+ Scope(ThreadChecker* threadChecker, const char *functionName) : pChecker(threadChecker)
+ { pChecker->Begin(functionName); }
+ ~Scope()
+ { pChecker->End(); }
+ private:
+ ThreadChecker* pChecker;
+ };
+
+private:
+ // If not 0, contains the name of the function that first entered the scope.
+ const char * pFunctionName;
+ ThreadId FirstThread;
+
+#endif // OVR_BUILD_DEBUG
+};
+
+
+//-------------------------------------------------------------------------------------
+// ***** HMDState
+
+// Describes a single HMD.
+class HMDState : public ListNode<HMDState>,
+ public ovrHmdStruct, public NewOverrideBase
+{
+public:
+
+ HMDState(HMDDevice* device);
+ HMDState(ovrHmdType hmdType);
+ virtual ~HMDState();
+
+
+ // *** Sensor Setup
+
+ bool StartSensor(unsigned supportedCaps, unsigned requiredCaps);
+ void StopSensor();
+ void ResetSensor();
+ ovrSensorState PredictedSensorState(double absTime);
+ bool GetSensorDesc(ovrSensorDesc* descOut);
+
+ bool ProcessLatencyTest(unsigned char rgbColorOut[3]);
+ void ProcessLatencyTest2(unsigned char rgbColorOut[3], double startTime);
+
+
+ // *** Rendering Setup
+
+ bool ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2],
+ const ovrEyeDesc eyeDescIn[2],
+ const ovrRenderAPIConfig* apiConfig,
+ unsigned hmdCaps,
+ unsigned distortionCaps);
+
+ ovrPosef BeginEyeRender(ovrEyeType eye);
+ void EndEyeRender(ovrEyeType eye, ovrPosef renderPose, ovrTexture* eyeTexture);
+
+
+ const char* GetLastError()
+ {
+ const char* p = pLastError;
+ pLastError = 0;
+ return p;
+ }
+
+ void NotifyAddDevice(DeviceType deviceType)
+ {
+ if (deviceType == Device_Sensor)
+ AddSensorCount++;
+ else if (deviceType == Device_LatencyTester)
+ {
+ AddLatencyTestCount++;
+ AddLatencyTestDisplayCount++;
+ }
+ }
+
+ bool checkCreateSensor();
+
+ void applyProfileToSensorFusion();
+
+ // INlines so that they can be easily compiled out.
+ // Does debug ASSERT checks for functions that require BeginFrame.
+ // Also verifies that we are on the right thread.
+ void checkBeginFrameScope(const char* functionName)
+ {
+ OVR_UNUSED1(functionName); // for Release build.
+ OVR_ASSERT_LOG(BeginFrameCalled == true,
+ ("%s called outside ovrHmd_BeginFrame."));
+ OVR_ASSERT_LOG(BeginFrameThreadId == OVR::GetCurrentThreadId(),
+ ("%s called on a different thread then ovrHmd_BeginFrame."));
+ }
+
+ void checkRenderingConfigured(const char* functionName)
+ {
+ OVR_UNUSED1(functionName); // for Release build.
+ OVR_ASSERT_LOG(RenderingConfigured == true,
+ ("%s called without ovrHmd_ConfigureRendering."));
+ }
+
+ void checkBeginFrameTimingScope(const char* functionName)
+ {
+ OVR_UNUSED1(functionName); // for Release build.
+ OVR_ASSERT_LOG(BeginFrameTimingCalled == true,
+ ("%s called outside ovrHmd_BeginFrameTiming."));
+ }
+
+
+ HMDState* getThis() { return this; }
+
+ void updateLowPersistenceMode(bool lowPersistence) const;
+ void updateLatencyTestForHmd(bool latencyTesting);
+
+ // Get properties by name.
+ float getFloatValue(const char* propertyName, float defaultVal);
+ bool setFloatValue(const char* propertyName, float value);
+ unsigned getFloatArray(const char* propertyName, float values[], unsigned arraySize);
+ bool setFloatArray(const char* propertyName, float values[], unsigned arraySize);
+ const char* getString(const char* propertyName, const char* defaultVal);
+public:
+
+ // Wrapper to support 'const'
+ struct HMDInfoWrapper
+ {
+ HMDInfoWrapper(ovrHmdType hmdType)
+ {
+ HmdTypeEnum t = HmdType_None;
+ if (hmdType == ovrHmd_DK1)
+ t = HmdType_DK1;
+ else if (hmdType == ovrHmd_CrystalCoveProto)
+ t = HmdType_CrystalCoveProto;
+ else if (hmdType == ovrHmd_DK2)
+ t = HmdType_DK2;
+ h = CreateDebugHMDInfo(t);
+ }
+ HMDInfoWrapper(HMDDevice* device) { if (device) device->GetDeviceInfo(&h); }
+ OVR::HMDInfo h;
+ };
+
+ // Note: pHMD can be null if we are representing a virtualized debug HMD.
+ Ptr<HMDDevice> pHMD;
+
+ // HMDInfo shouldn't change, as its string pointers are passed out.
+ const HMDInfoWrapper HMDInfoW;
+ const OVR::HMDInfo& HMDInfo;
+
+ const char* pLastError;
+
+
+ // *** Sensor
+
+ // Lock used to support thread-safe lifetime access to sensor.
+ Lock DevicesLock;
+
+ // Atomic integer used as a flag that we should check the sensor device.
+ AtomicInt<int> AddSensorCount;
+
+ // All of Sensor variables may be modified/used with DevicesLock, with exception that
+ // the {SensorStarted, SensorCreated} can be read outside the lock to see
+ // if device creation check is necessary.
+ // Whether we called StartSensor() and requested sensor caps.
+ volatile bool SensorStarted;
+ volatile bool SensorCreated;
+ // pSensor may still be null or non-running after start if it wasn't yet available
+ Ptr<SensorDevice> pSensor; // Head
+ unsigned SensorCaps;
+
+ // SensorFusion state may be accessible without a lock.
+ SensorFusion SFusion;
+
+
+ // Vision pose tracker is currently new-allocated
+ OVR_CAPI_VISION_CODE(
+ Vision::PoseTracker* pPoseTracker;
+ )
+
+ // Latency tester
+ Ptr<LatencyTestDevice> pLatencyTester;
+ Util::LatencyTest LatencyUtil;
+ AtomicInt<int> AddLatencyTestCount;
+
+ bool LatencyTestActive;
+ unsigned char LatencyTestDrawColor[3];
+
+ // Using latency tester as debug display
+ Ptr<LatencyTestDevice> pLatencyTesterDisplay;
+ AtomicInt<int> AddLatencyTestDisplayCount;
+ Util::LatencyTest2 LatencyUtil2;
+
+ bool LatencyTest2Active;
+ unsigned char LatencyTest2DrawColor[3];
+ //bool ReadbackColor;
+
+ // Rendering part
+ FrameTimeManager TimeManager;
+ HMDRenderState RenderState;
+ Ptr<DistortionRenderer> pRenderer;
+
+ // Last timing value reported by BeginFrame.
+ double LastFrameTimeSeconds;
+ // Last timing value reported by GetFrameTime. These are separate since the intended
+ // use is from different threads. TBD: Move to FrameTimeManager? Make atomic?
+ double LastGetFrameTimeSeconds;
+
+ // Last cached value returned by ovrHmd_GetString/ovrHmd_GetStringArray.
+ char LastGetStringValue[256];
+
+
+ // Debug flag set after ovrHmd_ConfigureRendering succeeds.
+ bool RenderingConfigured;
+ // Set after BeginFrame succeeds, and its corresponding thread id for debug checks.
+ bool BeginFrameCalled;
+ ThreadId BeginFrameThreadId;
+ // Graphics functions are not re-entrant from other threads.
+ ThreadChecker RenderAPIThreadChecker;
+ //
+ bool BeginFrameTimingCalled;
+
+ // Flags set when we've called BeginEyeRender on a given eye.
+ bool EyeRenderActive[2];
+};
+
+
+}} // namespace OVR::CAPI
+
+
+#endif // OVR_CAPI_HMDState_h
+
+
diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.cpp
new file mode 100644
index 0000000..d1ea4dc
--- /dev/null
+++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.cpp
@@ -0,0 +1,29 @@
+/************************************************************************************
+
+Filename : CAPI_D3D10_DistortionRenderer.cpp
+Content : Distortion renderer instantiation for D3D10
+Created : November 11, 2013
+Authors : Volga Aksoy, Michael Antonov
+
+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.
+
+************************************************************************************/
+
+#define OVR_D3D_VERSION 10
+#include "CAPI_D3D1X_Util.cpp"
+#include "CAPI_D3D1X_DistortionRenderer.cpp"
diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h
new file mode 100644
index 0000000..bb56cb4
--- /dev/null
+++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h
@@ -0,0 +1,34 @@
+/************************************************************************************
+
+Filename : CAPI_D3D10_DistortionRenderer.h
+Content : Distortion renderer header for D3D10
+Created : November 11, 2013
+Authors : Michael Antonov
+
+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 INC_CAPI_D3D10_DistortionRenderer_h
+#define INC_CAPI_D3D10_DistortionRenderer_h
+
+#define OVR_D3D_VERSION 10
+#include "CAPI_D3D1X_DistortionRenderer.h"
+#undef OVR_D3D_VERSION
+
+#endif \ No newline at end of file
diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.cpp
new file mode 100644
index 0000000..1184df8
--- /dev/null
+++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.cpp
@@ -0,0 +1,30 @@
+/************************************************************************************
+
+Filename : CAPI_D3D11_DistortionRenderer.cpp
+Content : Distortion renderer instantiation for D3D11
+Created : November 11, 2013
+Authors : Volga Aksoy, Michael Antonov
+
+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.
+
+************************************************************************************/
+
+#define OVR_D3D_VERSION 11
+#include "CAPI_D3D1X_Util.cpp"
+#include "CAPI_D3D1X_DistortionRenderer.cpp"
+
diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h
new file mode 100644
index 0000000..8b9863b
--- /dev/null
+++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h
@@ -0,0 +1,34 @@
+/************************************************************************************
+
+Filename : CAPI_D3D11_DistortionRenderer.h
+Content : Distortion renderer header for D3D11
+Created : November 11, 2013
+Authors : Michael Antonov
+
+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 INC_CAPI_D3D11_DistortionRenderer_h
+#define INC_CAPI_D3D11_DistortionRenderer_h
+
+#define OVR_D3D_VERSION 11
+#include "CAPI_D3D1X_DistortionRenderer.h"
+#undef OVR_D3D_VERSION
+
+#endif \ No newline at end of file
diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp
new file mode 100644
index 0000000..53f8948
--- /dev/null
+++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp
@@ -0,0 +1,773 @@
+/************************************************************************************
+
+Filename : CAPI_D3D1X_DistortionRenderer.cpp
+Content : Experimental distortion renderer
+Created : November 11, 2013
+Authors : Volga Aksoy, Michael Antonov
+
+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 "CAPI_D3D1X_DistortionRenderer.h"
+
+#include "../../OVR_CAPI_D3D.h"
+
+namespace OVR { namespace CAPI { namespace D3D_NS {
+
+#include "../Shaders/Distortion_vs.h"
+#include "../Shaders/Distortion_vs_refl.h"
+#include "../Shaders/Distortion_ps.h"
+#include "../Shaders/Distortion_ps_refl.h"
+#include "../Shaders/DistortionChroma_vs.h"
+#include "../Shaders/DistortionChroma_vs_refl.h"
+#include "../Shaders/DistortionChroma_ps.h"
+#include "../Shaders/DistortionChroma_ps_refl.h"
+#include "../Shaders/DistortionTimewarp_vs.h"
+#include "../Shaders/DistortionTimewarp_vs_refl.h"
+#include "../Shaders/DistortionTimewarpChroma_vs.h"
+#include "../Shaders/DistortionTimewarpChroma_vs_refl.h"
+
+#include "../Shaders/SimpleQuad_vs.h"
+#include "../Shaders/SimpleQuad_vs_refl.h"
+#include "../Shaders/SimpleQuad_ps.h"
+#include "../Shaders/SimpleQuad_ps_refl.h"
+
+// Distortion pixel shader lookup.
+// Bit 0: Chroma Correction
+// Bit 1: Timewarp
+
+enum {
+ DistortionVertexShaderBitMask = 3,
+ DistortionVertexShaderCount = DistortionVertexShaderBitMask + 1,
+ DistortionPixelShaderBitMask = 1,
+ DistortionPixelShaderCount = DistortionPixelShaderBitMask + 1
+};
+
+struct PrecompiledShader
+{
+ const unsigned char* ShaderData;
+ size_t ShaderSize;
+ const ShaderBase::Uniform* ReflectionData;
+ size_t ReflectionSize;
+};
+
+// Do add a new distortion shader use these macros (with or w/o reflection)
+#define PCS_NOREFL(shader) { shader, sizeof(shader), NULL, 0 }
+#define PCS_REFL__(shader) { shader, sizeof(shader), shader ## _refl, sizeof( shader ## _refl )/sizeof(*(shader ## _refl)) }
+
+
+static PrecompiledShader DistortionVertexShaderLookup[DistortionVertexShaderCount] =
+{
+ PCS_REFL__(Distortion_vs),
+ PCS_REFL__(DistortionChroma_vs),
+ PCS_REFL__(DistortionTimewarp_vs),
+ PCS_REFL__(DistortionTimewarpChroma_vs),
+};
+
+static PrecompiledShader DistortionPixelShaderLookup[DistortionPixelShaderCount] =
+{
+ PCS_NOREFL(Distortion_ps),
+ PCS_NOREFL(DistortionChroma_ps)
+};
+
+void DistortionShaderBitIndexCheck()
+{
+ OVR_COMPILER_ASSERT(ovrDistortion_Chromatic == 1);
+ OVR_COMPILER_ASSERT(ovrDistortion_TimeWarp == 2);
+}
+
+
+
+struct DistortionVertex
+{
+ Vector2f Pos;
+ Vector2f TexR;
+ Vector2f TexG;
+ Vector2f TexB;
+ Color Col;
+};
+
+
+// Vertex type; same format is used for all shapes for simplicity.
+// Shapes are built by adding vertices to Model.
+struct Vertex
+{
+ Vector3f Pos;
+ Color C;
+ float U, V;
+ Vector3f Norm;
+
+ 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)
+ {}
+ 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)
+ { }
+
+ bool operator==(const Vertex& b) const
+ {
+ return Pos == b.Pos && C == b.C && U == b.U && V == b.V;
+ }
+};
+
+
+//----------------------------------------------------------------------------
+// ***** D3D1X::DistortionRenderer
+
+DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager,
+ const HMDRenderState& renderState)
+ : CAPI::DistortionRenderer(ovrRenderAPI_D3D11, hmd, timeManager, renderState)
+{
+}
+
+DistortionRenderer::~DistortionRenderer()
+{
+ destroy();
+}
+
+// static
+CAPI::DistortionRenderer* DistortionRenderer::Create(ovrHmd hmd,
+ FrameTimeManager& timeManager,
+ const HMDRenderState& renderState)
+{
+ return new DistortionRenderer(hmd, timeManager, renderState);
+}
+
+
+bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig,
+ unsigned hmdCaps, 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)
+ {
+ // Cleanup
+ pEyeTextures[0].Clear();
+ pEyeTextures[1].Clear();
+ memset(&RParams, 0, sizeof(RParams));
+ return true;
+ }
+
+ if (!config->D3D_NS.pDevice || !config->D3D_NS.pBackBufferRT)
+ return false;
+
+ RParams.pDevice = config->D3D_NS.pDevice;
+ RParams.pContext = D3DSELECT_10_11(config->D3D_NS.pDevice, config->D3D_NS.pDeviceContext);
+ RParams.pBackBufferRT = config->D3D_NS.pBackBufferRT;
+ RParams.pSwapChain = config->D3D_NS.pSwapChain;
+ RParams.RTSize = config->D3D_NS.Header.RTSize;
+ RParams.Multisample = config->D3D_NS.Header.Multisample;
+
+ DistortionCaps = distortionCaps;
+
+ //DistortionWarper.SetVsync((hmdCaps & ovrHmdCap_NoVSync) ? false : true);
+
+ pEyeTextures[0] = *new Texture(&RParams, Texture_RGBA, Sizei(0),
+ getSamplerState(Sample_Linear|Sample_ClampBorder));
+ pEyeTextures[1] = *new Texture(&RParams, Texture_RGBA, Sizei(0),
+ getSamplerState(Sample_Linear|Sample_ClampBorder));
+
+ initBuffersAndShaders();
+
+ // Rasterizer state
+ D3D1X_(RASTERIZER_DESC) rs;
+ memset(&rs, 0, sizeof(rs));
+ rs.AntialiasedLineEnable = true;
+ rs.CullMode = D3D1X_(CULL_BACK);
+ rs.DepthClipEnable = true;
+ rs.FillMode = D3D1X_(FILL_SOLID);
+ RParams.pDevice->CreateRasterizerState(&rs, &Rasterizer.GetRawRef());
+
+ // TBD: Blend state.. not used?
+ // We'll want to turn off blending
+
+#if (OVR_D3D_VERSION == 11)
+ GpuProfiler.Init(RParams.pDevice, RParams.pContext);
+#endif
+
+ return true;
+}
+
+
+void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture)
+{
+ const ovrD3D1X(Texture)* tex = (const ovrD3D1X(Texture)*)eyeTexture;
+
+ if (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;
+
+ ovrHmd_GetRenderScaleAndOffset(HMD, ed, DistortionCaps, UVScaleOffset[eyeId]);
+
+ pEyeTextures[eyeId]->UpdatePlaceholderTexture(tex->D3D_NS.pTexture, tex->D3D_NS.pSRView,
+ tex->D3D_NS.Header.TextureSize);
+ }
+}
+
+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)
+ {
+ // Wait for timewarp distortion if it is time and Gpu idle
+ FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime);
+ }
+
+ renderDistortion(pEyeTextures[0], pEyeTextures[1]);
+ }
+ else
+ {
+ // If needed, measure distortion time so that TimeManager can better estimate
+ // latency-reducing time-warp wait timing.
+ WaitUntilGpuIdle();
+ double distortionStartTime = ovr_GetTimeInSeconds();
+
+ renderDistortion(pEyeTextures[0], pEyeTextures[1]);
+
+ WaitUntilGpuIdle();
+ TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime);
+ }
+#endif
+
+ if(latencyTesterDrawColor)
+ {
+ renderLatencyQuad(latencyTesterDrawColor);
+ }
+ else if(latencyTester2DrawColor)
+ {
+ renderLatencyPixel(latencyTester2DrawColor);
+ }
+
+ if (swapBuffers)
+ {
+ if (RParams.pSwapChain)
+ {
+ 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();
+ }
+ else
+ {
+ // TBD: Generate error - swapbuffer option used with null swapchain.
+ }
+ }
+}
+
+
+void DistortionRenderer::WaitUntilGpuIdle()
+{
+ // 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)
+ {
+ 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)))
+ );
+ }
+}
+
+double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime)
+{
+ 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;
+ }
+
+ 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;
+ }
+ newTime = ovr_GetTimeInSeconds();
+ }
+
+ // How long we waited
+ return newTime - initialTime;
+}
+
+void DistortionRenderer::initBuffersAndShaders()
+{
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ // Allocate & generate distortion mesh vertices.
+ ovrDistortionMesh meshData;
+
+// double startT = ovr_GetTimeInSeconds();
+
+ if (!ovrHmd_CreateDistortionMesh( HMD, RState.EyeRenderDesc[eyeNum].Desc,
+ RState.DistortionCaps,
+ UVScaleOffset[eyeNum], &meshData) )
+ {
+ OVR_ASSERT(false);
+ continue;
+ }
+
+// double deltaT = ovr_GetTimeInSeconds() - startT;
+// LogText("GenerateDistortion time = %f\n", deltaT);
+
+ // Now parse the vertex data and create a render ready vertex buffer from it
+ DistortionVertex * pVBVerts = (DistortionVertex*)OVR_ALLOC ( sizeof(DistortionVertex) * meshData.VertexCount );
+ DistortionVertex * pCurVBVert = pVBVerts;
+ ovrDistortionVertex* pCurOvrVert = meshData.pVertexData;
+
+ for ( unsigned vertNum = 0; vertNum < meshData.VertexCount; vertNum++ )
+ {
+ pCurVBVert->Pos.x = pCurOvrVert->Pos.x;
+ pCurVBVert->Pos.y = pCurOvrVert->Pos.y;
+ pCurVBVert->TexR = (*(Vector2f*)&pCurOvrVert->TexR);
+ pCurVBVert->TexG = (*(Vector2f*)&pCurOvrVert->TexG);
+ pCurVBVert->TexB = (*(Vector2f*)&pCurOvrVert->TexB);
+ // Convert [0.0f,1.0f] to [0,255]
+ pCurVBVert->Col.R = (OVR::UByte)( pCurOvrVert->VignetteFactor * 255.99f );
+ pCurVBVert->Col.G = pCurVBVert->Col.R;
+ pCurVBVert->Col.B = pCurVBVert->Col.R;
+ pCurVBVert->Col.A = (OVR::UByte)( pCurOvrVert->TimeWarpFactor * 255.99f );;
+ pCurOvrVert++;
+ pCurVBVert++;
+ }
+
+ DistortionMeshVBs[eyeNum] = *new Buffer(&RParams);
+ DistortionMeshVBs[eyeNum]->Data ( Buffer_Vertex, pVBVerts, sizeof(DistortionVertex) * meshData.VertexCount );
+ DistortionMeshIBs[eyeNum] = *new Buffer(&RParams);
+ DistortionMeshIBs[eyeNum]->Data ( Buffer_Index, meshData.pIndexData, ( sizeof(INT16) * meshData.IndexCount ) );
+
+ OVR_FREE ( pVBVerts );
+ ovrHmd_DestroyDistortionMesh( &meshData );
+ }
+
+ // Uniform buffers
+ for(int i = 0; i < Shader_Count; i++)
+ {
+ UniformBuffers[i] = *new Buffer(&RParams);
+ //MaxTextureSet[i] = 0;
+ }
+
+ initShaders();
+}
+
+void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* rightEyeTexture)
+{
+ RParams.pContext->RSSetState(Rasterizer);
+
+ RParams.pContext->OMSetRenderTargets(1, &RParams.pBackBufferRT, 0);
+
+ setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h));
+
+ // Not affected by viewport.
+ RParams.pContext->ClearRenderTargetView(RParams.pBackBufferRT, RState.ClearColor);
+
+ for(int eyeNum = 0; eyeNum < 2; eyeNum++)
+ {
+ ShaderFill distortionShaderFill(DistortionShader);
+ distortionShaderFill.SetTexture(0, eyeNum == 0 ? leftEyeTexture : rightEyeTexture);
+ distortionShaderFill.SetInputLayout(DistortionVertexIL);
+
+ 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)
+ {
+ ovrMatrix4f timeWarpMatrices[2];
+ ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum,
+ RState.EyeRenderPoses[eyeNum], timeWarpMatrices);
+
+ // Feed identity like matrices in until we get proper timewarp calculation going on
+ DistortionShader->SetUniform4x4f("EyeRotationStart", Matrix4f(timeWarpMatrices[0]));
+ DistortionShader->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1]));
+
+ renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum],
+ NULL, 0, (int)DistortionMeshVBs[eyeNum]->GetSize(), Prim_Triangles);
+ }
+ else
+ {
+ renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum],
+ NULL, 0, (int)DistortionMeshVBs[eyeNum]->GetSize(), Prim_Triangles);
+ }
+ }
+}
+
+void DistortionRenderer::createDrawQuad()
+{
+ const int numQuadVerts = 4;
+ LatencyTesterQuadVB = *new Buffer(&RParams);
+ if(!LatencyTesterQuadVB)
+ {
+ return;
+ }
+
+ LatencyTesterQuadVB->Data(Buffer_Vertex, NULL, numQuadVerts * sizeof(Vertex));
+ Vertex* vertices = (Vertex*)LatencyTesterQuadVB->Map(0, numQuadVerts * sizeof(Vertex), Map_Discard);
+ if(!vertices)
+ {
+ OVR_ASSERT(false); // failed to lock vertex buffer
+ return;
+ }
+
+ const float left = -1.0f;
+ const float top = -1.0f;
+ const float right = 1.0f;
+ const float bottom = 1.0f;
+
+ vertices[0] = Vertex(Vector3f(left, top, 0.0f), Color(255, 255, 255, 255));
+ vertices[1] = Vertex(Vector3f(left, bottom, 0.0f), Color(255, 255, 255, 255));
+ vertices[2] = Vertex(Vector3f(right, top, 0.0f), Color(255, 255, 255, 255));
+ vertices[3] = Vertex(Vector3f(right, bottom, 0.0f), Color(255, 255, 255, 255));
+
+ LatencyTesterQuadVB->Unmap(vertices);
+}
+
+void DistortionRenderer::renderLatencyQuad(unsigned char* latencyTesterDrawColor)
+{
+ const int numQuadVerts = 4;
+
+ if(!LatencyTesterQuadVB)
+ {
+ createDrawQuad();
+ }
+
+ ShaderFill quadFill(SimpleQuadShader);
+ quadFill.SetInputLayout(SimpleQuadVertexIL);
+
+ setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h));
+
+ SimpleQuadShader->SetUniform2f("Scale", 0.2f, 0.2f);
+ SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterDrawColor[0] / 255.99f,
+ (float)latencyTesterDrawColor[0] / 255.99f,
+ (float)latencyTesterDrawColor[0] / 255.99f,
+ 1.0f);
+
+ 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);
+ }
+}
+
+void DistortionRenderer::renderLatencyPixel(unsigned char* latencyTesterPixelColor)
+{
+ const int numQuadVerts = 4;
+
+ if(!LatencyTesterQuadVB)
+ {
+ createDrawQuad();
+ }
+
+ ShaderFill quadFill(SimpleQuadShader);
+ quadFill.SetInputLayout(SimpleQuadVertexIL);
+
+ setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h));
+
+ SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterPixelColor[0] / 255.99f,
+ (float)latencyTesterPixelColor[0] / 255.99f,
+ (float)latencyTesterPixelColor[0] / 255.99f,
+ 1.0f);
+
+ 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);
+}
+
+void DistortionRenderer::renderPrimitives(
+ const ShaderFill* fill,
+ Buffer* vertices, Buffer* indices,
+ Matrix4f* viewMatrix, int offset, int count,
+ PrimitiveType rprim)
+{
+ OVR_ASSERT(fill->GetInputLayout() != 0);
+ RParams.pContext->IASetInputLayout((ID3D1xInputLayout*)fill->GetInputLayout());
+
+ if (indices)
+ {
+ RParams.pContext->IASetIndexBuffer(indices->GetBuffer(), DXGI_FORMAT_R16_UINT, 0);
+ }
+
+ ID3D1xBuffer* vertexBuffer = vertices->GetBuffer();
+ UINT vertexStride = sizeof(Vertex);
+ UINT vertexOffset = offset;
+ RParams.pContext->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
+
+ ShaderSet* shaders = ((ShaderFill*)fill)->GetShaders();
+
+ ShaderBase* vshader = ((ShaderBase*)shaders->GetShader(Shader_Vertex));
+ unsigned char* vertexData = vshader->UniformData;
+ if (vertexData)
+ {
+ // TODO: some VSes don't start with StandardUniformData!
+ if ( viewMatrix )
+ {
+ StandardUniformData* stdUniforms = (StandardUniformData*) vertexData;
+ stdUniforms->View = viewMatrix->Transposed();
+ stdUniforms->Proj = StdUniforms.Proj;
+ }
+ UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, vertexData, vshader->UniformsSize);
+ vshader->SetUniformBuffer(UniformBuffers[Shader_Vertex]);
+ }
+
+ for(int i = Shader_Vertex + 1; i < Shader_Count; i++)
+ {
+ if (shaders->GetShader(i))
+ {
+ ((ShaderBase*)shaders->GetShader(i))->UpdateBuffer(UniformBuffers[i]);
+ ((ShaderBase*)shaders->GetShader(i))->SetUniformBuffer(UniformBuffers[i]);
+ }
+ }
+
+ D3D1X_(PRIMITIVE_TOPOLOGY) prim;
+ switch(rprim)
+ {
+ case Prim_Triangles:
+ prim = D3D1X_(PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ break;
+ case Prim_Lines:
+ prim = D3D1X_(PRIMITIVE_TOPOLOGY_LINELIST);
+ break;
+ case Prim_TriangleStrip:
+ prim = D3D1X_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+ break;
+ default:
+ OVR_ASSERT(0);
+ return;
+ }
+ RParams.pContext->IASetPrimitiveTopology(prim);
+
+ fill->Set(rprim);
+
+ if (indices)
+ {
+ RParams.pContext->DrawIndexed(count, 0, 0);
+ }
+ else
+ {
+ RParams.pContext->Draw(count, 0);
+ }
+}
+
+void DistortionRenderer::setViewport(const Recti& vp)
+{
+ D3D1x_VIEWPORT d3dvp;
+
+ d3dvp.Width = D3DSELECT_10_11(vp.w, (float)vp.w);
+ d3dvp.Height = D3DSELECT_10_11(vp.h, (float)vp.h);
+ d3dvp.TopLeftX = D3DSELECT_10_11(vp.x, (float)vp.x);
+ d3dvp.TopLeftY = D3DSELECT_10_11(vp.y, (float)vp.y);
+ d3dvp.MinDepth = 0;
+ d3dvp.MaxDepth = 1;
+ RParams.pContext->RSSetViewports(1, &d3dvp);
+}
+
+
+
+
+static D3D1X_(INPUT_ELEMENT_DESC) DistortionMeshVertexDesc[] =
+{
+ {"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},
+ {"TexCoord", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D1X_(INPUT_PER_VERTEX_DATA), 0},
+ {"TexCoord", 2, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D1X_(INPUT_PER_VERTEX_DATA), 0},
+ {"Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 32, D3D1X_(INPUT_PER_VERTEX_DATA), 0},
+};
+
+static D3D1X_(INPUT_ELEMENT_DESC) SimpleQuadMeshVertexDesc[] =
+{
+ {"Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D1X_(INPUT_PER_VERTEX_DATA), 0},
+};
+
+// TODO: this is D3D specific
+void DistortionRenderer::initShaders()
+{
+ {
+ PrecompiledShader vsShaderByteCode = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & DistortionCaps];
+ Ptr<D3D_NS::VertexShader> vtxShader = *new D3D_NS::VertexShader(
+ &RParams,
+ (void*)vsShaderByteCode.ShaderData, vsShaderByteCode.ShaderSize,
+ vsShaderByteCode.ReflectionData, vsShaderByteCode.ReflectionSize);
+
+ ID3D1xInputLayout** objRef = &DistortionVertexIL.GetRawRef();
+
+ HRESULT validate = RParams.pDevice->CreateInputLayout(
+ DistortionMeshVertexDesc, sizeof(DistortionMeshVertexDesc) / sizeof(DistortionMeshVertexDesc[0]),
+ vsShaderByteCode.ShaderData, vsShaderByteCode.ShaderSize, objRef);
+ OVR_UNUSED(validate);
+
+ DistortionShader = *new ShaderSet;
+ DistortionShader->SetShader(vtxShader);
+
+ PrecompiledShader psShaderByteCode = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & DistortionCaps];
+
+ Ptr<D3D_NS::PixelShader> ps = *new D3D_NS::PixelShader(
+ &RParams,
+ (void*)psShaderByteCode.ShaderData, psShaderByteCode.ShaderSize,
+ psShaderByteCode.ReflectionData, psShaderByteCode.ReflectionSize);
+
+ DistortionShader->SetShader(ps);
+ }
+
+ {
+ Ptr<D3D_NS::VertexShader> vtxShader = *new D3D_NS::VertexShader(
+ &RParams,
+ (void*)SimpleQuad_vs, sizeof(SimpleQuad_vs),
+ SimpleQuad_vs_refl, sizeof(SimpleQuad_vs_refl) / sizeof(SimpleQuad_vs_refl[0]));
+ //NULL, 0);
+
+ ID3D1xInputLayout** objRef = &SimpleQuadVertexIL.GetRawRef();
+
+ HRESULT validate = RParams.pDevice->CreateInputLayout(
+ SimpleQuadMeshVertexDesc, sizeof(SimpleQuadMeshVertexDesc) / sizeof(SimpleQuadMeshVertexDesc[0]),
+ (void*)SimpleQuad_vs, sizeof(SimpleQuad_vs), objRef);
+ OVR_UNUSED(validate);
+
+ SimpleQuadShader = *new ShaderSet;
+ SimpleQuadShader->SetShader(vtxShader);
+
+ Ptr<D3D_NS::PixelShader> ps = *new D3D_NS::PixelShader(
+ &RParams,
+ (void*)SimpleQuad_ps, sizeof(SimpleQuad_ps),
+ SimpleQuad_ps_refl, sizeof(SimpleQuad_ps_refl) / sizeof(SimpleQuad_ps_refl[0]));
+
+ SimpleQuadShader->SetShader(ps);
+ }
+}
+
+
+
+ID3D1xSamplerState* DistortionRenderer::getSamplerState(int sm)
+{
+ if (SamplerStates[sm])
+ return SamplerStates[sm];
+
+ D3D1X_(SAMPLER_DESC) ss;
+ memset(&ss, 0, sizeof(ss));
+ if (sm & Sample_Clamp)
+ ss.AddressU = ss.AddressV = ss.AddressW = D3D1X_(TEXTURE_ADDRESS_CLAMP);
+ else if (sm & Sample_ClampBorder)
+ ss.AddressU = ss.AddressV = ss.AddressW = D3D1X_(TEXTURE_ADDRESS_BORDER);
+ else
+ ss.AddressU = ss.AddressV = ss.AddressW = D3D1X_(TEXTURE_ADDRESS_WRAP);
+
+ if (sm & Sample_Nearest)
+ {
+ ss.Filter = D3D1X_(FILTER_MIN_MAG_MIP_POINT);
+ }
+ else if (sm & Sample_Anisotropic)
+ {
+ ss.Filter = D3D1X_(FILTER_ANISOTROPIC);
+ ss.MaxAnisotropy = 8;
+ }
+ else
+ {
+ ss.Filter = D3D1X_(FILTER_MIN_MAG_MIP_LINEAR);
+ }
+ ss.MaxLOD = 15;
+ RParams.pDevice->CreateSamplerState(&ss, &SamplerStates[sm].GetRawRef());
+ return SamplerStates[sm];
+}
+
+
+void DistortionRenderer::destroy()
+{
+ for(int eyeNum = 0; eyeNum < 2; eyeNum++)
+ {
+ DistortionMeshVBs[eyeNum].Clear();
+ DistortionMeshIBs[eyeNum].Clear();
+ }
+
+ DistortionVertexIL.Clear();
+
+ if (DistortionShader)
+ {
+ DistortionShader->UnsetShader(Shader_Vertex);
+ DistortionShader->UnsetShader(Shader_Pixel);
+ DistortionShader.Clear();
+ }
+
+ LatencyTesterQuadVB.Clear();
+}
+
+}}} // OVR::CAPI::D3D1X
diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h
new file mode 100644
index 0000000..f151d73
--- /dev/null
+++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h
@@ -0,0 +1,131 @@
+/************************************************************************************
+
+Filename : CAPI_D3D1X_DistortionRenderer.h
+Content : Experimental distortion renderer
+Created : November 11, 2013
+Authors : Volga Aksoy
+
+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.
+
+************************************************************************************/
+
+// No include guard, since this fill will be multiply-included.
+//#ifndef OVR_CAPI_D3D1X_DistortionRenderer_h
+
+#include "CAPI_D3D1X_Util.h"
+#include "../CAPI_DistortionRenderer.h"
+
+#include "../../Kernel/OVR_Log.h"
+
+namespace OVR { namespace CAPI { namespace D3D_NS {
+
+
+// ***** D3D1X::DistortionRenderer
+
+// Implementation of DistortionRenderer for D3D10/11.
+
+class DistortionRenderer : public CAPI::DistortionRenderer
+{
+public:
+ DistortionRenderer(ovrHmd hmd,
+ FrameTimeManager& timeManager,
+ const HMDRenderState& renderState);
+ ~DistortionRenderer();
+
+
+ // Creation function for the device.
+ static CAPI::DistortionRenderer* Create(ovrHmd hmd,
+ FrameTimeManager& timeManager,
+ const HMDRenderState& renderState);
+
+
+ // ***** Public DistortionRenderer interface
+
+ virtual bool Initialize(const ovrRenderAPIConfig* apiConfig,
+ unsigned hmdCaps, unsigned distortionCaps);
+
+ virtual void SubmitEye(int eyeId, ovrTexture* eyeTexture);
+
+ virtual void EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor);
+
+ // TBD: Make public?
+ void WaitUntilGpuIdle();
+
+ // Similar to ovr_WaitTillTime but it also flushes GPU.
+ // Note, it exits when time expires, even if GPU is not in idle state yet.
+ double FlushGpuAndWaitTillTime(double absTime);
+
+private:
+ // Helpers
+ void initBuffersAndShaders();
+ void initShaders();
+ void initFullscreenQuad();
+ void destroy();
+
+ void setViewport(const Recti& vp);
+
+ void renderDistortion(Texture* leftEyeTexture, Texture* rightEyeTexture);
+
+ void renderPrimitives(const ShaderFill* fill, Buffer* vertices, Buffer* indices,
+ Matrix4f* viewMatrix, int offset, int count,
+ PrimitiveType rprim);
+
+ void createDrawQuad();
+ void renderLatencyQuad(unsigned char* latencyTesterDrawColor);
+ void renderLatencyPixel(unsigned char* latencyTesterPixelColor);
+
+ // Create or get cached D3D sampler based on flags.
+ ID3D1xSamplerState* getSamplerState(int sm);
+
+
+ // TBD: Should we be using oe from RState instead?
+ unsigned DistortionCaps;
+
+ // D3DX device and utility variables.
+ RenderParams RParams;
+ Ptr<Texture> pEyeTextures[2];
+
+ // U,V scale and offset needed for timewarp.
+ ovrVector2f UVScaleOffset[2][2];
+
+ //Ptr<Buffer> mpFullScreenVertexBuffer;
+
+ Ptr<Buffer> DistortionMeshVBs[2]; // one per-eye
+ Ptr<Buffer> DistortionMeshIBs[2]; // one per-eye
+
+ Ptr<ShaderSet> DistortionShader;
+ Ptr<ID3D1xInputLayout> DistortionVertexIL;
+
+ struct StandardUniformData
+ {
+ Matrix4f Proj;
+ Matrix4f View;
+ } StdUniforms;
+ Ptr<Buffer> UniformBuffers[Shader_Count];
+
+ Ptr<ID3D1xSamplerState> SamplerStates[Sample_Count];
+ Ptr<ID3D1xRasterizerState> Rasterizer;
+
+ Ptr<Buffer> LatencyTesterQuadVB;
+ Ptr<ShaderSet> SimpleQuadShader;
+ Ptr<ID3D1xInputLayout> SimpleQuadVertexIL;
+
+ GpuTimer GpuProfiler;
+};
+
+}}} // OVR::CAPI::D3D1X
diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp
new file mode 100644
index 0000000..501a8e3
--- /dev/null
+++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp
@@ -0,0 +1,416 @@
+/************************************************************************************
+
+Filename : CAPI_D3D1X_Util.cpp
+Content : D3DX10 utility classes for rendering
+Created : September 10, 2012
+Authors : Andrew Reisse
+
+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 "CAPI_D3D1X_Util.h"
+
+#include <d3dcompiler.h>
+
+namespace OVR { namespace CAPI { namespace D3D_NS {
+
+
+//-------------------------------------------------------------------------------------
+// ***** ShaderFill
+
+void ShaderFill::Set(PrimitiveType prim) const
+{
+ Shaders->Set(prim);
+ for(int i = 0; i < 8; i++)
+ {
+ if(Textures[i])
+ {
+ Textures[i]->Set(i);
+ }
+ }
+}
+
+
+//-------------------------------------------------------------------------------------
+// ***** Buffer
+
+Buffer::~Buffer()
+{
+}
+
+bool Buffer::Data(int use, const void *buffer, size_t size)
+{
+ if (D3DBuffer && Size >= size)
+ {
+ if (Dynamic)
+ {
+ if (!buffer)
+ return true;
+
+ void* v = Map(0, size, Map_Discard);
+ if (v)
+ {
+ memcpy(v, buffer, size);
+ Unmap(v);
+ return true;
+ }
+ }
+ else
+ {
+ pParams->pContext->UpdateSubresource(D3DBuffer, 0, NULL, buffer, 0, 0);
+ return true;
+ }
+ }
+ if (D3DBuffer)
+ {
+ D3DBuffer = NULL;
+ Size = 0;
+ Use = 0;
+ Dynamic = 0;
+ }
+
+ D3D1X_(BUFFER_DESC) desc;
+ memset(&desc, 0, sizeof(desc));
+ if (use & Buffer_ReadOnly)
+ {
+ desc.Usage = D3D1X_(USAGE_IMMUTABLE);
+ desc.CPUAccessFlags = 0;
+ }
+ else
+ {
+ desc.Usage = D3D1X_(USAGE_DYNAMIC);
+ desc.CPUAccessFlags = D3D1X_(CPU_ACCESS_WRITE);
+ Dynamic = 1;
+ }
+
+ switch(use & Buffer_TypeMask)
+ {
+ case Buffer_Vertex: desc.BindFlags = D3D1X_(BIND_VERTEX_BUFFER); break;
+ case Buffer_Index: desc.BindFlags = D3D1X_(BIND_INDEX_BUFFER); break;
+ case Buffer_Uniform:
+ desc.BindFlags = D3D1X_(BIND_CONSTANT_BUFFER);
+ size += ((size + 15) & ~15) - size;
+ break;
+ }
+
+ desc.ByteWidth = (unsigned)size;
+
+ D3D1X_(SUBRESOURCE_DATA) sr;
+ sr.pSysMem = buffer;
+ sr.SysMemPitch = 0;
+ sr.SysMemSlicePitch = 0;
+
+ HRESULT hr = pParams->pDevice->CreateBuffer(&desc, buffer ? &sr : NULL, &D3DBuffer.GetRawRef());
+ if (SUCCEEDED(hr))
+ {
+ Use = use;
+ Size = desc.ByteWidth;
+ return 1;
+ }
+ return 0;
+}
+
+void* Buffer::Map(size_t start, size_t size, int flags)
+{
+ OVR_UNUSED(size);
+
+ D3D1X_(MAP) mapFlags = D3D1X_(MAP_WRITE);
+ if (flags & Map_Discard)
+ mapFlags = D3D1X_(MAP_WRITE_DISCARD);
+ if (flags & Map_Unsynchronized)
+ mapFlags = D3D1X_(MAP_WRITE_NO_OVERWRITE);
+
+#if (OVR_D3D_VERSION == 10)
+ void* map;
+ if (SUCCEEDED(D3DBuffer->Map(mapFlags, 0, &map)))
+ return ((char*)map) + start;
+#else
+ D3D11_MAPPED_SUBRESOURCE map;
+ if (SUCCEEDED(pParams->pContext->Map(D3DBuffer, 0, mapFlags, 0, &map)))
+ return ((char*)map.pData) + start;
+#endif
+
+ return NULL;
+}
+
+bool Buffer::Unmap(void *m)
+{
+ OVR_UNUSED(m);
+
+ D3DSELECT_10_11( D3DBuffer->Unmap(),
+ pParams->pContext->Unmap(D3DBuffer, 0) );
+ return true;
+}
+
+
+//-------------------------------------------------------------------------------------
+// Shaders
+
+template<> bool ShaderImpl<Shader_Vertex, ID3D1xVertexShader>::Load(void* shader, size_t size)
+{
+ return SUCCEEDED(pParams->pDevice->CreateVertexShader(shader, size D3D11_COMMA_0, &D3DShader));
+}
+template<> bool ShaderImpl<Shader_Pixel, ID3D1xPixelShader>::Load(void* shader, size_t size)
+{
+ return SUCCEEDED(pParams->pDevice->CreatePixelShader(shader, size D3D11_COMMA_0, &D3DShader));
+}
+
+template<> void ShaderImpl<Shader_Vertex, ID3D1xVertexShader>::Set(PrimitiveType) const
+{
+ pParams->pContext->VSSetShader(D3DShader D3D11_COMMA_0 D3D11_COMMA_0 );
+}
+template<> void ShaderImpl<Shader_Pixel, ID3D1xPixelShader>::Set(PrimitiveType) const
+{
+ pParams->pContext->PSSetShader(D3DShader D3D11_COMMA_0 D3D11_COMMA_0 ) ;
+}
+
+template<> void ShaderImpl<Shader_Vertex, ID3D1xVertexShader>::SetUniformBuffer(Buffer* buffer, int i)
+{
+ pParams->pContext->VSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef());
+}
+template<> void ShaderImpl<Shader_Pixel, ID3D1xPixelShader>::SetUniformBuffer(Buffer* buffer, int i)
+{
+ pParams->pContext->PSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef());
+}
+
+
+//-------------------------------------------------------------------------------------
+// ***** Shader Base
+
+ShaderBase::ShaderBase(RenderParams* rp, ShaderStage stage)
+ : Shader(stage), pParams(rp), UniformData(0)
+{
+}
+ShaderBase::~ShaderBase()
+{
+ if (UniformData)
+ OVR_FREE(UniformData);
+}
+
+bool ShaderBase::SetUniform(const char* name, int n, const float* v)
+{
+ for(unsigned i = 0; i < UniformReflSize; i++)
+ {
+ if (!strcmp(UniformRefl[i].Name, name))
+ {
+ memcpy(UniformData + UniformRefl[i].Offset, v, n * sizeof(float));
+ return 1;
+ }
+ }
+ return 0;
+}
+
+bool ShaderBase::SetUniformBool(const char* name, int n, const bool* v)
+{
+ OVR_UNUSED(n);
+ for(unsigned i = 0; i < UniformReflSize; i++)
+ {
+ if (!strcmp(UniformRefl[i].Name, name))
+ {
+ memcpy(UniformData + UniformRefl[i].Offset, v, UniformRefl[i].Size);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void ShaderBase::InitUniforms(const Uniform* refl, size_t reflSize)
+{
+ if(!refl)
+ {
+ UniformRefl = NULL;
+ UniformReflSize = 0;
+
+ UniformsSize = 0;
+ if (UniformData)
+ {
+ OVR_FREE(UniformData);
+ UniformData = 0;
+ }
+ return; // no reflection data
+ }
+
+ UniformRefl = refl;
+ UniformReflSize = reflSize;
+
+ UniformsSize = UniformRefl[UniformReflSize-1].Offset + UniformRefl[UniformReflSize-1].Size;
+ UniformData = (unsigned char*)OVR_ALLOC(UniformsSize);
+}
+
+void ShaderBase::UpdateBuffer(Buffer* buf)
+{
+ if (UniformsSize)
+ {
+ buf->Data(Buffer_Uniform, UniformData, UniformsSize);
+ }
+}
+
+
+//-------------------------------------------------------------------------------------
+// ***** Texture
+//
+Texture::Texture(RenderParams* rp, int fmt, const Sizei texSize,
+ ID3D1xSamplerState* sampler, int samples)
+ : pParams(rp), Tex(NULL), TexSv(NULL), TexRtv(NULL), TexDsv(NULL),
+ TextureSize(texSize),
+ Sampler(sampler),
+ Samples(samples)
+{
+ OVR_UNUSED(fmt);
+}
+
+Texture::~Texture()
+{
+}
+
+void Texture::Set(int slot, ShaderStage stage) const
+{
+ ID3D1xShaderResourceView* texSv = TexSv.GetPtr();
+
+ switch(stage)
+ {
+ case Shader_Fragment:
+ pParams->pContext->PSSetShaderResources(slot, 1, &texSv);
+ pParams->pContext->PSSetSamplers(slot, 1, &Sampler.GetRawRef());
+ break;
+
+ case Shader_Vertex:
+ pParams->pContext->VSSetShaderResources(slot, 1, &texSv);
+ break;
+ }
+}
+
+
+//-------------------------------------------------------------------------------------
+// ***** GpuTimer
+//
+#if (OVR_D3D_VERSION == 11)
+#define D3DQUERY_EXEC(_context_, _query_, _command_, ...) _context_->_command_(_query_, __VA_ARGS__)
+#else
+#define D3DQUERY_EXEC(_context_, _query_, _command_, ...) _query_->_command_(__VA_ARGS__)
+#endif
+
+
+void GpuTimer::Init(ID3D1xDevice* device, ID3D1xDeviceContext* content)
+{
+ D3dDevice = device;
+ Context = content;
+}
+
+void GpuTimer::BeginQuery()
+{
+ if(GotoNextFrame(LastQueuedFrame) == LastTimedFrame)
+ {
+ OVR_ASSERT(false); // too many queries queued
+ return;
+ }
+
+ LastQueuedFrame = GotoNextFrame(LastQueuedFrame);
+
+ GpuQuerySets& newQuerySet = QuerySets[LastQueuedFrame];
+ if(newQuerySet.DisjointQuery == NULL)
+ {
+ // Create the queries
+ D3D1x_QUERY_DESC desc;
+ desc.Query = D3D1X_(QUERY_TIMESTAMP_DISJOINT);
+ desc.MiscFlags = 0;
+ VERIFY_HRESULT(D3dDevice->CreateQuery(&desc, &newQuerySet.DisjointQuery));
+
+ desc.Query = D3D1X_(QUERY_TIMESTAMP);
+ VERIFY_HRESULT(D3dDevice->CreateQuery(&desc, &newQuerySet.TimeStartQuery));
+ VERIFY_HRESULT(D3dDevice->CreateQuery(&desc, &newQuerySet.TimeEndQuery));
+ }
+
+ OVR_ASSERT(!newQuerySet.QueryStarted);
+ OVR_ASSERT(!newQuerySet.QueryAwaitingTiming);
+
+
+ D3DQUERY_EXEC(Context, QuerySets[LastQueuedFrame].DisjointQuery, Begin, ); // First start a disjoint query
+ D3DQUERY_EXEC(Context, QuerySets[LastQueuedFrame].TimeStartQuery, End, ); // Insert start timestamp
+
+ newQuerySet.QueryStarted = true;
+ newQuerySet.QueryAwaitingTiming = false;
+ //newQuerySet.QueryTimed = false;
+}
+
+void GpuTimer::EndQuery()
+{
+ if(LastQueuedFrame > 0 && !QuerySets[LastQueuedFrame].QueryStarted)
+ return;
+
+ GpuQuerySets& doneQuerySet = QuerySets[LastQueuedFrame];
+ OVR_ASSERT(doneQuerySet.QueryStarted);
+ OVR_ASSERT(!doneQuerySet.QueryAwaitingTiming);
+
+ // Insert the end timestamp
+ D3DQUERY_EXEC(Context, doneQuerySet.TimeEndQuery, End, );
+
+ // End the disjoint query
+ D3DQUERY_EXEC(Context, doneQuerySet.DisjointQuery, End, );
+
+ doneQuerySet.QueryStarted = false;
+ doneQuerySet.QueryAwaitingTiming = true;
+}
+
+float GpuTimer::GetTiming(bool blockUntilValid)
+{
+ float time = -1.0f;
+
+ // loop until we hit a query that is not ready yet, or we have read all queued queries
+ while(LastTimedFrame != LastQueuedFrame)
+ {
+ int timeTestFrame = GotoNextFrame(LastTimedFrame);
+
+ GpuQuerySets& querySet = QuerySets[timeTestFrame];
+
+ OVR_ASSERT(!querySet.QueryStarted && querySet.QueryAwaitingTiming);
+
+ UINT64 startTime = 0;
+ UINT64 endTime = 0;
+ D3D1X_(QUERY_DATA_TIMESTAMP_DISJOINT) disjointData;
+
+ if(blockUntilValid)
+ {
+ while(D3DQUERY_EXEC(Context, querySet.TimeStartQuery, GetData, &startTime, sizeof(startTime), 0) != S_OK);
+ while(D3DQUERY_EXEC(Context, querySet.TimeEndQuery, GetData, &endTime, sizeof(endTime), 0) != S_OK);
+ while(D3DQUERY_EXEC(Context, querySet.DisjointQuery, GetData, &disjointData, sizeof(disjointData), 0) != S_OK);
+ }
+ else
+ {
+// Early return if we fail to get data for any of these
+ if(D3DQUERY_EXEC(Context, querySet.TimeStartQuery, GetData, &startTime, sizeof(startTime), 0) != S_OK) return time;
+ if(D3DQUERY_EXEC(Context, querySet.TimeEndQuery, GetData, &endTime, sizeof(endTime), 0) != S_OK) return time;
+ if(D3DQUERY_EXEC(Context, querySet.DisjointQuery, GetData, &disjointData, sizeof(disjointData), 0) != S_OK) return time;
+ }
+
+ querySet.QueryAwaitingTiming = false;
+ LastTimedFrame = timeTestFrame; // successfully retrieved the timing data
+
+ if(disjointData.Disjoint == false)
+ {
+ UINT64 delta = endTime - startTime;
+ float frequency = (float)(disjointData.Frequency);
+ time = (delta / frequency);
+ }
+ }
+
+ return time;
+}
+
+}}} // OVR::CAPI::D3DX
diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h
new file mode 100644
index 0000000..f8d7bd3
--- /dev/null
+++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h
@@ -0,0 +1,505 @@
+/************************************************************************************
+
+Filename : CAPI_D3D1X_Util.h
+Content : D3DX 10/11 utility classes for rendering
+Created : September 10, 2012
+Authors : Andrew Reisse
+
+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.
+
+************************************************************************************/
+
+// ***** IMPORTANT:
+// This file can be included twice, once with OVR_D3D_VERSION=10 and
+// once with OVR_D3D_VERSION=11.
+
+
+#ifndef OVR_D3D_VERSION
+#error define OVR_D3D_VERSION to 10 or 11
+#endif
+
+// Custom include guard, allowing one of each D3D10/11.
+#if (OVR_D3D_VERSION == 10 && !defined(INC_OVR_CAPI_D3D10_Util_h)) || \
+ (OVR_D3D_VERSION == 11 && !defined(INC_OVR_CAPI_D3D11_Util_h))
+
+#include "../../Kernel/OVR_String.h"
+#include "../../Kernel/OVR_Array.h"
+#include "../../Kernel/OVR_Math.h"
+
+#include <Windows.h>
+#include <comdef.h> // for _COM_SMARTPTR_TYPEDEF()
+
+#undef D3D_NS // namespace
+#undef D3D1X_
+#undef ID3D1X // interface prefix
+#undef ovrD3D1X // ovrD3D10Config, etc.
+#undef D3D11_COMMA_0 // Injects on ", 0" for D3D11 only
+#undef D3DSELECT_10_11
+#undef IID_ID3D1xShaderReflection
+
+#if (OVR_D3D_VERSION == 10)
+
+ #define INC_OVR_CAPI_D3D10_Util_h
+ #define D3D_NS D3D10
+ #define D3D1X_(x) D3D10_##x
+ #define ID3D1X(x) ID3D10##x
+ #define ovrD3D1X(x) ovrD3D10##x
+ #define D3DSELECT_10_11(a10, a11) a10
+ #define D3D11_COMMA_0
+ #define IID_ID3D1xShaderReflection IID_ID3D10ShaderReflection
+ #include <d3d10_1.h> // avoids warning?
+ #include <d3d10.h>
+
+#else // (OVR_D3D_VERSION == 11)
+
+ #define INC_OVR_CAPI_D3D11_Util_h
+ #define D3D_NS D3D11
+ #define D3D1X_(x) D3D11_##x
+ #define ID3D1X(x) ID3D11##x
+ #define ovrD3D1X(x) ovrD3D11##x
+ #define D3DSELECT_10_11(a10, a11) a11
+ #define D3D11_COMMA_0 , 0
+ #define IID_ID3D1xShaderReflection IID_ID3D11ShaderReflection
+ #include <d3d11.h>
+ #include <D3D11Shader.h>
+#endif
+
+
+namespace OVR { namespace CAPI { namespace D3D_NS {
+
+// D3D Namespace-local types.
+typedef ID3D1X(Device) ID3D1xDevice;
+typedef ID3D1X(RenderTargetView) ID3D1xRenderTargetView;
+typedef ID3D1X(Texture2D) ID3D1xTexture2D;
+typedef ID3D1X(ShaderResourceView) ID3D1xShaderResourceView;
+typedef ID3D1X(DepthStencilView) ID3D1xDepthStencilView;
+typedef ID3D1X(DepthStencilState) ID3D1xDepthStencilState;
+typedef ID3D1X(InputLayout) ID3D1xInputLayout;
+typedef ID3D1X(Buffer) ID3D1xBuffer;
+typedef ID3D1X(VertexShader) ID3D1xVertexShader;
+typedef ID3D1X(PixelShader) ID3D1xPixelShader;
+typedef ID3D1X(GeometryShader) ID3D1xGeometryShader;
+typedef ID3D1X(BlendState) ID3D1xBlendState;
+typedef ID3D1X(RasterizerState) ID3D1xRasterizerState;
+typedef ID3D1X(SamplerState) ID3D1xSamplerState;
+typedef ID3D1X(Query) ID3D1xQuery;
+typedef ID3D1X(ShaderReflection) ID3D1xShaderReflection;
+typedef ID3D1X(ShaderReflectionVariable) ID3D1xShaderReflectionVariable;
+typedef ID3D1X(ShaderReflectionConstantBuffer) ID3D1xShaderReflectionConstantBuffer;
+typedef D3D1X_(VIEWPORT) D3D1x_VIEWPORT;
+typedef D3D1X_(QUERY_DESC) D3D1x_QUERY_DESC;
+typedef D3D1X_(SHADER_BUFFER_DESC) D3D1x_SHADER_BUFFER_DESC;
+typedef D3D1X_(SHADER_VARIABLE_DESC) D3D1x_SHADER_VARIABLE_DESC;
+// Blob is the same
+typedef ID3D10Blob ID3D1xBlob;
+
+#if (OVR_D3D_VERSION == 10)
+ typedef ID3D10Device ID3D1xDeviceContext;
+#else
+ typedef ID3D11DeviceContext ID3D1xDeviceContext;
+#endif
+
+
+// Assert on HRESULT failure
+inline void VERIFY_HRESULT(HRESULT hr)
+{
+ if (FAILED(hr))
+ OVR_ASSERT(false);
+}
+
+class Buffer;
+
+// Rendering parameters/pointers describing D3DX rendering setup.
+struct RenderParams
+{
+ ID3D1xDevice* pDevice;
+ ID3D1xDeviceContext* pContext;
+ ID3D1xRenderTargetView* pBackBufferRT;
+ IDXGISwapChain* pSwapChain;
+ Sizei RTSize;
+ int Multisample;
+};
+
+
+// Rendering primitive type used to render Model.
+enum PrimitiveType
+{
+ Prim_Triangles,
+ Prim_Lines,
+ Prim_TriangleStrip,
+ Prim_Unknown,
+ Prim_Count
+};
+
+// Types of shaders that can be stored together in a ShaderSet.
+enum ShaderStage
+{
+ Shader_Vertex = 0,
+ Shader_Fragment = 2,
+ Shader_Pixel = 2,
+ Shader_Count = 3,
+};
+
+enum MapFlags
+{
+ Map_Discard = 1,
+ Map_Read = 2, // do not use
+ Map_Unsynchronized = 4, // like D3D11_MAP_NO_OVERWRITE
+};
+
+
+// Buffer types used for uploading geometry & constants.
+enum BufferUsage
+{
+ Buffer_Unknown = 0,
+ Buffer_Vertex = 1,
+ Buffer_Index = 2,
+ Buffer_Uniform = 4,
+ Buffer_TypeMask = 0xff,
+ Buffer_ReadOnly = 0x100, // Buffer must be created with Data().
+};
+
+enum TextureFormat
+{
+ Texture_RGBA = 0x0100,
+ Texture_Depth = 0x8000,
+ Texture_TypeMask = 0xff00,
+ Texture_SamplesMask = 0x00ff,
+ Texture_RenderTarget = 0x10000,
+ Texture_GenMipmaps = 0x20000,
+};
+
+// Texture sampling modes.
+enum SampleMode
+{
+ Sample_Linear = 0,
+ Sample_Nearest = 1,
+ Sample_Anisotropic = 2,
+ Sample_FilterMask = 3,
+
+ Sample_Repeat = 0,
+ Sample_Clamp = 4,
+ Sample_ClampBorder = 8, // If unsupported Clamp is used instead.
+ Sample_AddressMask =12,
+
+ Sample_Count =13,
+};
+
+// Base class for vertex and pixel shaders. Stored in ShaderSet.
+class Shader : public RefCountBase<Shader>
+{
+ friend class ShaderSet;
+
+protected:
+ ShaderStage Stage;
+
+public:
+ Shader(ShaderStage s) : Stage(s) {}
+ virtual ~Shader() {}
+
+ ShaderStage GetStage() const { return Stage; }
+
+ virtual void Set(PrimitiveType) const { }
+ virtual void SetUniformBuffer(class Buffer* buffers, int i = 0) { OVR_UNUSED2(buffers, i); }
+
+protected:
+ virtual bool SetUniform(const char* name, int n, const float* v) { OVR_UNUSED3(name, n, v); return false; }
+ virtual bool SetUniformBool(const char* name, int n, const bool* v) { OVR_UNUSED3(name, n, v); return false; }
+};
+
+
+
+// A group of shaders, one per stage.
+// A ShaderSet is applied to a RenderDevice for rendering with a given fill.
+class ShaderSet : public RefCountBase<ShaderSet>
+{
+protected:
+ Ptr<Shader> Shaders[Shader_Count];
+
+public:
+ ShaderSet() { }
+ ~ShaderSet() { }
+
+ virtual void SetShader(Shader *s)
+ {
+ Shaders[s->GetStage()] = s;
+ }
+ virtual void UnsetShader(int stage)
+ {
+ Shaders[stage] = NULL;
+ }
+ Shader* GetShader(int stage) { return Shaders[stage]; }
+
+ virtual void Set(PrimitiveType prim) const
+ {
+ for (int i = 0; i < Shader_Count; i++)
+ if (Shaders[i])
+ Shaders[i]->Set(prim);
+ }
+
+ // Set a uniform (other than the standard matrices). It is undefined whether the
+ // uniforms from one shader occupy the same space as those in other shaders
+ // (unless a buffer is used, then each buffer is independent).
+ virtual bool SetUniform(const char* name, int n, const float* v)
+ {
+ bool result = 0;
+ for (int i = 0; i < Shader_Count; i++)
+ if (Shaders[i])
+ result |= Shaders[i]->SetUniform(name, n, v);
+
+ return result;
+ }
+ bool SetUniform1f(const char* name, float x)
+ {
+ const float v[] = {x};
+ return SetUniform(name, 1, v);
+ }
+ bool SetUniform2f(const char* name, float x, float y)
+ {
+ const float v[] = {x,y};
+ return SetUniform(name, 2, v);
+ }
+ bool SetUniform3f(const char* name, float x, float y, float z)
+ {
+ const float v[] = {x,y,z};
+ return SetUniform(name, 3, v);
+ }
+ bool SetUniform4f(const char* name, float x, float y, float z, float w = 1)
+ {
+ const float v[] = {x,y,z,w};
+ return SetUniform(name, 4, v);
+ }
+
+ bool SetUniformv(const char* name, const Vector3f& v)
+ {
+ const float a[] = {v.x,v.y,v.z,1};
+ return SetUniform(name, 4, a);
+ }
+
+ virtual bool SetUniform4x4f(const char* name, const Matrix4f& m)
+ {
+ Matrix4f mt = m.Transposed();
+ return SetUniform(name, 16, &mt.M[0][0]);
+ }
+};
+
+
+// Fill combines a ShaderSet (vertex, pixel) with textures, if any.
+// Every model has a fill.
+class ShaderFill : public RefCountBase<ShaderFill>
+{
+ Ptr<ShaderSet> Shaders;
+ Ptr<class Texture> Textures[8];
+ void* InputLayout; // HACK this should be abstracted
+
+public:
+ ShaderFill(ShaderSet* sh) : Shaders(sh) { InputLayout = NULL; }
+ ShaderFill(ShaderSet& sh) : Shaders(sh) { InputLayout = NULL; }
+
+ ShaderSet* GetShaders() const { return Shaders; }
+ void* GetInputLayout() const { return InputLayout; }
+
+ virtual void Set(PrimitiveType prim = Prim_Unknown) const;
+ virtual void SetTexture(int i, class Texture* tex) { if (i < 8) Textures[i] = tex; }
+ void SetInputLayout(void* newIL) { InputLayout = (void*)newIL; }
+};
+
+
+class ShaderBase : public Shader
+{
+public:
+ RenderParams* pParams;
+ unsigned char* UniformData;
+ int UniformsSize;
+
+ enum VarType
+ {
+ VARTYPE_FLOAT,
+ VARTYPE_INT,
+ VARTYPE_BOOL,
+ };
+
+ struct Uniform
+ {
+ const char* Name;
+ VarType Type;
+ int Offset, Size;
+ };
+ const Uniform* UniformRefl;
+ size_t UniformReflSize;
+
+ ShaderBase(RenderParams* rp, ShaderStage stage);
+ ~ShaderBase();
+
+ ShaderStage GetStage() const { return Stage; }
+
+ 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);
+};
+
+
+template<ShaderStage SStage, class D3DShaderType>
+class ShaderImpl : public ShaderBase
+{
+public:
+ D3DShaderType* D3DShader;
+
+ ShaderImpl(RenderParams* rp, void* s, size_t size, const Uniform* refl, size_t reflSize) : ShaderBase(rp, SStage)
+ {
+ Load(s, size);
+ InitUniforms(refl, reflSize);
+ }
+ ~ShaderImpl()
+ {
+ if (D3DShader)
+ D3DShader->Release();
+ }
+
+ // These functions have specializations.
+ bool Load(void* shader, size_t size);
+ void Set(PrimitiveType prim) const;
+ void SetUniformBuffer(Buffer* buffers, int i = 0);
+};
+
+typedef ShaderImpl<Shader_Vertex, ID3D1xVertexShader> VertexShader;
+typedef ShaderImpl<Shader_Fragment, ID3D1xPixelShader> PixelShader;
+
+
+class Buffer : public RefCountBase<Buffer>
+{
+public:
+ RenderParams* pParams;
+ Ptr<ID3D1xBuffer> D3DBuffer;
+ size_t Size;
+ int Use;
+ bool Dynamic;
+
+public:
+ Buffer(RenderParams* rp) : pParams(rp), Size(0), Use(0) {}
+ ~Buffer();
+
+ ID3D1xBuffer* GetBuffer() const { return D3DBuffer; }
+
+ virtual size_t GetSize() { return Size; }
+ virtual void* Map(size_t start, size_t size, int flags = 0);
+ virtual bool Unmap(void *m);
+ virtual bool Data(int use, const void* buffer, size_t size);
+};
+
+
+class Texture : public RefCountBase<Texture>
+{
+public:
+ RenderParams* pParams;
+ Ptr<ID3D1xTexture2D> Tex;
+ Ptr<ID3D1xShaderResourceView> TexSv;
+ Ptr<ID3D1xRenderTargetView> TexRtv;
+ Ptr<ID3D1xDepthStencilView> TexDsv;
+ mutable Ptr<ID3D1xSamplerState> Sampler;
+ Sizei TextureSize;
+ int Samples;
+
+ Texture(RenderParams* rp, int fmt, const Sizei texSize,
+ ID3D1xSamplerState* sampler, int samples = 1);
+ ~Texture();
+
+ virtual Sizei GetSize() const { return TextureSize; }
+ virtual int GetSamples() const { return Samples; }
+
+ // virtual void SetSampleMode(int sm);
+
+ // Updates texture to point to specified resources
+ // - used for slave rendering.
+ void UpdatePlaceholderTexture(ID3D1xTexture2D* texture,
+ ID3D1xShaderResourceView* psrv,
+ const Sizei& textureSize)
+ {
+ Tex = texture;
+ TexSv = psrv;
+ TexRtv.Clear();
+ TexDsv.Clear();
+
+ TextureSize = textureSize;
+
+#ifdef OVR_BUILD_DEBUG
+ D3D1X_(TEXTURE2D_DESC) desc;
+ texture->GetDesc(&desc);
+ OVR_ASSERT(TextureSize == Sizei(desc.Width, desc.Height));
+#endif
+ }
+
+
+ virtual void Set(int slot, ShaderStage stage = Shader_Fragment) const;
+
+};
+
+
+class GpuTimer : public RefCountBase<GpuTimer>
+{
+public:
+ GpuTimer()
+ : QuerySets(MaxNumQueryFrames)
+ , D3dDevice(NULL)
+ , Context(NULL)
+ , LastQueuedFrame(-1)
+ , LastTimedFrame(-1)
+ { }
+
+ void Init(ID3D1xDevice* device, ID3D1xDeviceContext* content);
+
+ void BeginQuery();
+ void EndQuery();
+
+ // Returns -1 if timing is invalid
+ float GetTiming(bool blockUntilValid);
+
+protected:
+ static const unsigned MaxNumQueryFrames = 10;
+
+ int GotoNextFrame(int frame)
+ {
+ return (frame + 1) % MaxNumQueryFrames;
+ }
+
+ _COM_SMARTPTR_TYPEDEF(ID3D1xQuery, __uuidof(ID3D1xQuery));
+
+ struct GpuQuerySets
+ {
+ ID3D1xQueryPtr DisjointQuery;
+ ID3D1xQueryPtr TimeStartQuery;
+ ID3D1xQueryPtr TimeEndQuery;
+ bool QueryStarted;
+ bool QueryAwaitingTiming;
+
+ GpuQuerySets() : QueryStarted(false), QueryAwaitingTiming(false) {}
+ };
+ Array<GpuQuerySets> QuerySets;
+
+ int LastQueuedFrame;
+ int LastTimedFrame;
+
+ Ptr<ID3D1xDevice> D3dDevice;
+ Ptr<ID3D1xDeviceContext> Context;
+};
+
+}}} // OVR::CAPI::D3D1X
+
+#endif // INC_OVR_CAPI_D3D10/11_Util_h
diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp
new file mode 100644
index 0000000..21b885e
--- /dev/null
+++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.cpp
@@ -0,0 +1,251 @@
+/************************************************************************************
+
+Filename : CAPI_D3D1X_DistortionRenderer.cpp
+Content : Experimental distortion renderer
+Created : March 7th, 2014
+Authors : Tom Heath
+
+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 "CAPI_D3D9_DistortionRenderer.h"
+#define OVR_D3D_VERSION 9
+#include "../../OVR_CAPI_D3D.h"
+
+namespace OVR { namespace CAPI { namespace D3D9 {
+
+
+///QUESTION : Why not just a normal constructor?
+CAPI::DistortionRenderer* DistortionRenderer::Create(ovrHmd hmd,
+ FrameTimeManager& timeManager,
+ const HMDRenderState& renderState)
+{
+ return new DistortionRenderer(hmd, timeManager, renderState);
+}
+
+DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager,
+ const HMDRenderState& renderState)
+ : CAPI::DistortionRenderer(ovrRenderAPI_D3D9, hmd, timeManager, renderState)
+{
+}
+/**********************************************/
+DistortionRenderer::~DistortionRenderer()
+{
+ //Release any memory
+ eachEye[0].dxIndices->Release();
+ eachEye[0].dxVerts->Release();
+ eachEye[1].dxIndices->Release();
+ eachEye[1].dxVerts->Release();
+}
+
+
+/******************************************************************************/
+bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig,
+ unsigned hmdCaps, 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;
+ if (!config->D3D9.pDevice) return false;
+
+ //Glean all the required variables from the input structures
+ device = config->D3D9.pDevice;
+ screenSize = config->D3D9.Header.RTSize;
+ distortionCaps = arg_distortionCaps;
+
+ CreateVertexDeclaration();
+ CreateDistortionShaders();
+ Create_Distortion_Models();
+
+ return (true);
+}
+
+
+/**************************************************************/
+void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture)
+{
+ //Doesn't do a lot in here??
+ const ovrD3D9Texture* tex = (const ovrD3D9Texture*)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;
+
+ ovrHmd_GetRenderScaleAndOffset(HMD, ed, distortionCaps, eachEye[eyeId].UVScaleOffset);
+}
+
+
+/******************************************************************/
+void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor)
+{
+ OVR_UNUSED(swapBuffers);
+ OVR_UNUSED(latencyTesterDrawColor);
+
+ ///QUESTION : Should I be clearing the screen?
+ ///QUESTION : Should I be ensuring the screen is the render target
+
+ if (!TimeManager.NeedDistortionTimeMeasurement())
+ {
+ if (RState.DistortionCaps & ovrDistortion_TimeWarp)
+ {
+ // Wait for timewarp distortion if it is time and Gpu idle
+ WaitTillTimeAndFlushGpu(TimeManager.GetFrameTiming().TimewarpPointTime);
+ }
+
+ RenderBothDistortionMeshes();
+ }
+ else
+ {
+ // If needed, measure distortion time so that TimeManager can better estimate
+ // latency-reducing time-warp wait timing.
+ WaitUntilGpuIdle();
+ double distortionStartTime = ovr_GetTimeInSeconds();
+
+ RenderBothDistortionMeshes();
+ WaitUntilGpuIdle();
+
+ TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime);
+ }
+
+ if(latencyTesterDrawColor)
+ {
+ ///QUESTION : Is this still to be supported?
+ ///renderLatencyQuad(latencyTesterDrawColor);
+ }
+
+ if(latencyTester2DrawColor)
+ {
+ // TODO:
+ }
+
+ if (swapBuffers)
+ {
+ device->Present( NULL, NULL, NULL, NULL );
+
+ /// if (RParams.pSwapChain)
+ {
+ /// 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();
+ }
+ /// else
+ {
+ // TBD: Generate error - swapbuffer option used with null swapchain.
+ }
+ }
+}
+
+
+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)
+ {
+ 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
+}
+
+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;
+ }
+
+ 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;
+ }
+ newTime = ovr_GetTimeInSeconds();
+ }
+
+ // How long we waited
+ return newTime - initialTime;
+#endif
+ return 0; //dummy
+}
+
+
+
+
+
+
+
+}}} // OVR::CAPI::D3D1X
+
+
diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h
new file mode 100644
index 0000000..9332b83
--- /dev/null
+++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_DistortionRenderer.h
@@ -0,0 +1,120 @@
+/************************************************************************************
+
+Filename : CAPI_D3D1X_DistortionRenderer.h
+Content : Experimental distortion renderer
+Created : March 7, 2014
+Authors : Tom Heath
+
+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.
+
+************************************************************************************/
+
+#undef new
+
+#if _MSC_VER < 1700
+#include <d3dx9.h>
+#else
+#include <d3d9.h>
+#endif
+
+#if defined(OVR_DEFINE_NEW)
+#define new OVR_DEFINE_NEW
+#endif
+
+#include "../CAPI_DistortionRenderer.h"
+
+
+namespace OVR { namespace CAPI { namespace D3D9 {
+
+
+//Implementation of DistortionRenderer for D3D9.
+/***************************************************/
+class DistortionRenderer : public CAPI::DistortionRenderer
+{
+public:
+ DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager, const HMDRenderState& renderState);
+ ~DistortionRenderer();
+
+ // Creation function for the device.
+ static CAPI::DistortionRenderer* Create(ovrHmd hmd,
+ FrameTimeManager& timeManager,
+ const HMDRenderState& renderState);
+
+ // ***** Public DistortionRenderer interface
+ virtual bool Initialize(const ovrRenderAPIConfig* apiConfig,
+ unsigned hmdCaps, unsigned distortionCaps);
+
+ virtual void SubmitEye(int eyeId, ovrTexture* eyeTexture);
+
+ virtual void EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor);
+
+ // TBD: Make public?
+ void WaitUntilGpuIdle();
+
+ // Similar to ovr_WaitTillTime but it also flushes GPU.
+ // Note, it exits when time expires, even if GPU is not in idle state yet.
+ double WaitTillTimeAndFlushGpu(double absTime);
+
+private:
+
+ //Functions
+ void CreateDistortionShaders(void);
+ void Create_Distortion_Models(void);
+ void CreateVertexDeclaration(void);
+ void RenderBothDistortionMeshes();
+ void RecordAndSetState(int which, int type, DWORD newValue);
+ void RevertAllStates(void);
+
+
+ //Data, structures and pointers
+ IDirect3DDevice9 * device;
+ IDirect3DVertexDeclaration9 * vertexDecl;
+ IDirect3DPixelShader9 * pixelShader;
+ IDirect3DVertexShader9 * vertexShader;
+ IDirect3DVertexShader9 * vertexShaderTimewarp;
+ ovrSizei screenSize;
+ unsigned distortionCaps;
+
+ struct FOR_EACH_EYE
+ {
+ IDirect3DVertexBuffer9 * dxVerts;
+ IDirect3DIndexBuffer9 * dxIndices;
+ int numVerts;
+ int numIndices;
+ IDirect3DTexture9 * texture;
+ ovrVector2f UVScaleOffset[2];
+ } 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
new file mode 100644
index 0000000..ea36100
--- /dev/null
+++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D9_Util.cpp
@@ -0,0 +1,317 @@
+/************************************************************************************
+
+Filename : CAPI_D3D1X_Util.cpp
+Content : D3D9 utility functions for rendering
+Created : March 7 , 2014
+Authors : Tom Heath
+
+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 "CAPI_D3D9_DistortionRenderer.h"
+#define OVR_D3D_VERSION 9
+#include "../../OVR_CAPI_D3D.h"
+
+
+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.
+//Then cut and paste these from the output window.
+//Then turn off the flag.
+DWORD precompiledVertexShaderSrc[95] = {4294836736,3014654,1111577667,28,127,4294836736,2,28,33024,120,68,131074,655361,88,0,104,2,131073,88,0,1415936325,1668436847,1716475477,1952805734,2880154368,196609,131073,1,0,1415936325,1668436847,1666405973,6646881,845116278,1291858015,1869767529,1952870259,693250080,1397508128,1750278220,1919247457,1836008224,1701603696,775495794,959330610,858665525,3223857,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147614720,2416902145,33554463,2147483653,2416902146,33554463,2147549189,2416902147,33554463,2147614725,2416902148,33554433,2147680256,2699296768,67108868,3758292992,2162425856,2430861314,2699296770,67108868,3758292993,2162425856,2430861315,2699296770,67108868,3758292994,2162425856,2430861316,2699296770,67108868,3222208512,2416181248,2689597441,2686779393,33554433,3758161923,2415919105,65535,};
+DWORD precompiledVertexShaderTimewarpSrc[293] = {4294836736,4456446,1111577667,28,215,4294836736,4,28,33024,208,108,1310722,5373956,124,0,140,262146,1179652,124,0,157,131074,655361,176,0,192,2,131073,176,0,1382381893,1952543855,1164865385,2868929646,196611,262148,1,0,1382381893,1952543855,1399746409,1953653108,1702446336,1918070612,1331058019,1702061670,2880110708,196609,131073,1,0,1415936325,1668436847,1666405973,6646881,845116278,1291858015,1869767529,1952870259,693250080,1397508128,1750278220,1919247457,1836008224,1701603696,775495794,959330610,858665525,3223857,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147549184,2416902145,33554463,2147614720,2416902146,33554463,2147483653,2416902147,33554463,2147549189,2416902148,33554463,2147614725,2416902149,33554433,2147549184,2695495684,50331650,2147549185,2164260864,2695495700,33554433,2147614720,2695495685,50331650,2147614721,2169831424,2695495701,33554433,2147745792,2695495686,50331650,2147745793,2175401984,2695495702,33554433,2148007936,2695495687,50331650,2148007937,2180972544,2695495703,67108868,2148466688,2415919105,2162425857,2162425856,67108868,2148466689,2416181251,2689597441,2684682241,50331657,2147549186,2162425856,2162425857,33554438,2147549186,2147483650,33554433,2147680259,2699296772,50331650,2147876866,2177892355,2697986068,67108868,2147549187,2415919105,2158624770,2689925124,67108868,2147549188,2415919105,2153054210,2684354564,33554433,2147680261,2699296773,50331650,2147876866,2177105925,2697199637,67108868,2147614723,2415919105,2153054210,2689925125,67108868,2147614724,2415919105,2158624770,2684354565,33554433,2147680261,2699296774,50331650,2147811333,2177171461,2697265174,67108868,2147745795,2415919105,2147483653,2689925126,67108868,2147745796,2415919105,2158624773,2684354566,33554433,2147680261,2699296775,50331650,2148073477,2166685701,2686779415,67108868,2148007939,2415919105,2147483653,2689925127,67108868,2148007940,2415919105,2164195333,2684354567,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331653,2147680257,2147483650,2162425861,33554433,2147680258,2699296768,67108868,3758292992,2162425858,2162425857,2699296770,67108868,2148466689,2416181252,2689597441,2684682241,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331657,2147549185,2162425856,2162425857,33554438,2147549185,2147483649,50331653,2147680257,2147483649,2162425861,67108868,3758292993,2162425858,2162425857,2699296770,67108868,2148466689,2416181253,2689597441,2684682241,50331657,2147549188,2162425860,2162425857,50331657,2147614724,2162425859,2162425857,50331657,2147549184,2162425856,2162425857,33554438,2147549184,2147483648,50331653,2147680256,2147483648,2162425860,67108868,3758292994,2162425858,2162425856,2699296770,67108868,3222208512,2416181248,2689597441,2686779393,33554433,3758161923,2415919106,65535,};
+DWORD precompiledPixelShaderSrc[84] = {4294902528,2228222,1111577667,28,79,4294902528,1,28,33024,72,48,3,131073,56,0,1954047316,6648437,786436,65537,1,0,861893488,1291858015,1869767529,1952870259,693250080,1397508128,1750278220,1919247457,1836008224,1701603696,775495794,959330610,858665525,3223857,83886161,2685337600,1065353216,0,0,0,33554463,2147483653,2416115712,33554463,2147549189,2416115713,33554463,2147614725,2416115714,33554463,2147680261,2415984643,33554463,2415919104,2685339648,50331714,2148466688,2430861312,2699298816,67108868,2148073472,2147483648,2690908160,2686779392,50331714,2148466689,2430861313,2699298816,33554433,2147614720,2153054209,50331714,2148466689,2430861314,2699298816,33554433,2147745792,2158624769,50331653,2148468736,2162425856,2415919107,65535,};
+
+#else
+#include "d3dcompiler.h"
+/***************************************************************************/
+const char* VertexShaderSrc =
+
+ "float2 EyeToSourceUVScale : register(c0); \n"
+ "float2 EyeToSourceUVOffset : register(c2); \n"
+
+ "void main(in float2 Position : POSITION, in float TimeWarp : POSITION1, \n"
+ " in float Vignette : POSITION2, in float2 TexCoord0 : TEXCOORD0, \n"
+ " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, \n"
+ " out float4 oPosition : SV_Position, out float2 oTexCoord0 : TEXCOORD0, \n"
+ " out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2, \n"
+ " out float oVignette : TEXCOORD3) \n"
+ "{ \n"
+ " oTexCoord0 = EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset; \n"
+ " oTexCoord1 = EyeToSourceUVScale * TexCoord1 + EyeToSourceUVOffset; \n"
+ " oTexCoord2 = EyeToSourceUVScale * TexCoord2 + EyeToSourceUVOffset; \n"
+ " oVignette = Vignette; \n"
+ " oPosition = float4(Position.xy, 0.5, 1.0); \n"
+ "}";
+
+/***************************************************************************/
+const char* VertexShaderTimewarpSrc =
+
+ "float2 EyeToSourceUVScale : register(c0); \n"
+ "float2 EyeToSourceUVOffset : register(c2); \n"
+ "float4x4 EyeRotationStart : register(c4); \n"
+ "float4x4 EyeRotationEnd : register(c20); \n"
+
+ "float2 TimewarpTexCoord(float2 TexCoord, float4x4 rotMat) \n"
+ "{ \n"
+ " float3 transformed = float3( mul ( rotMat, float4(TexCoord.xy, 1, 1) ).xyz); \n"
+ " float2 flattened = (transformed.xy / transformed.z); \n"
+ " return(EyeToSourceUVScale * flattened + EyeToSourceUVOffset); \n"
+ "} \n"
+ "void main(in float2 Position : POSITION, in float TimeWarp : POSITION1, \n"
+ " in float Vignette : POSITION2, in float2 TexCoord0 : TEXCOORD0, \n"
+ " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, \n"
+ " out float4 oPosition : SV_Position, out float2 oTexCoord0 : TEXCOORD0, \n"
+ " out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2, \n"
+ " out float oVignette : TEXCOORD3) \n"
+ "{ \n"
+ " float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, TimeWarp); \n"
+ " oTexCoord0 = TimewarpTexCoord(TexCoord0,lerpedEyeRot); \n"
+ " oTexCoord1 = TimewarpTexCoord(TexCoord1,lerpedEyeRot); \n"
+ " oTexCoord2 = TimewarpTexCoord(TexCoord2,lerpedEyeRot); \n"
+ " oVignette = Vignette; \n"
+ " oPosition = float4(Position.xy, 0.5, 1.0); \n"
+ "}";
+
+/***************************************************************************/
+const char* PixelShaderSrc =
+
+ " sampler2D Texture : register(s0); \n"
+
+ "float4 main(in float4 oPosition : SV_Position, in float2 oTexCoord0 : TEXCOORD0, \n"
+ " in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2, \n"
+ " in float oVignette : TEXCOORD3) \n"
+ " : SV_Target \n"
+ "{ \n"
+ " float R = tex2D(Texture,oTexCoord0).r; \n"
+ " float G = tex2D(Texture,oTexCoord1).g; \n"
+ " float B = tex2D(Texture,oTexCoord2).b; \n"
+ " return (oVignette*float4(R,G,B,1)); \n"
+ "}";
+
+/*************************************************************/
+ID3DBlob* ShaderCompile(char * shaderName, const char * shaderSrcString, const char * profile)
+{
+ ID3DBlob* pShaderCode = NULL;
+ ID3DBlob* pErrorMsg = NULL;
+
+ if (FAILED(D3DCompile(shaderSrcString, strlen(shaderSrcString),NULL,NULL,NULL,
+ "main",profile,D3DCOMPILE_OPTIMIZATION_LEVEL3,0,
+ &pShaderCode,&pErrorMsg)))
+ MessageBoxA(NULL,(char *) pErrorMsg->GetBufferPointer(),"", MB_OK);
+ if (pErrorMsg) pErrorMsg->Release();
+
+ //Now write out blob
+ char tempString[1000];
+ int numDWORDs = ((int)pShaderCode->GetBufferSize())/4;
+ DWORD * ptr = (DWORD *)pShaderCode->GetBufferPointer();
+ sprintf_s(tempString,"DWORD %s[%d] = {",shaderName,numDWORDs);
+ OutputDebugStringA(tempString);
+ for (int i = 0;i < numDWORDs; i++)
+ {
+ sprintf_s(tempString,"%lu,",ptr[i]);
+ OutputDebugStringA(tempString);
+ }
+ OutputDebugStringA("};\n");
+
+ return(pShaderCode);
+}
+#endif
+
+/***********************************************************/
+void DistortionRenderer::CreateDistortionShaders(void)
+{
+#if PRECOMPILE_FLAG
+ ID3DBlob * pShaderCode;
+ pShaderCode = ShaderCompile("precompiledVertexShaderSrc",VertexShaderSrc,"vs_2_0");
+ device->CreateVertexShader( ( DWORD* )pShaderCode->GetBufferPointer(), &vertexShader );
+ pShaderCode->Release();
+
+ pShaderCode = ShaderCompile("precompiledVertexShaderTimewarpSrc",VertexShaderTimewarpSrc,"vs_2_0");
+ device->CreateVertexShader( ( DWORD* )pShaderCode->GetBufferPointer(), &vertexShaderTimewarp );
+ pShaderCode->Release();
+
+ pShaderCode = ShaderCompile("precompiledPixelShaderSrc",PixelShaderSrc,"ps_3_0");
+ device->CreatePixelShader( ( DWORD* )pShaderCode->GetBufferPointer(), &pixelShader );
+ pShaderCode->Release();
+#else
+ device->CreateVertexShader( precompiledVertexShaderSrc, &vertexShader );
+ device->CreateVertexShader( precompiledVertexShaderTimewarpSrc, &vertexShaderTimewarp );
+ device->CreatePixelShader( precompiledPixelShaderSrc, &pixelShader );
+#endif
+}
+
+
+/***************************************************/
+void DistortionRenderer::CreateVertexDeclaration(void)
+{
+ static const D3DVERTEXELEMENT9 VertexElements[7] = {
+ { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
+ { 0, 8, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1 },
+ { 0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 2 },
+ { 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
+ { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
+ { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 },
+ D3DDECL_END() };
+ device->CreateVertexDeclaration( VertexElements, &vertexDecl );
+}
+
+
+/******************************************************/
+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);
+
+ e->numVerts = meshData.VertexCount;
+ e->numIndices = meshData.IndexCount;
+
+ 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 );
+ unsigned short* dxi; e->dxIndices->Lock( 0, 0, (void**)&dxi, 0 );
+ for (int i=0;i<e->numIndices;i++) dxi[i] = meshData.pIndexData[i];
+
+ ovrHmd_DestroyDistortionMesh( &meshData );
+ }
+}
+
+/**********************************************************/
+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];
+ D3DVIEWPORT9 vp; vp.X=0; vp.Y=0; vp.Width=screenSize.w; vp.Height=screenSize.h; vp.MinZ=0; vp.MaxZ = 1;
+ device->SetViewport(&vp);
+ device->SetStreamSource( 0, e->dxVerts,0, sizeof(ovrDistortionVertex) );
+ device->SetVertexDeclaration( vertexDecl );
+ device->SetIndices( e->dxIndices );
+ device->SetPixelShader( pixelShader );
+ device->SetTexture( 0, e->texture);
+
+ //Choose which vertex shader, with associated additional inputs
+ if (distortionCaps & ovrDistortion_TimeWarp)
+ {
+ device->SetVertexShader( vertexShaderTimewarp );
+
+ ovrMatrix4f timeWarpMatrices[2];
+ ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eye,
+ RState.EyeRenderPoses[eye], timeWarpMatrices);
+
+ // 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);
+ }
+ else
+ {
+ 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
new file mode 100644
index 0000000..a953d73
--- /dev/null
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp
@@ -0,0 +1,1006 @@
+/************************************************************************************
+
+Filename : CAPI_GL_DistortionRenderer.h
+Content : Distortion renderer header for GL
+Created : November 11, 2013
+Authors : David Borel, Lee Cooper
+
+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.
+
+************************************************************************************/
+
+#include "CAPI_GL_DistortionRenderer.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
+
+enum {
+ DistortionVertexShaderBitMask = 3,
+ DistortionVertexShaderCount = DistortionVertexShaderBitMask + 1,
+ DistortionPixelShaderBitMask = 1,
+ DistortionPixelShaderCount = DistortionPixelShaderBitMask + 1
+};
+
+struct ShaderInfo
+{
+ const char* ShaderData;
+ size_t ShaderSize;
+ const ShaderBase::Uniform* ReflectionData;
+ size_t ReflectionSize;
+};
+
+// Do add a new distortion shader use these macros (with or w/o reflection)
+#define SI_NOREFL(shader) { shader, sizeof(shader), NULL, 0 }
+#define SI_REFL__(shader) { shader, sizeof(shader), shader ## _refl, sizeof( shader ## _refl )/sizeof(*(shader ## _refl)) }
+
+
+static ShaderInfo DistortionVertexShaderLookup[DistortionVertexShaderCount] =
+{
+ SI_REFL__(Distortion_vs),
+ SI_REFL__(DistortionChroma_vs),
+ SI_REFL__(DistortionTimewarp_vs),
+ SI_REFL__(DistortionTimewarpChroma_vs)
+ //SI_REFL__(DistortionPositionalTimewarp_vs),
+ //SI_REFL__(DistortionPositionalTimewarpChroma_vs)
+};
+
+static ShaderInfo DistortionPixelShaderLookup[DistortionPixelShaderCount] =
+{
+ SI_NOREFL(Distortion_fs),
+ SI_NOREFL(DistortionChroma_fs)
+};
+
+void DistortionShaderBitIndexCheck()
+{
+ OVR_COMPILER_ASSERT(ovrDistortion_Chromatic == 1);
+ OVR_COMPILER_ASSERT(ovrDistortion_TimeWarp == 2);
+}
+
+
+
+struct DistortionVertex
+{
+ Vector2f Pos;
+ Vector2f TexR;
+ Vector2f TexG;
+ Vector2f TexB;
+ Color Col;
+};
+
+
+// Vertex type; same format is used for all shapes for simplicity.
+// Shapes are built by adding vertices to Model.
+struct LatencyVertex
+{
+ Vector3f Pos;
+ LatencyVertex (const Vector3f& p) : Pos(p) {}
+};
+
+
+//----------------------------------------------------------------------------
+// ***** GL::DistortionRenderer
+
+DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager,
+ const HMDRenderState& renderState)
+ : CAPI::DistortionRenderer(ovrRenderAPI_OpenGL, hmd, timeManager, renderState)
+{
+}
+
+DistortionRenderer::~DistortionRenderer()
+{
+ destroy();
+}
+
+// static
+CAPI::DistortionRenderer* DistortionRenderer::Create(ovrHmd hmd,
+ FrameTimeManager& timeManager,
+ const HMDRenderState& renderState)
+{
+ InitGLExtensions();
+
+ return new DistortionRenderer(hmd, timeManager, renderState);
+}
+
+
+bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig,
+ unsigned hmdCaps, unsigned distortionCaps)
+{
+ // TBD: Decide if hmdCaps are needed here or are a part of RenderState
+ OVR_UNUSED(hmdCaps);
+
+ const ovrGLConfig* config = (const ovrGLConfig*)apiConfig;
+
+ if (!config)
+ {
+ // Cleanup
+ pEyeTextures[0].Clear();
+ pEyeTextures[1].Clear();
+ 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;
+
+ DistortionCaps = distortionCaps;
+
+ //DistortionWarper.SetVsync((hmdCaps & ovrHmdCap_NoVSync) ? false : true);
+
+ pEyeTextures[0] = *new Texture(&RParams, 0, 0);
+ pEyeTextures[1] = *new Texture(&RParams, 0, 0);
+
+ initBuffersAndShaders();
+
+ return true;
+}
+
+
+void DistortionRenderer::SubmitEye(int eyeId, ovrTexture* eyeTexture)
+{
+ //Doesn't do a lot in here??
+ const ovrGLTexture* tex = (const ovrGLTexture*)eyeTexture;
+
+ //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);
+
+ pEyeTextures[eyeId]->UpdatePlaceholderTexture(tex->OGL.TexId,
+ tex->OGL.Header.TextureSize);
+ }
+}
+
+void DistortionRenderer::EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor)
+{
+ if (!TimeManager.NeedDistortionTimeMeasurement())
+ {
+ if (RState.DistortionCaps & ovrDistortion_TimeWarp)
+ {
+ // Wait for timewarp distortion if it is time and Gpu idle
+ FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime);
+ }
+
+ renderDistortion(pEyeTextures[0], pEyeTextures[1]);
+ }
+ else
+ {
+ // If needed, measure distortion time so that TimeManager can better estimate
+ // latency-reducing time-warp wait timing.
+ WaitUntilGpuIdle();
+ double distortionStartTime = ovr_GetTimeInSeconds();
+
+ renderDistortion(pEyeTextures[0], pEyeTextures[1]);
+
+ WaitUntilGpuIdle();
+ TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime);
+ }
+
+ if(latencyTesterDrawColor)
+ {
+ renderLatencyQuad(latencyTesterDrawColor);
+ }
+ else if(latencyTester2DrawColor)
+ {
+ renderLatencyPixel(latencyTester2DrawColor);
+ }
+
+ if (swapBuffers)
+ {
+ bool useVsync = ((RState.HMDCaps & ovrHmdCap_NoVSync) == 0);
+ BOOL success;
+ int swapInterval = (useVsync) ? 1 : 0;
+ if (wglGetSwapIntervalEXT() != swapInterval)
+ wglSwapIntervalEXT(swapInterval);
+
+ success = SwapBuffers(RParams.GdiDc);
+ OVR_ASSERT(success);
+
+ // 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()
+{
+ glFlush();
+ glFinish();
+}
+
+double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime)
+{
+ double initialTime = ovr_GetTimeInSeconds();
+ if (initialTime >= absTime)
+ return 0.0;
+
+ glFlush();
+ glFinish();
+
+ double newTime = initialTime;
+ volatile int i;
+
+ while (newTime < absTime)
+ {
+ for (int j = 0; j < 50; j++)
+ i = 0;
+
+ newTime = ovr_GetTimeInSeconds();
+ }
+
+ // How long we waited
+ return newTime - initialTime;
+}
+
+
+void DistortionRenderer::initBuffersAndShaders()
+{
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ // Allocate & generate distortion mesh vertices.
+ ovrDistortionMesh meshData;
+
+// double startT = ovr_GetTimeInSeconds();
+
+ if (!ovrHmd_CreateDistortionMesh( HMD, RState.EyeRenderDesc[eyeNum].Desc,
+ RState.DistortionCaps,
+ UVScaleOffset[eyeNum], &meshData) )
+ {
+ OVR_ASSERT(false);
+ continue;
+ }
+
+ // Now parse the vertex data and create a render ready vertex buffer from it
+ DistortionVertex * pVBVerts = (DistortionVertex*)OVR_ALLOC ( sizeof(DistortionVertex) * meshData.VertexCount );
+ DistortionVertex * pCurVBVert = pVBVerts;
+ ovrDistortionVertex* pCurOvrVert = meshData.pVertexData;
+
+ for ( unsigned vertNum = 0; vertNum < meshData.VertexCount; vertNum++ )
+ {
+ pCurVBVert->Pos.x = pCurOvrVert->Pos.x;
+ pCurVBVert->Pos.y = pCurOvrVert->Pos.y;
+ pCurVBVert->TexR = (*(Vector2f*)&pCurOvrVert->TexR);
+ pCurVBVert->TexG = (*(Vector2f*)&pCurOvrVert->TexG);
+ pCurVBVert->TexB = (*(Vector2f*)&pCurOvrVert->TexB);
+ // Convert [0.0f,1.0f] to [0,255]
+ pCurVBVert->Col.R = (OVR::UByte)( pCurOvrVert->VignetteFactor * 255.99f );
+ pCurVBVert->Col.G = pCurVBVert->Col.R;
+ pCurVBVert->Col.B = pCurVBVert->Col.R;
+ pCurVBVert->Col.A = (OVR::UByte)( pCurOvrVert->TimeWarpFactor * 255.99f );;
+ pCurOvrVert++;
+ pCurVBVert++;
+ }
+
+ DistortionMeshVBs[eyeNum] = *new Buffer(&RParams);
+ DistortionMeshVBs[eyeNum]->Data ( Buffer_Vertex, pVBVerts, sizeof(DistortionVertex) * meshData.VertexCount );
+ DistortionMeshIBs[eyeNum] = *new Buffer(&RParams);
+ DistortionMeshIBs[eyeNum]->Data ( Buffer_Index, meshData.pIndexData, ( sizeof(INT16) * meshData.IndexCount ) );
+
+ OVR_FREE ( pVBVerts );
+ ovrHmd_DestroyDistortionMesh( &meshData );
+ }
+
+ initShaders();
+}
+
+void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* rightEyeTexture)
+{
+ setViewport( Recti(0,0, RParams.RTSize.w, RParams.RTSize.h) );
+
+ glClearColor(
+ RState.ClearColor[0],
+ RState.ClearColor[1],
+ RState.ClearColor[2],
+ RState.ClearColor[3] );
+
+ glClearDepth(0);
+
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_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);
+
+ if (DistortionCaps & ovrDistortion_TimeWarp)
+ {
+ ovrMatrix4f timeWarpMatrices[2];
+ ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum,
+ RState.EyeRenderPoses[eyeNum], timeWarpMatrices);
+
+ // Feed identity like matrices in until we get proper timewarp calculation going on
+ DistortionShader->SetUniform4x4f("EyeRotationStart", Matrix4f(timeWarpMatrices[0]).Transposed());
+ DistortionShader->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1]).Transposed());
+
+ renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum],
+ NULL, 0, (int)DistortionMeshVBs[eyeNum]->GetSize(), Prim_Triangles, true);
+ }
+ else
+ {
+ renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum],
+ NULL, 0, (int)DistortionMeshVBs[eyeNum]->GetSize(), Prim_Triangles, true);
+ }
+ }
+}
+
+void DistortionRenderer::createDrawQuad()
+{
+ const int numQuadVerts = 4;
+ LatencyTesterQuadVB = *new Buffer(&RParams);
+ if(!LatencyTesterQuadVB)
+ {
+ return;
+ }
+
+ LatencyTesterQuadVB->Data(Buffer_Vertex, NULL, numQuadVerts * sizeof(LatencyVertex));
+ LatencyVertex* vertices = (LatencyVertex*)LatencyTesterQuadVB->Map(0, numQuadVerts * sizeof(LatencyVertex), Map_Discard);
+ if(!vertices)
+ {
+ OVR_ASSERT(false); // failed to lock vertex buffer
+ return;
+ }
+
+ const float left = -1.0f;
+ const float top = -1.0f;
+ const float right = 1.0f;
+ const float bottom = 1.0f;
+
+ vertices[0] = LatencyVertex(Vector3f(left, top, 0.0f));
+ vertices[1] = LatencyVertex(Vector3f(left, bottom, 0.0f));
+ vertices[2] = LatencyVertex(Vector3f(right, top, 0.0f));
+ vertices[3] = LatencyVertex(Vector3f(right, bottom, 0.0f));
+
+ LatencyTesterQuadVB->Unmap(vertices);
+}
+
+void DistortionRenderer::renderLatencyQuad(unsigned char* latencyTesterDrawColor)
+{
+ const int numQuadVerts = 4;
+
+ if(!LatencyTesterQuadVB)
+ {
+ createDrawQuad();
+ }
+
+ ShaderFill quadFill(SimpleQuadShader);
+ //quadFill.SetInputLayout(SimpleQuadVertexIL);
+
+ setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h));
+
+ SimpleQuadShader->SetUniform2f("Scale", 0.2f, 0.2f);
+ SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterDrawColor[0] / 255.99f,
+ (float)latencyTesterDrawColor[0] / 255.99f,
+ (float)latencyTesterDrawColor[0] / 255.99f,
+ 1.0f);
+
+ 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);
+ }
+}
+
+void DistortionRenderer::renderLatencyPixel(unsigned char* latencyTesterPixelColor)
+{
+ const int numQuadVerts = 4;
+
+ if(!LatencyTesterQuadVB)
+ {
+ createDrawQuad();
+ }
+
+ ShaderFill quadFill(SimpleQuadShader);
+
+ setViewport(Recti(0,0, RParams.RTSize.w, RParams.RTSize.h));
+
+ SimpleQuadShader->SetUniform4f("Color", (float)latencyTesterPixelColor[0] / 255.99f,
+ (float)latencyTesterPixelColor[0] / 255.99f,
+ (float)latencyTesterPixelColor[0] / 255.99f,
+ 1.0f);
+
+ 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);
+}
+
+void DistortionRenderer::renderPrimitives(
+ const ShaderFill* fill,
+ Buffer* vertices, Buffer* indices,
+ Matrix4f* viewMatrix, int offset, int count,
+ PrimitiveType rprim, bool useDistortionVertex)
+{
+ ShaderSet* shaders = (ShaderSet*) ((ShaderFill*)fill)->GetShaders();
+
+ GLenum prim;
+ switch (rprim)
+ {
+ case Prim_Triangles:
+ prim = GL_TRIANGLES;
+ break;
+ case Prim_Lines:
+ prim = GL_LINES;
+ break;
+ case Prim_TriangleStrip:
+ prim = GL_TRIANGLE_STRIP;
+ break;
+ default:
+ assert(0);
+ 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)
+ {
+ 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");
+
+ glVertexAttribPointer(posLoc, 3, GL_FLOAT, false, sizeof(LatencyVertex), (char*)offset + offsetof(LatencyVertex, Pos));
+ }
+
+ 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);
+}
+
+
+void DistortionRenderer::initShaders()
+{
+ {
+ ShaderInfo vsShaderByteCode = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & DistortionCaps];
+ Ptr<GL::VertexShader> vtxShader = *new GL::VertexShader(
+ &RParams,
+ (void*)vsShaderByteCode.ShaderData, vsShaderByteCode.ShaderSize,
+ vsShaderByteCode.ReflectionData, vsShaderByteCode.ReflectionSize);
+
+ DistortionShader = *new ShaderSet;
+ DistortionShader->SetShader(vtxShader);
+
+ ShaderInfo psShaderByteCode = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & DistortionCaps];
+
+ Ptr<GL::FragmentShader> ps = *new GL::FragmentShader(
+ &RParams,
+ (void*)psShaderByteCode.ShaderData, psShaderByteCode.ShaderSize,
+ psShaderByteCode.ReflectionData, psShaderByteCode.ReflectionSize);
+
+ DistortionShader->SetShader(ps);
+ }
+ {
+ Ptr<GL::VertexShader> vtxShader = *new GL::VertexShader(
+ &RParams,
+ (void*)SimpleQuad_vs, sizeof(SimpleQuad_vs),
+ SimpleQuad_vs_refl, sizeof(SimpleQuad_vs_refl) / sizeof(SimpleQuad_vs_refl[0]));
+
+ SimpleQuadShader = *new ShaderSet;
+ SimpleQuadShader->SetShader(vtxShader);
+
+ Ptr<GL::FragmentShader> ps = *new GL::FragmentShader(
+ &RParams,
+ (void*)SimpleQuad_fs, sizeof(SimpleQuad_fs),
+ SimpleQuad_fs_refl, sizeof(SimpleQuad_fs_refl) / sizeof(SimpleQuad_fs_refl[0]));
+
+ SimpleQuadShader->SetShader(ps);
+ }
+}
+
+
+void DistortionRenderer::destroy()
+{
+ for(int eyeNum = 0; eyeNum < 2; eyeNum++)
+ {
+ DistortionMeshVBs[eyeNum].Clear();
+ DistortionMeshIBs[eyeNum].Clear();
+ }
+
+ if (DistortionShader)
+ {
+ DistortionShader->UnsetShader(Shader_Vertex);
+ DistortionShader->UnsetShader(Shader_Pixel);
+ DistortionShader.Clear();
+ }
+
+ LatencyTesterQuadVB.Clear();
+}
+
+}}} // OVR::CAPI::GL
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h
new file mode 100644
index 0000000..8e0b72e
--- /dev/null
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h
@@ -0,0 +1,125 @@
+/************************************************************************************
+
+Filename : CAPI_GL_DistortionRenderer.h
+Content : Distortion renderer header for GL
+Created : November 11, 2013
+Authors : David Borel, Lee Cooper
+
+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_DistortionRenderer_h
+#define OVR_CAPI_GL_DistortionRenderer_h
+
+#include "../CAPI_DistortionRenderer.h"
+
+#include "../../Kernel/OVR_Log.h"
+#include "CAPI_GL_Util.h"
+
+namespace OVR { namespace CAPI { namespace GL {
+
+// ***** GL::DistortionRenderer
+
+// Implementation of DistortionRenderer for GL.
+
+class DistortionRenderer : public CAPI::DistortionRenderer
+{
+public:
+ DistortionRenderer(ovrHmd hmd,
+ FrameTimeManager& timeManager,
+ const HMDRenderState& renderState);
+ ~DistortionRenderer();
+
+
+ // Creation function for the device.
+ static CAPI::DistortionRenderer* Create(ovrHmd hmd,
+ FrameTimeManager& timeManager,
+ const HMDRenderState& renderState);
+
+
+ // ***** Public DistortionRenderer interface
+
+ virtual bool Initialize(const ovrRenderAPIConfig* apiConfig,
+ unsigned hmdCaps, unsigned distortionCaps);
+
+ virtual void SubmitEye(int eyeId, ovrTexture* eyeTexture);
+
+ virtual void EndFrame(bool swapBuffers, unsigned char* latencyTesterDrawColor, unsigned char* latencyTester2DrawColor);
+
+ void WaitUntilGpuIdle();
+
+ // Similar to ovr_WaitTillTime but it also flushes GPU.
+ // Note, it exits when time expires, even if GPU is not in idle state yet.
+ double FlushGpuAndWaitTillTime(double absTime);
+
+private:
+ // TBD: Should we be using oe from RState instead?
+ unsigned DistortionCaps;
+
+ struct FOR_EACH_EYE
+ {
+#if 0
+ IDirect3DVertexBuffer9 * dxVerts;
+ IDirect3DIndexBuffer9 * dxIndices;
+#endif
+ int numVerts;
+ int numIndices;
+
+ GLuint texture;
+
+ ovrVector2f UVScaleOffset[2];
+ } eachEye[2];
+
+ // GL context and utility variables.
+ RenderParams RParams;
+
+ // Helpers
+ void initBuffersAndShaders();
+ void initShaders();
+ void initFullscreenQuad();
+ void destroy();
+
+ void setViewport(const Recti& vp);
+
+ 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);
+
+ void createDrawQuad();
+ void renderLatencyQuad(unsigned char* latencyTesterDrawColor);
+ void renderLatencyPixel(unsigned char* latencyTesterPixelColor);
+
+ 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
+
+ Ptr<ShaderSet> DistortionShader;
+
+ struct StandardUniformData
+ {
+ Matrix4f Proj;
+ Matrix4f View;
+ } StdUniforms;
+
+ Ptr<Buffer> LatencyTesterQuadVB;
+ Ptr<ShaderSet> SimpleQuadShader;
+
+ Ptr<Texture> CurRenderTarget;
+ Array<Ptr<Texture> > DepthBuffers;
+ GLuint CurrentFbo;
+};
+
+}}} // OVR::CAPI::GL
+
+#endif // OVR_CAPI_GL_DistortionRenderer_h \ No newline at end of file
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp
new file mode 100644
index 0000000..b82939a
--- /dev/null
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp
@@ -0,0 +1,516 @@
+/************************************************************************************
+
+Filename : Render_GL_Device.cpp
+Content : RenderDevice implementation for OpenGL
+Created : September 10, 2012
+Authors : David Borel, Andrew Reisse
+
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+************************************************************************************/
+
+#include "CAPI_GL_Util.h"
+#include "../../Kernel/OVR_Log.h"
+
+namespace OVR { namespace CAPI { namespace GL {
+
+
+
+// GL Hooks for PC.
+#if defined(OVR_OS_WIN32)
+
+PFNWGLGETPROCADDRESS wglGetProcAddress;
+
+PFNGLCLEARPROC glClear;
+PFNGLCLEARCOLORPROC glClearColor;
+PFNGLCLEARDEPTHPROC glClearDepth;
+PFNGLVIEWPORTPROC glViewport;
+PFNGLDRAWELEMENTSPROC glDrawElements;
+PFNGLTEXPARAMETERIPROC glTexParameteri;
+PFNGLFLUSHPROC glFlush;
+PFNGLFINISHPROC glFinish;
+PFNGLDRAWARRAYSPROC glDrawArrays;
+PFNGLGENTEXTURESPROC glGenTextures;
+PFNGLDELETETEXTURESPROC glDeleteTextures;
+PFNGLBINDTEXTUREPROC glBindTexture;
+
+PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;
+PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
+PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
+PFNGLDELETESHADERPROC glDeleteShader;
+PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
+PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
+PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
+PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
+PFNGLACTIVETEXTUREPROC glActiveTexture;
+PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
+PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
+PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
+PFNGLBINDBUFFERPROC glBindBuffer;
+PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv;
+PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
+PFNGLDELETEBUFFERSPROC glDeleteBuffers;
+PFNGLBUFFERDATAPROC glBufferData;
+PFNGLGENBUFFERSPROC glGenBuffers;
+PFNGLMAPBUFFERPROC glMapBuffer;
+PFNGLUNMAPBUFFERPROC glUnmapBuffer;
+PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
+PFNGLGETSHADERIVPROC glGetShaderiv;
+PFNGLCOMPILESHADERPROC glCompileShader;
+PFNGLSHADERSOURCEPROC glShaderSource;
+PFNGLCREATESHADERPROC glCreateShader;
+PFNGLCREATEPROGRAMPROC glCreateProgram;
+PFNGLATTACHSHADERPROC glAttachShader;
+PFNGLDETACHSHADERPROC glDetachShader;
+PFNGLDELETEPROGRAMPROC glDeleteProgram;
+PFNGLUNIFORM1IPROC glUniform1i;
+PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
+PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
+PFNGLUSEPROGRAMPROC glUseProgram;
+PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
+PFNGLGETPROGRAMIVPROC glGetProgramiv;
+PFNGLLINKPROGRAMPROC glLinkProgram;
+PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
+PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
+PFNGLUNIFORM4FVPROC glUniform4fv;
+PFNGLUNIFORM3FVPROC glUniform3fv;
+PFNGLUNIFORM2FVPROC glUniform2fv;
+PFNGLUNIFORM1FVPROC glUniform1fv;
+PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
+PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
+PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
+PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT;
+PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
+
+PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
+
+void InitGLExtensions()
+{
+ 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");
+}
+
+#endif
+
+Buffer::Buffer(RenderParams* rp) : pParams(rp), Size(0), Use(0), GLBuffer(0)
+{
+}
+
+Buffer::~Buffer()
+{
+ if (GLBuffer)
+ glDeleteBuffers(1, &GLBuffer);
+}
+
+bool Buffer::Data(int use, const void* buffer, size_t size)
+{
+ Size = size;
+
+ switch (use & Buffer_TypeMask)
+ {
+ case Buffer_Index: Use = GL_ELEMENT_ARRAY_BUFFER; break;
+ default: Use = GL_ARRAY_BUFFER; break;
+ }
+
+ if (!GLBuffer)
+ glGenBuffers(1, &GLBuffer);
+
+ int mode = GL_DYNAMIC_DRAW;
+ if (use & Buffer_ReadOnly)
+ mode = GL_STATIC_DRAW;
+
+ glBindBuffer(Use, GLBuffer);
+ glBufferData(Use, size, buffer, mode);
+ glBindBuffer(Use, 0);
+ return 1;
+}
+
+void* Buffer::Map(size_t, size_t, int)
+{
+ int mode = GL_WRITE_ONLY;
+ //if (flags & Map_Unsynchronized)
+ // mode |= GL_MAP_UNSYNCHRONIZED;
+
+ glBindBuffer(Use, GLBuffer);
+ void* v = glMapBuffer(Use, mode);
+ glBindBuffer(Use, 0);
+ return v;
+}
+
+bool Buffer::Unmap(void*)
+{
+ glBindBuffer(Use, GLBuffer);
+ int r = glUnmapBuffer(Use);
+ glBindBuffer(Use, 0);
+ return r != 0;
+}
+
+ShaderSet::ShaderSet()
+{
+ Prog = glCreateProgram();
+}
+ShaderSet::~ShaderSet()
+{
+ glDeleteProgram(Prog);
+}
+
+GLint ShaderSet::GetGLShader(Shader* s)
+{
+ switch (s->Stage)
+ {
+ case Shader_Vertex: {
+ ShaderImpl<Shader_Vertex, GL_VERTEX_SHADER>* gls = (ShaderImpl<Shader_Vertex, GL_VERTEX_SHADER>*)s;
+ return gls->GLShader;
+ } break;
+ case Shader_Fragment: {
+ ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER>* gls = (ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER>*)s;
+ return gls->GLShader;
+ } break;
+ }
+
+ return -1;
+}
+
+void ShaderSet::SetShader(Shader *s)
+{
+ Shaders[s->Stage] = s;
+ GLint GLShader = GetGLShader(s);
+ glAttachShader(Prog, GLShader);
+ if (Shaders[Shader_Vertex] && Shaders[Shader_Fragment])
+ Link();
+}
+
+void ShaderSet::UnsetShader(int stage)
+{
+ if (Shaders[stage] == NULL)
+ return;
+
+ GLint GLShader = GetGLShader(Shaders[stage]);
+ glDetachShader(Prog, GLShader);
+
+ Shaders[stage] = NULL;
+
+ //Link();
+}
+
+bool ShaderSet::SetUniform(const char* name, int n, const float* v)
+{
+ for (unsigned int i = 0; i < UniformInfo.GetSize(); i++)
+ if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
+ {
+ OVR_ASSERT(UniformInfo[i].Location >= 0);
+ glUseProgram(Prog);
+ switch (UniformInfo[i].Type)
+ {
+ case 1: glUniform1fv(UniformInfo[i].Location, n, v); break;
+ case 2: glUniform2fv(UniformInfo[i].Location, n/2, v); break;
+ case 3: glUniform3fv(UniformInfo[i].Location, n/3, v); break;
+ case 4: glUniform4fv(UniformInfo[i].Location, n/4, v); break;
+ case 12: glUniformMatrix3fv(UniformInfo[i].Location, 1, 1, v); break;
+ case 16: glUniformMatrix4fv(UniformInfo[i].Location, 1, 1, v); break;
+ default: OVR_ASSERT(0);
+ }
+ return 1;
+ }
+
+ OVR_DEBUG_LOG(("Warning: uniform %s not present in selected shader", name));
+ return 0;
+}
+
+bool ShaderSet::Link()
+{
+ glLinkProgram(Prog);
+ GLint r;
+ glGetProgramiv(Prog, GL_LINK_STATUS, &r);
+ if (!r)
+ {
+ GLchar msg[1024];
+ glGetProgramInfoLog(Prog, sizeof(msg), 0, msg);
+ OVR_DEBUG_LOG(("Linking shaders failed: %s\n", msg));
+ if (!r)
+ return 0;
+ }
+ glUseProgram(Prog);
+
+ UniformInfo.Clear();
+ LightingVer = 0;
+ UsesLighting = 0;
+
+ GLint uniformCount = 0;
+ glGetProgramiv(Prog, GL_ACTIVE_UNIFORMS, &uniformCount);
+ OVR_ASSERT(uniformCount >= 0);
+
+ for(GLuint i = 0; i < (GLuint)uniformCount; i++)
+ {
+ GLsizei namelen;
+ GLint size = 0;
+ GLenum type;
+ GLchar name[32];
+ glGetActiveUniform(Prog, i, sizeof(name), &namelen, &size, &type, name);
+
+ if (size)
+ {
+ int l = glGetUniformLocation(Prog, name);
+ char *np = name;
+ while (*np)
+ {
+ if (*np == '[')
+ *np = 0;
+ np++;
+ }
+ Uniform u;
+ u.Name = name;
+ u.Location = l;
+ u.Size = size;
+ switch (type)
+ {
+ case GL_FLOAT: u.Type = 1; break;
+ case GL_FLOAT_VEC2: u.Type = 2; break;
+ case GL_FLOAT_VEC3: u.Type = 3; break;
+ case GL_FLOAT_VEC4: u.Type = 4; break;
+ case GL_FLOAT_MAT3: u.Type = 12; break;
+ case GL_FLOAT_MAT4: u.Type = 16; break;
+ default:
+ continue;
+ }
+ UniformInfo.PushBack(u);
+ if (!strcmp(name, "LightCount"))
+ UsesLighting = 1;
+ }
+ else
+ break;
+ }
+
+ ProjLoc = glGetUniformLocation(Prog, "Proj");
+ ViewLoc = glGetUniformLocation(Prog, "View");
+ for (int i = 0; i < 8; i++)
+ {
+ char texv[32];
+ OVR_sprintf(texv, 10, "Texture%d", i);
+ TexLoc[i] = glGetUniformLocation(Prog, texv);
+ if (TexLoc[i] < 0)
+ break;
+
+ glUniform1i(TexLoc[i], i);
+ }
+ if (UsesLighting)
+ OVR_ASSERT(ProjLoc >= 0 && ViewLoc >= 0);
+ return 1;
+}
+
+bool ShaderBase::SetUniform(const char* name, int n, const float* v)
+{
+ for(unsigned i = 0; i < UniformReflSize; i++)
+ {
+ if (!strcmp(UniformRefl[i].Name, name))
+ {
+ memcpy(UniformData + UniformRefl[i].Offset, v, n * sizeof(float));
+ return 1;
+ }
+ }
+ return 0;
+}
+
+bool ShaderBase::SetUniformBool(const char* name, int n, const bool* v)
+{
+ OVR_UNUSED(n);
+ for(unsigned i = 0; i < UniformReflSize; i++)
+ {
+ if (!strcmp(UniformRefl[i].Name, name))
+ {
+ memcpy(UniformData + UniformRefl[i].Offset, v, UniformRefl[i].Size);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void ShaderBase::InitUniforms(const Uniform* refl, size_t reflSize)
+{
+ if(!refl)
+ {
+ UniformRefl = NULL;
+ UniformReflSize = 0;
+
+ UniformsSize = 0;
+ if (UniformData)
+ {
+ OVR_FREE(UniformData);
+ UniformData = 0;
+ }
+ return; // no reflection data
+ }
+
+ UniformRefl = refl;
+ UniformReflSize = reflSize;
+
+ UniformsSize = UniformRefl[UniformReflSize-1].Offset + UniformRefl[UniformReflSize-1].Size;
+ 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)
+ glGenTextures(1, &TexId);
+}
+
+Texture::~Texture()
+{
+ if (TexId && !IsUserAllocated)
+ glDeleteTextures(1, &TexId);
+}
+
+void Texture::Set(int slot, ShaderStage) const
+{
+ glActiveTexture(GL_TEXTURE0 + slot);
+ glBindTexture(GL_TEXTURE_2D, TexId);
+ glActiveTexture(GL_TEXTURE0);
+}
+
+void Texture::SetSampleMode(int sm)
+{
+ glBindTexture(GL_TEXTURE_2D, TexId);
+ switch (sm & Sample_FilterMask)
+ {
+ case Sample_Linear:
+ 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, 1);
+ break;
+
+ 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);
+ break;
+
+ case Sample_Nearest:
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
+ break;
+ }
+
+ switch (sm & Sample_AddressMask)
+ {
+ case Sample_Repeat:
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ break;
+
+ case Sample_Clamp:
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ break;
+
+ case Sample_ClampBorder:
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+ 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)
+{
+ if (!IsUserAllocated && TexId && texId != TexId)
+ glDeleteTextures(1, &TexId);
+
+ TexId = texId;
+ Width = textureSize.w;
+ Height = textureSize.h;
+
+ IsUserAllocated = true;
+}
+
+}}}
diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h
new file mode 100644
index 0000000..5e694cc
--- /dev/null
+++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h
@@ -0,0 +1,522 @@
+/************************************************************************************
+
+Filename : CAPI_GL_Util.h
+Content : Utility header for OpenGL
+Created : March 27, 2014
+Authors : Andrew Reisse, David Borel
+
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+************************************************************************************/
+
+#ifndef INC_OVR_CAPI_GL_Util_h
+#define INC_OVR_CAPI_GL_Util_h
+
+#include "../../OVR_CAPI.h"
+#include "../../Kernel/OVR_Array.h"
+#include "../../Kernel/OVR_Math.h"
+#include "../../Kernel/OVR_RefCount.h"
+#include "../../Kernel/OVR_String.h"
+#include "../../Kernel/OVR_Types.h"
+
+#if defined(OVR_OS_WIN32)
+#include <Windows.h>
+#endif
+
+#if defined(OVR_OS_MAC)
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.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
+#endif
+
+namespace OVR { namespace CAPI { namespace GL {
+
+// GL extension Hooks for PC.
+#if defined(OVR_OS_WIN32)
+
+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 *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);
+typedef void (__stdcall *PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
+typedef void (__stdcall *PFNGLCLEARCOLORPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a);
+typedef void (__stdcall *PFNGLCLEARDEPTHPROC) (GLclampd depth);
+typedef void (__stdcall *PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (__stdcall *PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+
+extern PFNWGLGETPROCADDRESS wglGetProcAddress;
+extern PFNGLCLEARPROC glClear;
+extern PFNGLCLEARCOLORPROC glClearColor;
+extern PFNGLCLEARDEPTHPROC glClearDepth;
+extern PFNGLVIEWPORTPROC glViewport;
+extern PFNGLDRAWARRAYSPROC glDrawArrays;
+extern PFNGLDRAWELEMENTSPROC glDrawElements;
+extern PFNGLGENTEXTURESPROC glGenTextures;
+extern PFNGLDELETETEXTURESPROC glDeleteTextures;
+extern PFNGLBINDTEXTUREPROC glBindTexture;
+extern PFNGLTEXPARAMETERIPROC glTexParameteri;
+extern PFNGLFLUSHPROC glFlush;
+extern PFNGLFINISHPROC glFinish;
+
+extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;
+extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
+extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
+extern PFNGLDELETESHADERPROC glDeleteShader;
+extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
+extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
+extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
+extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
+extern PFNGLACTIVETEXTUREPROC glActiveTexture;
+extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
+extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
+extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
+extern PFNGLBINDBUFFERPROC glBindBuffer;
+extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
+extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
+extern PFNGLBUFFERDATAPROC glBufferData;
+extern PFNGLGENBUFFERSPROC glGenBuffers;
+extern PFNGLMAPBUFFERPROC glMapBuffer;
+extern PFNGLUNMAPBUFFERPROC glUnmapBuffer;
+extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
+extern PFNGLGETSHADERIVPROC glGetShaderiv;
+extern PFNGLCOMPILESHADERPROC glCompileShader;
+extern PFNGLSHADERSOURCEPROC glShaderSource;
+extern PFNGLCREATESHADERPROC glCreateShader;
+extern PFNGLCREATEPROGRAMPROC glCreateProgram;
+extern PFNGLATTACHSHADERPROC glAttachShader;
+extern PFNGLDETACHSHADERPROC glDetachShader;
+extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
+extern PFNGLUNIFORM1IPROC glUniform1i;
+extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
+extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
+extern PFNGLUSEPROGRAMPROC glUseProgram;
+extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
+extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
+extern PFNGLLINKPROGRAMPROC glLinkProgram;
+extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
+extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
+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 void InitGLExtensions();
+
+#endif
+
+
+// Rendering primitive type used to render Model.
+enum PrimitiveType
+{
+ Prim_Triangles,
+ Prim_Lines,
+ Prim_TriangleStrip,
+ Prim_Unknown,
+ Prim_Count
+};
+
+// Types of shaders that can be stored together in a ShaderSet.
+enum ShaderStage
+{
+ Shader_Vertex = 0,
+ Shader_Fragment = 2,
+ Shader_Pixel = 2,
+ Shader_Count = 3,
+};
+
+enum MapFlags
+{
+ Map_Discard = 1,
+ Map_Read = 2, // do not use
+ Map_Unsynchronized = 4, // like D3D11_MAP_NO_OVERWRITE
+};
+
+
+// Buffer types used for uploading geometry & constants.
+enum BufferUsage
+{
+ Buffer_Unknown = 0,
+ Buffer_Vertex = 1,
+ Buffer_Index = 2,
+ Buffer_Uniform = 4,
+ Buffer_TypeMask = 0xff,
+ Buffer_ReadOnly = 0x100, // Buffer must be created with Data().
+};
+
+enum TextureFormat
+{
+ Texture_RGBA = 0x0100,
+ Texture_Depth = 0x8000,
+ Texture_TypeMask = 0xff00,
+ Texture_SamplesMask = 0x00ff,
+ Texture_RenderTarget = 0x10000,
+ Texture_GenMipmaps = 0x20000,
+};
+
+// Texture sampling modes.
+enum SampleMode
+{
+ Sample_Linear = 0,
+ Sample_Nearest = 1,
+ Sample_Anisotropic = 2,
+ Sample_FilterMask = 3,
+
+ Sample_Repeat = 0,
+ Sample_Clamp = 4,
+ Sample_ClampBorder = 8, // If unsupported Clamp is used instead.
+ Sample_AddressMask =12,
+
+ Sample_Count =13,
+};
+
+
+// Rendering parameters/pointers describing GL rendering setup.
+struct RenderParams
+{
+#ifdef OVR_OS_WIN32
+ HWND Window;
+ HGLRC WglContext;
+ HDC GdiDc;
+#endif
+
+ ovrSizei RTSize;
+ int Multisample;
+};
+
+
+class Buffer : public RefCountBase<Buffer>
+{
+public:
+ RenderParams* pParams;
+ size_t Size;
+ GLenum Use;
+ GLuint GLBuffer;
+
+public:
+ Buffer(RenderParams* r);
+ ~Buffer();
+
+ GLuint GetBuffer() { return GLBuffer; }
+
+ virtual size_t GetSize() { return Size; }
+ virtual void* Map(size_t start, size_t size, int flags = 0);
+ virtual bool Unmap(void *m);
+ virtual bool Data(int use, const void* buffer, size_t size);
+};
+
+class Texture : public RefCountBase<Texture>
+{
+ bool IsUserAllocated;
+
+public:
+ RenderParams* pParams;
+ GLuint TexId;
+ int Width, Height;
+
+ Texture(RenderParams* rp, int w, int h);
+ ~Texture();
+
+ virtual int GetWidth() const { return Width; }
+ virtual int GetHeight() const { return Height; }
+
+ virtual void SetSampleMode(int sm);
+
+ // Updates texture to point to specified resources
+ // - used for slave rendering.
+ void UpdatePlaceholderTexture(GLuint texId,
+ const Sizei& textureSize);
+
+ virtual void Set(int slot, ShaderStage stage = Shader_Fragment) const;
+};
+
+// Base class for vertex and pixel shaders. Stored in ShaderSet.
+class Shader : public RefCountBase<Shader>
+{
+ friend class ShaderSet;
+
+protected:
+ ShaderStage Stage;
+
+public:
+ Shader(ShaderStage s) : Stage(s) {}
+ virtual ~Shader() {}
+
+ ShaderStage GetStage() const { return Stage; }
+
+ virtual void Set(PrimitiveType) const { }
+ virtual void SetUniformBuffer(class Buffer* buffers, int i = 0) { OVR_UNUSED2(buffers, i); }
+
+protected:
+ virtual bool SetUniform(const char* name, int n, const float* v) { OVR_UNUSED3(name, n, v); return false; }
+ virtual bool SetUniformBool(const char* name, int n, const bool* v) { OVR_UNUSED3(name, n, v); return false; }
+};
+
+
+
+// A group of shaders, one per stage.
+// A ShaderSet is applied for rendering with a given fill.
+class ShaderSet : public RefCountBase<ShaderSet>
+{
+protected:
+ Ptr<Shader> Shaders[Shader_Count];
+
+ struct Uniform
+ {
+ String Name;
+ int Location, Size;
+ int Type; // currently number of floats in vector
+ };
+ Array<Uniform> UniformInfo;
+
+public:
+ GLuint Prog;
+ GLint ProjLoc, ViewLoc;
+ GLint TexLoc[8];
+ bool UsesLighting;
+ int LightingVer;
+
+ ShaderSet();
+ ~ShaderSet();
+
+ virtual void SetShader(Shader *s);
+ virtual void UnsetShader(int stage);
+ Shader* GetShader(int stage) { return Shaders[stage]; }
+
+ virtual void Set(PrimitiveType prim) const
+ {
+ glUseProgram(Prog);
+
+ for (int i = 0; i < Shader_Count; i++)
+ if (Shaders[i])
+ Shaders[i]->Set(prim);
+ }
+
+ // Set a uniform (other than the standard matrices). It is undefined whether the
+ // uniforms from one shader occupy the same space as those in other shaders
+ // (unless a buffer is used, then each buffer is independent).
+ virtual bool SetUniform(const char* name, int n, const float* v);
+ bool SetUniform1f(const char* name, float x)
+ {
+ const float v[] = {x};
+ return SetUniform(name, 1, v);
+ }
+ bool SetUniform2f(const char* name, float x, float y)
+ {
+ const float v[] = {x,y};
+ return SetUniform(name, 2, v);
+ }
+ bool SetUniform3f(const char* name, float x, float y, float z)
+ {
+ const float v[] = {x,y,z};
+ return SetUniform(name, 3, v);
+ }
+ bool SetUniform4f(const char* name, float x, float y, float z, float w = 1)
+ {
+ const float v[] = {x,y,z,w};
+ return SetUniform(name, 4, v);
+ }
+
+ bool SetUniformv(const char* name, const Vector3f& v)
+ {
+ const float a[] = {v.x,v.y,v.z,1};
+ return SetUniform(name, 4, a);
+ }
+
+ virtual bool SetUniform4x4f(const char* name, const Matrix4f& m)
+ {
+ Matrix4f mt = m.Transposed();
+ return SetUniform(name, 16, &mt.M[0][0]);
+ }
+
+protected:
+ GLint GetGLShader(Shader* s);
+ bool Link();
+};
+
+
+// Fill combines a ShaderSet (vertex, pixel) with textures, if any.
+// Every model has a fill.
+class ShaderFill : public RefCountBase<ShaderFill>
+{
+ Ptr<ShaderSet> Shaders;
+ Ptr<class Texture> Textures[8];
+ void* InputLayout; // HACK this should be abstracted
+
+public:
+ ShaderFill(ShaderSet* sh) : Shaders(sh) { InputLayout = NULL; }
+ ShaderFill(ShaderSet& sh) : Shaders(sh) { InputLayout = NULL; }
+
+ ShaderSet* GetShaders() const { return Shaders; }
+ void* GetInputLayout() const { return InputLayout; }
+
+ virtual void Set(PrimitiveType prim = Prim_Unknown) const {
+ Shaders->Set(prim);
+ for(int i = 0; i < 8; i++)
+ {
+ if(Textures[i])
+ {
+ Textures[i]->Set(i);
+ }
+ }
+ }
+
+ virtual void SetTexture(int i, class Texture* tex) { if (i < 8) Textures[i] = tex; }
+};
+
+
+struct DisplayId
+{
+ // Windows
+ String MonitorName; // Monitor name for fullscreen mode
+
+ // MacOS
+ long CgDisplayId; // CGDirectDisplayID
+
+ DisplayId() : CgDisplayId(0) {}
+ DisplayId(long id) : CgDisplayId(id) {}
+ DisplayId(String m, long id=0) : MonitorName(m), CgDisplayId(id) {}
+
+ operator bool () const
+ {
+ return MonitorName.GetLength() || CgDisplayId;
+ }
+
+ bool operator== (const DisplayId& b) const
+ {
+ return CgDisplayId == b.CgDisplayId &&
+ (strstr(MonitorName.ToCStr(), b.MonitorName.ToCStr()) ||
+ strstr(b.MonitorName.ToCStr(), MonitorName.ToCStr()));
+ }
+};
+
+
+class ShaderBase : public Shader
+{
+public:
+ RenderParams* pParams;
+ unsigned char* UniformData;
+ int UniformsSize;
+
+ enum VarType
+ {
+ VARTYPE_FLOAT,
+ VARTYPE_INT,
+ VARTYPE_BOOL,
+ };
+
+ struct Uniform
+ {
+ const char* Name;
+ VarType Type;
+ int Offset, Size;
+ };
+ const Uniform* UniformRefl;
+ size_t UniformReflSize;
+
+ ShaderBase(RenderParams* rp, ShaderStage stage) : Shader(stage), pParams(rp), UniformData(0), UniformsSize(0) {}
+ ~ShaderBase()
+ {
+ if (UniformData)
+ OVR_FREE(UniformData);
+ }
+
+ 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);
+};
+
+
+template<ShaderStage SStage, GLenum SType>
+class ShaderImpl : public ShaderBase
+{
+ friend class ShaderSet;
+
+public:
+ ShaderImpl(RenderParams* rp, void* s, size_t size, const Uniform* refl, size_t reflSize)
+ : ShaderBase(rp, SStage)
+ , GLShader(0)
+ {
+ BOOL success;
+ OVR_UNUSED(size);
+ success = Compile((const char*) s);
+ OVR_ASSERT(success);
+ InitUniforms(refl, reflSize);
+ }
+ ~ShaderImpl()
+ {
+ if (GLShader)
+ {
+ glDeleteShader(GLShader);
+ GLShader = 0;
+ }
+ }
+ bool Compile(const char* src)
+ {
+ if (!GLShader)
+ GLShader = glCreateShader(GLStage());
+
+ glShaderSource(GLShader, 1, &src, 0);
+ glCompileShader(GLShader);
+ GLint r;
+ glGetShaderiv(GLShader, GL_COMPILE_STATUS, &r);
+ if (!r)
+ {
+ GLchar msg[1024];
+ glGetShaderInfoLog(GLShader, sizeof(msg), 0, msg);
+ if (msg[0])
+ OVR_DEBUG_LOG(("Compiling shader\n%s\nfailed: %s\n", src, msg));
+
+ return 0;
+ }
+ return 1;
+ }
+
+ GLenum GLStage() const
+ {
+ return SType;
+ }
+
+private:
+ GLuint GLShader;
+};
+
+typedef ShaderImpl<Shader_Vertex, GL_VERTEX_SHADER> VertexShader;
+typedef ShaderImpl<Shader_Fragment, GL_FRAGMENT_SHADER> FragmentShader;
+
+}}}
+
+#endif // INC_OVR_CAPI_GL_Util_h
diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh
new file mode 100644
index 0000000..5c95ade
--- /dev/null
+++ b/LibOVR/Src/CAPI/Shaders/DistortionChroma_ps.psh
@@ -0,0 +1,12 @@
+Texture2D Texture : register(t0);
+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;
+ return float4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0);
+ //" return oColor.rrrr;
+}
diff --git a/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.vsh b/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.vsh
new file mode 100644
index 0000000..6e11647
--- /dev/null
+++ b/LibOVR/Src/CAPI/Shaders/DistortionChroma_vs.vsh
@@ -0,0 +1,24 @@
+float2 EyeToSourceUVScale;
+float2 EyeToSourceUVOffset;
+
+void main(in float2 Position : POSITION, in float4 Color : COLOR0,
+ in float2 TexCoord0 : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2,
+ out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float3 oTexCoord0 : TEXCOORD0,
+ out float3 oTexCoord1 : TEXCOORD1, out float3 oTexCoord2 : TEXCOORD2)
+{
+ oPosition.x = Position.x;
+ oPosition.y = Position.y;
+ oPosition.z = 0.5;
+ oPosition.w = 1.0;
+
+ // Scale them into UV lookup space
+ float2 tc0scaled = EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset;
+ float2 tc1scaled = EyeToSourceUVScale * TexCoord1 + EyeToSourceUVOffset;
+ float2 tc2scaled = EyeToSourceUVScale * TexCoord2 + EyeToSourceUVOffset;
+
+ oTexCoord0 = float3(tc0scaled, 1); // R sample.
+ oTexCoord1 = float3(tc1scaled, 1); // G sample.
+ oTexCoord2 = float3(tc2scaled, 1); // B sample.
+ oColor = Color; // Used for vignette fade.
+}
+
diff --git a/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.vsh b/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.vsh
new file mode 100644
index 0000000..d629ddd
--- /dev/null
+++ b/LibOVR/Src/CAPI/Shaders/DistortionTimewarpChroma_vs.vsh
@@ -0,0 +1,40 @@
+float2 EyeToSourceUVScale;
+float2 EyeToSourceUVOffset;
+float4x4 EyeRotationStart;
+float4x4 EyeRotationEnd;
+
+float2 TimewarpTexCoordToWarpedPos(float2 inTexCoord, float4x4 rotMat)
+{
+ // 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 3x3 timewarp rotation to these vectors.
+ float3 transformed = float3( mul ( rotMat, float4(inTexCoord.xy, 1, 1) ).xyz);
+ // Project them back onto the Z=1 plane of the rendered images.
+ float2 flattened = transformed.xy / transformed.z;
+ // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye)
+ return flattened * EyeToSourceUVScale + EyeToSourceUVOffset;
+
+}
+
+void main(in float2 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord0 : TEXCOORD0,
+ in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2,
+ out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float3 oTexCoord0 : TEXCOORD0,
+ out float3 oTexCoord1 : TEXCOORD1, out float3 oTexCoord2 : TEXCOORD2)
+{
+
+ oPosition.x = Position.x;
+ oPosition.y = Position.y;
+ oPosition.z = 0.5;
+ oPosition.w = 1.0;
+
+ float timewarpLerpFactor = Color.a;
+ float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, timewarpLerpFactor);
+ //" float4x4 lerpedEyeRot = EyeRotationStart;
+
+ // warped positions are a bit more involved, hence a separate function
+ oTexCoord0 = float3(TimewarpTexCoordToWarpedPos(TexCoord0, lerpedEyeRot), 1);
+ oTexCoord1 = float3(TimewarpTexCoordToWarpedPos(TexCoord1, lerpedEyeRot), 1);
+ oTexCoord2 = float3(TimewarpTexCoordToWarpedPos(TexCoord2, lerpedEyeRot), 1);
+
+ oColor = Color.r; // Used for vignette fade.
+}
diff --git a/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.vsh b/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.vsh
new file mode 100644
index 0000000..627970f
--- /dev/null
+++ b/LibOVR/Src/CAPI/Shaders/DistortionTimewarp_vs.vsh
@@ -0,0 +1,36 @@
+float2 EyeToSourceUVScale;
+float2 EyeToSourceUVOffset;
+float4x4 EyeRotationStart;
+float4x4 EyeRotationEnd;
+
+float2 TimewarpTexCoordToWarpedPos(float2 inTexCoord, float4x4 rotMat)
+{
+ // 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 3x3 timewarp rotation to these vectors.
+ float3 transformed = float3( mul ( rotMat, float4(inTexCoord,1,1) ).xyz);
+ // Project them back onto the Z=1 plane of the rendered images.
+ float2 flattened = transformed.xy / transformed.z;
+ // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye)
+ return flattened * EyeToSourceUVScale + EyeToSourceUVOffset;
+
+}
+
+void main(in float2 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord0 : TEXCOORD0,
+ out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float3 oTexCoord0 : TEXCOORD0)
+{
+
+ oPosition.x = Position.x;
+ oPosition.y = Position.y;
+ oPosition.z = 0.5;
+ oPosition.w = 1.0;
+
+ float timewarpLerpFactor = Color.a;
+ float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, timewarpLerpFactor);
+
+ // Warped positions are a bit more involved, hence a separate function
+ oTexCoord0 = float3(TimewarpTexCoordToWarpedPos(TexCoord0, lerpedEyeRot), 1);
+ oColor = Color.r; // Used for vignette fade.
+}
+
+
diff --git a/LibOVR/Src/CAPI/Shaders/Distortion_ps.psh b/LibOVR/Src/CAPI/Shaders/Distortion_ps.psh
new file mode 100644
index 0000000..4a33de5
--- /dev/null
+++ b/LibOVR/Src/CAPI/Shaders/Distortion_ps.psh
@@ -0,0 +1,9 @@
+Texture2D Texture : register(t0);
+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;
+ return float4(Result.r * oColor.r, Result.g * oColor.g, Result.b * oColor.b, 1.0);
+}
diff --git a/LibOVR/Src/CAPI/Shaders/Distortion_vs.vsh b/LibOVR/Src/CAPI/Shaders/Distortion_vs.vsh
new file mode 100644
index 0000000..d22ea02
--- /dev/null
+++ b/LibOVR/Src/CAPI/Shaders/Distortion_vs.vsh
@@ -0,0 +1,14 @@
+float2 EyeToSourceUVScale;
+float2 EyeToSourceUVOffset;
+
+void main(in float2 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord0 : TEXCOORD0,
+ out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float3 oTexCoord0 : TEXCOORD0)
+{
+ oPosition.x = Position.x;
+ oPosition.y = Position.y;
+ oPosition.z = 0.5;
+ oPosition.w = 1.0;
+ oTexCoord0 = float3(EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset, 1);
+ oColor = Color; // Used for vignette fade.
+}
+
diff --git a/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.psh b/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.psh
new file mode 100644
index 0000000..9ea10cd
--- /dev/null
+++ b/LibOVR/Src/CAPI/Shaders/SimpleQuad_ps.psh
@@ -0,0 +1,6 @@
+float4 Color;
+
+float4 main() : SV_Target
+{
+ return Color;
+}
diff --git a/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.vsh b/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.vsh
new file mode 100644
index 0000000..4625371
--- /dev/null
+++ b/LibOVR/Src/CAPI/Shaders/SimpleQuad_vs.vsh
@@ -0,0 +1,8 @@
+float2 PositionOffset = float2(0, 0);
+float2 Scale = float2(1, 1);
+
+void main( in float3 Position : POSITION,
+out float4 oPosition : SV_Position)
+{
+ oPosition = float4(Position.xy * Scale + PositionOffset, 0.5, 1.0);
+} \ No newline at end of file
diff --git a/LibOVR/Src/CAPI/Shaders/genPixelShaderHeader.bat b/LibOVR/Src/CAPI/Shaders/genPixelShaderHeader.bat
new file mode 100644
index 0000000..a1311b2
--- /dev/null
+++ b/LibOVR/Src/CAPI/Shaders/genPixelShaderHeader.bat
@@ -0,0 +1,15 @@
+@echo off
+pushd %~dp0
+echo Compiling shader and packing into header: %~2
+setlocal
+
+set PATH=%PATH%;"%DXSDK_DIR%Utilities\bin\x86\"
+fxc.exe /nologo /E main /T ps_4_0 /Fo "%1" %2
+bin2header.exe "%1"
+
+echo Generating shader reflection data for %1
+ShaderReflector "%1" "%1_refl.h"
+
+del "%1"
+endlocal
+popd
diff --git a/LibOVR/Src/CAPI/Shaders/genVertexShaderHeader.bat b/LibOVR/Src/CAPI/Shaders/genVertexShaderHeader.bat
new file mode 100644
index 0000000..4591d20
--- /dev/null
+++ b/LibOVR/Src/CAPI/Shaders/genVertexShaderHeader.bat
@@ -0,0 +1,15 @@
+@echo off
+pushd %~dp0
+echo Compiling shader and packing into header: %~2
+setlocal
+
+set PATH=%PATH%;"%DXSDK_DIR%Utilities\bin\x86\"
+fxc.exe /nologo /E main /T vs_4_0 /Fo "%1" %2
+bin2header.exe "%1"
+
+echo Generating shader reflection data for %1
+ShaderReflector "%1" "%1_refl.h"
+
+del "%1"
+endlocal
+popd
diff --git a/LibOVR/Src/Kernel/OVR_Alg.cpp b/LibOVR/Src/Kernel/OVR_Alg.cpp
index 0c564ab..2e52bc3 100644
--- a/LibOVR/Src/Kernel/OVR_Alg.cpp
+++ b/LibOVR/Src/Kernel/OVR_Alg.cpp
@@ -5,16 +5,16 @@ Content : Static lookup tables for Alg functions
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_Alg.h b/LibOVR/Src/Kernel/OVR_Alg.h
index 51261d3..783af21 100644
--- a/LibOVR/Src/Kernel/OVR_Alg.h
+++ b/LibOVR/Src/Kernel/OVR_Alg.h
@@ -6,16 +6,16 @@ Content : Simple general purpose algorithms: Sort, Binary Search, etc.
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -433,7 +433,29 @@ void InsertionSort(Array& arr)
InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess<ValueType>::Compare);
}
+//-----------------------------------------------------------------------------------
+// ***** Median
+// Returns a median value of the input array.
+// Caveats: partially sorts the array, returns a reference to the array element
+// TBD: This needs to be optimized and generalized
+//
+template<class Array>
+typename Array::ValueType& Median(Array& arr)
+{
+ UPInt count = arr.GetSize();
+ UPInt mid = (count - 1) / 2;
+ OVR_ASSERT(count > 0);
+ for (int j = 0; j <= mid; j++)
+ {
+ int min = j;
+ for (int k = j + 1; k < count; k++)
+ if (arr[k] < arr[min])
+ min = k;
+ Swap(arr[j], arr[min]);
+ }
+ return arr[mid];
+}
//-----------------------------------------------------------------------------------
// ***** LowerBoundSliced
@@ -651,13 +673,13 @@ inline UByte UpperBit(UPInt val)
if (val & 0xFFFF0000)
{
- return static_cast<UByte>((val & 0xFF000000) ?
+ return (val & 0xFF000000) ?
UpperBitTable[(val >> 24) ] + 24:
- UpperBitTable[(val >> 16) & 0xFF] + 16);
+ UpperBitTable[(val >> 16) & 0xFF] + 16;
}
- return static_cast<UByte>((val & 0xFF00) ?
+ return (val & 0xFF00) ?
UpperBitTable[(val >> 8) & 0xFF] + 8:
- UpperBitTable[(val ) & 0xFF]);
+ UpperBitTable[(val ) & 0xFF];
#else
@@ -696,13 +718,13 @@ inline UByte LowerBit(UPInt val)
if (val & 0xFFFF)
{
- return static_cast<UByte>( (val & 0xFF) ?
+ return (val & 0xFF) ?
LowerBitTable[ val & 0xFF]:
- LowerBitTable[(val >> 8) & 0xFF] + 8 );
+ LowerBitTable[(val >> 8) & 0xFF] + 8;
}
- return static_cast<UByte>( (val & 0xFF0000) ?
+ return (val & 0xFF0000) ?
LowerBitTable[(val >> 16) & 0xFF] + 16:
- LowerBitTable[(val >> 24) & 0xFF] + 24 );
+ LowerBitTable[(val >> 24) & 0xFF] + 24;
#else
@@ -813,7 +835,7 @@ namespace ByteUtil {
// Swap the byte order of primitive types
inline UByte SwapOrder(UByte v) { return v; }
inline SByte SwapOrder(SByte v) { return v; }
- inline UInt16 SwapOrder(UInt16 v) { return static_cast<UInt16>( UInt16(v>>8)|UInt16(v<<8) ); }
+ inline UInt16 SwapOrder(UInt16 v) { return UInt16(v>>8)|UInt16(v<<8); }
inline SInt16 SwapOrder(SInt16 v) { return SInt16((UInt16(v)>>8)|(v<<8)); }
inline UInt32 SwapOrder(UInt32 v) { return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); }
inline SInt32 SwapOrder(SInt32 p) { return (SInt32)SwapOrder(UInt32(p)); }
@@ -959,6 +981,80 @@ namespace ByteUtil {
+// Used primarily for hardware interfacing such as sensor reports, firmware, etc.
+// Reported data is all little-endian.
+inline UInt16 DecodeUInt16(const UByte* buffer)
+{
+ return ByteUtil::LEToSystem ( *(const UInt16*)buffer );
+}
+
+inline SInt16 DecodeSInt16(const UByte* buffer)
+{
+ return ByteUtil::LEToSystem ( *(const SInt16*)buffer );
+}
+
+inline UInt32 DecodeUInt32(const UByte* buffer)
+{
+ return ByteUtil::LEToSystem ( *(const UInt32*)buffer );
+}
+
+inline SInt32 DecodeSInt32(const UByte* buffer)
+{
+ return ByteUtil::LEToSystem ( *(const SInt32*)buffer );
+}
+
+inline float DecodeFloat(const UByte* buffer)
+{
+ union {
+ UInt32 U;
+ float F;
+ };
+
+ U = DecodeUInt32(buffer);
+ return F;
+}
+
+inline void EncodeUInt16(UByte* buffer, UInt16 val)
+{
+ *(UInt16*)buffer = ByteUtil::SystemToLE ( val );
+}
+
+inline void EncodeSInt16(UByte* buffer, SInt16 val)
+{
+ *(SInt16*)buffer = ByteUtil::SystemToLE ( val );
+}
+
+inline void EncodeUInt32(UByte* buffer, UInt32 val)
+{
+ *(UInt32*)buffer = ByteUtil::SystemToLE ( val );
+}
+
+inline void EncodeSInt32(UByte* buffer, SInt32 val)
+{
+ *(SInt32*)buffer = ByteUtil::SystemToLE ( val );
+}
+
+inline void EncodeFloat(UByte* buffer, float val)
+{
+ union {
+ UInt32 U;
+ float F;
+ };
+
+ F = val;
+ EncodeUInt32(buffer, U);
+}
+
+// Converts an 8-bit binary-coded decimal
+inline SByte DecodeBCD(UByte byte)
+{
+ UByte digit1 = (byte >> 4) & 0x0f;
+ UByte digit2 = byte & 0x0f;
+ int decimal = digit1 * 10 + digit2; // maximum value = 99
+ return (SByte)decimal;
+}
+
+
}} // OVR::Alg
#endif
diff --git a/LibOVR/Src/Kernel/OVR_Allocator.cpp b/LibOVR/Src/Kernel/OVR_Allocator.cpp
index 51eebba..0f82561 100644
--- a/LibOVR/Src/Kernel/OVR_Allocator.cpp
+++ b/LibOVR/Src/Kernel/OVR_Allocator.cpp
@@ -5,16 +5,16 @@ Content : Installable memory allocator implementation
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_Allocator.h b/LibOVR/Src/Kernel/OVR_Allocator.h
index b2e0472..b862557 100644
--- a/LibOVR/Src/Kernel/OVR_Allocator.h
+++ b/LibOVR/Src/Kernel/OVR_Allocator.h
@@ -6,16 +6,16 @@ Content : Installable memory allocator
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -104,7 +104,7 @@ namespace OVR {
template <class T>
OVR_FORCE_INLINE T* Construct(void *p)
{
- return ::new(p) T;
+ return ::new(p) T();
}
template <class T>
diff --git a/LibOVR/Src/Kernel/OVR_Array.h b/LibOVR/Src/Kernel/OVR_Array.h
index 552ddcc..7a715ba 100644
--- a/LibOVR/Src/Kernel/OVR_Array.h
+++ b/LibOVR/Src/Kernel/OVR_Array.h
@@ -6,16 +6,16 @@ Content : Template implementation for Array
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -222,7 +222,7 @@ struct ArrayData : ArrayDataBase<T, Allocator, SizePolicy>
ArrayData()
: BaseType() { }
- ArrayData(int size)
+ ArrayData(UPInt size)
: BaseType() { Resize(size); }
ArrayData(const SelfType& a)
@@ -281,7 +281,7 @@ struct ArrayDataCC : ArrayDataBase<T, Allocator, SizePolicy>
ArrayDataCC(const ValueType& defval)
: BaseType(), DefaultValue(defval) { }
- ArrayDataCC(const ValueType& defval, int size)
+ ArrayDataCC(const ValueType& defval, UPInt size)
: BaseType(), DefaultValue(defval) { Resize(size); }
ArrayDataCC(const SelfType& a)
@@ -359,14 +359,14 @@ public:
ArrayBase()
: Data() {}
- ArrayBase(int size)
+ ArrayBase(UPInt size)
: Data(size) {}
ArrayBase(const SelfType& a)
: Data(a.Data) {}
ArrayBase(const ValueType& defval)
: Data(defval) {}
- ArrayBase(const ValueType& defval, int size)
+ ArrayBase(const ValueType& defval, UPInt size)
: Data(defval, size) {}
SizePolicyType* GetSizePolicy() const { return Data.Policy; }
@@ -499,6 +499,9 @@ public:
// Removing an element from the array is an expensive operation!
// It compacts only after removing the last element.
+ // If order of elements in the array is not important then use
+ // RemoveAtUnordered, that could be much faster than the regular
+ // RemoveAt.
void RemoveAt(UPInt index)
{
OVR_ASSERT(index < Data.Size);
@@ -517,6 +520,32 @@ public:
}
}
+ // Removes an element from the array without respecting of original order of
+ // elements for better performance. Do not use on array where order of elements
+ // is important, otherwise use it instead of regular RemoveAt().
+ void RemoveAtUnordered(UPInt index)
+ {
+ OVR_ASSERT(index < Data.Size);
+ if (Data.Size == 1)
+ {
+ Clear();
+ }
+ else
+ {
+ // copy the last element into the 'index' position
+ // and decrement the size (instead of moving all elements
+ // in [index + 1 .. size - 1] range).
+ const UPInt lastElemIndex = Data.Size - 1;
+ if (index < lastElemIndex)
+ {
+ AllocatorType::Destruct(Data.Data + index);
+ AllocatorType::Construct(Data.Data + index, Data.Data[lastElemIndex]);
+ }
+ AllocatorType::Destruct(Data.Data + lastElemIndex);
+ --Data.Size;
+ }
+ }
+
// Insert the given object at the given index shifting all the elements up.
void InsertAt(UPInt index, const ValueType& val = ValueType())
{
@@ -725,7 +754,7 @@ public:
typedef ArrayBase<ArrayData<T, ContainerAllocator<T>, SizePolicy> > BaseType;
Array() : BaseType() {}
- Array(int size) : BaseType(size) {}
+ Array(UPInt size) : BaseType(size) {}
Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
Array(const SelfType& a) : BaseType(a) {}
const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
@@ -747,7 +776,7 @@ public:
typedef ArrayBase<ArrayData<T, ContainerAllocator_POD<T>, SizePolicy> > BaseType;
ArrayPOD() : BaseType() {}
- ArrayPOD(int size) : BaseType(size) {}
+ ArrayPOD(UPInt size) : BaseType(size) {}
ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
ArrayPOD(const SelfType& a) : BaseType(a) {}
const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
@@ -769,7 +798,7 @@ public:
typedef ArrayBase<ArrayData<T, ContainerAllocator_CPP<T>, SizePolicy> > BaseType;
ArrayCPP() : BaseType() {}
- ArrayCPP(int size) : BaseType(size) {}
+ ArrayCPP(UPInt size) : BaseType(size) {}
ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); }
ArrayCPP(const SelfType& a) : BaseType(a) {}
const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
@@ -793,7 +822,7 @@ public:
typedef ArrayBase<ArrayDataCC<T, ContainerAllocator<T>, SizePolicy> > BaseType;
ArrayCC(const ValueType& defval) : BaseType(defval) {}
- ArrayCC(const ValueType& defval, int size) : BaseType(defval, size) {}
+ ArrayCC(const ValueType& defval, UPInt size) : BaseType(defval, size) {}
ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); }
ArrayCC(const SelfType& a) : BaseType(a) {}
const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; }
diff --git a/LibOVR/Src/Kernel/OVR_Atomic.cpp b/LibOVR/Src/Kernel/OVR_Atomic.cpp
index 1c0efc2..9ea6e76 100644
--- a/LibOVR/Src/Kernel/OVR_Atomic.cpp
+++ b/LibOVR/Src/Kernel/OVR_Atomic.cpp
@@ -7,16 +7,16 @@ Content : Contains atomic operations and inline fastest locking
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -27,6 +27,7 @@ limitations under the License.
************************************************************************************/
#include "OVR_Atomic.h"
+#include "OVR_Allocator.h"
#ifdef OVR_ENABLE_THREADS
@@ -88,6 +89,74 @@ Lock::~Lock()
#endif
+
+//-------------------------------------------------------------------------------------
+// ***** SharedLock
+
+// This is a general purpose globally shared Lock implementation that should probably be
+// moved to Kernel.
+// May in theory busy spin-wait if we hit contention on first lock creation,
+// but this shouldn't matter in practice since Lock* should be cached.
+
+
+enum { LockInitMarker = 0xFFFFFFFF };
+
+Lock* SharedLock::GetLockAddRef()
+{
+ int oldUseCount;
+
+ do {
+ oldUseCount = UseCount;
+ if (oldUseCount == LockInitMarker)
+ continue;
+
+ if (oldUseCount == 0)
+ {
+ // Initialize marker
+ if (AtomicOps<int>::CompareAndSet_Sync(&UseCount, 0, LockInitMarker))
+ {
+ Construct<Lock>(Buffer);
+ do { }
+ while (!AtomicOps<int>::CompareAndSet_Sync(&UseCount, LockInitMarker, 1));
+ return toLock();
+ }
+ continue;
+ }
+
+ } while (!AtomicOps<int>::CompareAndSet_NoSync(&UseCount, oldUseCount, oldUseCount + 1));
+
+ return toLock();
+}
+
+void SharedLock::ReleaseLock(Lock* plock)
+{
+ OVR_UNUSED(plock);
+ OVR_ASSERT(plock == toLock());
+
+ int oldUseCount;
+
+ do {
+ oldUseCount = UseCount;
+ OVR_ASSERT(oldUseCount != LockInitMarker);
+
+ if (oldUseCount == 1)
+ {
+ // Initialize marker
+ if (AtomicOps<int>::CompareAndSet_Sync(&UseCount, 1, LockInitMarker))
+ {
+ Destruct<Lock>(toLock());
+
+ do { }
+ while (!AtomicOps<int>::CompareAndSet_Sync(&UseCount, LockInitMarker, 0));
+
+ return;
+ }
+ continue;
+ }
+
+ } while (!AtomicOps<int>::CompareAndSet_NoSync(&UseCount, oldUseCount, oldUseCount - 1));
+}
+
} // OVR
#endif // OVR_ENABLE_THREADS
diff --git a/LibOVR/Src/Kernel/OVR_Atomic.h b/LibOVR/Src/Kernel/OVR_Atomic.h
index b539ccd..b826251 100644
--- a/LibOVR/Src/Kernel/OVR_Atomic.h
+++ b/LibOVR/Src/Kernel/OVR_Atomic.h
@@ -8,16 +8,16 @@ Content : Contains atomic operations and inline fastest locking
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -865,6 +865,25 @@ public:
};
+//-------------------------------------------------------------------------------------
+// Globally shared Lock implementation used for MessageHandlers, etc.
+
+class SharedLock
+{
+public:
+ SharedLock() : UseCount(0) {}
+
+ Lock* GetLockAddRef();
+ void ReleaseLock(Lock* plock);
+
+private:
+ Lock* toLock() { return (Lock*)Buffer; }
+
+ // UseCount and max alignment.
+ volatile int UseCount;
+ UInt64 Buffer[(sizeof(Lock)+sizeof(UInt64)-1)/sizeof(UInt64)];
+};
+
} // OVR
diff --git a/LibOVR/Src/Kernel/OVR_Color.h b/LibOVR/Src/Kernel/OVR_Color.h
index 0881997..cf536da 100644
--- a/LibOVR/Src/Kernel/OVR_Color.h
+++ b/LibOVR/Src/Kernel/OVR_Color.h
@@ -6,16 +6,16 @@ Content : Contains color struct.
Created : February 7, 2013
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_ContainerAllocator.h b/LibOVR/Src/Kernel/OVR_ContainerAllocator.h
index 36c22d1..afc0e6a 100644
--- a/LibOVR/Src/Kernel/OVR_ContainerAllocator.h
+++ b/LibOVR/Src/Kernel/OVR_ContainerAllocator.h
@@ -6,16 +6,16 @@ Content : Template allocators and constructors for containers.
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_Deque.h b/LibOVR/Src/Kernel/OVR_Deque.h
new file mode 100644
index 0000000..747810e
--- /dev/null
+++ b/LibOVR/Src/Kernel/OVR_Deque.h
@@ -0,0 +1,310 @@
+/************************************************************************************
+
+Filename : OVR_Deque.h
+Content : Deque container
+Created : Nov. 15, 2013
+Authors : Dov Katz
+
+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_Deque_h
+#define OVR_Deque_h
+
+namespace OVR{
+
+template <class Elem>
+class Deque
+{
+public:
+ enum
+ {
+ DefaultCapacity = 500
+ };
+
+ Deque(int capacity = DefaultCapacity);
+ Deque(const Deque<Elem> &OtherDeque);
+ virtual ~Deque(void);
+
+ virtual void PushBack (const Elem &Item); // Adds Item to the end
+ virtual void PushFront (const Elem &Item); // Adds Item to the beginning
+ virtual Elem PopBack (void); // Removes Item from the end
+ virtual Elem PopFront (void); // Removes Item from the beginning
+ virtual const Elem& PeekBack (int count = 0) const; // Returns count-th Item from the end
+ virtual const Elem& PeekFront (int count = 0) const; // Returns count-th Item from the beginning
+
+ virtual inline UPInt GetSize (void) const; // Returns Number of Elements
+ virtual inline UPInt GetCapacity(void) const; // Returns the maximum possible number of elements
+ virtual void Clear (void); // Remove all elements
+ virtual inline bool IsEmpty () const;
+ virtual inline bool IsFull () const;
+
+protected:
+ Elem *Data; // The actual Data array
+ const int Capacity; // Deque capacity
+ int Beginning; // Index of the first element
+ int End; // Index of the next after last element
+
+ // Instead of calculating the number of elements, using this variable
+ // is much more convenient.
+ int ElemCount;
+
+private:
+ Deque& operator= (const Deque& q) { }; // forbidden
+};
+
+template <class Elem>
+class InPlaceMutableDeque : public Deque<Elem>
+{
+public:
+ InPlaceMutableDeque( int capacity = Deque<Elem>::DefaultCapacity ) : Deque<Elem>( capacity ) {}
+ virtual ~InPlaceMutableDeque() {};
+
+ 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>
+{
+public:
+ CircularBuffer(int MaxSize = Deque<Elem>::DefaultCapacity) : Deque<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
+ inline virtual void PushBack (const Elem &Item); // Adds Item to the end, overwriting the oldest element at the beginning if necessary
+ inline virtual void PushFront (const Elem &Item); // Adds Item to the beginning, overwriting the oldest element at the end if necessary
+};
+
+//----------------------------------------------------------------------------------
+
+// Deque Constructor function
+template <class Elem>
+Deque<Elem>::Deque(int capacity) :
+Capacity( capacity ), Beginning(0), End(0), ElemCount(0)
+{
+ Data = (Elem*) OVR_ALLOC(Capacity * sizeof(Elem));
+ 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)
+{
+ DestructArray<Elem>(Data, Capacity);
+ OVR_FREE(Data);
+}
+
+template <class Elem>
+void Deque<Elem>::Clear()
+{
+ Beginning = 0;
+ End = 0;
+ ElemCount = 0;
+
+ DestructArray<Elem>(Data, Capacity);
+ ConstructArray<Elem>(Data, Capacity);
+}
+
+// Push functions
+template <class Elem>
+void Deque<Elem>::PushBack(const Elem &Item)
+{
+ // Error Check: Make sure we aren't
+ // exceeding our maximum storage space
+ OVR_ASSERT( ElemCount < Capacity );
+
+ Data[ End++ ] = Item;
+ ++ElemCount;
+
+ // Check for wrap-around
+ if (End >= Capacity)
+ End -= Capacity;
+}
+
+template <class Elem>
+void Deque<Elem>::PushFront(const Elem &Item)
+{
+ // Error Check: Make sure we aren't
+ // exceeding our maximum storage space
+ OVR_ASSERT( ElemCount < Capacity );
+
+ Beginning--;
+ // Check for wrap-around
+ if (Beginning < 0)
+ Beginning += Capacity;
+
+ Data[ Beginning ] = Item;
+ ++ElemCount;
+}
+
+// Pop functions
+template <class Elem>
+Elem Deque<Elem>::PopFront(void)
+{
+ // Error Check: Make sure we aren't reading from an empty Deque
+ OVR_ASSERT( ElemCount > 0 );
+
+ Elem ReturnValue = Data[ Beginning ];
+ Destruct<Elem>(&Data[ Beginning ]);
+ Construct<Elem>(&Data[ Beginning ]);
+
+ ++Beginning;
+ --ElemCount;
+
+ // Check for wrap-around
+ if (Beginning >= Capacity)
+ Beginning -= Capacity;
+
+ return ReturnValue;
+}
+
+template <class Elem>
+Elem Deque<Elem>::PopBack(void)
+{
+ // Error Check: Make sure we aren't reading from an empty Deque
+ OVR_ASSERT( ElemCount > 0 );
+
+ End--;
+ --ElemCount;
+
+ // Check for wrap-around
+ if (End < 0)
+ End += Capacity;
+
+ Elem ReturnValue = Data[ End ];
+ Destruct<Elem>(&Data[ End ]);
+ Construct<Elem>(&Data[ End ]);
+
+ return ReturnValue;
+}
+
+// Peek functions
+template <class Elem>
+const Elem& Deque<Elem>::PeekFront(int count) const
+{
+ // Error Check: Make sure we aren't reading from an empty Deque
+ OVR_ASSERT( ElemCount > count );
+
+ int idx = Beginning + count;
+ if (idx >= Capacity)
+ idx -= Capacity;
+ return Data[ idx ];
+}
+
+template <class Elem>
+const Elem& Deque<Elem>::PeekBack(int count) const
+{
+ // Error Check: Make sure we aren't reading from an empty Deque
+ OVR_ASSERT( ElemCount > count );
+
+ int idx = End - count - 1;
+ if (idx < 0)
+ idx += Capacity;
+ return Data[ idx ];
+}
+
+// Mutable Peek functions
+template <class Elem>
+Elem& InPlaceMutableDeque<Elem>::PeekFront(int count)
+{
+ // Error Check: Make sure we aren't reading from an empty Deque
+ OVR_ASSERT( Deque<Elem>::ElemCount > count );
+
+ int idx = Deque<Elem>::Beginning + count;
+ if (idx >= Deque<Elem>::Capacity)
+ idx -= Deque<Elem>::Capacity;
+ return Deque<Elem>::Data[ idx ];
+}
+
+template <class Elem>
+Elem& InPlaceMutableDeque<Elem>::PeekBack(int count)
+{
+ // 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)
+ idx += Deque<Elem>::Capacity;
+ return Deque<Elem>::Data[ idx ];
+}
+
+template <class Elem>
+inline UPInt Deque<Elem>::GetCapacity(void) const
+{
+ return Deque<Elem>::Capacity;
+}
+
+template <class Elem>
+inline UPInt Deque<Elem>::GetSize(void) const
+{
+ return Deque<Elem>::ElemCount;
+}
+
+template <class Elem>
+inline bool Deque<Elem>::IsEmpty(void) const
+{
+ return Deque<Elem>::ElemCount==0;
+}
+
+template <class Elem>
+inline bool Deque<Elem>::IsFull(void) const
+{
+ return Deque<Elem>::ElemCount==Deque<Elem>::Capacity;
+}
+
+// ******* CircularBuffer<Elem> *******
+// Push functions
+template <class Elem>
+void CircularBuffer<Elem>::PushBack(const Elem &Item)
+{
+ if (this->IsFull())
+ this->PopFront();
+ Deque<Elem>::PushBack(Item);
+}
+
+template <class Elem>
+void CircularBuffer<Elem>::PushFront(const Elem &Item)
+{
+ if (this->IsFull())
+ this->PopBack();
+ Deque<Elem>::PushFront(Item);
+}
+
+};
+
+#endif
diff --git a/LibOVR/Src/Kernel/OVR_File.cpp b/LibOVR/Src/Kernel/OVR_File.cpp
index 3f52488..31ab516 100644
--- a/LibOVR/Src/Kernel/OVR_File.cpp
+++ b/LibOVR/Src/Kernel/OVR_File.cpp
@@ -6,16 +6,16 @@ Content : File wrapper class implementation (Win32)
Created : April 5, 1999
Authors : Michael Antonov
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_File.h b/LibOVR/Src/Kernel/OVR_File.h
index 92c53ab..a8dc615 100644
--- a/LibOVR/Src/Kernel/OVR_File.h
+++ b/LibOVR/Src/Kernel/OVR_File.h
@@ -11,16 +11,16 @@ Notes : errno may not be preserved across use of BaseFile member functio
: Directories cannot be deleted while files opened from them are in use
(For the GetFullName function)
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_FileFILE.cpp b/LibOVR/Src/Kernel/OVR_FileFILE.cpp
index fd01118..4fe4cbe 100644
--- a/LibOVR/Src/Kernel/OVR_FileFILE.cpp
+++ b/LibOVR/Src/Kernel/OVR_FileFILE.cpp
@@ -6,16 +6,16 @@ Content : File wrapper class implementation (Win32)
Created : April 5, 1999
Authors : Michael Antonov
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -561,9 +561,10 @@ bool FILEFile::CloseCancel()
}
*/
-File *FileFILEOpen(const String& path, int flags, int mode)
+Ptr<File> FileFILEOpen(const String& path, int flags, int mode)
{
- return new FILEFile(path, flags, mode);
+ Ptr<File> result = *new FILEFile(path, flags, mode);
+ return result;
}
// Helper function: obtain file information time.
diff --git a/LibOVR/Src/Kernel/OVR_Hash.h b/LibOVR/Src/Kernel/OVR_Hash.h
index 98c206b..04c4db8 100644
--- a/LibOVR/Src/Kernel/OVR_Hash.h
+++ b/LibOVR/Src/Kernel/OVR_Hash.h
@@ -6,16 +6,16 @@ Content : Template hash-table/set implementation
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_KeyCodes.h b/LibOVR/Src/Kernel/OVR_KeyCodes.h
index 42d98ee..b5c5930 100644
--- a/LibOVR/Src/Kernel/OVR_KeyCodes.h
+++ b/LibOVR/Src/Kernel/OVR_KeyCodes.h
@@ -5,16 +5,16 @@ Filename : OVR_KeyCodes.h
Content : Common keyboard constants
Created : September 19, 2012
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -147,7 +147,7 @@ enum KeyCode
Key_Semicolon = 59,
Key_Equal = 61,
- Key_Bar = 192,
+ Key_Backtick = 96, // ` and tilda~ when shifted (US keyboard)
Key_BracketLeft = 91,
Key_Backslash,
Key_BracketRight,
diff --git a/LibOVR/Src/Kernel/OVR_List.h b/LibOVR/Src/Kernel/OVR_List.h
index d5e79a3..6b49f37 100644
--- a/LibOVR/Src/Kernel/OVR_List.h
+++ b/LibOVR/Src/Kernel/OVR_List.h
@@ -6,16 +6,16 @@ Content : Template implementation for doubly-connected linked List
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_Lockless.cpp b/LibOVR/Src/Kernel/OVR_Lockless.cpp
new file mode 100644
index 0000000..0f25805
--- /dev/null
+++ b/LibOVR/Src/Kernel/OVR_Lockless.cpp
@@ -0,0 +1,231 @@
+/************************************************************************************
+
+PublicHeader: OVR.h
+Filename : OVR_Lockless.cpp
+Content : Test logic for lock-less classes
+Created : December 27, 2013
+Authors : Michael Antonov
+
+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 "OVR_Lockless.h"
+
+#ifdef OVR_LOCKLESS_TEST
+
+#include "OVR_Threads.h"
+#include "OVR_Timer.h"
+#include "OVR_Log.h"
+
+
+namespace OVR { namespace LocklessTest {
+
+
+const int TestIterations = 10000000;
+
+// Use volatile dummys to force compiler to do spinning.
+volatile int Dummy1;
+int Unused1[32];
+volatile int Dummy2;
+int Unused2[32];
+volatile int Dummy3;
+int Unused3[32];
+
+
+// Data block out of 20 consecutive integers, should be internally consistent.
+struct TestData
+{
+ enum { ItemCount = 20 };
+
+ int Data[ItemCount];
+
+
+ void Set(int val)
+ {
+ for (int i=0; i<ItemCount; i++)
+ {
+ Data[i] = val*100 + i;
+ }
+ }
+
+ int ReadAndCheckConsistency(int prevValue) const
+ {
+ int val = Data[0];
+
+ for (int i=1; i<ItemCount; i++)
+ {
+
+ if (Data[i] != (val + i))
+ {
+ // Only complain once per same-value entry
+ if (prevValue != val / 100)
+ {
+ LogText("LocklessTest Fail - corruption at %d inside block %d\n",
+ i, val/100);
+ // OVR_ASSERT(Data[i] == val + i);
+ }
+ break;
+ }
+ }
+
+ return val / 100;
+ }
+};
+
+
+
+volatile bool FirstItemWritten = false;
+LocklessUpdater<TestData> TestDataUpdater;
+
+// Use this lock to verify that testing algorithm is otherwise correct...
+Lock TestLock;
+
+
+//-------------------------------------------------------------------------------------
+
+// Consumer thread reads values from TestDataUpdater and
+// ensures that each one is internally consistent.
+
+class Consumer : public Thread
+{
+ virtual int Run()
+ {
+ LogText("LocklessTest::Consumer::Run started.\n");
+
+
+ while (!FirstItemWritten)
+ {
+ // spin until producer wrote first value...
+ }
+
+ TestData d;
+ int oldValue = 0;
+ int newValue;
+
+ do
+ {
+ {
+ //Lock::Locker scope(&TestLock);
+ d = TestDataUpdater.GetState();
+ }
+
+ newValue = d.ReadAndCheckConsistency(oldValue);
+
+ // Values should increase or stay the same!
+ if (newValue < oldValue)
+ {
+ LogText("LocklessTest Fail - %d after %d; delta = %d\n",
+ newValue, oldValue, newValue - oldValue);
+ // OVR_ASSERT(0);
+ }
+
+
+ if (oldValue != newValue)
+ {
+ oldValue = newValue;
+
+ if (oldValue % (TestIterations/30) == 0)
+ {
+ LogText("LocklessTest::Consumer - %5.2f%% done\n",
+ 100.0f * (float)oldValue/(float)TestIterations);
+ }
+ }
+
+ // Spin a while
+ for (int j = 0; j< 300; j++)
+ {
+ Dummy3 = j;
+ }
+
+
+ } while (oldValue < (TestIterations * 99 / 100));
+
+ LogText("LocklessTest::Consumer::Run exiting.\n");
+ return 0;
+ }
+
+};
+
+
+//-------------------------------------------------------------------------------------
+
+class Producer : public Thread
+{
+
+ virtual int Run()
+ {
+ LogText("LocklessTest::Producer::Run started.\n");
+
+ for (int testVal = 0; testVal < TestIterations; testVal++)
+ {
+ TestData d;
+ d.Set(testVal);
+
+ {
+ //Lock::Locker scope(&TestLock);
+ TestDataUpdater.SetState(d);
+ }
+
+ FirstItemWritten = true;
+
+ // Spin a bit
+ for(int j = 0; j < 1000; j++)
+ {
+ Dummy2 = j;
+ }
+
+ if (testVal % (TestIterations/30) == 0)
+ {
+ LogText("LocklessTest::Producer - %5.2f%% done\n",
+ 100.0f * (float)testVal/(float)TestIterations);
+ }
+ }
+
+ LogText("LocklessTest::Producer::Run exiting.\n");
+ return 0;
+ }
+};
+
+
+} // namespace LocklessTest
+
+
+
+void StartLocklessTest()
+{
+ // These threads will release themselves once done
+ Ptr<LocklessTest::Producer> producerThread = *new LocklessTest::Producer;
+ Ptr<LocklessTest::Consumer> consumerThread = *new LocklessTest::Consumer;
+
+ producerThread->Start();
+ consumerThread->Start();
+
+ /*
+ while (!producerThread->IsFinished() && consumerThread->IsFinished())
+ {
+ Thread::MSleep(500);
+ } */
+
+ // TBD: Cleanup
+}
+
+
+} // namespace OVR
+
+#endif // OVR_LOCKLESS_TEST
diff --git a/LibOVR/Src/Kernel/OVR_Lockless.h b/LibOVR/Src/Kernel/OVR_Lockless.h
new file mode 100644
index 0000000..a12f824
--- /dev/null
+++ b/LibOVR/Src/Kernel/OVR_Lockless.h
@@ -0,0 +1,107 @@
+/************************************************************************************
+
+PublicHeader: OVR.h
+Filename : OVR_Lockless.h
+Content : Lock-less classes for producer/consumer communication
+Created : November 9, 2013
+Authors : John Carmack
+
+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_Lockless_h
+#define OVR_Lockless_h
+
+#include "OVR_Atomic.h"
+
+// Define this to compile-in Lockless test logic
+//#define OVR_LOCKLESS_TEST
+
+namespace OVR {
+
+
+// ***** LocklessUpdater
+
+// For single producer cases where you only care about the most recent update, not
+// necessarily getting every one that happens (vsync timing, SensorFusion updates).
+//
+// This is multiple consumer safe, but is currently only used with a single consumer.
+
+template<class T>
+class LocklessUpdater
+{
+public:
+ LocklessUpdater() : UpdateBegin( 0 ), UpdateEnd( 0 ) {}
+
+ T GetState() const
+ {
+ // Copy the state out, then retry with the alternate slot
+ // if we determine that our copy may have been partially
+ // stepped on by a new update.
+ T state;
+ int begin, end, final;
+
+ for(;;)
+ {
+ // We are adding 0, only using these as atomic memory barriers, so it
+ // is ok to cast off the const, allowing GetState() to remain const.
+ end = UpdateEnd.ExchangeAdd_Sync(0);
+ state = Slots[ end & 1 ];
+ begin = UpdateBegin.ExchangeAdd_Sync(0);
+ if ( begin == end ) {
+ break;
+ }
+
+ // The producer is potentially blocked while only having partially
+ // written the update, so copy out the other slot.
+ state = Slots[ (begin & 1) ^ 1 ];
+ final = UpdateBegin.ExchangeAdd_NoSync(0);
+ if ( final == begin ) {
+ break;
+ }
+
+ // The producer completed the last update and started a new one before
+ // we got it copied out, so try fetching the current buffer again.
+ }
+ return state;
+ }
+
+ void SetState( T state )
+ {
+ const int slot = UpdateBegin.ExchangeAdd_Sync(1) & 1;
+ // Write to (slot ^ 1) because ExchangeAdd returns 'previous' value before add.
+ Slots[slot ^ 1] = state;
+ UpdateEnd.ExchangeAdd_Sync(1);
+ }
+
+ mutable AtomicInt<int> UpdateBegin;
+ mutable AtomicInt<int> UpdateEnd;
+ T Slots[2];
+};
+
+
+#ifdef OVR_LOCKLESS_TEST
+void StartLocklessTest();
+#endif
+
+
+} // namespace OVR
+
+#endif // OVR_Lockless_h
+
diff --git a/LibOVR/Src/Kernel/OVR_Log.cpp b/LibOVR/Src/Kernel/OVR_Log.cpp
index 76b09ad..d5f8a68 100644
--- a/LibOVR/Src/Kernel/OVR_Log.cpp
+++ b/LibOVR/Src/Kernel/OVR_Log.cpp
@@ -5,16 +5,16 @@ Content : Logging support
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_Log.h b/LibOVR/Src/Kernel/OVR_Log.h
index 9c6feb6..4d9acc1 100644
--- a/LibOVR/Src/Kernel/OVR_Log.h
+++ b/LibOVR/Src/Kernel/OVR_Log.h
@@ -6,16 +6,16 @@ Content : Logging support
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -108,7 +108,7 @@ public:
virtual ~Log();
// Log formating buffer size used by default LogMessageVarg. Longer strings are truncated.
- enum { MaxLogBufferMessageSize = 2048 };
+ enum { MaxLogBufferMessageSize = 4096 };
unsigned GetLoggingMask() const { return LoggingMask; }
void SetLoggingMask(unsigned logMask) { LoggingMask = logMask; }
diff --git a/LibOVR/Src/Kernel/OVR_Math.cpp b/LibOVR/Src/Kernel/OVR_Math.cpp
index e5a1f0e..396d3ff 100644
--- a/LibOVR/Src/Kernel/OVR_Math.cpp
+++ b/LibOVR/Src/Kernel/OVR_Math.cpp
@@ -5,16 +5,16 @@ Content : Implementation of 3D primitives such as vectors, matrices.
Created : September 4, 2012
Authors : Andrew Reisse, Michael Antonov, Anna Yershova
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -72,83 +72,20 @@ const double Math<double>::SingularityRadius = 0.000000000001; // Use for Gimbal
//-------------------------------------------------------------------------------------
-// ***** Matrix4f
-
-
-Matrix4f Matrix4f::LookAtRH(const Vector3f& eye, const Vector3f& at, const Vector3f& up)
-{
- Vector3f z = (eye - at).Normalized(); // Forward
- Vector3f x = up.Cross(z).Normalized(); // Right
- Vector3f y = z.Cross(x);
-
- Matrix4f m(x.x, x.y, x.z, -(x.Dot(eye)),
- y.x, y.y, y.z, -(y.Dot(eye)),
- z.x, z.y, z.z, -(z.Dot(eye)),
- 0, 0, 0, 1 );
- return m;
-}
-
-Matrix4f Matrix4f::LookAtLH(const Vector3f& eye, const Vector3f& at, const Vector3f& up)
-{
- Vector3f z = (at - eye).Normalized(); // Forward
- Vector3f x = up.Cross(z).Normalized(); // Right
- Vector3f y = z.Cross(x);
-
- Matrix4f m(x.x, x.y, x.z, -(x.Dot(eye)),
- y.x, y.y, y.z, -(y.Dot(eye)),
- z.x, z.y, z.z, -(z.Dot(eye)),
- 0, 0, 0, 1 );
- return m;
-}
-
-
-Matrix4f Matrix4f::PerspectiveLH(float yfov, float aspect, float znear, float zfar)
-{
- Matrix4f m;
- float tanHalfFov = tan(yfov * 0.5f);
-
- m.M[0][0] = 1.0f / (aspect * tanHalfFov);
- m.M[1][1] = 1.0f / tanHalfFov;
- m.M[2][2] = zfar / (zfar - znear);
- m.M[3][2] = 1.0f;
- m.M[2][3] = (zfar * znear) / (znear - zfar);
- m.M[3][3] = 0.0f;
-
- // Note: Post-projection matrix result assumes Left-Handed coordinate system,
- // with Y up, X right and Z forward. This supports positive z-buffer values.
- return m;
-}
-
-
-Matrix4f Matrix4f::PerspectiveRH(float yfov, float aspect, float znear, float zfar)
-{
- Matrix4f m;
- float tanHalfFov = tan(yfov * 0.5f);
-
- m.M[0][0] = 1.0f / (aspect * tanHalfFov);
- m.M[1][1] = 1.0f / tanHalfFov;
- m.M[2][2] = zfar / (znear - zfar);
- // m.M[2][2] = zfar / (zfar - znear);
- m.M[3][2] = -1.0f;
- m.M[2][3] = (zfar * znear) / (znear - zfar);
- m.M[3][3] = 0.0f;
-
- // Note: Post-projection matrix result assumes Left-Handed coordinate system,
- // with Y up, X right and Z forward. This supports positive z-buffer values.
- // This is the case even for RHS cooridnate input.
- return m;
-}
-
-Matrix4f Matrix4f::Ortho2D(float w, float h)
-{
- Matrix4f m;
- m.M[0][0] = 2.0f/w;
- m.M[1][1] = -2.0f/h;
- m.M[0][3] = -1.0;
- m.M[1][3] = 1.0;
- m.M[2][2] = 0;
- return m;
-}
+// ***** Matrix4
+
+template<>
+const Matrix4<float> Matrix4<float>::IdentityValue = Matrix4<float>(1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f);
+
+template<>
+const Matrix4<double> Matrix4<double>::IdentityValue = Matrix4<double>(1.0, 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0);
+
} // Namespace OVR
diff --git a/LibOVR/Src/Kernel/OVR_Math.h b/LibOVR/Src/Kernel/OVR_Math.h
index cdcce81..9bd5bad 100644
--- a/LibOVR/Src/Kernel/OVR_Math.h
+++ b/LibOVR/Src/Kernel/OVR_Math.h
@@ -4,18 +4,19 @@ PublicHeader: OVR.h
Filename : OVR_Math.h
Content : Implementation of 3D primitives such as vectors, matrices.
Created : September 4, 2012
-Authors : Andrew Reisse, Michael Antonov, Steve LaValle, Anna Yershova, Max Katsev
+Authors : Andrew Reisse, Michael Antonov, Steve LaValle,
+ Anna Yershova, Max Katsev, Dov Katz
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -35,6 +36,8 @@ limitations under the License.
#include "OVR_Types.h"
#include "OVR_RefCount.h"
#include "OVR_Std.h"
+#include "OVR_Alg.h"
+
namespace OVR {
@@ -86,15 +89,85 @@ struct WorldAxes
{ OVR_ASSERT(abs(x) != abs(y) && abs(y) != abs(z) && abs(z) != abs(x));}
};
+} // namespace OVR
+
+
+//------------------------------------------------------------------------------------//
+// ***** C Compatibility Types
+
+// These declarations are used to support conversion between C types used in
+// LibOVR C interfaces and their C++ versions. As an example, they allow passing
+// Vector3f into a function that expects ovrVector3f.
+
+typedef struct ovrQuatf_ ovrQuatf;
+typedef struct ovrQuatd_ ovrQuatd;
+typedef struct ovrSizei_ ovrSizei;
+typedef struct ovrSizef_ ovrSizef;
+typedef struct ovrRecti_ ovrRecti;
+typedef struct ovrVector2i_ ovrVector2i;
+typedef struct ovrVector2f_ ovrVector2f;
+typedef struct ovrVector3f_ ovrVector3f;
+typedef struct ovrVector3d_ ovrVector3d;
+typedef struct ovrMatrix3d_ ovrMatrix3d;
+typedef struct ovrMatrix4f_ ovrMatrix4f;
+typedef struct ovrPosef_ ovrPosef;
+typedef struct ovrPosed_ ovrPosed;
+typedef struct ovrPoseStatef_ ovrPoseStatef;
+typedef struct ovrPoseStated_ ovrPoseStated;
+
+namespace OVR {
+
+// Forward-declare our templates.
+template<class T> class Quat;
+template<class T> class Size;
+template<class T> class Rect;
+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 PoseState;
+
+// CompatibleTypes::Type is used to lookup a compatible C-version of a C++ class.
+template<class C>
+struct CompatibleTypes
+{
+ // Declaration here seems necessary for MSVC; specializations are
+ // used instead.
+ typedef float Type;
+};
+
+// 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<Matrix4<float> > { typedef ovrMatrix4f Type; };
+template<> struct CompatibleTypes<Size<int> > { typedef ovrSizei Type; };
+template<> struct CompatibleTypes<Size<float> > { typedef ovrSizef Type; };
+template<> struct CompatibleTypes<Rect<int> > { typedef ovrRecti Type; };
+template<> struct CompatibleTypes<Vector2<int> > { typedef ovrVector2i Type; };
+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<Pose<double> > { typedef ovrPosed Type; };
+template<> struct CompatibleTypes<PoseState<double> >{ typedef ovrPoseStated Type; };
//------------------------------------------------------------------------------------//
-// ************************************ Math *****************************************//
+// ***** Math
//
// Math class contains constants and functions. This class is a template specialized
// per type, with Math<float> and Math<double> being distinct.
template<class Type>
class Math
{
+public:
+ // By default, support explicit conversion to float. This allows Vector2<int> to
+ // compile, for example.
+ typedef float OtherFloatType;
};
// Single-precision Math constants class.
@@ -116,6 +189,9 @@ public:
static const float Tolerance; // 0.00001f;
static const float SingularityRadius; // 0.0000001f for Gimbal lock numerical problems
+
+ // Used to support direct conversions in template classes.
+ typedef double OtherFloatType;
};
// Double-precision Math constants class.
@@ -136,10 +212,12 @@ public:
static const double DegreeToRadFactor;
static const double Tolerance; // 0.00001;
- static const double SingularityRadius; // 0.000000000001 for Gimbal lock numerical problems
+ static const double SingularityRadius; // 0.000000000001 for Gimbal lock numerical problems
+ typedef float OtherFloatType;
};
+
typedef Math<float> Mathf;
typedef Math<double> Mathd;
@@ -172,6 +250,7 @@ inline int isnan(double x) { return _isnan(x); };
template<class T>
class Quat;
+
//-------------------------------------------------------------------------------------
// ***** Vector2<>
@@ -187,7 +266,22 @@ public:
Vector2() : x(0), y(0) { }
Vector2(T x_, T y_) : x(x_), y(y_) { }
explicit Vector2(T s) : x(s), y(s) { }
+ explicit Vector2(const Vector2<typename Math<T>::OtherFloatType> &src)
+ : x((T)src.x), y((T)src.y) { }
+
+ // C-interop support.
+ typedef typename CompatibleTypes<Vector2<T> >::Type CompatibleType;
+
+ Vector2(const CompatibleType& s) : x(s.x), y(s.y) { }
+
+ operator const CompatibleType& () const
+ {
+ OVR_COMPILER_ASSERT(sizeof(Vector2<T>) == sizeof(CompatibleType));
+ return reinterpret_cast<const CompatibleType&>(*this);
+ }
+
+
bool operator== (const Vector2& b) const { return x == b.x && y == b.y; }
bool operator!= (const Vector2& b) const { return x != b.x || y != b.y; }
@@ -207,6 +301,11 @@ public:
x *= rcp; y *= rcp;
return *this; }
+ static Vector2 Min(const Vector2& a, const Vector2& b) { return Vector2((a.x < b.x) ? a.x : b.x,
+ (a.y < b.y) ? a.y : b.y); }
+ static Vector2 Max(const Vector2& a, const Vector2& b) { return Vector2((a.x > b.x) ? a.x : b.x,
+ (a.y > b.y) ? a.y : b.y); }
+
// Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
bool Compare(const Vector2&b, T tolerance = Mathf::Tolerance)
{
@@ -216,10 +315,15 @@ public:
// Entrywise product of two vectors
Vector2 EntrywiseMultiply(const Vector2& b) const { return Vector2(x * b.x, y * b.y);}
+
+ // Multiply and divide operators do entry-wise math. Used Dot() for dot product.
+ Vector2 operator* (const Vector2& b) const { return Vector2(x * b.x, y * b.y); }
+ Vector2 operator/ (const Vector2& b) const { return Vector2(x / b.x, y / b.y); }
+
// Dot product
// Used to calculate angle q between two vectors among other things,
// as (A dot B) = |a||b|cos(q).
- T Dot(const Vector2& b) const { return x*b.x + y*b.y; }
+ T Dot(const Vector2& b) const { return x*b.x + y*b.y; }
// Returns the angle from this vector to b, in radians.
T Angle(const Vector2& b) const
@@ -232,9 +336,13 @@ public:
// Return Length of the vector squared.
T LengthSq() const { return (x * x + y * y); }
+
// Return vector length.
T Length() const { return sqrt(LengthSq()); }
+ // Returns squared distance between two points represented by vectors.
+ T DistanceSq(Vector2& b) const { return (*this - b).LengthSq(); }
+
// Returns distance between two points represented by vectors.
T Distance(Vector2& b) const { return (*this - b).Length(); }
@@ -273,7 +381,7 @@ public:
typedef Vector2<float> Vector2f;
typedef Vector2<double> Vector2d;
-
+typedef Vector2<int> Vector2i;
//-------------------------------------------------------------------------------------
// ***** Vector3<> - 3D vector of {x, y, z}
@@ -291,6 +399,20 @@ public:
Vector3() : x(0), y(0), z(0) { }
Vector3(T x_, T y_, T z_ = 0) : x(x_), y(y_), z(z_) { }
explicit Vector3(T s) : x(s), y(s), z(s) { }
+ explicit Vector3(const Vector3<typename Math<T>::OtherFloatType> &src)
+ : x((T)src.x), y((T)src.y), z((T)src.z) { }
+
+
+ // C-interop support.
+ typedef typename CompatibleTypes<Vector3<T> >::Type CompatibleType;
+
+ Vector3(const CompatibleType& s) : x(s.x), y(s.y), z(s.z) { }
+
+ operator const CompatibleType& () const
+ {
+ OVR_COMPILER_ASSERT(sizeof(Vector3<T>) == sizeof(CompatibleType));
+ return reinterpret_cast<const CompatibleType&>(*this);
+ }
bool operator== (const Vector3& b) const { return x == b.x && y == b.y && z == b.z; }
bool operator!= (const Vector3& b) const { return x != b.x || y != b.y || z != b.z; }
@@ -311,6 +433,19 @@ public:
x *= rcp; y *= rcp; z *= rcp;
return *this; }
+ static Vector3 Min(const Vector3& a, const Vector3& b)
+ {
+ return Vector3((a.x < b.x) ? a.x : b.x,
+ (a.y < b.y) ? a.y : b.y,
+ (a.z < b.z) ? a.z : b.z);
+ }
+ static Vector3 Max(const Vector3& a, const Vector3& b)
+ {
+ return Vector3((a.x > b.x) ? a.x : b.x,
+ (a.y > b.y) ? a.y : b.y,
+ (a.z > b.z) ? a.z : b.z);
+ }
+
// Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
bool Compare(const Vector3&b, T tolerance = Mathf::Tolerance)
{
@@ -319,11 +454,33 @@ public:
(fabs(b.z-z) < tolerance);
}
+ T& operator[] (int idx)
+ {
+ OVR_ASSERT(0 <= idx && idx < 3);
+ return *(&x + idx);
+ }
+
+ const T& operator[] (int idx) const
+ {
+ OVR_ASSERT(0 <= idx && idx < 3);
+ return *(&x + idx);
+ }
+
// Entrywise product of two vectors
Vector3 EntrywiseMultiply(const Vector3& b) const { return Vector3(x * b.x,
y * b.y,
z * b.z);}
+ // Multiply and divide operators do entry-wise math
+ Vector3 operator* (const Vector3& b) const { return Vector3(x * b.x,
+ y * b.y,
+ z * b.z); }
+
+ Vector3 operator/ (const Vector3& b) const { return Vector3(x / b.x,
+ y / b.y,
+ z / b.z); }
+
+
// Dot product
// Used to calculate angle q between two vectors among other things,
// as (A dot B) = |a||b|cos(q).
@@ -347,11 +504,15 @@ public:
// Return Length of the vector squared.
T LengthSq() const { return (x * x + y * y + z * z); }
+
// Return vector length.
T Length() const { return sqrt(LengthSq()); }
+ // Returns squared distance between two points represented by vectors.
+ T DistanceSq(Vector3& b) const { return (*this - b).LengthSq(); }
+
// Returns distance between two points represented by vectors.
- T Distance(Vector3& b) const { return (*this - b).Length(); }
+ T Distance(Vector3 const& b) const { return (*this - b).Length(); }
// Determine if this a unit vector.
bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance; }
@@ -392,6 +553,24 @@ public:
typedef Vector3<float> Vector3f;
typedef Vector3<double> Vector3d;
+typedef Vector3<SInt32> Vector3i;
+
+
+// JDC: this was defined in Render_Device.h, I moved it here, but it
+// needs to be fleshed out like the other Vector types.
+//
+// A vector with a dummy w component for alignment in uniform buffers (and for float colors).
+// The w component is not used in any calculations.
+
+struct Vector4f : public Vector3f
+{
+ float w;
+
+ Vector4f() : w(1) {}
+ Vector4f(const Vector3f& v) : Vector3f(v), w(1) {}
+ Vector4f(float r, float g, float b, float a) : Vector3f(r,g,b), w(a) {}
+};
+
//-------------------------------------------------------------------------------------
@@ -404,34 +583,53 @@ template<class T>
class Size
{
public:
- T Width, Height;
+ T w, h;
+
+ Size() : w(0), h(0) { }
+ Size(T w_, T h_) : w(w_), h(h_) { }
+ explicit Size(T s) : w(s), h(s) { }
+ explicit Size(const Size<typename Math<T>::OtherFloatType> &src)
+ : w((T)src.w), h((T)src.h) { }
+
+ // C-interop support.
+ typedef typename CompatibleTypes<Size<T> >::Type CompatibleType;
- Size() : Width(0), Height(0) { }
- Size(T w_, T h_) : Width(w_), Height(h_) { }
- explicit Size(T s) : Width(s), Height(s) { }
+ Size(const CompatibleType& s) : w(s.w), h(s.h) { }
+
+ operator const CompatibleType& () const
+ {
+ OVR_COMPILER_ASSERT(sizeof(Size<T>) == sizeof(CompatibleType));
+ return reinterpret_cast<const CompatibleType&>(*this);
+ }
- bool operator== (const Size& b) const { return Width == b.Width && Height == b.Height; }
- bool operator!= (const Size& b) const { return Width != b.Width || Height != b.Height; }
+ bool operator== (const Size& b) const { return w == b.w && h == b.h; }
+ bool operator!= (const Size& b) const { return w != b.w || h != b.h; }
- Size operator+ (const Size& b) const { return Size(Width + b.Width, Height + b.Height); }
- Size& operator+= (const Size& b) { Width += b.Width; Height += b.Height; return *this; }
- Size operator- (const Size& b) const { return Size(Width - b.Width, Height - b.Height); }
- Size& operator-= (const Size& b) { Width -= b.Width; Height -= b.Height; return *this; }
- Size operator- () const { return Size(-Width, -Height); }
- Size operator* (const Size& b) const { return Size(Width * b.Width, Height * b.Height); }
- Size& operator*= (const Size& b) { Width *= b.Width; Height *= b.Height; return *this; }
- Size operator/ (const Size& b) const { return Size(Width / b.Width, Height / b.Height); }
- Size& operator/= (const Size& b) { Width /= b.Width; Height /= b.Height; return *this; }
+ Size operator+ (const Size& b) const { return Size(w + b.w, h + b.h); }
+ Size& operator+= (const Size& b) { w += b.w; h += b.h; return *this; }
+ Size operator- (const Size& b) const { return Size(w - b.w, h - b.h); }
+ Size& operator-= (const Size& b) { w -= b.w; h -= b.h; return *this; }
+ Size operator- () const { return Size(-w, -h); }
+ Size operator* (const Size& b) const { return Size(w * b.w, h * b.h); }
+ Size& operator*= (const Size& b) { w *= b.w; h *= b.h; return *this; }
+ Size operator/ (const Size& b) const { return Size(w / b.w, h / b.h); }
+ Size& operator/= (const Size& b) { w /= b.w; h /= b.h; return *this; }
// Scalar multiplication/division scales both components.
- Size operator* (T s) const { return Size(Width*s, Height*s); }
- Size& operator*= (T s) { Width *= s; Height *= s; return *this; }
- Size operator/ (T s) const { return Size(Width/s, Height/s); }
- Size& operator/= (T s) { Width /= s; Height /= s; return *this; }
+ Size operator* (T s) const { return Size(w*s, h*s); }
+ Size& operator*= (T s) { w *= s; h *= s; return *this; }
+ Size operator/ (T s) const { return Size(w/s, h/s); }
+ Size& operator/= (T s) { w /= s; h /= s; return *this; }
+
+ static Size Min(const Size& a, const Size& b) { return Size((a.w < b.w) ? a.w : b.w,
+ (a.h < b.h) ? a.h : b.h); }
+ static Size Max(const Size& a, const Size& b) { return Size((a.w > b.w) ? a.w : b.w,
+ (a.h > b.h) ? a.h : b.h); }
+
- T Area() const { return Width * Height; }
+ T Area() const { return w * h; }
- inline Vector2<T> ToVector() const { return Vector2<T>(Width, Height); }
+ inline Vector2<T> ToVector() const { return Vector2<T>(w, h); }
};
@@ -441,10 +639,494 @@ typedef Size<float> Sizef;
typedef Size<double> Sized;
+
+//-----------------------------------------------------------------------------------
+// ***** Rect
+
+// Rect describes a rectangular area for rendering, that includes position and size.
+template<class T>
+class Rect
+{
+public:
+ T x, y;
+ T w, h;
+
+ Rect() { }
+ Rect(T x1, T y1, T w1, T h1) : x(x1), y(y1), w(w1), h(h1) { }
+ Rect(const Vector2<T>& pos, const Size<T>& sz) : x(pos.x), y(pos.y), w(sz.w), h(sz.h) { }
+ Rect(const Size<T>& sz) : x(0), y(0), w(sz.w), h(sz.h) { }
+
+ // C-interop support.
+ typedef typename CompatibleTypes<Rect<T> >::Type CompatibleType;
+
+ Rect(const CompatibleType& s) : x(s.Pos.x), y(s.Pos.y), w(s.Size.w), h(s.Size.h) { }
+
+ operator const CompatibleType& () const
+ {
+ OVR_COMPILER_ASSERT(sizeof(Rect<T>) == sizeof(CompatibleType));
+ return reinterpret_cast<const CompatibleType&>(*this);
+ }
+
+ Vector2<T> GetPos() const { return Vector2<T>(x, y); }
+ Size<T> GetSize() const { return Size<T>(w, h); }
+ void SetPos(const Vector2<T>& pos) { x = pos.x; y = pos.y; }
+ void SetSize(const Size<T>& sz) { w = sz.w; h = sz.h; }
+
+ bool operator == (const Rect& vp) const
+ { return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); }
+ bool operator != (const Rect& vp) const
+ { return !operator == (vp); }
+};
+
+typedef Rect<int> Recti;
+
+
+//-------------------------------------------------------------------------------------//
+// ***** Quat
+//
+// Quatf represents a quaternion class used for rotations.
+//
+// Quaternion multiplications are done in right-to-left order, to match the
+// behavior of matrices.
+
+
+template<class T>
+class Quat
+{
+public:
+ // w + Xi + Yj + Zk
+ T x, y, z, w;
+
+ Quat() : x(0), y(0), z(0), w(1) { }
+ Quat(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) { }
+ explicit Quat(const Quat<typename Math<T>::OtherFloatType> &src)
+ : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w) { }
+
+ // 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
+ {
+ typename CompatibleTypes<Quat<T> >::Type result;
+ result.x = x;
+ result.y = y;
+ result.z = z;
+ result.w = w;
+ return result;
+ }
+
+ // Constructs quaternion for rotation around the axis by an angle.
+ Quat(const Vector3<T>& axis, T angle)
+ {
+ // Make sure we don't divide by zero.
+ if (axis.LengthSq() == 0)
+ {
+ // Assert if the axis is zero, but the angle isn't
+ OVR_ASSERT(angle == 0);
+ x = 0; y = 0; z = 0; w = 1;
+ return;
+ }
+
+ Vector3<T> unitAxis = axis.Normalized();
+ T sinHalfAngle = sin(angle * T(0.5));
+
+ w = cos(angle * T(0.5));
+ x = unitAxis.x * sinHalfAngle;
+ y = unitAxis.y * sinHalfAngle;
+ z = unitAxis.z * sinHalfAngle;
+ }
+
+ // Constructs quaternion for rotation around one of the coordinate axis by an angle.
+ Quat(Axis A, T angle, RotateDirection d = Rotate_CCW, HandedSystem s = Handed_R)
+ {
+ T sinHalfAngle = s * d *sin(angle * T(0.5));
+ T v[3];
+ v[0] = v[1] = v[2] = T(0);
+ v[A] = sinHalfAngle;
+
+ w = cos(angle * T(0.5));
+ x = v[0];
+ y = v[1];
+ z = v[2];
+ }
+
+ // Compute axis and angle from quaternion
+ void GetAxisAngle(Vector3<T>* axis, T* angle) const
+ {
+ if ( x*x + y*y + z*z > Math<T>::Tolerance * Math<T>::Tolerance ) {
+ *axis = Vector3<T>(x, y, z).Normalized();
+ *angle = 2 * Acos(w);
+ if (*angle > Math<T>::Pi) // Reduce the magnitude of the angle, if necessary
+ {
+ *angle = Math<T>::TwoPi - *angle;
+ *axis = *axis * (-1);
+ }
+ }
+ else
+ {
+ *axis = Vector3<T>(1, 0, 0);
+ *angle= 0;
+ }
+ }
+
+ // Constructs the quaternion from a rotation matrix
+ explicit Quat(const Matrix4<T>& m)
+ {
+ T trace = m.M[0][0] + m.M[1][1] + m.M[2][2];
+
+ // In almost all cases, the first part is executed.
+ // However, if the trace is not positive, the other
+ // cases arise.
+ if (trace > T(0))
+ {
+ T s = sqrt(trace + T(1)) * T(2); // s=4*qw
+ w = T(0.25) * s;
+ x = (m.M[2][1] - m.M[1][2]) / s;
+ y = (m.M[0][2] - m.M[2][0]) / s;
+ z = (m.M[1][0] - m.M[0][1]) / s;
+ }
+ else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2]))
+ {
+ T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2);
+ w = (m.M[2][1] - m.M[1][2]) / s;
+ x = T(0.25) * s;
+ y = (m.M[0][1] + m.M[1][0]) / s;
+ z = (m.M[2][0] + m.M[0][2]) / s;
+ }
+ else if (m.M[1][1] > m.M[2][2])
+ {
+ T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy
+ w = (m.M[0][2] - m.M[2][0]) / s;
+ x = (m.M[0][1] + m.M[1][0]) / s;
+ y = T(0.25) * s;
+ z = (m.M[1][2] + m.M[2][1]) / s;
+ }
+ else
+ {
+ T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz
+ w = (m.M[1][0] - m.M[0][1]) / s;
+ x = (m.M[0][2] + m.M[2][0]) / s;
+ y = (m.M[1][2] + m.M[2][1]) / s;
+ z = T(0.25) * s;
+ }
+ }
+
+ // Constructs the quaternion from a rotation matrix
+ explicit Quat(const Matrix3<T>& m)
+ {
+ T trace = m.M[0][0] + m.M[1][1] + m.M[2][2];
+
+ // In almost all cases, the first part is executed.
+ // However, if the trace is not positive, the other
+ // cases arise.
+ if (trace > T(0))
+ {
+ T s = sqrt(trace + T(1)) * T(2); // s=4*qw
+ w = T(0.25) * s;
+ x = (m.M[2][1] - m.M[1][2]) / s;
+ y = (m.M[0][2] - m.M[2][0]) / s;
+ z = (m.M[1][0] - m.M[0][1]) / s;
+ }
+ else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2]))
+ {
+ T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2);
+ w = (m.M[2][1] - m.M[1][2]) / s;
+ x = T(0.25) * s;
+ y = (m.M[0][1] + m.M[1][0]) / s;
+ z = (m.M[2][0] + m.M[0][2]) / s;
+ }
+ else if (m.M[1][1] > m.M[2][2])
+ {
+ T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy
+ w = (m.M[0][2] - m.M[2][0]) / s;
+ x = (m.M[0][1] + m.M[1][0]) / s;
+ y = T(0.25) * s;
+ z = (m.M[1][2] + m.M[2][1]) / s;
+ }
+ else
+ {
+ T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz
+ w = (m.M[1][0] - m.M[0][1]) / s;
+ x = (m.M[0][2] + m.M[2][0]) / s;
+ y = (m.M[1][2] + m.M[2][1]) / s;
+ z = T(0.25) * s;
+ }
+ }
+
+ bool operator== (const Quat& b) const { return x == b.x && y == b.y && z == b.z && w == b.w; }
+ bool operator!= (const Quat& b) const { return x != b.x || y != b.y || z != b.z || w != b.w; }
+
+ Quat operator+ (const Quat& b) const { return Quat(x + b.x, y + b.y, z + b.z, w + b.w); }
+ Quat& operator+= (const Quat& b) { w += b.w; x += b.x; y += b.y; z += b.z; return *this; }
+ Quat operator- (const Quat& b) const { return Quat(x - b.x, y - b.y, z - b.z, w - b.w); }
+ Quat& operator-= (const Quat& b) { w -= b.w; x -= b.x; y -= b.y; z -= b.z; return *this; }
+
+ Quat operator* (T s) const { return Quat(x * s, y * s, z * s, w * s); }
+ Quat& operator*= (T s) { w *= s; x *= s; y *= s; z *= s; return *this; }
+ Quat operator/ (T s) const { T rcp = T(1)/s; return Quat(x * rcp, y * rcp, z * rcp, w *rcp); }
+ Quat& operator/= (T s) { T rcp = T(1)/s; w *= rcp; x *= rcp; y *= rcp; z *= rcp; return *this; }
+
+
+ // Get Imaginary part vector
+ Vector3<T> Imag() const { return Vector3<T>(x,y,z); }
+
+ // Get quaternion length.
+ T Length() const { return sqrt(LengthSq()); }
+
+ // Get quaternion length squared.
+ T LengthSq() const { return (x * x + y * y + z * z + w * w); }
+
+ // Simple Euclidean distance in R^4 (not SLERP distance, but at least respects Haar measure)
+ T Distance(const Quat& q) const
+ {
+ T d1 = (*this - q).Length();
+ T d2 = (*this + q).Length(); // Antipodal point check
+ return (d1 < d2) ? d1 : d2;
+ }
+
+ T DistanceSq(const Quat& q) const
+ {
+ T d1 = (*this - q).LengthSq();
+ T d2 = (*this + q).LengthSq(); // Antipodal point check
+ return (d1 < d2) ? d1 : d2;
+ }
+
+ T Dot(const Quat& q) const
+ {
+ return x * q.x + y * q.y + z * q.z + w * q.w;
+ }
+
+ // Angle between two quaternions in radians
+ T Angle(const Quat& q) const
+ {
+ return 2 * Acos(Alg::Abs(Dot(q)));
+ }
+
+ // Normalize
+ bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance; }
+
+ void Normalize()
+ {
+ T l = Length();
+ OVR_ASSERT(l != T(0));
+ *this /= l;
+ }
+
+ Quat Normalized() const
+ {
+ T l = Length();
+ OVR_ASSERT(l != T(0));
+ return *this / l;
+ }
+
+ // Returns conjugate of the quaternion. Produces inverse rotation if quaternion is normalized.
+ Quat Conj() const { return Quat(-x, -y, -z, w); }
+
+ // Quaternion multiplication. Combines quaternion rotations, performing the one on the
+ // right hand side first.
+ Quat operator* (const Quat& b) const { return Quat(w * b.x + x * b.w + y * b.z - z * b.y,
+ w * b.y - x * b.z + y * b.w + z * b.x,
+ w * b.z + x * b.y - y * b.x + z * b.w,
+ w * b.w - x * b.x - y * b.y - z * b.z); }
+
+ //
+ // this^p normalized; same as rotating by this p times.
+ Quat PowNormalized(T p) const
+ {
+ Vector3<T> v;
+ T a;
+ GetAxisAngle(&v, &a);
+ return Quat(v, a * p);
+ }
+
+ // Normalized linear interpolation of quaternions
+ Quat Nlerp(const Quat& other, T a)
+ {
+ T sign = (Dot(other) >= 0) ? 1 : -1;
+ return (*this * sign * a + other * (1-a)).Normalized();
+ }
+
+ // Rotate transforms vector in a manner that matches Matrix rotations (counter-clockwise,
+ // assuming negative direction of the axis). Standard formula: q(t) * V * q(t)^-1.
+ Vector3<T> Rotate(const Vector3<T>& v) const
+ {
+ return ((*this * Quat<T>(v.x, v.y, v.z, T(0))) * Inverted()).Imag();
+ }
+
+ // Inversed quaternion rotates in the opposite direction.
+ Quat Inverted() const
+ {
+ return Quat(-x, -y, -z, w);
+ }
+
+ // Sets this quaternion to the one rotates in the opposite direction.
+ void Invert()
+ {
+ *this = Quat(-x, -y, -z, w);
+ }
+
+ // GetEulerAngles extracts Euler angles from the quaternion, in the specified order of
+ // axis rotations and the specified coordinate system. Right-handed coordinate system
+ // is the default, with CCW rotations while looking in the negative axis direction.
+ // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
+ // rotation a around axis A1
+ // is followed by rotation b around axis A2
+ // is followed by rotation c around axis A3
+ // rotations are CCW or CW (D) in LH or RH coordinate system (S)
+ template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
+ void GetEulerAngles(T *a, T *b, T *c) const
+ {
+ OVR_COMPILER_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3));
+
+ T Q[3] = { x, y, z }; //Quaternion components x,y,z
+
+ T ww = w*w;
+ T Q11 = Q[A1]*Q[A1];
+ T Q22 = Q[A2]*Q[A2];
+ T Q33 = Q[A3]*Q[A3];
+
+ T psign = T(-1);
+ // Determine whether even permutation
+ if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3))
+ psign = T(1);
+
+ T s2 = psign * T(2) * (psign*w*Q[A2] + Q[A1]*Q[A3]);
+
+ if (s2 < T(-1) + Math<T>::SingularityRadius)
+ { // South pole singularity
+ *a = T(0);
+ *b = -S*D*Math<T>::PiOver2;
+ *c = S*D*atan2(T(2)*(psign*Q[A1]*Q[A2] + w*Q[A3]),
+ ww + Q22 - Q11 - Q33 );
+ }
+ else if (s2 > T(1) - Math<T>::SingularityRadius)
+ { // North pole singularity
+ *a = T(0);
+ *b = S*D*Math<T>::PiOver2;
+ *c = S*D*atan2(T(2)*(psign*Q[A1]*Q[A2] + w*Q[A3]),
+ ww + Q22 - Q11 - Q33);
+ }
+ else
+ {
+ *a = -S*D*atan2(T(-2)*(w*Q[A1] - psign*Q[A2]*Q[A3]),
+ ww + Q33 - Q11 - Q22);
+ *b = S*D*asin(s2);
+ *c = S*D*atan2(T(2)*(w*Q[A3] - psign*Q[A1]*Q[A2]),
+ ww + Q11 - Q22 - Q33);
+ }
+ return;
+ }
+
+ template <Axis A1, Axis A2, Axis A3, RotateDirection D>
+ void GetEulerAngles(T *a, T *b, T *c) const
+ { GetEulerAngles<A1, A2, A3, D, Handed_R>(a, b, c); }
+
+ template <Axis A1, Axis A2, Axis A3>
+ void GetEulerAngles(T *a, T *b, T *c) const
+ { GetEulerAngles<A1, A2, A3, Rotate_CCW, Handed_R>(a, b, c); }
+
+
+ // GetEulerAnglesABA extracts Euler angles from the quaternion, in the specified order of
+ // axis rotations and the specified coordinate system. Right-handed coordinate system
+ // is the default, with CCW rotations while looking in the negative axis direction.
+ // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
+ // rotation a around axis A1
+ // is followed by rotation b around axis A2
+ // is followed by rotation c around axis A1
+ // Rotations are CCW or CW (D) in LH or RH coordinate system (S)
+ template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
+ void GetEulerAnglesABA(T *a, T *b, T *c) const
+ {
+ OVR_COMPILER_ASSERT(A1 != A2);
+
+ T Q[3] = {x, y, z}; // Quaternion components
+
+ // Determine the missing axis that was not supplied
+ int m = 3 - A1 - A2;
+
+ T ww = w*w;
+ T Q11 = Q[A1]*Q[A1];
+ T Q22 = Q[A2]*Q[A2];
+ T Qmm = Q[m]*Q[m];
+
+ T psign = T(-1);
+ if ((A1 + 1) % 3 == A2) // Determine whether even permutation
+ {
+ psign = T(1);
+ }
+
+ T c2 = ww + Q11 - Q22 - Qmm;
+ if (c2 < T(-1) + Math<T>::SingularityRadius)
+ { // South pole singularity
+ *a = T(0);
+ *b = S*D*Math<T>::Pi;
+ *c = S*D*atan2( T(2)*(w*Q[A1] - psign*Q[A2]*Q[m]),
+ ww + Q22 - Q11 - Qmm);
+ }
+ else if (c2 > T(1) - Math<T>::SingularityRadius)
+ { // North pole singularity
+ *a = T(0);
+ *b = T(0);
+ *c = S*D*atan2( T(2)*(w*Q[A1] - psign*Q[A2]*Q[m]),
+ ww + Q22 - Q11 - Qmm);
+ }
+ else
+ {
+ *a = S*D*atan2( psign*w*Q[m] + Q[A1]*Q[A2],
+ w*Q[A2] -psign*Q[A1]*Q[m]);
+ *b = S*D*acos(c2);
+ *c = S*D*atan2( -psign*w*Q[m] + Q[A1]*Q[A2],
+ w*Q[A2] + psign*Q[A1]*Q[m]);
+ }
+ return;
+ }
+};
+
+typedef Quat<float> Quatf;
+typedef Quat<double> Quatd;
+
//-------------------------------------------------------------------------------------
-// ***** Matrix4f
+// ***** Pose
+
+// Position and orientation combined.
+
+template<class T>
+class Pose
+{
+public:
+
+ typedef typename CompatibleTypes<Pose<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) { }
+
+ operator const typename CompatibleTypes<Pose<T> >::Type () const
+ {
+ typename CompatibleTypes<Pose<T> >::Type result;
+ result.Orientation = Orientation;
+ result.Position = Position;
+ return result;
+ }
+
+ Quat<T> Orientation;
+ Vector3<T> Position;
+};
+
+typedef Pose<float> Posef;
+typedef Pose<double> Posed;
+
+
+//-------------------------------------------------------------------------------------
+// ***** Matrix4
//
-// Matrix4f is a 4x4 matrix used for 3d transformations and projections.
+// Matrix4 is a 4x4 matrix used for 3d transformations and projections.
// Translation stored in the last column.
// The matrix is stored in row-major order in memory, meaning that values
// of the first row are stored before the next one.
@@ -469,28 +1151,29 @@ typedef Size<double> Sized;
//
// The basis vectors are first three columns.
-class Matrix4f
+template<class T>
+class Matrix4
{
- static Matrix4f IdentityValue;
+ static const Matrix4 IdentityValue;
public:
- float M[4][4];
+ T M[4][4];
enum NoInitType { NoInit };
// Construct with no memory initialization.
- Matrix4f(NoInitType) { }
+ Matrix4(NoInitType) { }
// By default, we construct identity matrix.
- Matrix4f()
+ Matrix4()
{
SetIdentity();
}
- Matrix4f(float m11, float m12, float m13, float m14,
- float m21, float m22, float m23, float m24,
- float m31, float m32, float m33, float m34,
- float m41, float m42, float m43, float m44)
+ Matrix4(T m11, T m12, T m13, T m14,
+ T m21, T m22, T m23, T m24,
+ T m31, T m32, T m33, T m34,
+ T m41, T m42, T m43, T m44)
{
M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = m14;
M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = m24;
@@ -498,9 +1181,9 @@ public:
M[3][0] = m41; M[3][1] = m42; M[3][2] = m43; M[3][3] = m44;
}
- Matrix4f(float m11, float m12, float m13,
- float m21, float m22, float m23,
- float m31, float m32, float m33)
+ Matrix4(T m11, T m12, T m13,
+ T m21, T m22, T m23,
+ T m31, T m32, T m33)
{
M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = 0;
M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = 0;
@@ -508,7 +1191,50 @@ public:
M[3][0] = 0; M[3][1] = 0; M[3][2] = 0; M[3][3] = 1;
}
- void ToString(char* dest, UPInt destsize)
+ explicit Matrix4(const Quat<T>& q)
+ {
+ T ww = q.w*q.w;
+ T xx = q.x*q.x;
+ T yy = q.y*q.y;
+ T zz = q.z*q.z;
+
+ M[0][0] = ww + xx - yy - zz; M[0][1] = 2 * (q.x*q.y - q.w*q.z); M[0][2] = 2 * (q.x*q.z + q.w*q.y); M[0][3] = 0;
+ M[1][0] = 2 * (q.x*q.y + q.w*q.z); M[1][1] = ww - xx + yy - zz; M[1][2] = 2 * (q.y*q.z - q.w*q.x); M[1][3] = 0;
+ M[2][0] = 2 * (q.x*q.z - q.w*q.y); M[2][1] = 2 * (q.y*q.z + q.w*q.x); M[2][2] = ww - xx - yy + zz; M[2][3] = 0;
+ M[3][0] = 0; M[3][1] = 0; M[3][2] = 0; M[3][3] = 1;
+ }
+
+ explicit Matrix4(const Pose<T>& p)
+ {
+ Matrix4 result(p.Orientation);
+ result.SetTranslation(p.Position);
+ *this = result;
+ }
+
+ // C-interop support
+ explicit Matrix4(const Matrix4<typename Math<T>::OtherFloatType> &src)
+ {
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ M[i][j] = (T)src.M[i][j];
+ }
+
+ // C-interop support.
+ Matrix4(const typename CompatibleTypes<Matrix4<T> >::Type& s)
+ {
+ OVR_COMPILER_ASSERT(sizeof(s) == sizeof(Matrix4));
+ memcpy(M, s.M, sizeof(M));
+ }
+
+ operator const typename CompatibleTypes<Matrix4<T> >::Type () const
+ {
+ typename CompatibleTypes<Matrix4<T> >::Type result;
+ OVR_COMPILER_ASSERT(sizeof(result) == sizeof(Matrix4));
+ memcpy(result.M, M, sizeof(M));
+ return result;
+ }
+
+ void ToString(char* dest, UPInt destsize) const
{
UPInt pos = 0;
for (int r=0; r<4; r++)
@@ -516,13 +1242,13 @@ public:
pos += OVR_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]);
}
- static Matrix4f FromString(const char* src)
+ static Matrix4 FromString(const char* src)
{
- Matrix4f result;
+ Matrix4 result;
for (int r=0; r<4; r++)
for (int c=0; c<4; c++)
{
- result.M[r][c] = (float)atof(src);
+ result.M[r][c] = (T)atof(src);
while (src && *src != ' ')
src++;
while (src && *src == ' ')
@@ -531,7 +1257,7 @@ public:
return result;
}
- static const Matrix4f& Identity() { return IdentityValue; }
+ static const Matrix4& Identity() { return IdentityValue; }
void SetIdentity()
{
@@ -541,14 +1267,24 @@ public:
M[0][3] = M[1][3] = M[2][1] = M[3][0] = 0;
}
- Matrix4f operator+ (const Matrix4f& b) const
+ bool operator== (const Matrix4& b) const
+ {
+ bool isEqual = true;
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ isEqual &= (M[i][j] == b.M[i][j]);
+
+ return isEqual;
+ }
+
+ Matrix4 operator+ (const Matrix4& b) const
{
- Matrix4f result(*this);
+ Matrix4 result(*this);
result += b;
return result;
}
- Matrix4f& operator+= (const Matrix4f& b)
+ Matrix4& operator+= (const Matrix4& b)
{
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
@@ -556,14 +1292,14 @@ public:
return *this;
}
- Matrix4f operator- (const Matrix4f& b) const
+ Matrix4 operator- (const Matrix4& b) const
{
- Matrix4f result(*this);
+ Matrix4 result(*this);
result -= b;
return result;
}
- Matrix4f& operator-= (const Matrix4f& b)
+ Matrix4& operator-= (const Matrix4& b)
{
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
@@ -572,7 +1308,7 @@ public:
}
// Multiplies two matrices into destination with minimum copying.
- static Matrix4f& Multiply(Matrix4f* d, const Matrix4f& a, const Matrix4f& b)
+ static Matrix4& Multiply(Matrix4* d, const Matrix4& a, const Matrix4& b)
{
OVR_ASSERT((d != &a) && (d != &b));
int i = 0;
@@ -586,26 +1322,26 @@ public:
return *d;
}
- Matrix4f operator* (const Matrix4f& b) const
+ Matrix4 operator* (const Matrix4& b) const
{
- Matrix4f result(Matrix4f::NoInit);
+ Matrix4 result(Matrix4::NoInit);
Multiply(&result, *this, b);
return result;
}
- Matrix4f& operator*= (const Matrix4f& b)
+ Matrix4& operator*= (const Matrix4& b)
{
- return Multiply(this, Matrix4f(*this), b);
+ return Multiply(this, Matrix4(*this), b);
}
- Matrix4f operator* (float s) const
+ Matrix4 operator* (T s) const
{
- Matrix4f result(*this);
+ Matrix4 result(*this);
result *= s;
return result;
}
- Matrix4f& operator*= (float s)
+ Matrix4& operator*= (T s)
{
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
@@ -614,14 +1350,14 @@ public:
}
- Matrix4f operator/ (float s) const
+ Matrix4 operator/ (T s) const
{
- Matrix4f result(*this);
+ Matrix4 result(*this);
result /= s;
return result;
}
- Matrix4f& operator/= (float s)
+ Matrix4& operator/= (T s)
{
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
@@ -629,16 +1365,16 @@ public:
return *this;
}
- Vector3f Transform(const Vector3f& v) const
+ Vector3<T> Transform(const Vector3<T>& v) const
{
- return Vector3f(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3],
- M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3],
- M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3]);
+ return Vector3<T>(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3],
+ M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3],
+ M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3]);
}
- Matrix4f Transposed() const
+ Matrix4 Transposed() const
{
- return Matrix4f(M[0][0], M[1][0], M[2][0], M[3][0],
+ return Matrix4(M[0][0], M[1][0], M[2][0], M[3][0],
M[0][1], M[1][1], M[2][1], M[3][1],
M[0][2], M[1][2], M[2][2], M[3][2],
M[0][3], M[1][3], M[2][3], M[3][3]);
@@ -650,35 +1386,35 @@ public:
}
- float SubDet (const UPInt* rows, const UPInt* cols) const
+ T SubDet (const UPInt* rows, const UPInt* cols) const
{
return M[rows[0]][cols[0]] * (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]])
- M[rows[0]][cols[1]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]])
+ M[rows[0]][cols[2]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]);
}
- float Cofactor(UPInt I, UPInt J) const
+ T Cofactor(UPInt I, UPInt J) const
{
const UPInt indices[4][3] = {{1,2,3},{0,2,3},{0,1,3},{0,1,2}};
return ((I+J)&1) ? -SubDet(indices[I],indices[J]) : SubDet(indices[I],indices[J]);
}
- float Determinant() const
+ T Determinant() const
{
return M[0][0] * Cofactor(0,0) + M[0][1] * Cofactor(0,1) + M[0][2] * Cofactor(0,2) + M[0][3] * Cofactor(0,3);
}
- Matrix4f Adjugated() const
+ Matrix4 Adjugated() const
{
- return Matrix4f(Cofactor(0,0), Cofactor(1,0), Cofactor(2,0), Cofactor(3,0),
+ return Matrix4(Cofactor(0,0), Cofactor(1,0), Cofactor(2,0), Cofactor(3,0),
Cofactor(0,1), Cofactor(1,1), Cofactor(2,1), Cofactor(3,1),
Cofactor(0,2), Cofactor(1,2), Cofactor(2,2), Cofactor(3,2),
Cofactor(0,3), Cofactor(1,3), Cofactor(2,3), Cofactor(3,3));
}
- Matrix4f Inverted() const
+ Matrix4 Inverted() const
{
- float det = Determinant();
+ T det = Determinant();
assert(det != 0);
return Adjugated() * (1.0f/det);
}
@@ -690,14 +1426,14 @@ public:
// This is more efficient than general inverse, but ONLY works
// correctly if it is a homogeneous transform matrix (rot + trans)
- Matrix4f InvertedHomogeneousTransform() const
+ Matrix4 InvertedHomogeneousTransform() const
{
// Make the inverse rotation matrix
- Matrix4f rinv = this->Transposed();
+ Matrix4 rinv = this->Transposed();
rinv.M[3][0] = rinv.M[3][1] = rinv.M[3][2] = 0.0f;
// Make the inverse translation matrix
- Vector3f tvinv = Vector3f(-M[0][3],-M[1][3],-M[2][3]);
- Matrix4f tinv = Matrix4f::Translation(tvinv);
+ Vector3<T> tvinv(-M[0][3],-M[1][3],-M[2][3]);
+ Matrix4 tinv = Matrix4::Translation(tvinv);
return rinv * tinv; // "untranslate", then "unrotate"
}
@@ -715,25 +1451,25 @@ public:
// is followed by rotation c around axis A3
// rotations are CCW or CW (D) in LH or RH coordinate system (S)
template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
- void ToEulerAngles(float *a, float *b, float *c)
+ void ToEulerAngles(T *a, T *b, T *c)
{
OVR_COMPILER_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3));
- float psign = -1.0f;
+ T psign = -1;
if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) // Determine whether even permutation
- psign = 1.0f;
+ psign = 1;
- float pm = psign*M[A1][A3];
- if (pm < -1.0f + Math<float>::SingularityRadius)
+ T pm = psign*M[A1][A3];
+ if (pm < -1.0f + Math<T>::SingularityRadius)
{ // South pole singularity
- *a = 0.0f;
- *b = -S*D*Math<float>::PiOver2;
+ *a = 0;
+ *b = -S*D*Math<T>::PiOver2;
*c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
}
- else if (pm > 1.0f - Math<float>::SingularityRadius)
+ else if (pm > 1.0f - Math<T>::SingularityRadius)
{ // North pole singularity
- *a = 0.0f;
- *b = S*D*Math<float>::PiOver2;
+ *a = 0;
+ *b = S*D*Math<T>::PiOver2;
*c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
}
else
@@ -753,28 +1489,28 @@ public:
// is followed by rotation c around axis A1
// rotations are CCW or CW (D) in LH or RH coordinate system (S)
template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
- void ToEulerAnglesABA(float *a, float *b, float *c)
+ void ToEulerAnglesABA(T *a, T *b, T *c)
{
OVR_COMPILER_ASSERT(A1 != A2);
// Determine the axis that was not supplied
int m = 3 - A1 - A2;
- float psign = -1.0f;
+ T psign = -1;
if ((A1 + 1) % 3 == A2) // Determine whether even permutation
psign = 1.0f;
- float c2 = M[A1][A1];
- if (c2 < -1.0f + Math<float>::SingularityRadius)
+ T c2 = M[A1][A1];
+ if (c2 < -1 + Math<T>::SingularityRadius)
{ // South pole singularity
- *a = 0.0f;
- *b = S*D*Math<float>::Pi;
+ *a = 0;
+ *b = S*D*Math<T>::Pi;
*c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
}
- else if (c2 > 1.0f - Math<float>::SingularityRadius)
+ else if (c2 > 1.0f - Math<T>::SingularityRadius)
{ // North pole singularity
- *a = 0.0f;
- *b = 0.0f;
+ *a = 0;
+ *b = 0;
*c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
}
else
@@ -788,7 +1524,7 @@ public:
// Creates a matrix that converts the vertices from one coordinate system
// to another.
- static Matrix4f AxisConversion(const WorldAxes& to, const WorldAxes& from)
+ static Matrix4 AxisConversion(const WorldAxes& to, const WorldAxes& from)
{
// Holds axis values from the 'to' structure
int toArray[3] = { to.XAxis, to.YAxis, to.ZAxis };
@@ -799,22 +1535,22 @@ public:
inv[abs(to.YAxis)] = 1;
inv[abs(to.ZAxis)] = 2;
- Matrix4f m(0, 0, 0,
- 0, 0, 0,
- 0, 0, 0);
+ Matrix4 m(0, 0, 0,
+ 0, 0, 0,
+ 0, 0, 0);
// Only three values in the matrix need to be changed to 1 or -1.
- m.M[inv[abs(from.XAxis)]][0] = float(from.XAxis/toArray[inv[abs(from.XAxis)]]);
- m.M[inv[abs(from.YAxis)]][1] = float(from.YAxis/toArray[inv[abs(from.YAxis)]]);
- m.M[inv[abs(from.ZAxis)]][2] = float(from.ZAxis/toArray[inv[abs(from.ZAxis)]]);
+ m.M[inv[abs(from.XAxis)]][0] = T(from.XAxis/toArray[inv[abs(from.XAxis)]]);
+ m.M[inv[abs(from.YAxis)]][1] = T(from.YAxis/toArray[inv[abs(from.YAxis)]]);
+ m.M[inv[abs(from.ZAxis)]][2] = T(from.ZAxis/toArray[inv[abs(from.ZAxis)]]);
return m;
}
// Creates a matrix for translation by vector
- static Matrix4f Translation(const Vector3f& v)
+ static Matrix4 Translation(const Vector3<T>& v)
{
- Matrix4f t;
+ Matrix4 t;
t.M[0][3] = v.x;
t.M[1][3] = v.y;
t.M[2][3] = v.z;
@@ -822,19 +1558,32 @@ public:
}
// Creates a matrix for translation by vector
- static Matrix4f Translation(float x, float y, float z = 0.0f)
+ static Matrix4 Translation(T x, T y, T z = 0.0f)
{
- Matrix4f t;
+ Matrix4 t;
t.M[0][3] = x;
t.M[1][3] = y;
t.M[2][3] = z;
return t;
}
+ // Sets the translation part
+ void SetTranslation(const Vector3<T>& v)
+ {
+ M[0][3] = v.x;
+ M[1][3] = v.y;
+ M[2][3] = v.z;
+ }
+
+ Vector3<T> GetTranslation() const
+ {
+ return Vector3<T>( M[0][3], M[1][3], M[2][3] );
+ }
+
// Creates a matrix for scaling by vector
- static Matrix4f Scaling(const Vector3f& v)
+ static Matrix4 Scaling(const Vector3<T>& v)
{
- Matrix4f t;
+ Matrix4 t;
t.M[0][0] = v.x;
t.M[1][1] = v.y;
t.M[2][2] = v.z;
@@ -842,9 +1591,9 @@ public:
}
// Creates a matrix for scaling by vector
- static Matrix4f Scaling(float x, float y, float z)
+ static Matrix4 Scaling(T x, T y, T z)
{
- Matrix4f t;
+ Matrix4 t;
t.M[0][0] = x;
t.M[1][1] = y;
t.M[2][2] = z;
@@ -852,38 +1601,50 @@ public:
}
// Creates a matrix for scaling by constant
- static Matrix4f Scaling(float s)
+ static Matrix4 Scaling(T s)
{
- Matrix4f t;
+ Matrix4 t;
t.M[0][0] = s;
t.M[1][1] = s;
t.M[2][2] = s;
return t;
}
-
+ // Simple L1 distance in R^12
+ T Distance(const Matrix4& m2) const
+ {
+ T d = fabs(M[0][0] - m2.M[0][0]) + fabs(M[0][1] - m2.M[0][1]);
+ d += fabs(M[0][2] - m2.M[0][2]) + fabs(M[0][3] - m2.M[0][3]);
+ d += fabs(M[1][0] - m2.M[1][0]) + fabs(M[1][1] - m2.M[1][1]);
+ d += fabs(M[1][2] - m2.M[1][2]) + fabs(M[1][3] - m2.M[1][3]);
+ d += fabs(M[2][0] - m2.M[2][0]) + fabs(M[2][1] - m2.M[2][1]);
+ d += fabs(M[2][2] - m2.M[2][2]) + fabs(M[2][3] - m2.M[2][3]);
+ d += fabs(M[3][0] - m2.M[3][0]) + fabs(M[3][1] - m2.M[3][1]);
+ d += fabs(M[3][2] - m2.M[3][2]) + fabs(M[3][3] - m2.M[3][3]);
+ return d;
+ }
// Creates a rotation matrix rotating around the X axis by 'angle' radians.
// Just for quick testing. Not for final API. Need to remove case.
- static Matrix4f RotationAxis(Axis A, float angle, RotateDirection d, HandedSystem s)
+ static Matrix4 RotationAxis(Axis A, T angle, RotateDirection d, HandedSystem s)
{
- float sina = s * d *sin(angle);
- float cosa = cos(angle);
+ T sina = s * d *sin(angle);
+ T cosa = cos(angle);
switch(A)
{
case Axis_X:
- return Matrix4f(1, 0, 0,
- 0, cosa, -sina,
- 0, sina, cosa);
+ return Matrix4(1, 0, 0,
+ 0, cosa, -sina,
+ 0, sina, cosa);
case Axis_Y:
- return Matrix4f(cosa, 0, sina,
- 0, 1, 0,
- -sina, 0, cosa);
+ return Matrix4(cosa, 0, sina,
+ 0, 1, 0,
+ -sina, 0, cosa);
case Axis_Z:
- return Matrix4f(cosa, -sina, 0,
- sina, cosa, 0,
- 0, 0, 1);
+ return Matrix4(cosa, -sina, 0,
+ sina, cosa, 0,
+ 0, 0, 1);
}
}
@@ -895,13 +1656,13 @@ public:
// same as looking down from positive axis values towards origin.
// LHS: Positive angle values rotate clock-wise (CW), while looking in the
// negative axis direction.
- static Matrix4f RotationX(float angle)
+ static Matrix4 RotationX(T angle)
{
- float sina = sin(angle);
- float cosa = cos(angle);
- return Matrix4f(1, 0, 0,
- 0, cosa, -sina,
- 0, sina, cosa);
+ T sina = sin(angle);
+ T cosa = cos(angle);
+ return Matrix4(1, 0, 0,
+ 0, cosa, -sina,
+ 0, sina, cosa);
}
// Creates a rotation matrix rotating around the Y axis by 'angle' radians.
@@ -911,13 +1672,13 @@ public:
// same as looking down from positive axis values towards origin.
// LHS: Positive angle values rotate clock-wise (CW), while looking in the
// negative axis direction.
- static Matrix4f RotationY(float angle)
+ static Matrix4 RotationY(T angle)
{
- float sina = sin(angle);
- float cosa = cos(angle);
- return Matrix4f(cosa, 0, sina,
- 0, 1, 0,
- -sina, 0, cosa);
+ T sina = sin(angle);
+ T cosa = cos(angle);
+ return Matrix4(cosa, 0, sina,
+ 0, 1, 0,
+ -sina, 0, cosa);
}
// Creates a rotation matrix rotating around the Z axis by 'angle' radians.
@@ -927,27 +1688,47 @@ public:
// same as looking down from positive axis values towards origin.
// LHS: Positive angle values rotate clock-wise (CW), while looking in the
// negative axis direction.
- static Matrix4f RotationZ(float angle)
+ static Matrix4 RotationZ(T angle)
{
- float sina = sin(angle);
- float cosa = cos(angle);
- return Matrix4f(cosa, -sina, 0,
- sina, cosa, 0,
- 0, 0, 1);
+ T sina = sin(angle);
+ T cosa = cos(angle);
+ return Matrix4(cosa, -sina, 0,
+ sina, cosa, 0,
+ 0, 0, 1);
}
-
// LookAtRH creates a View transformation matrix for right-handed coordinate system.
// The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
// specifying the up vector. The resulting matrix should be used with PerspectiveRH
// projection.
- static Matrix4f LookAtRH(const Vector3f& eye, const Vector3f& at, const Vector3f& up);
-
+ static Matrix4 LookAtRH(const Vector3<T>& eye, const Vector3<T>& at, const Vector3<T>& up)
+ {
+ Vector3<T> z = (eye - at).Normalized(); // Forward
+ Vector3<T> x = up.Cross(z).Normalized(); // Right
+ Vector3<T> y = z.Cross(x);
+
+ Matrix4 m(x.x, x.y, x.z, -(x.Dot(eye)),
+ y.x, y.y, y.z, -(y.Dot(eye)),
+ z.x, z.y, z.z, -(z.Dot(eye)),
+ 0, 0, 0, 1 );
+ return m;
+ }
+
// LookAtLH creates a View transformation matrix for left-handed coordinate system.
// The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
// specifying the up vector.
- static Matrix4f LookAtLH(const Vector3f& eye, const Vector3f& at, const Vector3f& up);
-
+ static Matrix4 LookAtLH(const Vector3<T>& eye, const Vector3<T>& at, const Vector3<T>& up)
+ {
+ Vector3<T> z = (at - eye).Normalized(); // Forward
+ Vector3<T> x = up.Cross(z).Normalized(); // Right
+ Vector3<T> y = z.Cross(x);
+
+ Matrix4 m(x.x, x.y, x.z, -(x.Dot(eye)),
+ y.x, y.y, y.z, -(y.Dot(eye)),
+ z.x, z.y, z.z, -(z.Dot(eye)),
+ 0, 0, 0, 1 );
+ return m;
+ }
// PerspectiveRH creates a right-handed perspective projection matrix that can be
// used with the Oculus sample renderer.
@@ -958,8 +1739,22 @@ public:
// zfar - Absolute value of far Z clipping clipping range (larger then near).
// Even though RHS usually looks in the direction of negative Z, positive values
// are expected for znear and zfar.
- static Matrix4f PerspectiveRH(float yfov, float aspect, float znear, float zfar);
-
+ static Matrix4 PerspectiveRH(T yfov, T aspect, T znear, T zfar)
+ {
+ Matrix4 m;
+ T tanHalfFov = tan(yfov * 0.5f);
+
+ m.M[0][0] = 1 / (aspect * tanHalfFov);
+ m.M[1][1] = 1 / tanHalfFov;
+ m.M[2][2] = zfar / (zfar - znear);
+ m.M[3][2] = 1;
+ m.M[2][3] = (zfar * znear) / (znear - zfar);
+ m.M[3][3] = 0;
+
+ // Note: Post-projection matrix result assumes Left-Handed coordinate system,
+ // with Y up, X right and Z forward. This supports positive z-buffer values.
+ return m;
+ }
// PerspectiveRH creates a left-handed perspective projection matrix that can be
// used with the Oculus sample renderer.
@@ -968,350 +1763,601 @@ public:
// Note that xfov = yfov * aspect.
// znear - Absolute value of near Z clipping clipping range.
// zfar - Absolute value of far Z clipping clipping range (larger then near).
- static Matrix4f PerspectiveLH(float yfov, float aspect, float znear, float zfar);
-
+ static Matrix4 PerspectiveLH(T yfov, T aspect, T znear, T zfar)
+ {
+ Matrix4 m;
+ T tanHalfFov = tan(yfov * 0.5f);
+
+ m.M[0][0] = 1.0 / (aspect * tanHalfFov);
+ m.M[1][1] = 1.0 / tanHalfFov;
+ m.M[2][2] = zfar / (znear - zfar);
+ // m.M[2][2] = zfar / (zfar - znear);
+ m.M[3][2] = -1.0;
+ m.M[2][3] = (zfar * znear) / (znear - zfar);
+ m.M[3][3] = 0.0;
+
+ // Note: Post-projection matrix result assumes Left-Handed coordinate system,
+ // with Y up, X right and Z forward. This supports positive z-buffer values.
+ // This is the case even for RHS cooridnate input.
+ return m;
+ }
- static Matrix4f Ortho2D(float w, float h);
+ static Matrix4 Ortho2D(T w, T h)
+ {
+ Matrix4 m;
+ m.M[0][0] = 2.0/w;
+ m.M[1][1] = -2.0/h;
+ m.M[0][3] = -1.0;
+ m.M[1][3] = 1.0;
+ m.M[2][2] = 0;
+ return m;
+ }
};
+typedef Matrix4<float> Matrix4f;
+typedef Matrix4<double> Matrix4d;
-//-------------------------------------------------------------------------------------//
-// **************************************** Quat **************************************//
+//-------------------------------------------------------------------------------------
+// ***** Matrix3
//
-// Quatf represents a quaternion class used for rotations.
-//
-// Quaternion multiplications are done in right-to-left order, to match the
-// behavior of matrices.
+// Matrix3 is a 3x3 matrix used for representing a rotation matrix.
+// The matrix is stored in row-major order in memory, meaning that values
+// of the first row are stored before the next one.
+//
+// The arrangement of the matrix is chosen to be in Right-Handed
+// coordinate system and counterclockwise rotations when looking down
+// the axis
+//
+// Transformation Order:
+// - Transformations are applied from right to left, so the expression
+// M1 * M2 * M3 * V means that the vector V is transformed by M3 first,
+// followed by M2 and M1.
+//
+// Coordinate system: Right Handed
+//
+// Rotations: Counterclockwise when looking down the axis. All angles are in radians.
+template<typename T>
+class SymMat3;
template<class T>
-class Quat
+class Matrix3
{
+ static const Matrix3 IdentityValue;
+
public:
- // w + Xi + Yj + Zk
- T x, y, z, w;
+ T M[3][3];
- Quat() : x(0), y(0), z(0), w(1) {}
- Quat(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) {}
+ enum NoInitType { NoInit };
+ // Construct with no memory initialization.
+ Matrix3(NoInitType) { }
- // Constructs quaternion for rotation around the axis by an angle.
- Quat(const Vector3<T>& axis, T angle)
- {
- Vector3<T> unitAxis = axis.Normalized();
- T sinHalfAngle = sin(angle * T(0.5));
+ // By default, we construct identity matrix.
+ Matrix3()
+ {
+ SetIdentity();
+ }
- w = cos(angle * T(0.5));
- x = unitAxis.x * sinHalfAngle;
- y = unitAxis.y * sinHalfAngle;
- z = unitAxis.z * sinHalfAngle;
+ Matrix3(T m11, T m12, T m13,
+ T m21, T m22, T m23,
+ T m31, T m32, T m33)
+ {
+ M[0][0] = m11; M[0][1] = m12; M[0][2] = m13;
+ M[1][0] = m21; M[1][1] = m22; M[1][2] = m23;
+ M[2][0] = m31; M[2][1] = m32; M[2][2] = m33;
+ }
+
+ /*
+ explicit Matrix3(const Quat<T>& q)
+ {
+ T ww = q.w*q.w;
+ T xx = q.x*q.x;
+ T yy = q.y*q.y;
+ T zz = q.z*q.z;
+
+ M[0][0] = ww + xx - yy - zz; M[0][1] = 2 * (q.x*q.y - q.w*q.z); M[0][2] = 2 * (q.x*q.z + q.w*q.y);
+ M[1][0] = 2 * (q.x*q.y + q.w*q.z); M[1][1] = ww - xx + yy - zz; M[1][2] = 2 * (q.y*q.z - q.w*q.x);
+ M[2][0] = 2 * (q.x*q.z - q.w*q.y); M[2][1] = 2 * (q.y*q.z + q.w*q.x); M[2][2] = ww - xx - yy + zz;
+ }
+ */
+
+ explicit Matrix3(const Quat<T>& q)
+ {
+ const T tx = q.x+q.x, ty = q.y+q.y, tz = q.z+q.z;
+ const T twx = q.w*tx, twy = q.w*ty, twz = q.w*tz;
+ const T txx = q.x*tx, txy = q.x*ty, txz = q.x*tz;
+ const T tyy = q.y*ty, tyz = q.y*tz, tzz = q.z*tz;
+ M[0][0] = T(1) - (tyy + tzz); M[0][1] = txy - twz; M[0][2] = txz + twy;
+ M[1][0] = txy + twz; M[1][1] = T(1) - (txx + tzz); M[1][2] = tyz - twx;
+ M[2][0] = txz - twy; M[2][1] = tyz + twx; M[2][2] = T(1) - (txx + tyy);
+ }
+
+ inline explicit Matrix3(T s)
+ {
+ M[0][0] = M[1][1] = M[2][2] = s;
+ M[0][1] = M[0][2] = M[1][0] = M[1][2] = M[2][0] = M[2][1] = 0;
}
- // Constructs quaternion for rotation around one of the coordinate axis by an angle.
- void AxisAngle(Axis A, T angle, RotateDirection d, HandedSystem s)
- {
- T sinHalfAngle = s * d *sin(angle * T(0.5));
- T v[3];
- v[0] = v[1] = v[2] = T(0);
- v[A] = sinHalfAngle;
+ explicit Matrix3(const Pose<T>& p)
+ {
+ Matrix3 result(p.Orientation);
+ result.SetTranslation(p.Position);
+ *this = result;
+ }
- w = cos(angle * T(0.5));
- x = v[0];
- y = v[1];
- z = v[2];
- }
+ // C-interop support
+ explicit Matrix3(const Matrix4<typename Math<T>::OtherFloatType> &src)
+ {
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ M[i][j] = (T)src.M[i][j];
+ }
+ // C-interop support.
+ Matrix3(const typename CompatibleTypes<Matrix3<T> >::Type& s)
+ {
+ OVR_COMPILER_ASSERT(sizeof(s) == sizeof(Matrix3));
+ memcpy(M, s.M, sizeof(M));
+ }
- // Compute axis and angle from quaternion
- void GetAxisAngle(Vector3<T>* axis, T* angle) const
- {
- if ( x*x + y*y + z*z > Math<T>::Tolerance * Math<T>::Tolerance ) {
- *axis = Vector3<T>(x, y, z).Normalized();
- *angle = T(2) * Acos(w);
- }
- else
- {
- *axis = Vector3<T>(1, 0, 0);
- *angle= 0;
- }
- }
+ operator const typename CompatibleTypes<Matrix3<T> >::Type () const
+ {
+ typename CompatibleTypes<Matrix3<T> >::Type result;
+ OVR_COMPILER_ASSERT(sizeof(result) == sizeof(Matrix3));
+ memcpy(result.M, M, sizeof(M));
+ return result;
+ }
- bool operator== (const Quat& b) const { return x == b.x && y == b.y && z == b.z && w == b.w; }
- bool operator!= (const Quat& b) const { return x != b.x || y != b.y || z != b.z || w != b.w; }
+ void ToString(char* dest, UPInt destsize) const
+ {
+ UPInt pos = 0;
+ for (int r=0; r<3; r++)
+ for (int c=0; c<3; c++)
+ pos += OVR_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]);
+ }
- Quat operator+ (const Quat& b) const { return Quat(x + b.x, y + b.y, z + b.z, w + b.w); }
- Quat& operator+= (const Quat& b) { w += b.w; x += b.x; y += b.y; z += b.z; return *this; }
- Quat operator- (const Quat& b) const { return Quat(x - b.x, y - b.y, z - b.z, w - b.w); }
- Quat& operator-= (const Quat& b) { w -= b.w; x -= b.x; y -= b.y; z -= b.z; return *this; }
+ static Matrix3 FromString(const char* src)
+ {
+ Matrix3 result;
+ for (int r=0; r<3; r++)
+ for (int c=0; c<3; c++)
+ {
+ result.M[r][c] = (T)atof(src);
+ while (src && *src != ' ')
+ src++;
+ while (src && *src == ' ')
+ src++;
+ }
+ return result;
+ }
- Quat operator* (T s) const { return Quat(x * s, y * s, z * s, w * s); }
- Quat& operator*= (T s) { w *= s; x *= s; y *= s; z *= s; return *this; }
- Quat operator/ (T s) const { T rcp = T(1)/s; return Quat(x * rcp, y * rcp, z * rcp, w *rcp); }
- Quat& operator/= (T s) { T rcp = T(1)/s; w *= rcp; x *= rcp; y *= rcp; z *= rcp; return *this; }
+ static const Matrix3& Identity() { return IdentityValue; }
+ void SetIdentity()
+ {
+ M[0][0] = M[1][1] = M[2][2] = 1;
+ M[0][1] = M[1][0] = M[2][0] = 0;
+ M[0][2] = M[1][2] = M[2][1] = 0;
+ }
- // Get Imaginary part vector
- Vector3<T> Imag() const { return Vector3<T>(x,y,z); }
+ bool operator== (const Matrix3& b) const
+ {
+ bool isEqual = true;
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ isEqual &= (M[i][j] == b.M[i][j]);
- // Get quaternion length.
- T Length() const { return sqrt(x * x + y * y + z * z + w * w); }
- // Get quaternion length squared.
- T LengthSq() const { return (x * x + y * y + z * z + w * w); }
+ return isEqual;
+ }
- // Simple Eulidean distance in R^4 (not SLERP distance, but at least respects Haar measure)
- T Distance(const Quat& q) const
- {
- T d1 = (*this - q).Length();
- T d2 = (*this + q).Length(); // Antipodal point check
- return (d1 < d2) ? d1 : d2;
+ Matrix3 operator+ (const Matrix3& b) const
+ {
+ Matrix4<T> result(*this);
+ result += b;
+ return result;
}
- T DistanceSq(const Quat& q) const
- {
- T d1 = (*this - q).LengthSq();
- T d2 = (*this + q).LengthSq(); // Antipodal point check
- return (d1 < d2) ? d1 : d2;
- }
+ Matrix3& operator+= (const Matrix3& b)
+ {
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ M[i][j] += b.M[i][j];
+ return *this;
+ }
- // Normalize
- bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance; }
+ void operator= (const Matrix3& b)
+ {
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ M[i][j] = b.M[i][j];
+ return;
+ }
- void Normalize()
+ void operator= (const SymMat3<T>& b)
{
- T l = Length();
- OVR_ASSERT(l != T(0));
- *this /= l;
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ M[i][j] = 0;
+
+ M[0][0] = b.v[0];
+ M[0][1] = b.v[1];
+ M[0][2] = b.v[2];
+ M[1][1] = b.v[3];
+ M[1][2] = b.v[4];
+ M[2][2] = b.v[5];
+
+ return;
}
- Quat Normalized() const
- {
- T l = Length();
- OVR_ASSERT(l != T(0));
- return *this / l;
+ Matrix3 operator- (const Matrix3& b) const
+ {
+ Matrix3 result(*this);
+ result -= b;
+ return result;
}
- // Returns conjugate of the quaternion. Produces inverse rotation if quaternion is normalized.
- Quat Conj() const { return Quat(-x, -y, -z, w); }
+ Matrix3& operator-= (const Matrix3& b)
+ {
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ M[i][j] -= b.M[i][j];
+ return *this;
+ }
- // Quaternion multiplication. Combines quaternion rotations, performing the one on the
- // right hand side first.
- Quat operator* (const Quat& b) const { return Quat(w * b.x + x * b.w + y * b.z - z * b.y,
- w * b.y - x * b.z + y * b.w + z * b.x,
- w * b.z + x * b.y - y * b.x + z * b.w,
- w * b.w - x * b.x - y * b.y - z * b.z); }
+ // Multiplies two matrices into destination with minimum copying.
+ static Matrix3& Multiply(Matrix3* d, const Matrix3& a, const Matrix3& b)
+ {
+ OVR_ASSERT((d != &a) && (d != &b));
+ int i = 0;
+ do {
+ d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0];
+ d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1];
+ d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2];
+ } while((++i) < 3);
+
+ return *d;
+ }
- //
- // this^p normalized; same as rotating by this p times.
- Quat PowNormalized(T p) const
- {
- Vector3<T> v;
- T a;
- GetAxisAngle(&v, &a);
- return Quat(v, a * p);
- }
-
- // Rotate transforms vector in a manner that matches Matrix rotations (counter-clockwise,
- // assuming negative direction of the axis). Standard formula: q(t) * V * q(t)^-1.
- Vector3<T> Rotate(const Vector3<T>& v) const
- {
- return ((*this * Quat<T>(v.x, v.y, v.z, T(0))) * Inverted()).Imag();
- }
+ Matrix3 operator* (const Matrix3& b) const
+ {
+ Matrix3 result(Matrix3::NoInit);
+ Multiply(&result, *this, b);
+ return result;
+ }
-
- // Inversed quaternion rotates in the opposite direction.
- Quat Inverted() const
- {
- return Quat(-x, -y, -z, w);
- }
+ Matrix3& operator*= (const Matrix3& b)
+ {
+ return Multiply(this, Matrix3(*this), b);
+ }
- // Sets this quaternion to the one rotates in the opposite direction.
- void Invert()
- {
- *this = Quat(-x, -y, -z, w);
- }
-
- // Converting quaternion to matrix.
- operator Matrix4f() const
- {
- T ww = w*w;
- T xx = x*x;
- T yy = y*y;
- T zz = z*z;
+ Matrix3 operator* (T s) const
+ {
+ Matrix3 result(*this);
+ result *= s;
+ return result;
+ }
- return Matrix4f(float(ww + xx - yy - zz), float(T(2) * (x*y - w*z)), float(T(2) * (x*z + w*y)),
- float(T(2) * (x*y + w*z)), float(ww - xx + yy - zz), float(T(2) * (y*z - w*x)),
- float(T(2) * (x*z - w*y)), float(T(2) * (y*z + w*x)), float(ww - xx - yy + zz) );
- }
+ Matrix3& operator*= (T s)
+ {
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ M[i][j] *= s;
+ return *this;
+ }
+ Vector3<T> operator* (const Vector3<T> &b) const
+ {
+ Vector3<T> result;
+ result.x = M[0][0]*b.x + M[0][1]*b.y + M[0][2]*b.z;
+ result.y = M[1][0]*b.x + M[1][1]*b.y + M[1][2]*b.z;
+ result.z = M[2][0]*b.x + M[2][1]*b.y + M[2][2]*b.z;
+
+ return result;
+ }
- // Converting matrix to quaternion
- static Quat<T> Matrix4fToQuat(const Matrix4f& m)
+ Matrix3 operator/ (T s) const
{
- T trace = m.M[0][0] + m.M[1][1] + m.M[2][2];
- Quat<T> q;
+ Matrix3 result(*this);
+ result /= s;
+ return result;
+ }
- // In almost all cases, the first part is executed.
- // However, if the trace is not positive, the other
- // cases arise.
- if (trace > T(0))
- {
- T s = sqrt(trace + T(1)) * T(2); // s=4*qw
- q.w = T(0.25) * s;
- q.x = (m.M[2][1] - m.M[1][2]) / s;
- q.y = (m.M[0][2] - m.M[2][0]) / s;
- q.z = (m.M[1][0] - m.M[0][1]) / s;
- }
- else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2]))
- {
- T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2);
- q.w = (m.M[2][1] - m.M[1][2]) / s;
- q.x = T(0.25) * s;
- q.y = (m.M[0][1] + m.M[1][0]) / s;
- q.z = (m.M[2][0] + m.M[0][2]) / s;
- }
- else if (m.M[1][1] > m.M[2][2])
- {
- T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy
- q.w = (m.M[0][2] - m.M[2][0]) / s;
- q.x = (m.M[0][1] + m.M[1][0]) / s;
- q.y = T(0.25) * s;
- q.z = (m.M[1][2] + m.M[2][1]) / s;
- }
- else
- {
- T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz
- q.w = (m.M[1][0] - m.M[0][1]) / s;
- q.x = (m.M[0][2] + m.M[2][0]) / s;
- q.y = (m.M[1][2] + m.M[2][1]) / s;
- q.z = T(0.25) * s;
- }
- return q;
+ Matrix3& operator/= (T s)
+ {
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ M[i][j] /= s;
+ return *this;
}
+ Vector3<T> Transform(const Vector3<T>& v) const
+ {
+ return Vector3<T>(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z,
+ M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z,
+ M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z);
+ }
-
- // GetEulerAngles extracts Euler angles from the quaternion, in the specified order of
- // axis rotations and the specified coordinate system. Right-handed coordinate system
- // is the default, with CCW rotations while looking in the negative axis direction.
- // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
- // rotation a around axis A1
- // is followed by rotation b around axis A2
- // is followed by rotation c around axis A3
- // rotations are CCW or CW (D) in LH or RH coordinate system (S)
- template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
- void GetEulerAngles(T *a, T *b, T *c)
+ Matrix3 Transposed() const
+ {
+ return Matrix3(M[0][0], M[1][0], M[2][0],
+ M[0][1], M[1][1], M[2][1],
+ M[0][2], M[1][2], M[2][2]);
+ }
+
+ void Transpose()
+ {
+ *this = Transposed();
+ }
+
+
+ T SubDet (const UPInt* rows, const UPInt* cols) const
+ {
+ return M[rows[0]][cols[0]] * (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]])
+ - M[rows[0]][cols[1]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]])
+ + M[rows[0]][cols[2]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]);
+ }
+
+ // M += a*b.t()
+ inline void Rank1Add(const Vector3<T> &a, const Vector3<T> &b)
+ {
+ M[0][0] += a.x*b.x; M[0][1] += a.x*b.y; M[0][2] += a.x*b.z;
+ M[1][0] += a.y*b.x; M[1][1] += a.y*b.y; M[1][2] += a.y*b.z;
+ M[2][0] += a.z*b.x; M[2][1] += a.z*b.y; M[2][2] += a.z*b.z;
+ }
+
+ // M -= a*b.t()
+ inline void Rank1Sub(const Vector3<T> &a, const Vector3<T> &b)
+ {
+ M[0][0] -= a.x*b.x; M[0][1] -= a.x*b.y; M[0][2] -= a.x*b.z;
+ M[1][0] -= a.y*b.x; M[1][1] -= a.y*b.y; M[1][2] -= a.y*b.z;
+ M[2][0] -= a.z*b.x; M[2][1] -= a.z*b.y; M[2][2] -= a.z*b.z;
+ }
+
+ inline Vector3<T> Col(int c) const
+ {
+ return Vector3<T>(M[0][c], M[1][c], M[2][c]);
+ }
+
+ inline Vector3<T> Row(int r) const
+ {
+ return Vector3<T>(M[r][0], M[r][1], M[r][2]);
+ }
+
+ inline T Determinant() const
+ {
+ const Matrix3<T>& m = *this;
+ T d;
+
+ d = m.M[0][0] * (m.M[1][1]*m.M[2][2] - m.M[1][2] * m.M[2][1]);
+ d -= m.M[0][1] * (m.M[1][0]*m.M[2][2] - m.M[1][2] * m.M[2][0]);
+ d += m.M[0][2] * (m.M[1][0]*m.M[2][1] - m.M[1][1] * m.M[2][0]);
+
+ return d;
+ }
+
+ inline Matrix3<T> Inverse() const
{
- OVR_COMPILER_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3));
+ Matrix3<T> a;
+ const Matrix3<T>& m = *this;
+ T d = Determinant();
- T Q[3] = { x, y, z }; //Quaternion components x,y,z
+ assert(d != 0);
+ T s = T(1)/d;
- T ww = w*w;
- T Q11 = Q[A1]*Q[A1];
- T Q22 = Q[A2]*Q[A2];
- T Q33 = Q[A3]*Q[A3];
+ a.M[0][0] = s * (m.M[1][1] * m.M[2][2] - m.M[1][2] * m.M[2][1]);
+ a.M[1][0] = s * (m.M[1][2] * m.M[2][0] - m.M[1][0] * m.M[2][2]);
+ a.M[2][0] = s * (m.M[1][0] * m.M[2][1] - m.M[1][1] * m.M[2][0]);
- T psign = T(-1);
- // Determine whether even permutation
- if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3))
- psign = T(1);
+ a.M[0][1] = s * (m.M[0][2] * m.M[2][1] - m.M[0][1] * m.M[2][2]);
+ a.M[1][1] = s * (m.M[0][0] * m.M[2][2] - m.M[0][2] * m.M[2][0]);
+ a.M[2][1] = s * (m.M[0][1] * m.M[2][0] - m.M[0][0] * m.M[2][1]);
- T s2 = psign * T(2) * (psign*w*Q[A2] + Q[A1]*Q[A3]);
-
- if (s2 < T(-1) + Math<T>::SingularityRadius)
- { // South pole singularity
- *a = T(0);
- *b = -S*D*Math<T>::PiOver2;
- *c = S*D*atan2(T(2)*(psign*Q[A1]*Q[A2] + w*Q[A3]),
- ww + Q22 - Q11 - Q33 );
- }
- else if (s2 > T(1) - Math<T>::SingularityRadius)
- { // North pole singularity
- *a = T(0);
- *b = S*D*Math<T>::PiOver2;
- *c = S*D*atan2(T(2)*(psign*Q[A1]*Q[A2] + w*Q[A3]),
- ww + Q22 - Q11 - Q33);
- }
- else
- {
- *a = -S*D*atan2(T(-2)*(w*Q[A1] - psign*Q[A2]*Q[A3]),
- ww + Q33 - Q11 - Q22);
- *b = S*D*asin(s2);
- *c = S*D*atan2(T(2)*(w*Q[A3] - psign*Q[A1]*Q[A2]),
- ww + Q11 - Q22 - Q33);
- }
- return;
+ a.M[0][2] = s * (m.M[0][1] * m.M[1][2] - m.M[0][2] * m.M[1][1]);
+ a.M[1][2] = s * (m.M[0][2] * m.M[1][0] - m.M[0][0] * m.M[1][2]);
+ a.M[2][2] = s * (m.M[0][0] * m.M[1][1] - m.M[0][1] * m.M[1][0]);
+
+ return a;
}
+
+};
- template <Axis A1, Axis A2, Axis A3, RotateDirection D>
- void GetEulerAngles(T *a, T *b, T *c)
- { GetEulerAngles<A1, A2, A3, D, Handed_R>(a, b, c); }
+typedef Matrix3<float> Matrix3f;
+typedef Matrix3<double> Matrix3d;
- template <Axis A1, Axis A2, Axis A3>
- void GetEulerAngles(T *a, T *b, T *c)
- { GetEulerAngles<A1, A2, A3, Rotate_CCW, Handed_R>(a, b, c); }
+//-------------------------------------------------------------------------------------
+template<typename T>
+class SymMat3
+{
+private:
+ typedef SymMat3<T> this_type;
- // GetEulerAnglesABA extracts Euler angles from the quaternion, in the specified order of
- // axis rotations and the specified coordinate system. Right-handed coordinate system
- // is the default, with CCW rotations while looking in the negative axis direction.
- // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
- // rotation a around axis A1
- // is followed by rotation b around axis A2
- // is followed by rotation c around axis A1
- // Rotations are CCW or CW (D) in LH or RH coordinate system (S)
- template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
- void GetEulerAnglesABA(T *a, T *b, T *c)
- {
- OVR_COMPILER_ASSERT(A1 != A2);
+public:
+ typedef T Value_t;
+ // Upper symmetric
+ T v[6]; // _00 _01 _02 _11 _12 _22
- T Q[3] = {x, y, z}; // Quaternion components
+ inline SymMat3() {}
- // Determine the missing axis that was not supplied
- int m = 3 - A1 - A2;
+ inline explicit SymMat3(T s)
+ {
+ v[0] = v[3] = v[5] = s;
+ v[1] = v[2] = v[4] = 0;
+ }
- T ww = w*w;
- T Q11 = Q[A1]*Q[A1];
- T Q22 = Q[A2]*Q[A2];
- T Qmm = Q[m]*Q[m];
+ inline explicit SymMat3(T a00, T a01, T a02, T a11, T a12, T a22)
+ {
+ v[0] = a00; v[1] = a01; v[2] = a02;
+ v[3] = a11; v[4] = a12;
+ v[5] = a22;
+ }
- T psign = T(-1);
- if ((A1 + 1) % 3 == A2) // Determine whether even permutation
- {
- psign = T(1);
- }
+ static inline int Index(unsigned int i, unsigned int j)
+ {
+ return (i <= j) ? (3*i - i*(i+1)/2 + j) : (3*j - j*(j+1)/2 + i);
+ }
- T c2 = ww + Q11 - Q22 - Qmm;
- if (c2 < T(-1) + Math<T>::SingularityRadius)
- { // South pole singularity
- *a = T(0);
- *b = S*D*Math<T>::Pi;
- *c = S*D*atan2( T(2)*(w*Q[A1] - psign*Q[A2]*Q[m]),
- ww + Q22 - Q11 - Qmm);
- }
- else if (c2 > T(1) - Math<T>::SingularityRadius)
- { // North pole singularity
- *a = T(0);
- *b = T(0);
- *c = S*D*atan2( T(2)*(w*Q[A1] - psign*Q[A2]*Q[m]),
- ww + Q22 - Q11 - Qmm);
- }
- else
- {
- *a = S*D*atan2( psign*w*Q[m] + Q[A1]*Q[A2],
- w*Q[A2] -psign*Q[A1]*Q[m]);
- *b = S*D*acos(c2);
- *c = S*D*atan2( -psign*w*Q[m] + Q[A1]*Q[A2],
- w*Q[A2] + psign*Q[A1]*Q[m]);
- }
- return;
- }
+ inline T operator()(int i, int j) const { return v[Index(i,j)]; }
+
+ inline T &operator()(int i, int j) { return v[Index(i,j)]; }
-};
+ template<typename U>
+ inline SymMat3<U> CastTo() const
+ {
+ return SymMat3<U>(static_cast<U>(v[0]), static_cast<U>(v[1]), static_cast<U>(v[2]),
+ static_cast<U>(v[3]), static_cast<U>(v[4]), static_cast<U>(v[5]));
+ }
-typedef Quat<float> Quatf;
-typedef Quat<double> Quatd;
+ inline this_type& operator+=(const this_type& b)
+ {
+ v[0]+=b.v[0];
+ v[1]+=b.v[1];
+ v[2]+=b.v[2];
+ v[3]+=b.v[3];
+ v[4]+=b.v[4];
+ v[5]+=b.v[5];
+ return *this;
+ }
+
+ inline this_type& operator-=(const this_type& b)
+ {
+ v[0]-=b.v[0];
+ v[1]-=b.v[1];
+ v[2]-=b.v[2];
+ v[3]-=b.v[3];
+ v[4]-=b.v[4];
+ v[5]-=b.v[5];
+
+ return *this;
+ }
+
+ inline this_type& operator*=(T s)
+ {
+ v[0]*=s;
+ v[1]*=s;
+ v[2]*=s;
+ v[3]*=s;
+ v[4]*=s;
+ v[5]*=s;
+
+ return *this;
+ }
+
+ inline SymMat3 operator*(T s) const
+ {
+ SymMat3 d;
+ d.v[0] = v[0]*s;
+ d.v[1] = v[1]*s;
+ d.v[2] = v[2]*s;
+ d.v[3] = v[3]*s;
+ d.v[4] = v[4]*s;
+ d.v[5] = v[5]*s;
+
+ return d;
+ }
+
+ // Multiplies two matrices into destination with minimum copying.
+ static SymMat3& Multiply(SymMat3* d, const SymMat3& a, const SymMat3& b)
+ {
+ // _00 _01 _02 _11 _12 _22
+
+ d->v[0] = a.v[0] * b.v[0];
+ d->v[1] = a.v[0] * b.v[1] + a.v[1] * b.v[3];
+ d->v[2] = a.v[0] * b.v[2] + a.v[1] * b.v[4];
+
+ d->v[3] = a.v[3] * b.v[3];
+ d->v[4] = a.v[3] * b.v[4] + a.v[4] * b.v[5];
+
+ d->v[5] = a.v[5] * b.v[5];
+
+ return *d;
+ }
+
+ inline T Determinant() const
+ {
+ const this_type& m = *this;
+ T d;
+
+ d = m(0,0) * (m(1,1)*m(2,2) - m(1,2) * m(2,1));
+ d -= m(0,1) * (m(1,0)*m(2,2) - m(1,2) * m(2,0));
+ d += m(0,2) * (m(1,0)*m(2,1) - m(1,1) * m(2,0));
+
+ return d;
+ }
+
+ inline this_type Inverse() const
+ {
+ this_type a;
+ const this_type& m = *this;
+ T d = Determinant();
+
+ assert(d != 0);
+ T s = T(1)/d;
+
+ a(0,0) = s * (m(1,1) * m(2,2) - m(1,2) * m(2,1));
+
+ a(0,1) = s * (m(0,2) * m(2,1) - m(0,1) * m(2,2));
+ a(1,1) = s * (m(0,0) * m(2,2) - m(0,2) * m(2,0));
+
+ a(0,2) = s * (m(0,1) * m(1,2) - m(0,2) * m(1,1));
+ a(1,2) = s * (m(0,2) * m(1,0) - m(0,0) * m(1,2));
+ a(2,2) = s * (m(0,0) * m(1,1) - m(0,1) * m(1,0));
+
+ return a;
+ }
+ inline T Trace() const { return v[0] + v[3] + v[5]; }
+ // M = a*a.t()
+ inline void Rank1(const Vector3<T> &a)
+ {
+ v[0] = a.x*a.x; v[1] = a.x*a.y; v[2] = a.x*a.z;
+ v[3] = a.y*a.y; v[4] = a.y*a.z;
+ v[5] = a.z*a.z;
+ }
+
+ // M += a*a.t()
+ inline void Rank1Add(const Vector3<T> &a)
+ {
+ v[0] += a.x*a.x; v[1] += a.x*a.y; v[2] += a.x*a.z;
+ v[3] += a.y*a.y; v[4] += a.y*a.z;
+ v[5] += a.z*a.z;
+ }
+
+ // M -= a*a.t()
+ inline void Rank1Sub(const Vector3<T> &a)
+ {
+ v[0] -= a.x*a.x; v[1] -= a.x*a.y; v[2] -= a.x*a.z;
+ v[3] -= a.y*a.y; v[4] -= a.y*a.z;
+ v[5] -= a.z*a.z;
+ }
+};
+
+typedef SymMat3<float> SymMat3f;
+typedef SymMat3<double> SymMat3d;
+
+template<typename T>
+inline Matrix3<T> operator*(const SymMat3<T>& a, const SymMat3<T>& b)
+{
+ #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c))
+ return Matrix3<T>(
+ AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2),
+ AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2),
+ AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2));
+ #undef AJB_ARBC
+}
+
+template<typename T>
+inline Matrix3<T> operator*(const Matrix3<T>& a, const SymMat3<T>& b)
+{
+ #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c))
+ return Matrix3<T>(
+ AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2),
+ AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2),
+ AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2));
+ #undef AJB_ARBC
+}
//-------------------------------------------------------------------------------------
// ***** Angle
diff --git a/LibOVR/Src/Kernel/OVR_RefCount.cpp b/LibOVR/Src/Kernel/OVR_RefCount.cpp
index 8bb80ef..c6301ed 100644
--- a/LibOVR/Src/Kernel/OVR_RefCount.cpp
+++ b/LibOVR/Src/Kernel/OVR_RefCount.cpp
@@ -5,16 +5,16 @@ Content : Reference counting implementation
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_RefCount.h b/LibOVR/Src/Kernel/OVR_RefCount.h
index 8f2e3ad..775e24c 100644
--- a/LibOVR/Src/Kernel/OVR_RefCount.h
+++ b/LibOVR/Src/Kernel/OVR_RefCount.h
@@ -6,16 +6,16 @@ Content : Reference counting implementation headers
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -62,7 +62,7 @@ class RefCountNTSImpl;
class RefCountImplCore
{
protected:
- volatile int RefCount;
+ volatile int RefCount;
public:
// RefCountImpl constructor always initializes RefCount to 1 by default.
@@ -145,7 +145,7 @@ public:
// RefCountVImpl provides Thread-Safe implementation of reference counting, plus,
// virtual AddRef and Release.
-class RefCountVImpl : public RefCountImplCore
+class RefCountVImpl : virtual public RefCountImplCore
{
public:
// Thread-Safe Ref-Count Implementation.
@@ -194,6 +194,8 @@ public:
// Redefine all new & delete operators.
OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE)
+#undef OVR_REFCOUNTALLOC_CHECK_DELETE
+
#ifdef OVR_DEFINE_NEW
#define new OVR_DEFINE_NEW
#endif
@@ -202,6 +204,35 @@ public:
};
+template<class Base>
+class RefCountBaseStatVImpl : virtual public Base
+{
+public:
+ RefCountBaseStatVImpl() { }
+
+ // *** Override New and Delete
+
+ // DOM-IGNORE-BEGIN
+ // Undef new temporarily if it is being redefined
+#ifdef OVR_DEFINE_NEW
+#undef new
+#endif
+
+#define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p)
+
+ // Redefine all new & delete operators.
+ OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE)
+
+#undef OVR_REFCOUNTALLOC_CHECK_DELETE
+
+#ifdef OVR_DEFINE_NEW
+#define new OVR_DEFINE_NEW
+#endif
+ // OVR_BUILD_DEFINE_NEW
+ // DOM-IGNORE-END
+};
+
+
//-----------------------------------------------------------------------------------
// *** End user RefCountBase<> classes
@@ -225,11 +256,11 @@ public:
// RefCountBaseV is the same as RefCountBase but with virtual AddRef/Release
template<class C>
-class RefCountBaseV : public RefCountBaseStatImpl<RefCountVImpl>
+class RefCountBaseV : virtual public RefCountBaseStatVImpl<RefCountVImpl>
{
public:
// Constructor.
- OVR_FORCE_INLINE RefCountBaseV() : RefCountBaseStatImpl<RefCountVImpl>() { }
+ OVR_FORCE_INLINE RefCountBaseV() : RefCountBaseStatVImpl<RefCountVImpl>() { }
};
diff --git a/LibOVR/Src/Kernel/OVR_Std.cpp b/LibOVR/Src/Kernel/OVR_Std.cpp
index 4159652..6b5be18 100644
--- a/LibOVR/Src/Kernel/OVR_Std.cpp
+++ b/LibOVR/Src/Kernel/OVR_Std.cpp
@@ -5,16 +5,16 @@ Content : Standard C function implementation
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_Std.h b/LibOVR/Src/Kernel/OVR_Std.h
index 4ec8d65..c11f853 100644
--- a/LibOVR/Src/Kernel/OVR_Std.h
+++ b/LibOVR/Src/Kernel/OVR_Std.h
@@ -6,16 +6,16 @@ Content : Standard C function interface
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -229,7 +229,7 @@ inline long OVR_CDECL OVR_strtol(const char* string, char** tailptr, int radix)
return strtol(string, tailptr, radix);
}
-inline unsigned long OVR_CDECL OVR_strtoul(const char* string, char** tailptr, int radix)
+inline long OVR_CDECL OVR_strtoul(const char* string, char** tailptr, int radix)
{
return strtoul(string, tailptr, radix);
}
@@ -281,7 +281,7 @@ inline UPInt OVR_CDECL OVR_sprintf(char *dest, UPInt destsize, const char* forma
{
va_list argList;
va_start(argList,format);
- SInt32 ret;
+ UPInt ret;
#if defined(OVR_CC_MSVC)
#if defined(OVR_MSVC_SAFESTRING)
ret = _vsnprintf_s(dest, destsize, _TRUNCATE, format, argList);
@@ -298,7 +298,7 @@ inline UPInt OVR_CDECL OVR_sprintf(char *dest, UPInt destsize, const char* forma
OVR_ASSERT(ret < destsize);
#endif
va_end(argList);
- return (UPInt)ret;
+ return ret;
}
inline UPInt OVR_CDECL OVR_vsprintf(char *dest, UPInt destsize, const char * format, va_list argList)
diff --git a/LibOVR/Src/Kernel/OVR_String.cpp b/LibOVR/Src/Kernel/OVR_String.cpp
index 8c72c6d..86aa126 100644
--- a/LibOVR/Src/Kernel/OVR_String.cpp
+++ b/LibOVR/Src/Kernel/OVR_String.cpp
@@ -6,16 +6,16 @@ Content : String UTF8 string implementation with copy-on-write semantics
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_String.h b/LibOVR/Src/Kernel/OVR_String.h
index 6c09178..f7151c7 100644
--- a/LibOVR/Src/Kernel/OVR_String.h
+++ b/LibOVR/Src/Kernel/OVR_String.h
@@ -7,16 +7,16 @@ Content : String UTF8 string implementation with copy-on-write semantics
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -236,7 +236,7 @@ public:
// String& Insert(const UInt32* substr, UPInt posAt, SPInt size = -1);
// Get Byte index of the character at position = index
- UPInt GetByteIndex(UPInt index) const { return (UPInt)UTF8Util::GetByteIndex(static_cast<SPInt>(index), GetData()->Data); }
+ UPInt GetByteIndex(UPInt index) const { return (UPInt)UTF8Util::GetByteIndex(index, GetData()->Data); }
// Utility: case-insensitive string compare. stricmp() & strnicmp() are not
// ANSI or POSIX, do not seem to appear in Linux.
@@ -286,7 +286,7 @@ public:
void operator += (const String& src);
void operator += (const char* psrc) { AppendString(psrc); }
void operator += (const wchar_t* psrc) { AppendString(psrc); }
- void operator += (char ch) { AppendChar( static_cast<UInt32>(ch) ); }
+ void operator += (char ch) { AppendChar(ch); }
String operator + (const char* str) const;
String operator + (const String& src) const;
@@ -476,10 +476,10 @@ public:
void operator = (const String& src);
// Addition
- void operator += (const String& src) { AppendString(src.ToCStr(),static_cast<SPInt>(src.GetSize())); }
+ void operator += (const String& src) { AppendString(src.ToCStr(),src.GetSize()); }
void operator += (const char* psrc) { AppendString(psrc); }
void operator += (const wchar_t* psrc) { AppendString(psrc); }
- void operator += (char ch) { AppendChar( static_cast<SPInt>(ch) ); }
+ void operator += (char ch) { AppendChar(ch); }
//String operator + (const char* str) const ;
//String operator + (const String& src) const ;
diff --git a/LibOVR/Src/Kernel/OVR_StringHash.h b/LibOVR/Src/Kernel/OVR_StringHash.h
index 90679e0..baa80a7 100644
--- a/LibOVR/Src/Kernel/OVR_StringHash.h
+++ b/LibOVR/Src/Kernel/OVR_StringHash.h
@@ -7,16 +7,16 @@ Content : String hash table used when optional case-insensitive
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp b/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp
index e0db5d4..e196dd7 100644
--- a/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp
+++ b/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp
@@ -5,16 +5,16 @@ Content : String format functions.
Created : February 27, 2013
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp b/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp
index 4a7e87a..02abe15 100644
--- a/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp
+++ b/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp
@@ -5,16 +5,16 @@ Content : String filename/url helper function
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_SysFile.cpp b/LibOVR/Src/Kernel/OVR_SysFile.cpp
index cdbc843..f487492 100644
--- a/LibOVR/Src/Kernel/OVR_SysFile.cpp
+++ b/LibOVR/Src/Kernel/OVR_SysFile.cpp
@@ -6,16 +6,16 @@ Content : File wrapper class implementation (Win32)
Created : April 5, 1999
Authors : Michael Antonov
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -83,7 +83,7 @@ SysFile::SysFile() : DelegatedFile(0)
pFile = *new UnopenedFile;
}
-File* FileFILEOpen(const String& path, int flags, int mode);
+Ptr<File> FileFILEOpen(const String& path, int flags, int mode);
// Opens a file
SysFile::SysFile(const String& path, int flags, int mode) : DelegatedFile(0)
@@ -96,7 +96,7 @@ SysFile::SysFile(const String& path, int flags, int mode) : DelegatedFile(0)
// Will fail if file's already open
bool SysFile::Open(const String& path, int flags, int mode)
{
- pFile = *FileFILEOpen(path, flags, mode);
+ pFile = FileFILEOpen(path, flags, mode);
if ((!pFile) || (!pFile->IsValid()))
{
pFile = *new UnopenedFile;
diff --git a/LibOVR/Src/Kernel/OVR_SysFile.h b/LibOVR/Src/Kernel/OVR_SysFile.h
index 3241e67..d492377 100644
--- a/LibOVR/Src/Kernel/OVR_SysFile.h
+++ b/LibOVR/Src/Kernel/OVR_SysFile.h
@@ -11,16 +11,16 @@ Notes : errno may not be preserved across use of GBaseFile member functi
: Directories cannot be deleted while files opened from them are in use
(For the GetFullName function)
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_System.cpp b/LibOVR/Src/Kernel/OVR_System.cpp
index e57a663..3144ade 100644
--- a/LibOVR/Src/Kernel/OVR_System.cpp
+++ b/LibOVR/Src/Kernel/OVR_System.cpp
@@ -6,16 +6,16 @@ Content : General kernel initialization/cleanup, including that
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_System.h b/LibOVR/Src/Kernel/OVR_System.h
index 1e4065f..253fe19 100644
--- a/LibOVR/Src/Kernel/OVR_System.h
+++ b/LibOVR/Src/Kernel/OVR_System.h
@@ -7,16 +7,16 @@ Content : General kernel initialization/cleanup, including that
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_Threads.h b/LibOVR/Src/Kernel/OVR_Threads.h
index 0585972..e1f5abe 100644
--- a/LibOVR/Src/Kernel/OVR_Threads.h
+++ b/LibOVR/Src/Kernel/OVR_Threads.h
@@ -6,16 +6,16 @@ Content : Contains thread-related (safe) functionality
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp b/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp
deleted file mode 100644
index bf87f8c..0000000
--- a/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp
+++ /dev/null
@@ -1,821 +0,0 @@
-/************************************************************************************
-
-PublicHeader: OVR
-Filename : OVR_Threads.h
-Content :
-Created :
-Notes :
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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 "OVR_Threads.h"
-#include "OVR_Hash.h"
-
-#ifdef OVR_ENABLE_THREADS
-
-#include "OVR_Timer.h"
-#include "OVR_Log.h"
-
-#include <pthread.h>
-#include <time.h>
-
-#ifdef OVR_OS_PS3
-#include <sys/sys_time.h>
-#include <sys/timer.h>
-#include <sys/synchronization.h>
-#define sleep(x) sys_timer_sleep(x)
-#define usleep(x) sys_timer_usleep(x)
-using std::timespec;
-#else
-#include <unistd.h>
-#include <sys/time.h>
-#include <errno.h>
-#endif
-
-namespace OVR {
-
-// ***** Mutex implementation
-
-
-// *** Internal Mutex implementation structure
-
-class MutexImpl : public NewOverrideBase
-{
- // System mutex or semaphore
- pthread_mutex_t SMutex;
- bool Recursive;
- unsigned LockCount;
- pthread_t LockedBy;
-
- friend class WaitConditionImpl;
-
-public:
- // Constructor/destructor
- MutexImpl(Mutex* pmutex, bool recursive = 1);
- ~MutexImpl();
-
- // Locking functions
- void DoLock();
- bool TryLock();
- void Unlock(Mutex* pmutex);
- // Returns 1 if the mutes is currently locked
- bool IsLockedByAnotherThread(Mutex* pmutex);
- bool IsSignaled() const;
-};
-
-pthread_mutexattr_t Lock::RecursiveAttr;
-bool Lock::RecursiveAttrInit = 0;
-
-// *** Constructor/destructor
-MutexImpl::MutexImpl(Mutex* pmutex, bool recursive)
-{
- Recursive = recursive;
- LockCount = 0;
-
- if (Recursive)
- {
- if (!Lock::RecursiveAttrInit)
- {
- pthread_mutexattr_init(&Lock::RecursiveAttr);
- pthread_mutexattr_settype(&Lock::RecursiveAttr, PTHREAD_MUTEX_RECURSIVE);
- Lock::RecursiveAttrInit = 1;
- }
-
- pthread_mutex_init(&SMutex, &Lock::RecursiveAttr);
- }
- else
- pthread_mutex_init(&SMutex, 0);
-}
-
-MutexImpl::~MutexImpl()
-{
- pthread_mutex_destroy(&SMutex);
-}
-
-
-// Lock and try lock
-void MutexImpl::DoLock()
-{
- while (pthread_mutex_lock(&SMutex));
- LockCount++;
- LockedBy = pthread_self();
-}
-
-bool MutexImpl::TryLock()
-{
- if (!pthread_mutex_trylock(&SMutex))
- {
- LockCount++;
- LockedBy = pthread_self();
- return 1;
- }
-
- return 0;
-}
-
-void MutexImpl::Unlock(Mutex* pmutex)
-{
- OVR_ASSERT(pthread_self() == LockedBy && LockCount > 0);
-
- unsigned lockCount;
- LockCount--;
- lockCount = LockCount;
-
- pthread_mutex_unlock(&SMutex);
-}
-
-bool MutexImpl::IsLockedByAnotherThread(Mutex* pmutex)
-{
- // There could be multiple interpretations of IsLocked with respect to current thread
- if (LockCount == 0)
- return 0;
- if (pthread_self() != LockedBy)
- return 1;
- return 0;
-}
-
-bool MutexImpl::IsSignaled() const
-{
- // An mutex is signaled if it is not locked ANYWHERE
- // Note that this is different from IsLockedByAnotherThread function,
- // that takes current thread into account
- return LockCount == 0;
-}
-
-
-// *** Actual Mutex class implementation
-
-Mutex::Mutex(bool recursive)
-{
- // NOTE: RefCount mode already thread-safe for all waitables.
- pImpl = new MutexImpl(this, recursive);
-}
-
-Mutex::~Mutex()
-{
- delete pImpl;
-}
-
-// Lock and try lock
-void Mutex::DoLock()
-{
- pImpl->DoLock();
-}
-bool Mutex::TryLock()
-{
- return pImpl->TryLock();
-}
-void Mutex::Unlock()
-{
- pImpl->Unlock(this);
-}
-bool Mutex::IsLockedByAnotherThread()
-{
- return pImpl->IsLockedByAnotherThread(this);
-}
-
-
-
-//-----------------------------------------------------------------------------------
-// ***** Event
-
-bool Event::Wait(unsigned delay)
-{
- Mutex::Locker lock(&StateMutex);
-
- // Do the correct amount of waiting
- if (delay == OVR_WAIT_INFINITE)
- {
- while(!State)
- StateWaitCondition.Wait(&StateMutex);
- }
- else if (delay)
- {
- if (!State)
- StateWaitCondition.Wait(&StateMutex, delay);
- }
-
- bool state = State;
- // Take care of temporary 'pulsing' of a state
- if (Temporary)
- {
- Temporary = false;
- State = false;
- }
- return state;
-}
-
-void Event::updateState(bool newState, bool newTemp, bool mustNotify)
-{
- Mutex::Locker lock(&StateMutex);
- State = newState;
- Temporary = newTemp;
- if (mustNotify)
- StateWaitCondition.NotifyAll();
-}
-
-
-
-// ***** Wait Condition Implementation
-
-// Internal implementation class
-class WaitConditionImpl : public NewOverrideBase
-{
- pthread_mutex_t SMutex;
- pthread_cond_t Condv;
-
-public:
-
- // Constructor/destructor
- WaitConditionImpl();
- ~WaitConditionImpl();
-
- // Release mutex and wait for condition. The mutex is re-aqured after the wait.
- bool Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE);
-
- // Notify a condition, releasing at one object waiting
- void Notify();
- // Notify a condition, releasing all objects waiting
- void NotifyAll();
-};
-
-
-WaitConditionImpl::WaitConditionImpl()
-{
- pthread_mutex_init(&SMutex, 0);
- pthread_cond_init(&Condv, 0);
-}
-
-WaitConditionImpl::~WaitConditionImpl()
-{
- pthread_mutex_destroy(&SMutex);
- pthread_cond_destroy(&Condv);
-}
-
-bool WaitConditionImpl::Wait(Mutex *pmutex, unsigned delay)
-{
- bool result = 1;
- unsigned lockCount = pmutex->pImpl->LockCount;
-
- // Mutex must have been locked
- if (lockCount == 0)
- return 0;
-
- pthread_mutex_lock(&SMutex);
-
- // Finally, release a mutex or semaphore
- if (pmutex->pImpl->Recursive)
- {
- // Release the recursive mutex N times
- pmutex->pImpl->LockCount = 0;
- for(unsigned i=0; i<lockCount; i++)
- pthread_mutex_unlock(&pmutex->pImpl->SMutex);
- }
- else
- {
- pmutex->pImpl->LockCount = 0;
- pthread_mutex_unlock(&pmutex->pImpl->SMutex);
- }
-
- // Note that there is a gap here between mutex.Unlock() and Wait().
- // The other mutex protects this gap.
-
- if (delay == OVR_WAIT_INFINITE)
- pthread_cond_wait(&Condv,&SMutex);
- else
- {
- timespec ts;
-#ifdef OVR_OS_PS3
- sys_time_sec_t s;
- sys_time_nsec_t ns;
- sys_time_get_current_time(&s, &ns);
-
- ts.tv_sec = s + (delay / 1000);
- ts.tv_nsec = ns + (delay % 1000) * 1000000;
-
-#else
- struct timeval tv;
- gettimeofday(&tv, 0);
-
- ts.tv_sec = tv.tv_sec + (delay / 1000);
- ts.tv_nsec = (tv.tv_usec + (delay % 1000) * 1000) * 1000;
-#endif
- if (ts.tv_nsec > 999999999)
- {
- ts.tv_sec++;
- ts.tv_nsec -= 1000000000;
- }
- int r = pthread_cond_timedwait(&Condv,&SMutex, &ts);
- OVR_ASSERT(r == 0 || r == ETIMEDOUT);
- if (r)
- result = 0;
- }
-
- pthread_mutex_unlock(&SMutex);
-
- // Re-aquire the mutex
- for(unsigned i=0; i<lockCount; i++)
- pmutex->DoLock();
-
- // Return the result
- return result;
-}
-
-// Notify a condition, releasing the least object in a queue
-void WaitConditionImpl::Notify()
-{
- pthread_mutex_lock(&SMutex);
- pthread_cond_signal(&Condv);
- pthread_mutex_unlock(&SMutex);
-}
-
-// Notify a condition, releasing all objects waiting
-void WaitConditionImpl::NotifyAll()
-{
- pthread_mutex_lock(&SMutex);
- pthread_cond_broadcast(&Condv);
- pthread_mutex_unlock(&SMutex);
-}
-
-
-
-// *** Actual implementation of WaitCondition
-
-WaitCondition::WaitCondition()
-{
- pImpl = new WaitConditionImpl;
-}
-WaitCondition::~WaitCondition()
-{
- delete pImpl;
-}
-
-bool WaitCondition::Wait(Mutex *pmutex, unsigned delay)
-{
- return pImpl->Wait(pmutex, delay);
-}
-// Notification
-void WaitCondition::Notify()
-{
- pImpl->Notify();
-}
-void WaitCondition::NotifyAll()
-{
- pImpl->NotifyAll();
-}
-
-
-// ***** Current thread
-
-// Per-thread variable
-/*
-static __thread Thread* pCurrentThread = 0;
-
-// Static function to return a pointer to the current thread
-void Thread::InitCurrentThread(Thread *pthread)
-{
- pCurrentThread = pthread;
-}
-
-// Static function to return a pointer to the current thread
-Thread* Thread::GetThread()
-{
- return pCurrentThread;
-}
-*/
-
-
-// *** Thread constructors.
-
-Thread::Thread(UPInt stackSize, int processor)
-{
- // NOTE: RefCount mode already thread-safe for all Waitable objects.
- CreateParams params;
- params.stackSize = stackSize;
- params.processor = processor;
- Init(params);
-}
-
-Thread::Thread(Thread::ThreadFn threadFunction, void* userHandle, UPInt stackSize,
- int processor, Thread::ThreadState initialState)
-{
- CreateParams params(threadFunction, userHandle, stackSize, processor, initialState);
- Init(params);
-}
-
-Thread::Thread(const CreateParams& params)
-{
- Init(params);
-}
-
-void Thread::Init(const CreateParams& params)
-{
- // Clear the variables
- ThreadFlags = 0;
- ThreadHandle = 0;
- ExitCode = 0;
- SuspendCount = 0;
- StackSize = params.stackSize;
- Processor = params.processor;
- Priority = params.priority;
-
- // Clear Function pointers
- ThreadFunction = params.threadFunction;
- UserHandle = params.userHandle;
- if (params.initialState != NotRunning)
- Start(params.initialState);
-}
-
-Thread::~Thread()
-{
- // Thread should not running while object is being destroyed,
- // this would indicate ref-counting issue.
- //OVR_ASSERT(IsRunning() == 0);
-
- // Clean up thread.
- ThreadHandle = 0;
-}
-
-
-
-// *** Overridable User functions.
-
-// Default Run implementation
-int Thread::Run()
-{
- // Call pointer to function, if available.
- return (ThreadFunction) ? ThreadFunction(this, UserHandle) : 0;
-}
-void Thread::OnExit()
-{
-}
-
-
-// Finishes the thread and releases internal reference to it.
-void Thread::FinishAndRelease()
-{
- // Note: thread must be US.
- ThreadFlags &= (UInt32)~(OVR_THREAD_STARTED);
- ThreadFlags |= OVR_THREAD_FINISHED;
-
- // Release our reference; this is equivalent to 'delete this'
- // from the point of view of our thread.
- Release();
-}
-
-
-
-// *** ThreadList - used to track all created threads
-
-class ThreadList : public NewOverrideBase
-{
- //------------------------------------------------------------------------
- struct ThreadHashOp
- {
- size_t operator()(const Thread* ptr)
- {
- return (((size_t)ptr) >> 6) ^ (size_t)ptr;
- }
- };
-
- HashSet<Thread*, ThreadHashOp> ThreadSet;
- Mutex ThreadMutex;
- WaitCondition ThreadsEmpty;
- // Track the root thread that created us.
- pthread_t RootThreadId;
-
- static ThreadList* volatile pRunningThreads;
-
- void addThread(Thread *pthread)
- {
- Mutex::Locker lock(&ThreadMutex);
- ThreadSet.Add(pthread);
- }
-
- void removeThread(Thread *pthread)
- {
- Mutex::Locker lock(&ThreadMutex);
- ThreadSet.Remove(pthread);
- if (ThreadSet.GetSize() == 0)
- ThreadsEmpty.Notify();
- }
-
- void finishAllThreads()
- {
- // Only original root thread can call this.
- OVR_ASSERT(pthread_self() == RootThreadId);
-
- Mutex::Locker lock(&ThreadMutex);
- while (ThreadSet.GetSize() != 0)
- ThreadsEmpty.Wait(&ThreadMutex);
- }
-
-public:
-
- ThreadList()
- {
- RootThreadId = pthread_self();
- }
- ~ThreadList() { }
-
-
- static void AddRunningThread(Thread *pthread)
- {
- // Non-atomic creation ok since only the root thread
- if (!pRunningThreads)
- {
- pRunningThreads = new ThreadList;
- OVR_ASSERT(pRunningThreads);
- }
- pRunningThreads->addThread(pthread);
- }
-
- // NOTE: 'pthread' might be a dead pointer when this is
- // called so it should not be accessed; it is only used
- // for removal.
- static void RemoveRunningThread(Thread *pthread)
- {
- OVR_ASSERT(pRunningThreads);
- pRunningThreads->removeThread(pthread);
- }
-
- static void FinishAllThreads()
- {
- // This is ok because only root thread can wait for other thread finish.
- if (pRunningThreads)
- {
- pRunningThreads->finishAllThreads();
- delete pRunningThreads;
- pRunningThreads = 0;
- }
- }
-};
-
-// By default, we have no thread list.
-ThreadList* volatile ThreadList::pRunningThreads = 0;
-
-
-// FinishAllThreads - exposed publicly in Thread.
-void Thread::FinishAllThreads()
-{
- ThreadList::FinishAllThreads();
-}
-
-// *** Run override
-
-int Thread::PRun()
-{
- // Suspend us on start, if requested
- if (ThreadFlags & OVR_THREAD_START_SUSPENDED)
- {
- Suspend();
- ThreadFlags &= (UInt32)~OVR_THREAD_START_SUSPENDED;
- }
-
- // Call the virtual run function
- ExitCode = Run();
- return ExitCode;
-}
-
-
-
-
-// *** User overridables
-
-bool Thread::GetExitFlag() const
-{
- return (ThreadFlags & OVR_THREAD_EXIT) != 0;
-}
-
-void Thread::SetExitFlag(bool exitFlag)
-{
- // The below is atomic since ThreadFlags is AtomicInt.
- if (exitFlag)
- ThreadFlags |= OVR_THREAD_EXIT;
- else
- ThreadFlags &= (UInt32) ~OVR_THREAD_EXIT;
-}
-
-
-// Determines whether the thread was running and is now finished
-bool Thread::IsFinished() const
-{
- return (ThreadFlags & OVR_THREAD_FINISHED) != 0;
-}
-// Determines whether the thread is suspended
-bool Thread::IsSuspended() const
-{
- return SuspendCount > 0;
-}
-// Returns current thread state
-Thread::ThreadState Thread::GetThreadState() const
-{
- if (IsSuspended())
- return Suspended;
- if (ThreadFlags & OVR_THREAD_STARTED)
- return Running;
- return NotRunning;
-}
-/*
-static const char* mapsched_policy(int policy)
-{
- switch(policy)
- {
- case SCHED_OTHER:
- return "SCHED_OTHER";
- case SCHED_RR:
- return "SCHED_RR";
- case SCHED_FIFO:
- return "SCHED_FIFO";
-
- }
- return "UNKNOWN";
-}
- int policy;
- sched_param sparam;
- pthread_getschedparam(pthread_self(), &policy, &sparam);
- int max_prior = sched_get_priority_max(policy);
- int min_prior = sched_get_priority_min(policy);
- printf(" !!!! policy: %s, priority: %d, max priority: %d, min priority: %d\n", mapsched_policy(policy), sparam.sched_priority, max_prior, min_prior);
-#include <stdio.h>
-*/
-// ***** Thread management
-
-// The actual first function called on thread start
-void* Thread_PthreadStartFn(void* phandle)
-{
- Thread* pthread = (Thread*)phandle;
- int result = pthread->PRun();
- // Signal the thread as done and release it atomically.
- pthread->FinishAndRelease();
- // At this point Thread object might be dead; however we can still pass
- // it to RemoveRunningThread since it is only used as a key there.
- ThreadList::RemoveRunningThread(pthread);
- return (void*) result;
-}
-
-int Thread::InitAttr = 0;
-pthread_attr_t Thread::Attr;
-
-/* static */
-int Thread::GetOSPriority(ThreadPriority p)
-//static inline int MapToSystemPrority(Thread::ThreadPriority p)
-{
-#ifdef OVR_OS_PS3
- switch(p)
- {
- case Thread::CriticalPriority: return 0;
- case Thread::HighestPriority: return 300;
- case Thread::AboveNormalPriority: return 600;
- case Thread::NormalPriority: return 1000;
- case Thread::BelowNormalPriority: return 1500;
- case Thread::LowestPriority: return 2500;
- case Thread::IdlePriority: return 3071;
- } return 1000;
-#else
- OVR_UNUSED(p);
- return -1;
-#endif
-}
-
-bool Thread::Start(ThreadState initialState)
-{
- if (initialState == NotRunning)
- return 0;
- if (GetThreadState() != NotRunning)
- {
- OVR_DEBUG_LOG(("Thread::Start failed - thread %p already running", this));
- return 0;
- }
-
- if (!InitAttr)
- {
- pthread_attr_init(&Attr);
- pthread_attr_setdetachstate(&Attr, PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize(&Attr, 128 * 1024);
- sched_param sparam;
- sparam.sched_priority = Thread::GetOSPriority(NormalPriority);
- pthread_attr_setschedparam(&Attr, &sparam);
- InitAttr = 1;
- }
-
- ExitCode = 0;
- SuspendCount = 0;
- ThreadFlags = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED;
-
- // AddRef to us until the thread is finished
- AddRef();
- ThreadList::AddRunningThread(this);
-
- int result;
- if (StackSize != 128 * 1024 || Priority != NormalPriority)
- {
- pthread_attr_t attr;
-
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- pthread_attr_setstacksize(&attr, StackSize);
- sched_param sparam;
- sparam.sched_priority = Thread::GetOSPriority(Priority);
- pthread_attr_setschedparam(&attr, &sparam);
- result = pthread_create(&ThreadHandle, &attr, Thread_PthreadStartFn, this);
- pthread_attr_destroy(&attr);
- }
- else
- result = pthread_create(&ThreadHandle, &Attr, Thread_PthreadStartFn, this);
-
- if (result)
- {
- ThreadFlags = 0;
- Release();
- ThreadList::RemoveRunningThread(this);
- return 0;
- }
- return 1;
-}
-
-
-// Suspend the thread until resumed
-bool Thread::Suspend()
-{
- OVR_DEBUG_LOG(("Thread::Suspend - cannot suspend threads on this system"));
- return 0;
-}
-
-// Resumes currently suspended thread
-bool Thread::Resume()
-{
- return 0;
-}
-
-
-// Quits with an exit code
-void Thread::Exit(int exitCode)
-{
- // Can only exist the current thread
- // if (GetThread() != this)
- // return;
-
- // Call the virtual OnExit function
- OnExit();
-
- // Signal this thread object as done and release it's references.
- FinishAndRelease();
- ThreadList::RemoveRunningThread(this);
-
- pthread_exit((void *) exitCode);
-}
-
-ThreadId GetCurrentThreadId()
-{
- return (void*)pthread_self();
-}
-
-// *** Sleep functions
-
-/* static */
-bool Thread::Sleep(unsigned secs)
-{
- sleep(secs);
- return 1;
-}
-/* static */
-bool Thread::MSleep(unsigned msecs)
-{
- usleep(msecs*1000);
- return 1;
-}
-
-/* static */
-int Thread::GetCPUCount()
-{
- return 1;
-}
-
-
-#ifdef OVR_OS_PS3
-
-sys_lwmutex_attribute_t Lock::LockAttr = { SYS_SYNC_PRIORITY, SYS_SYNC_RECURSIVE };
-
-#endif
-
-}
-
-#endif // OVR_ENABLE_THREADS
diff --git a/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp b/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp
index 8880082..663d859 100644
--- a/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp
+++ b/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp
@@ -6,16 +6,16 @@ Content : Windows specific thread-related (safe) functionality
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_Timer.cpp b/LibOVR/Src/Kernel/OVR_Timer.cpp
index 84ff4a1..a8de47d 100644
--- a/LibOVR/Src/Kernel/OVR_Timer.cpp
+++ b/LibOVR/Src/Kernel/OVR_Timer.cpp
@@ -5,16 +5,16 @@ Content : Provides static functions for precise timing
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -39,49 +39,48 @@ limitations under the License.
namespace OVR {
+// For recorded data playback
+bool Timer::useFakeSeconds = false;
+double Timer::FakeSeconds = 0;
+
//------------------------------------------------------------------------
// *** Timer - Platform Independent functions
-double ovr_GetTimeInSeconds()
+// Returns global high-resolution application timer in seconds.
+double Timer::GetSeconds()
{
- return Timer::GetSeconds();
+ if(useFakeSeconds)
+ return FakeSeconds;
+
+ return double(Timer::GetTicksNanos()) * 0.000000001;
}
-UInt64 Timer::GetProfileTicks()
+#ifndef OVR_OS_WIN32
+
+// Unused on OSs other then Win32.
+void Timer::initializeTimerSystem()
{
- return (GetRawTicks() * MksPerSecond) / GetRawFrequency();
}
-double Timer::GetProfileSeconds()
+void Timer::shutdownTimerSystem()
{
- static UInt64 StartTime = GetProfileTicks();
- return TicksToSeconds(GetProfileTicks()-StartTime);
}
-#ifndef OVR_OS_ANDROID
-
-double Timer::GetSeconds()
-{
- return (double)Timer::GetRawTicks() / (double) GetRawFrequency();
-}
#endif
+
//------------------------------------------------------------------------
// *** Android Specific Timer
-
#if defined(OVR_OS_ANDROID)
-// Returns global high-resolution application timer in seconds.
-double Timer::GetSeconds()
+UInt64 Timer::GetTicksNanos()
{
- return double(Timer::GetRawTicks()) * 0.000000001;
-}
+ if (useFakeSeconds)
+ return (UInt64) (FakeSeconds * NanosPerSecond);
-UInt64 Timer::GetRawTicks()
-{
// Choreographer vsync timestamp is based on.
struct timespec tp;
const int status = clock_gettime(CLOCK_MONOTONIC, &tp);
@@ -94,108 +93,178 @@ UInt64 Timer::GetRawTicks()
return result;
}
-UInt64 Timer::GetRawFrequency()
-{
- return MksPerSecond * 1000;
-}
-
-#endif
-
//------------------------------------------------------------------------
// *** Win32 Specific Timer
-#if defined (OVR_OS_WIN32)
+#elif defined (OVR_OS_WIN32)
-CRITICAL_SECTION WinAPI_GetTimeCS;
-volatile UInt32 WinAPI_OldTime = 0;
-volatile UInt32 WinAPI_WrapCounter = 0;
+// This helper class implements high-resolution wrapper that combines timeGetTime() output
+// with QueryPerformanceCounter. timeGetTime() is lower precision but drives the high bits,
+// as it's tied to the system clock.
+struct PerformanceTimer
+{
+ PerformanceTimer()
+ : OldMMTimeMs(0), MMTimeWrapCounter(0), PrefFrequency(0),
+ LastResultNanos(0), PerfMinusTicksDeltaNanos(0)
+ { }
+
+ enum {
+ MMTimerResolutionNanos = 1000000
+ };
+
+ void Initialize();
+ void Shutdown();
+
+ UInt64 GetTimeNanos();
+
+
+ UINT64 getFrequency()
+ {
+ if (PrefFrequency == 0)
+ {
+ LARGE_INTEGER freq;
+ QueryPerformanceFrequency(&freq);
+ PrefFrequency = freq.QuadPart;
+ }
+ return PrefFrequency;
+ }
+
+
+ CRITICAL_SECTION TimeCS;
+ // timeGetTime() support with wrap.
+ UInt32 OldMMTimeMs;
+ UInt32 MMTimeWrapCounter;
+ // Cached performance frequency result.
+ UInt64 PrefFrequency;
+
+ // Computed as (perfCounterNanos - ticksCounterNanos) initially,
+ // and used to adjust timing.
+ UInt64 PerfMinusTicksDeltaNanos;
+ // Last returned value in nanoseconds, to ensure we don't back-step in time.
+ UInt64 LastResultNanos;
+};
+
+PerformanceTimer Win32_PerfTimer;
+
+
+void PerformanceTimer::Initialize()
+{
+ timeBeginPeriod(1);
+ InitializeCriticalSection(&TimeCS);
+ MMTimeWrapCounter = 0;
+ getFrequency();
+}
-UInt32 Timer::GetTicksMs()
+void PerformanceTimer::Shutdown()
{
- return timeGetTime();
+ DeleteCriticalSection(&TimeCS);
+ timeEndPeriod(1);
}
-UInt64 Timer::GetTicks()
+UInt64 PerformanceTimer::GetTimeNanos()
{
- DWORD ticks = timeGetTime();
- UInt64 result;
+ UInt64 resultNanos;
+ LARGE_INTEGER li;
+ DWORD mmTimeMs;
// On Win32 QueryPerformanceFrequency is unreliable due to SMP and
// performance levels, so use this logic to detect wrapping and track
// high bits.
- ::EnterCriticalSection(&WinAPI_GetTimeCS);
-
- if (WinAPI_OldTime > ticks)
- WinAPI_WrapCounter++;
- WinAPI_OldTime = ticks;
+ ::EnterCriticalSection(&TimeCS);
- result = (UInt64(WinAPI_WrapCounter) << 32) | ticks;
- ::LeaveCriticalSection(&WinAPI_GetTimeCS);
-
- return result * MksPerMs;
-}
-
-UInt64 Timer::GetRawTicks()
-{
- LARGE_INTEGER li;
+ // Get raw value and perf counter "At the same time".
+ mmTimeMs = timeGetTime();
QueryPerformanceCounter(&li);
- return li.QuadPart;
-}
-UInt64 Timer::GetRawFrequency()
-{
- static UInt64 perfFreq = 0;
- if (perfFreq == 0)
+ if (OldMMTimeMs > mmTimeMs)
+ MMTimeWrapCounter++;
+ OldMMTimeMs = mmTimeMs;
+
+ // Normalize to nanoseconds.
+ UInt64 mmCounterNanos = ((UInt64(MMTimeWrapCounter) << 32) | mmTimeMs) * 1000000;
+ UInt64 frequency = getFrequency();
+ UInt64 perfCounterSeconds = UInt64(li.QuadPart) / frequency;
+ UInt64 perfRemainderNanos = ( (UInt64(li.QuadPart) - perfCounterSeconds * frequency) *
+ Timer::NanosPerSecond ) / frequency;
+ UInt64 perfCounterNanos = perfCounterSeconds * Timer::NanosPerSecond + perfRemainderNanos;
+
+ if (PerfMinusTicksDeltaNanos == 0)
+ PerfMinusTicksDeltaNanos = perfCounterNanos - mmCounterNanos;
+
+
+ // Compute result before snapping.
+ //
+ // On first call, this evaluates to:
+ // resultNanos = mmCounterNanos.
+ // Next call, assuming no wrap:
+ // resultNanos = prev_mmCounterNanos + (perfCounterNanos - prev_perfCounterNanos).
+ // After wrap, this would be:
+ // resultNanos = snapped(prev_mmCounterNanos +/- 1ms) + (perfCounterNanos - prev_perfCounterNanos).
+ //
+ resultNanos = perfCounterNanos - PerfMinusTicksDeltaNanos;
+
+ // Snap the range so that resultNanos never moves further apart then its target resolution.
+ // It's better to allow more slack on the high side as timeGetTime() may be updated at sporadically
+ // larger then 1 ms intervals even when 1 ms resolution is requested.
+ if (resultNanos > (mmCounterNanos + MMTimerResolutionNanos*2))
{
- LARGE_INTEGER freq;
- QueryPerformanceFrequency(&freq);
- perfFreq = freq.QuadPart;
+ resultNanos = mmCounterNanos + MMTimerResolutionNanos*2;
+ if (resultNanos < LastResultNanos)
+ resultNanos = LastResultNanos;
+ PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos;
+ }
+ else if (resultNanos < (mmCounterNanos - MMTimerResolutionNanos))
+ {
+ resultNanos = mmCounterNanos - MMTimerResolutionNanos;
+ if (resultNanos < LastResultNanos)
+ resultNanos = LastResultNanos;
+ PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos;
}
- return perfFreq;
-}
-void Timer::initializeTimerSystem()
-{
- timeBeginPeriod(1);
- InitializeCriticalSection(&WinAPI_GetTimeCS);
+ LastResultNanos = resultNanos;
+ ::LeaveCriticalSection(&TimeCS);
-}
-void Timer::shutdownTimerSystem()
-{
- DeleteCriticalSection(&WinAPI_GetTimeCS);
- timeEndPeriod(1);
-}
+ //Tom's addition, to keep precision
+ static UInt64 initial_time = 0;
+ if (!initial_time) initial_time = resultNanos;
+ resultNanos -= initial_time;
-#else // !OVR_OS_WIN32
+ return resultNanos;
+}
-//------------------------------------------------------------------------
-// *** Standard OS Timer
-UInt32 Timer::GetTicksMs()
-{
- return (UInt32)(GetProfileTicks() / 1000);
-}
-// The profile ticks implementation is just fine for a normal timer.
-UInt64 Timer::GetTicks()
+// Delegate to PerformanceTimer.
+UInt64 Timer::GetTicksNanos()
{
- return GetProfileTicks();
-}
+ if (useFakeSeconds)
+ return (UInt64) (FakeSeconds * NanosPerSecond);
+ return Win32_PerfTimer.GetTimeNanos();
+}
void Timer::initializeTimerSystem()
{
+ Win32_PerfTimer.Initialize();
+
}
void Timer::shutdownTimerSystem()
{
+ Win32_PerfTimer.Shutdown();
}
+#else // !OVR_OS_WIN32 && !OVR_OS_ANDROID
+
-#if !defined(OVR_OS_ANDROID)
+//------------------------------------------------------------------------
+// *** Standard OS Timer
-UInt64 Timer::GetRawTicks()
+UInt64 Timer::GetTicksNanos()
{
+ if (useFakeSeconds)
+ return (UInt64) (FakeSeconds * NanosPerSecond);
+
// TODO: prefer rdtsc when available?
UInt64 result;
@@ -207,17 +276,10 @@ UInt64 Timer::GetRawTicks()
result = (UInt64)tv.tv_sec * 1000000;
result += tv.tv_usec;
- return result;
-}
-
-UInt64 Timer::GetRawFrequency()
-{
- return MksPerSecond;
+ return result * 1000;
}
-#endif // !OVR_OS_ANDROID
-
-#endif // !OVR_OS_WIN32
+#endif // OS-specific
diff --git a/LibOVR/Src/Kernel/OVR_Timer.h b/LibOVR/Src/Kernel/OVR_Timer.h
index 937b2cd..12cba3b 100644
--- a/LibOVR/Src/Kernel/OVR_Timer.h
+++ b/LibOVR/Src/Kernel/OVR_Timer.h
@@ -6,16 +6,16 @@ Content : Provides static functions for precise timing
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -43,62 +43,32 @@ class Timer
public:
enum {
MsPerSecond = 1000, // Milliseconds in one second.
- MksPerMs = 1000, // Microseconds in one millisecond.
- MksPerSecond = MsPerSecond * MksPerMs
+ NanosPerSecond = MsPerSecond * 1000 * 1000,
+ MksPerSecond = MsPerSecond * 1000
};
-
// ***** Timing APIs for Application
+
// These APIs should be used to guide animation and other program functions
// that require precision.
- // Returns ticks in milliseconds, as a 32-bit number. May wrap around every
- // 49.2 days. Use either time difference of two values of GetTicks to avoid
- // wrap-around. GetTicksMs may perform better then GetTicks.
- static UInt32 OVR_STDCALL GetTicksMs();
-
- // GetTicks returns general-purpose high resolution application timer value,
- // measured in microseconds (mks, or 1/1000000 of a second). The actual precision
- // is system-specific and may be much lower, such as 1 ms.
- static UInt64 OVR_STDCALL GetTicks();
-
// Returns global high-resolution application timer in seconds.
- static double OVR_STDCALL GetSeconds();
-
-
- // ***** Profiling APIs.
- // These functions should be used for profiling, but may have system specific
- // artifacts that make them less appropriate for general system use.
- // On Win32, for example these rely on QueryPerformanceConter may have
- // problems with thread-core switching and power modes.
-
- // Return a hi-res timer value in mks (1/1000000 of a sec).
- // Generally you want to call this at the start and end of an
- // operation, and pass the difference to
- // TicksToSeconds() to find out how long the operation took.
- static UInt64 OVR_STDCALL GetProfileTicks();
-
- // More convenient zero-based profile timer in seconds. First call initializes
- // the "zero" value; future calls return the difference. Not thread safe for first call.
- // Due to low precision of Double, may malfunction after long runtime.
- static double OVR_STDCALL GetProfileSeconds();
-
- // Get the raw cycle counter value, providing the maximum possible timer resolution.
- static UInt64 OVR_STDCALL GetRawTicks();
- static UInt64 OVR_STDCALL GetRawFrequency();
-
-
- // ***** Tick and time unit conversion.
-
- // Convert micro-second ticks value into seconds value.
- static inline double TicksToSeconds(UInt64 ticks)
- {
- return static_cast<double>(ticks) * (1.0 / (double)MksPerSecond);
- }
- // Convert Raw or frequency-unit ticks to seconds based on specified frequency.
- static inline double RawTicksToSeconds(UInt64 rawTicks, UInt64 rawFrequency)
- {
- return static_cast<double>(rawTicks) * rawFrequency;
+ static double OVR_STDCALL GetSeconds();
+
+ // Returns time in Nanoseconds, using highest possible system resolution.
+ static UInt64 OVR_STDCALL GetTicksNanos();
+
+ // Kept for compatibility.
+ // Returns ticks in milliseconds, as a 32-bit number. May wrap around every 49.2 days.
+ // Use either time difference of two values of GetTicks to avoid wrap-around.
+ static UInt32 OVR_STDCALL GetTicksMs()
+ { return UInt32(GetTicksNanos() / 1000000); }
+
+ // for recorded data playback
+ static void SetFakeSeconds(double fakeSeconds)
+ {
+ FakeSeconds = fakeSeconds;
+ useFakeSeconds = true;
}
private:
@@ -106,12 +76,11 @@ private:
// System called during program startup/shutdown.
static void initializeTimerSystem();
static void shutdownTimerSystem();
-};
-
-
-// Global high-resolution time in seconds. This is intended to replace Timer class in OVR.
-double ovr_GetTimeInSeconds();
+ // for recorded data playback
+ static double FakeSeconds;
+ static bool useFakeSeconds;
+};
} // OVR::Timer
diff --git a/LibOVR/Src/Kernel/OVR_Types.h b/LibOVR/Src/Kernel/OVR_Types.h
index 6b2922e..f45df59 100644
--- a/LibOVR/Src/Kernel/OVR_Types.h
+++ b/LibOVR/Src/Kernel/OVR_Types.h
@@ -6,16 +6,16 @@ Content : Standard library defines and simple types
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -140,6 +140,8 @@ limitations under the License.
// MSVC 8.0 (VC2005) = 1400
// MSVC 9.0 (VC2008) = 1500
// MSVC 10.0 (VC2010) = 1600
+// MSVC 11.0 (VC2012) = 1700
+// MSVC 12.0 (VC2013) = 1800
# define OVR_CC_MSVC _MSC_VER
#elif defined(__GNUC__)
@@ -159,11 +161,9 @@ limitations under the License.
// Disable MSVC warnings
#if defined(OVR_CC_MSVC)
# pragma warning(disable : 4127) // Inconsistent dll linkage
-# pragma warning(disable : 4514) // Unreferenced inline function has been removed
# pragma warning(disable : 4530) // Exception handling
-# pragma warning(disable : 4711) // function 'x()' selected for automatic inline expansion
-# pragma warning(disable : 4820) // 'n' bytes padding added after data member 'item'
# if (OVR_CC_MSVC<1300)
+# pragma warning(disable : 4514) // Unreferenced inline function has been removed
# pragma warning(disable : 4710) // Function not inlined
# pragma warning(disable : 4714) // _force_inline not inlined
# pragma warning(disable : 4786) // Debug variable name longer than 255 chars
@@ -195,12 +195,14 @@ limitations under the License.
# include <stdlib.h>
# include <crtdbg.h>
+#if 0
// Uncomment this to help debug memory leaks under Visual Studio in OVR apps only.
// This shouldn't be defined in customer releases.
# ifndef OVR_DEFINE_NEW
# define OVR_DEFINE_NEW new(__FILE__, __LINE__)
# define new OVR_DEFINE_NEW
# endif
+#endif
#endif
@@ -374,6 +376,7 @@ namespace BaseTypes
// If not in debug build, macros do nothing
#ifndef OVR_BUILD_DEBUG
+# define OVR_DEBUG_CODE(c) c
# define OVR_DEBUG_BREAK ((void)0)
# define OVR_ASSERT(p) ((void)0)
@@ -399,6 +402,8 @@ namespace BaseTypes
# define OVR_DEBUG_BREAK do { *((int *) 0) = 1; } while(0)
#endif
+#define OVR_DEBUG_CODE(c)
+
// This will cause compiler breakpoint
#define OVR_ASSERT(p) do { if (!(p)) { OVR_DEBUG_BREAK; } } while(0)
diff --git a/LibOVR/Src/Kernel/OVR_UTF8Util.cpp b/LibOVR/Src/Kernel/OVR_UTF8Util.cpp
index 9d337a7..f8aa697 100644
--- a/LibOVR/Src/Kernel/OVR_UTF8Util.cpp
+++ b/LibOVR/Src/Kernel/OVR_UTF8Util.cpp
@@ -7,16 +7,16 @@ Notes :
Notes : Much useful info at "UTF-8 and Unicode FAQ"
http://www.cl.cam.ac.uk/~mgk25/unicode.html
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Kernel/OVR_UTF8Util.h b/LibOVR/Src/Kernel/OVR_UTF8Util.h
index 9509629..6a596012 100644
--- a/LibOVR/Src/Kernel/OVR_UTF8Util.h
+++ b/LibOVR/Src/Kernel/OVR_UTF8Util.h
@@ -6,22 +6,23 @@ Content : UTF8 Unicode character encoding/decoding support
Created : September 19, 2012
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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_UTF8Util_h
diff --git a/LibOVR/Src/OVR_CAPI.cpp b/LibOVR/Src/OVR_CAPI.cpp
new file mode 100644
index 0000000..253bb3b
--- /dev/null
+++ b/LibOVR/Src/OVR_CAPI.cpp
@@ -0,0 +1,911 @@
+/************************************************************************************
+
+Filename : OVR_CAPI.cpp
+Content : Experimental simple C interface to the HMD - version 1.
+Created : November 30, 2013
+Authors : Michael Antonov
+
+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 "OVR_CAPI.h"
+#include "Kernel/OVR_Timer.h"
+#include "Kernel/OVR_Math.h"
+#include "Kernel/OVR_System.h"
+#include "OVR_Stereo.h"
+#include "OVR_Profile.h"
+
+#include "CAPI/CAPI_GlobalState.h"
+#include "CAPI/CAPI_HMDState.h"
+#include "CAPI/CAPI_FrameTimeManager.h"
+
+
+using namespace OVR;
+using namespace OVR::Util::Render;
+
+//-------------------------------------------------------------------------------------
+// Math
+namespace OVR {
+
+
+// ***** FovPort
+
+// C-interop support: FovPort <-> ovrFovPort
+FovPort::FovPort(const ovrFovPort &src)
+ : UpTan(src.UpTan), DownTan(src.DownTan), LeftTan(src.LeftTan), RightTan(src.RightTan)
+{ }
+
+FovPort::operator const ovrFovPort () const
+{
+ ovrFovPort result;
+ result.LeftTan = LeftTan;
+ result.RightTan = RightTan;
+ result.UpTan = UpTan;
+ result.DownTan = DownTan;
+ return result;
+}
+
+// Converts Fov Tan angle units to [-1,1] render target NDC space
+Vector2f FovPort::TanAngleToRendertargetNDC(Vector2f const &tanEyeAngle)
+{
+ ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(*this);
+ return tanEyeAngle * eyeToSourceNDC.Scale + eyeToSourceNDC.Offset;
+}
+
+
+// ***** SensorState
+
+SensorState::SensorState(const ovrSensorState& s)
+{
+ Predicted = s.Predicted;
+ Recorded = s.Recorded;
+ Temperature = s.Temperature;
+ StatusFlags = s.StatusFlags;
+}
+
+SensorState::operator const ovrSensorState() const
+{
+ ovrSensorState result;
+ result.Predicted = Predicted;
+ result.Recorded = Recorded;
+ result.Temperature = Temperature;
+ result.StatusFlags = StatusFlags;
+ return result;
+}
+
+
+} // namespace OVR
+
+//-------------------------------------------------------------------------------------
+
+using namespace OVR::CAPI;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+// Used to generate projection from ovrEyeDesc::Fov
+OVR_EXPORT ovrMatrix4f ovrMatrix4f_Projection(ovrFovPort fov, float znear, float zfar, ovrBool rightHanded)
+{
+ return CreateProjection(rightHanded ? true : false, fov, znear, zfar);
+}
+
+
+OVR_EXPORT ovrMatrix4f ovrMatrix4f_OrthoSubProjection(ovrMatrix4f projection, ovrVector2f orthoScale,
+ float orthoDistance, float eyeViewAdjustX)
+{
+
+ float orthoHorizontalOffset = eyeViewAdjustX / orthoDistance;
+
+ // Current projection maps real-world vector (x,y,1) to the RT.
+ // We want to find the projection that maps the range [-FovPixels/2,FovPixels/2] to
+ // the physical [-orthoHalfFov,orthoHalfFov]
+ // Note moving the offset from M[0][2]+M[1][2] to M[0][3]+M[1][3] - this means
+ // we don't have to feed in Z=1 all the time.
+ // The horizontal offset math is a little hinky because the destination is
+ // actually [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset]
+ // So we need to first map [-FovPixels/2,FovPixels/2] to
+ // [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset]:
+ // x1 = x0 * orthoHalfFov/(FovPixels/2) + orthoHorizontalOffset;
+ // = x0 * 2*orthoHalfFov/FovPixels + orthoHorizontalOffset;
+ // But then we need the sam mapping as the existing projection matrix, i.e.
+ // x2 = x1 * Projection.M[0][0] + Projection.M[0][2];
+ // = x0 * (2*orthoHalfFov/FovPixels + orthoHorizontalOffset) * Projection.M[0][0] + Projection.M[0][2];
+ // = x0 * Projection.M[0][0]*2*orthoHalfFov/FovPixels +
+ // orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2];
+ // So in the new projection matrix we need to scale by Projection.M[0][0]*2*orthoHalfFov/FovPixels and
+ // offset by orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2].
+
+ Matrix4f ortho;
+ ortho.M[0][0] = projection.M[0][0] * orthoScale.x;
+ ortho.M[0][1] = 0.0f;
+ ortho.M[0][2] = 0.0f;
+ ortho.M[0][3] = -projection.M[0][2] + ( orthoHorizontalOffset * projection.M[0][0] );
+
+ ortho.M[1][0] = 0.0f;
+ ortho.M[1][1] = -projection.M[1][1] * orthoScale.y; // Note sign flip (text rendering uses Y=down).
+ ortho.M[1][2] = 0.0f;
+ ortho.M[1][3] = -projection.M[1][2];
+
+ /*
+ if ( fabsf ( zNear - zFar ) < 0.001f )
+ {
+ ortho.M[2][0] = 0.0f;
+ ortho.M[2][1] = 0.0f;
+ ortho.M[2][2] = 0.0f;
+ ortho.M[2][3] = zFar;
+ }
+ else
+ {
+ ortho.M[2][0] = 0.0f;
+ ortho.M[2][1] = 0.0f;
+ ortho.M[2][2] = zFar / (zNear - zFar);
+ ortho.M[2][3] = (zFar * zNear) / (zNear - zFar);
+ }
+ */
+
+ // MA: Undo effect of sign
+ ortho.M[2][0] = 0.0f;
+ ortho.M[2][1] = 0.0f;
+ //ortho.M[2][2] = projection.M[2][2] * projection.M[3][2] * -1.0f; // reverse right-handedness
+ ortho.M[2][2] = 0.0f;
+ ortho.M[2][3] = 0.0f;
+ //projection.M[2][3];
+
+ // No perspective correction for ortho.
+ ortho.M[3][0] = 0.0f;
+ ortho.M[3][1] = 0.0f;
+ ortho.M[3][2] = 0.0f;
+ ortho.M[3][3] = 1.0f;
+
+ return ortho;
+}
+
+
+OVR_EXPORT double ovr_GetTimeInSeconds()
+{
+ return Timer::GetSeconds();
+}
+
+// Waits until the specified absolute time.
+OVR_EXPORT double ovr_WaitTillTime(double absTime)
+{
+ volatile int i;
+ double initialTime = ovr_GetTimeInSeconds();
+ double newTime = initialTime;
+
+ while(newTime < absTime)
+ {
+ for (int j = 0; j < 50; j++)
+ i = 0;
+ newTime = ovr_GetTimeInSeconds();
+ }
+
+ // How long we waited
+ return newTime - initialTime;
+}
+
+//-------------------------------------------------------------------------------------
+
+// 1. Init/shutdown.
+
+static ovrBool CAPI_SystemInitCalled = FALSE;
+
+OVR_EXPORT ovrBool ovr_Initialize()
+{
+ if (OVR::CAPI::GlobalState::pInstance)
+ return TRUE;
+
+ // 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;
+ }
+
+ // Constructor detects devices
+ GlobalState::pInstance = new GlobalState;
+ return TRUE;
+}
+
+OVR_EXPORT void ovr_Shutdown()
+{
+ if (!GlobalState::pInstance)
+ return;
+
+ delete GlobalState::pInstance;
+ GlobalState::pInstance = 0;
+
+ // We should clean up the system to be complete
+ if (CAPI_SystemInitCalled)
+ {
+ OVR::System::Destroy();
+ CAPI_SystemInitCalled = FALSE;
+ }
+ return;
+}
+
+
+// There is a thread safety issue with ovrHmd_Detect in that multiple calls from different
+// threads can corrupt the global array state. This would lead to two problems:
+// a) Create(index) enumerator may miss or overshoot items. Probably not a big deal
+// as game logic can easily be written to only do Detect(s)/Creates in one place.
+// The alternative would be to return list handle.
+// b) TBD: Un-mutexed Detect access from two threads could lead to crash. We should
+// probably check this.
+//
+
+OVR_EXPORT int ovrHmd_Detect()
+{
+ if (!GlobalState::pInstance)
+ return 0;
+ return GlobalState::pInstance->EnumerateDevices();
+}
+
+
+// ovrHmd_Create us explicitly separated from StartSensor and Configure to allow creation of
+// a relatively light-weight handle that would reference the device going forward and would
+// survive future ovrHmd_Detect calls. That is once ovrHMD is returned, index is no longer
+// necessary and can be changed by a ovrHmd_Detect call.
+
+OVR_EXPORT ovrHmd ovrHmd_Create(int index)
+{
+ if (!GlobalState::pInstance)
+ return 0;
+ Ptr<HMDDevice> device = *GlobalState::pInstance->CreateDevice(index);
+ if (!device)
+ return 0;
+
+ HMDState* hmds = new HMDState(device);
+ if (!hmds)
+ return 0;
+
+ return hmds;
+}
+
+OVR_EXPORT ovrHmd ovrHmd_CreateDebug(ovrHmdType type)
+{
+ if (!GlobalState::pInstance)
+ return 0;
+
+ HMDState* hmds = new HMDState(type);
+ return hmds;
+}
+
+OVR_EXPORT void ovrHmd_Destroy(ovrHmd hmd)
+{
+ if (!hmd)
+ return;
+ // TBD: Any extra shutdown?
+ HMDState* hmds = (HMDState*)hmd;
+
+ { // Thread checker in its own scope, to avoid access after 'delete'.
+ // Essentially just checks that no other RenderAPI function is executing.
+ ThreadChecker::Scope checkScope(&hmds->RenderAPIThreadChecker, "ovrHmd_Destroy");
+ }
+
+ delete (HMDState*)hmd;
+}
+
+
+OVR_EXPORT const char* ovrHmd_GetLastError(ovrHmd hmd)
+{
+ using namespace OVR;
+ if (!hmd)
+ {
+ if (!GlobalState::pInstance)
+ return "LibOVR not initialized.";
+ return GlobalState::pInstance->GetLastError();
+ }
+ HMDState* p = (HMDState*)hmd;
+ return p->GetLastError();
+}
+
+
+//-------------------------------------------------------------------------------------
+// *** Sensor
+
+// Sensor APIs are separated from Create & Configure for several reasons:
+// - They need custom parameters that control allocation of heavy resources
+// such as Vision tracking, which you don't want to create unless necessary.
+// - A game may want to switch some sensor settings based on user input,
+// or at lease enable/disable features such as Vision for debugging.
+// - The same or syntactically similar sensor interface is likely to be used if we
+// introduce controllers.
+//
+// - Sensor interface functions are all Thread-safe, unlike the frame/render API
+// functions that have different rules (all frame access functions
+// must be on render thread)
+
+OVR_EXPORT ovrBool ovrHmd_StartSensor(ovrHmd hmd, unsigned int supportedCaps, unsigned int requiredCaps)
+{
+ HMDState* p = (HMDState*)hmd;
+ // TBD: Decide if we null-check arguments.
+ return p->StartSensor(supportedCaps, requiredCaps);
+}
+
+OVR_EXPORT void ovrHmd_StopSensor(ovrHmd hmd)
+{
+ HMDState* p = (HMDState*)hmd;
+ p->StopSensor();
+}
+
+OVR_EXPORT void ovrHmd_ResetSensor(ovrHmd hmd)
+{
+ HMDState* p = (HMDState*)hmd;
+ p->ResetSensor();
+}
+
+OVR_EXPORT ovrSensorState ovrHmd_GetSensorState(ovrHmd hmd, double absTime)
+{
+ HMDState* p = (HMDState*)hmd;
+ return p->PredictedSensorState(absTime);
+}
+
+// Returns information about a sensor. Only valid after SensorStart.
+OVR_EXPORT ovrBool ovrHmd_GetSensorDesc(ovrHmd hmd, ovrSensorDesc* descOut)
+{
+ HMDState* p = (HMDState*)hmd;
+ return p->GetSensorDesc(descOut) ? TRUE : FALSE;
+}
+
+
+
+//-------------------------------------------------------------------------------------
+// *** General Setup
+
+
+OVR_EXPORT void ovrHmd_GetDesc(ovrHmd hmd, ovrHmdDesc* desc)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ *desc = hmds->RenderState.GetDesc();
+ desc->Handle = hmd;
+}
+
+// Per HMD -> calculateIdealPixelSize
+OVR_EXPORT ovrSizei ovrHmd_GetFovTextureSize(ovrHmd hmd, ovrEyeType eye, ovrFovPort fov,
+ float pixelsPerDisplayPixel)
+{
+ if (!hmd) return Sizei(0);
+
+ HMDState* hmds = (HMDState*)hmd;
+ return hmds->RenderState.GetFOVTextureSize(eye, fov, pixelsPerDisplayPixel);
+}
+
+
+//-------------------------------------------------------------------------------------
+
+
+OVR_EXPORT
+ovrBool ovrHmd_ConfigureRendering( ovrHmd hmd,
+ const ovrRenderAPIConfig* apiConfig,
+ unsigned int hmdCaps,
+ unsigned int distortionCaps,
+ const ovrEyeDesc eyeDescIn[2],
+ ovrEyeRenderDesc eyeRenderDescOut[2] )
+{
+ if (!hmd) return FALSE;
+ return ((HMDState*)hmd)->ConfigureRendering(eyeRenderDescOut, eyeDescIn,
+ apiConfig, hmdCaps, distortionCaps);
+}
+
+
+
+// TBD: MA - Deprecated, need alternative
+void ovrHmd_SetVsync(ovrHmd hmd, ovrBool vsync)
+{
+ if (!hmd) return;
+
+ return ((HMDState*)hmd)->TimeManager.SetVsync(vsync? true : false);
+}
+
+
+OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrame(ovrHmd hmd, unsigned int frameIndex)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (!hmds)
+ {
+ ovrFrameTiming f;
+ memset(&f, 0, sizeof(f));
+ return f;
+ }
+
+ // Check: Proper configure and threading state for the call.
+ hmds->checkRenderingConfigured("ovrHmd_BeginFrame");
+ OVR_ASSERT_LOG(hmds->BeginFrameCalled == false, ("ovrHmd_BeginFrame called multiple times."));
+ ThreadChecker::Scope checkScope(&hmds->RenderAPIThreadChecker, "ovrHmd_BeginFrame");
+
+ hmds->BeginFrameCalled = true;
+ hmds->BeginFrameThreadId = OVR::GetCurrentThreadId();
+
+ return ovrHmd_BeginFrameTiming(hmd, frameIndex);
+}
+
+
+// Renders textures to frame buffer
+OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmd)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (!hmds) return;
+
+ // Debug state checks: Must be in BeginFrame, on the same thread.
+ hmds->checkBeginFrameScope("ovrHmd_EndFrame");
+ ThreadChecker::Scope checkScope(&hmds->RenderAPIThreadChecker, "ovrHmd_EndFrame");
+
+ // TBD: Move directly into renderer
+ bool dk2LatencyTest = (hmds->HMDInfo.HmdType == HmdType_DK2) &&
+ (hmds->SensorCaps & ovrHmdCap_LatencyTest);
+ if (dk2LatencyTest)
+ {
+ hmds->LatencyTest2DrawColor[0] = hmds->TimeManager.GetFrameLatencyTestDrawColor();
+ hmds->LatencyTest2DrawColor[1] = hmds->LatencyTest2DrawColor[0];
+ hmds->LatencyTest2DrawColor[2] = hmds->LatencyTest2DrawColor[0];
+ }
+
+ if (hmds->pRenderer)
+ {
+ 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
+ );
+ }
+ // Call after present
+ ovrHmd_EndFrameTiming(hmd);
+
+ if (dk2LatencyTest)
+ {
+ hmds->TimeManager.UpdateFrameLatencyTrackingAfterEndFrame(
+ hmds->LatencyTest2DrawColor[0], hmds->LatencyUtil2.GetLocklessState());
+ }
+
+ // Out of BeginFrame
+ hmds->BeginFrameThreadId = 0;
+ hmds->BeginFrameCalled = false;
+}
+
+
+OVR_EXPORT ovrPosef ovrHmd_BeginEyeRender(ovrHmd hmd, ovrEyeType eye)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (!hmds) return ovrPosef();
+ return hmds->BeginEyeRender(eye);
+}
+
+OVR_EXPORT void ovrHmd_EndEyeRender(ovrHmd hmd, ovrEyeType eye,
+ ovrPosef renderPose, ovrTexture* eyeTexture)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (!hmds) return;
+ hmds->EndEyeRender(eye, renderPose, eyeTexture);
+}
+
+
+//-------------------------------------------------------------------------------------
+// ***** Frame Timing logic
+
+
+OVR_EXPORT ovrFrameTiming ovrHmd_GetFrameTiming(ovrHmd hmd, unsigned int frameIndex)
+{
+ ovrFrameTiming f;
+ memset(&f, 0, sizeof(f));
+
+ HMDState* hmds = (HMDState*)hmd;
+ if (hmds)
+ {
+ FrameTimeManager::Timing frameTiming = hmds->TimeManager.GetFrameTiming(frameIndex);
+
+ f.ThisFrameSeconds = frameTiming.ThisFrameTime;
+ f.NextFrameSeconds = frameTiming.NextFrameTime;
+ f.TimewarpPointSeconds = frameTiming.TimewarpPointTime;
+ f.ScanoutMidpointSeconds= frameTiming.MidpointTime;
+ f.EyeScanoutSeconds[0] = frameTiming.EyeRenderTimes[0];
+ f.EyeScanoutSeconds[1] = frameTiming.EyeRenderTimes[1];
+
+ // Compute DeltaSeconds.
+ f.DeltaSeconds = (hmds->LastGetFrameTimeSeconds == 0.0f) ? 0.0f :
+ (float) (f.ThisFrameSeconds - hmds->LastFrameTimeSeconds);
+ hmds->LastGetFrameTimeSeconds = f.ThisFrameSeconds;
+ if (f.DeltaSeconds > 1.0f)
+ f.DeltaSeconds = 1.0f;
+ }
+
+ return f;
+}
+
+OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrameTiming(ovrHmd hmd, unsigned int frameIndex)
+{
+ ovrFrameTiming f;
+ memset(&f, 0, sizeof(f));
+
+ HMDState* hmds = (HMDState*)hmd;
+ if (!hmds) return f;
+
+ // Check: Proper state for the call.
+ OVR_ASSERT_LOG(hmds->BeginFrameTimingCalled == false,
+ ("ovrHmd_BeginFrameTiming called multiple times."));
+ hmds->BeginFrameTimingCalled = true;
+
+ double thisFrameTime = hmds->TimeManager.BeginFrame(frameIndex);
+
+ const FrameTimeManager::Timing &frameTiming = hmds->TimeManager.GetFrameTiming();
+
+ f.ThisFrameSeconds = thisFrameTime;
+ f.NextFrameSeconds = frameTiming.NextFrameTime;
+ f.TimewarpPointSeconds = frameTiming.TimewarpPointTime;
+ f.ScanoutMidpointSeconds= frameTiming.MidpointTime;
+ f.EyeScanoutSeconds[0] = frameTiming.EyeRenderTimes[0];
+ f.EyeScanoutSeconds[1] = frameTiming.EyeRenderTimes[1];
+
+ // Compute DeltaSeconds.
+ f.DeltaSeconds = (hmds->LastFrameTimeSeconds == 0.0f) ? 0.0f :
+ (float) (thisFrameTime - hmds->LastFrameTimeSeconds);
+ hmds->LastFrameTimeSeconds = thisFrameTime;
+ if (f.DeltaSeconds > 1.0f)
+ f.DeltaSeconds = 1.0f;
+
+ return f;
+}
+
+
+OVR_EXPORT void ovrHmd_EndFrameTiming(ovrHmd hmd)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (!hmds) return;
+
+ // Debug state checks: Must be in BeginFrameTiming, on the same thread.
+ hmds->checkBeginFrameTimingScope("ovrHmd_EndTiming");
+ // MA TBD: Correct chek or not?
+ // ThreadChecker::Scope checkScope(&hmds->RenderAPIThreadChecker, "ovrHmd_EndFrame");
+
+ hmds->TimeManager.EndFrame();
+ hmds->BeginFrameTimingCalled = false;
+}
+
+
+OVR_EXPORT void ovrHmd_ResetFrameTiming(ovrHmd hmd, unsigned int frameIndex, bool vsync)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (!hmds) return;
+
+ hmds->TimeManager.ResetFrameTiming(frameIndex, vsync, false,
+ hmds->RenderingConfigured);
+ hmds->LastFrameTimeSeconds = 0.0;
+ hmds->LastGetFrameTimeSeconds = 0.0;
+}
+
+
+
+OVR_EXPORT ovrPosef ovrHmd_GetEyePose(ovrHmd hmd, ovrEyeType eye)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (!hmds) return ovrPosef();
+
+ hmds->checkBeginFrameTimingScope("ovrHmd_GetEyePose");
+ return hmds->TimeManager.GetEyePredictionPose(hmd, eye);
+}
+
+
+OVR_EXPORT void ovrHmd_GetEyeTimewarpMatrices(ovrHmd hmd, ovrEyeType eye,
+ ovrPosef renderPose, ovrMatrix4f twmOut[2])
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (!hmd)
+ return;
+
+ // Debug checks: BeginFrame was called, on the same thread.
+ hmds->checkBeginFrameTimingScope("ovrHmd_GetTimewarpEyeMatrices");
+
+ hmds->TimeManager.GetTimewarpMatrices(hmd, eye, renderPose, twmOut);
+
+ /*
+ // MA: Took this out because new latency test approach just sames
+ // the sample times in FrameTimeManager.
+ // TODO: if no timewarp, then test latency in begin eye render
+ if (eye == 0)
+ {
+ hmds->ProcessLatencyTest2(hmds->LatencyTest2DrawColor, -1.0f);
+ }
+ */
+}
+
+
+
+OVR_EXPORT ovrEyeRenderDesc ovrHmd_GetRenderDesc(ovrHmd hmd, const ovrEyeDesc eyeDesc)
+{
+ ovrEyeRenderDesc erd;
+
+ HMDState* hmds = (HMDState*)hmd;
+ if (!hmds)
+ {
+ memset(&erd, 0, sizeof(erd));
+ return erd;
+ }
+
+ return hmds->RenderState.calcRenderDesc(eyeDesc);
+}
+
+
+
+#define OVR_OFFSET_OF(s, field) ((size_t)&((s*)0)->field)
+
+
+
+// Generate distortion mesh per eye.
+// scaleAndOffsetOut - this will be needed for shader
+OVR_EXPORT ovrBool ovrHmd_CreateDistortionMesh( ovrHmd hmd, ovrEyeDesc eyeDesc,
+ unsigned int distortionCaps,
+ ovrVector2f uvScaleOffsetOut[2],
+ ovrDistortionMesh *meshData )
+{
+ if (!meshData)
+ return FALSE;
+ HMDState* hmds = (HMDState*)hmd;
+
+ // Not used now, but Chromatic flag or others could possibly be checked for in the future.
+ OVR_UNUSED1(distortionCaps);
+
+ // 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));
+ OVR_COMPILER_ASSERT(OVR_OFFSET_OF(DistortionMeshVertexData, TimewarpLerp) == OVR_OFFSET_OF(ovrDistortionVertex, TimeWarpFactor));
+ OVR_COMPILER_ASSERT(OVR_OFFSET_OF(DistortionMeshVertexData, Shade) == OVR_OFFSET_OF(ovrDistortionVertex, VignetteFactor));
+ 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));
+
+
+ // *** Calculate a part of "StereoParams" needed for mesh generation
+
+ // Note that mesh distortion generation is invariant of RenderTarget UVs, allowing
+ // render target size and location to be changed after the fact dynamically.
+ // 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;
+
+ const DistortionRenderDesc& distortion = hmds->RenderState.Distortion[eyeDesc.Eye];
+
+ // 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;
+
+ int triangleCount = 0;
+ int vertexCount = 0;
+
+ DistortionMeshCreate((DistortionMeshVertexData**)&meshData->pVertexData, (UInt16**)&meshData->pIndexData,
+ &vertexCount, &triangleCount,
+ (stereoEye == StereoEye_Right),
+ hmdri, distortion, eyeToSourceNDC);
+
+ if (meshData->pVertexData)
+ {
+ // Convert to index
+ meshData->IndexCount = triangleCount * 3;
+ meshData->VertexCount = vertexCount;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+// Frees distortion mesh allocated by ovrHmd_GenerateDistortionMesh. meshData elements
+// are set to null and 0s after the call.
+OVR_EXPORT void ovrHmd_DestroyDistortionMesh(ovrDistortionMesh* meshData)
+{
+ if (meshData->pVertexData)
+ DistortionMeshDestroy((DistortionMeshVertexData*)meshData->pVertexData,
+ meshData->pIndexData);
+ meshData->pVertexData = 0;
+ meshData->pIndexData = 0;
+ meshData->VertexCount = 0;
+ meshData->IndexCount = 0;
+}
+
+
+
+// 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,
+ 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);
+ // Find the mapping from TanAngle space to textureUV space.
+ ScaleAndOffset2D eyeToSourceUV = CreateUVScaleAndOffsetfromNDCScaleandOffset(
+ eyeToSourceNDC,
+ eyeDesc.RenderViewport, eyeDesc.TextureSize );
+
+ uvScaleOffsetOut[0] = eyeToSourceUV.Scale;
+ uvScaleOffsetOut[1] = eyeToSourceUV.Offset;
+}
+
+
+//-------------------------------------------------------------------------------------
+// ***** Latency Test interface
+
+OVR_EXPORT ovrBool ovrHmd_GetLatencyTestDrawColor(ovrHmd hmd, unsigned char rgbColorOut[3])
+{
+ HMDState* p = (HMDState*)hmd;
+ rgbColorOut[0] = p->LatencyTestDrawColor[0];
+ rgbColorOut[1] = p->LatencyTestDrawColor[1];
+ rgbColorOut[2] = p->LatencyTestDrawColor[2];
+ return p->LatencyTestActive;
+}
+
+OVR_EXPORT const char* ovrHmd_GetLatencyTestResult(ovrHmd hmd)
+{
+ HMDState* p = (HMDState*)hmd;
+ return p->LatencyUtil.GetResultsString();
+}
+
+OVR_EXPORT double ovrHmd_GetMeasuredLatencyTest2(ovrHmd hmd)
+{
+ HMDState* p = (HMDState*)hmd;
+
+ // MA Test
+ float latencies[3];
+ p->TimeManager.GetLatencyTimings(latencies);
+ return latencies[2];
+ // return p->LatencyUtil2.GetMeasuredLatency();
+}
+
+
+// -----------------------------------------------------------------------------------
+// ***** Property Access
+
+OVR_EXPORT float ovrHmd_GetFloat(ovrHmd hmd, const char* propertyName, float defaultVal)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (hmds)
+ {
+ return hmds->getFloatValue(propertyName, defaultVal);
+ }
+
+ return defaultVal;
+}
+
+OVR_EXPORT ovrBool ovrHmd_SetFloat(ovrHmd hmd, const char* propertyName, float value)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (hmds)
+ {
+ return hmds->setFloatValue(propertyName, value);
+ }
+ return false;
+}
+
+
+
+OVR_EXPORT unsigned int ovrHmd_GetFloatArray(ovrHmd hmd, const char* propertyName,
+ float values[], unsigned int arraySize)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (hmds)
+ {
+ return hmds->getFloatArray(propertyName, values, arraySize);
+ }
+
+ return 0;
+}
+
+
+// Modify float[] property; false if property doesn't exist or is readonly.
+OVR_EXPORT ovrBool ovrHmd_SetFloatArray(ovrHmd hmd, const char* propertyName,
+ float values[], unsigned int arraySize)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (hmds)
+ {
+ return hmds->setFloatArray(propertyName, values, arraySize);
+ }
+
+ return 0;
+}
+
+OVR_EXPORT const char* ovrHmd_GetString(ovrHmd hmd, const char* propertyName,
+ const char* defaultVal)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (hmds)
+ {
+ return hmds->getString(propertyName, defaultVal);
+ }
+
+ return defaultVal;
+}
+
+/* Not needed yet.
+
+// Get array of strings, i.e. const char* [] property.
+// Returns the number of elements filled in, 0 if property doesn't exist.
+// Maximum of arraySize elements will be written.
+// String memory is guaranteed to exist until next call to GetString or GetStringArray, or HMD is destroyed.
+OVR_EXPORT
+unsigned int ovrHmd_GetStringArray(ovrHmd hmd, const char* propertyName,
+ const char* values[], unsigned int arraySize)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (hmds && hmds->pHMD && arraySize)
+ {
+ Profile* p = hmds->pHMD->GetProfile();
+
+ hmds->LastGetStringValue[0] = 0;
+ if (p && p->GetValue(propertyName, hmds->LastGetStringValue, sizeof(hmds->LastGetStringValue)))
+ {
+ values[0] = hmds->LastGetStringValue;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+*/
+
+// Returns array size of a property, 0 if property doesn't exist.
+// Can be used to check existence of a property.
+OVR_EXPORT unsigned int ovrHmd_GetArraySize(ovrHmd hmd, const char* propertyName)
+{
+ HMDState* hmds = (HMDState*)hmd;
+ if (hmds && hmds->pHMD)
+ {
+ // For now, just access the profile.
+ Profile* p = hmds->pHMD->GetProfile();
+
+ if (p)
+ return p->GetNumValues(propertyName);
+ }
+ return 0;
+}
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+//-------------------------------------------------------------------------------------
+// ****** Special access for VRConfig
+
+// Return the sensor fusion object for the purposes of magnetometer calibration. The
+// function is private and is only exposed through VRConfig header declarations
+OVR::SensorFusion* ovrHmd_GetSensorFusion(ovrHmd hmd)
+{
+ HMDState* p = (HMDState*)hmd;
+ return &p->SFusion;
+}
+
+
diff --git a/LibOVR/Src/OVR_CAPI.h b/LibOVR/Src/OVR_CAPI.h
new file mode 100644
index 0000000..d5cce01
--- /dev/null
+++ b/LibOVR/Src/OVR_CAPI.h
@@ -0,0 +1,762 @@
+/************************************************************************************
+
+Filename : OVR_CAPI.h
+Content : C Interface to Oculus sensors and rendering.
+Created : November 23, 2013
+Authors : Michael Antonov
+
+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_CAPI_h
+#define OVR_CAPI_h
+
+#include <stdint.h>
+
+typedef char ovrBool;
+
+//-----------------------------------------------------------------------------------
+// ***** OVR_EXPORT definition
+
+#if !defined(OVR_EXPORT)
+ #if defined(WIN32)
+ #define OVR_EXPORT __declspec(dllexport)
+ #else
+ #define OVR_EXPORT
+ #endif
+#endif
+
+//-----------------------------------------------------------------------------------
+// ***** Simple Math Structures
+
+// 2D integer
+typedef struct ovrVector2i_
+{
+ int x, y;
+} ovrVector2i;
+typedef struct ovrSizei_
+{
+ int w, h;
+} ovrSizei;
+typedef struct ovrRecti_
+{
+ ovrVector2i Pos;
+ ovrSizei Size;
+} ovrRecti;
+
+// 3D
+typedef struct ovrQuatf_
+{
+ float x, y, z, w;
+} ovrQuatf;
+typedef struct ovrVector2f_
+{
+ float x, y;
+} ovrVector2f;
+typedef struct ovrVector3f_
+{
+ float x, y, z;
+} ovrVector3f;
+typedef struct ovrMatrix4f_
+{
+ float M[4][4];
+} ovrMatrix4f;
+// Position and orientation together.
+typedef struct ovrPosef_
+{
+ ovrQuatf Orientation;
+ ovrVector3f Position;
+} ovrPosef;
+
+// Full pose (rigid body) configuration with first and second derivatives.
+typedef struct ovrPoseStatef_
+{
+ ovrPosef Pose;
+ ovrVector3f AngularVelocity;
+ ovrVector3f LinearVelocity;
+ ovrVector3f AngularAcceleration;
+ ovrVector3f LinearAcceleration;
+ double TimeInSeconds; // Absolute time of this state sample.
+} ovrPoseStatef;
+
+// Field Of View (FOV) in tangent of the angle units.
+// As an example, for a standard 90 degree vertical FOV, we would
+// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }.
+typedef struct ovrFovPort_
+{
+ float UpTan;
+ float DownTan;
+ float LeftTan;
+ float RightTan;
+} ovrFovPort;
+
+
+//-----------------------------------------------------------------------------------
+// ***** HMD Types
+
+// Enumerates all HMD types that we support.
+typedef enum
+{
+ ovrHmd_None = 0,
+ ovrHmd_DK1 = 3,
+ ovrHmd_DKHD = 4,
+ ovrHmd_CrystalCoveProto = 5,
+ ovrHmd_DK2 = 6,
+ ovrHmd_Other // Some HMD other then the one in the enumeration.
+} ovrHmdType;
+
+// HMD capability bits reported by device.
+typedef enum
+{
+ 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.
+ ovrHmdCap_LowPersistence = 0x0080, // Supports low persistence mode.
+ ovrHmdCap_LatencyTest = 0x0100, // Supports pixel reading for continous latency testing.
+ ovrHmdCap_DynamicPrediction = 0x0200, // Adjust prediction dynamically based on DK2 Latency.
+
+ // Support rendering without VSync for debugging
+ ovrHmdCap_NoVSync = 0x1000
+} ovrHmdCapBits;
+
+// Describes distortion rendering parameters for ovrHmd_ConfigureRenderAPI or for
+// ovrHmd_GenerateDistortionMesh.
+typedef enum
+{
+ ovrDistortion_Chromatic = 0x01,
+ ovrDistortion_TimeWarp = 0x02,
+ ovrDistortion_Vignette = 0x08
+} ovrDistortionCaps;
+
+
+// Specifies which eye is being used for rendering.
+// This type explicitly does not include a third "NoStereo" option, as such is
+// not required for an HMD-centered API.
+typedef enum
+{
+ ovrEye_Left = 0,
+ ovrEye_Right = 1,
+ ovrEye_Count = 2
+} ovrEyeType;
+
+
+// Handle to HMD; returned by ovrHmd_Create.
+typedef struct ovrHmdStruct* ovrHmd;
+
+// This is a complete descriptor of the HMD.
+typedef struct ovrHmdDesc_
+{
+ ovrHmd Handle; // Handle of this HMD.
+ ovrHmdType Type;
+
+ // Name string describing the product: "Oculus Rift DK1", etc.
+ const char* ProductName;
+ const char* Manufacturer;
+
+ // Capability bits described by ovrHmdCapBits.
+ unsigned int Caps;
+ unsigned int DistortionCaps;
+
+ // Resolution of the entire HMD screen (for both eyes) in pixels.
+ ovrSizei Resolution;
+ // Where monitor window should be on screen or (0,0).
+ ovrVector2i WindowsPos;
+
+ // These define the recommended and maximum optical FOVs for the HMD.
+ ovrFovPort DefaultEyeFov[ovrEye_Count];
+ ovrFovPort MaxEyeFov[ovrEye_Count];
+
+ // Preferred eye rendering order for best performance.
+ // Can help reduce latency on sideways-scanned screens.
+ ovrEyeType EyeRenderOrder[ovrEye_Count];
+
+ // Display that HMD should present on.
+ // TBD: It may be good to remove this information relying on WidowPos instead.
+ // Ultimately, we may need to come up with a more convenient alternative,
+ // such as a API-specific functions that return adapter, ot something that will
+ // work with our monitor driver.
+
+ // Windows: "\\\\.\\DISPLAY3", etc. Can be used in EnumDisplaySettings/CreateDC.
+ const char* DisplayDeviceName;
+ // MacOS
+ long DisplayId;
+} ovrHmdDesc;
+
+// Describes the type of positional tracking being done.
+/*
+typedef enum
+{
+ ovrPose_None,
+ ovrPose_HeadModel,
+ ovrPose_Positional
+} ovrPoseType;
+*/
+
+
+// Bit flags describing the current status of sensor tracking.
+typedef enum
+{
+ ovrStatus_OrientationTracked = 0x0001, // Orientation is currently tracked (connected and in use).
+ ovrStatus_PositionTracked = 0x0002, // Position is currently tracked (FALSE if out of range).
+ ovrStatus_PositionConnected = 0x0020, // Position tracking HW is connected.
+ ovrStatus_HmdConnected = 0x0080 // HMD Display is available & connected.
+} ovrStatusBits;
+
+
+// State of the sensor at given a absolute time.
+typedef struct ovrSensorState_
+{
+ // Predicted pose configuration at requested absolute time.
+ // One can determine the time difference between predicted and actual
+ // readings by comparing ovrPoseState.TimeInSeconds.
+ ovrPoseStatef Predicted;
+ // Actual recorded pose configuration based on the sensor sample at a
+ // moment closest to the requested time.
+ ovrPoseStatef Recorded;
+
+ // Sensor temperature reading, in degrees Celsius, as sample time.
+ float Temperature;
+ // Sensor status described by ovrStatusBits.
+ unsigned int StatusFlags;
+} ovrSensorState;
+
+// For now.
+// TBD: Decide if this becomes a part of HMDDesc
+typedef struct ovrSensorDesc_
+{
+ // HID Vendor and ProductId of the device.
+ short VendorId;
+ short ProductId;
+ // Sensor (and display) serial number.
+ char SerialNumber[24];
+} ovrSensorDesc;
+
+
+
+// Frame data reported by ovrHmd_BeginFrameTiming().
+typedef struct ovrFrameTiming_
+{
+ // The amount of time that has passed since the previous frame returned
+ // BeginFrameSeconds value, usable for movement scaling.
+ // This will be clamped to no more than 0.1 seconds to prevent
+ // excessive movement after pauses for loading or initialization.
+ float DeltaSeconds;
+
+ // It is generally expected that the following hold:
+ // ThisFrameSeconds < TimewarpPointSeconds < NextFrameSeconds <
+ // EyeScanoutSeconds[EyeOrder[0]] <= ScanoutMidpointSeconds <= EyeScanoutSeconds[EyeOrder[1]]
+
+ // Absolute time value of when rendering of this frame began or is expected to
+ // begin; generally equal to NextFrameSeconds of the previous frame. Can be used
+ // for animation timing.
+ double ThisFrameSeconds;
+ // Absolute point when IMU expects to be sampled for this frame.
+ double TimewarpPointSeconds;
+ // Absolute time when frame Present + GPU Flush will finish, and the next frame starts.
+ double NextFrameSeconds;
+
+ // Time when when half of the screen will be scanned out. Can be passes as a prediction
+ // value to ovrHmd_GetSensorState() go get general orientation.
+ double ScanoutMidpointSeconds;
+ // Timing points when each eye will be scanned out to display. Used for rendering each eye.
+ double EyeScanoutSeconds[2];
+
+} 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
+// (a) calling ovrHmd_GetRenderScaleAndOffset with game-rendered api,
+// or (b) passing different values in ovrTexture in case of SDK-rendered distortion.
+typedef struct ovrEyeDesc_
+{
+ 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.
+} ovrEyeRenderDesc;
+
+
+//-----------------------------------------------------------------------------------
+// ***** Platform-independent Rendering Configuration
+
+// These types are used to hide platform-specific details when passing
+// render device, OS and texture data to the APIs.
+//
+// The benefit of having these wrappers vs. platform-specific API functions is
+// that they allow game glue code to be portable. A typical example is an
+// engine that has multiple back ends, say GL and D3D. Portable code that calls
+// these back ends may also use LibOVR. To do this, back ends can be modified
+// to return portable types such as ovrTexture and ovrRenderAPIConfig.
+
+typedef enum
+{
+ ovrRenderAPI_None,
+ ovrRenderAPI_OpenGL,
+ ovrRenderAPI_Android_GLES, // May include extra native window pointers, etc.
+ ovrRenderAPI_D3D9,
+ ovrRenderAPI_D3D10,
+ ovrRenderAPI_D3D11,
+ ovrRenderAPI_Count
+} ovrRenderAPIType;
+
+// Platform-independent part of rendering API-configuration data.
+// It is a part of ovrRenderAPIConfig, passed to ovrHmd_Configure.
+typedef struct ovrRenderAPIConfigHeader_
+{
+ ovrRenderAPIType API;
+ ovrSizei RTSize;
+ int Multisample;
+} ovrRenderAPIConfigHeader;
+
+typedef struct ovrRenderAPIConfig_
+{
+ ovrRenderAPIConfigHeader Header;
+ uintptr_t PlatformData[8];
+} ovrRenderAPIConfig;
+
+// Platform-independent part of eye texture descriptor.
+// It is a part of ovrTexture, passed to ovrHmd_EndFrame.
+// - If RenderViewport is all zeros, will be used.
+typedef struct ovrTextureHeader_
+{
+ ovrRenderAPIType API;
+ ovrSizei TextureSize;
+ ovrRecti RenderViewport; // Pixel viewport in texture that holds eye image.
+} ovrTextureHeader;
+
+typedef struct ovrTexture_
+{
+ ovrTextureHeader Header;
+ uintptr_t PlatformData[8];
+} ovrTexture;
+
+
+// -----------------------------------------------------------------------------------
+// ***** API Interfaces
+
+// Basic steps to use the API:
+//
+// Setup:
+// 1. ovrInitialize();
+// 2. ovrHMD hmd = ovrHmd_Create(0); ovrHmd_GetDesc(hmd, &hmdDesc);
+// 3. Use hmdDesc and ovrHmd_GetFovTextureSize() to determine graphics configuration.
+// 4. Call ovrHmd_StartSensor() to configure and initialize tracking.
+// 5. Call ovrHmd_ConfigureRendering() to setup graphics for SDK rendering,
+// which is the preferred approach.
+// Please refer to "Game-Side Rendering" below if you prefer to do that instead.
+// 5. Allocate textures as needed.
+//
+// Game Loop:
+// 6. Call ovrHmd_BeginFrame() to get frame timing and orientation information.
+// 7. Render each eye in between ovrHmd_BeginEyeRender and ovrHmd_EndEyeRender calls,
+// providing the result texture to the API.
+// 8. Call ovrHmd_EndFrame() to render distorted textures to the back buffer
+// and present them on the Hmd.
+//
+// Shutdown:
+// 9. ovrHmd_Destroy(hmd)
+// 10. ovr_Shutdown()
+//
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Library init/shutdown, must be called around all other OVR code.
+// No other functions calls are allowed before ovr_Initialize succeeds or after ovr_Shutdown.
+OVR_EXPORT ovrBool ovr_Initialize();
+OVR_EXPORT void ovr_Shutdown();
+
+
+// Detects or re-detects HMDs and reports the total number detected.
+// Users can get information about each HMD by calling ovrHmd_Create with an index.
+OVR_EXPORT int ovrHmd_Detect();
+
+
+// Creates a handle to an HMD and optionally fills in data about it.
+// Index can [0 .. ovrHmd_Detect()-1]; index mappings can cange after each ovrHmd_Detect call.
+// If not null, returned handle must be freed with ovrHmd_Destroy.
+OVR_EXPORT ovrHmd ovrHmd_Create(int index);
+OVR_EXPORT void ovrHmd_Destroy(ovrHmd hmd);
+
+// Creates a "fake" HMD used for debugging only. This is not tied to specific hardware,
+// but may be used to debug some of the related rendering.
+OVR_EXPORT ovrHmd ovrHmd_CreateDebug(ovrHmdType type);
+
+
+// Returns last error for HMD state. Returns null for no error.
+// String is valid until next call or GetLastError or HMD is destroyed.
+// Pass null hmd to get global error (for create, etc).
+OVR_EXPORT const char* ovrHmd_GetLastError(ovrHmd hmd);
+
+
+//-------------------------------------------------------------------------------------
+// ***** 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);
+// Stops sensor sampling, shutting down internal resources.
+OVR_EXPORT void ovrHmd_StopSensor(ovrHmd hmd);
+// Resets sensor orientation.
+OVR_EXPORT void ovrHmd_ResetSensor(ovrHmd hmd);
+
+// Returns sensor state reading based on the specified absolute system time.
+// Pass absTime value of 0.0 to request the most recent sensor reading; in this case
+// both PredictedPose and SamplePose will have the same value.
+// ovrHmd_GetEyePredictedSensorState relies on this internally.
+// This may also be used for more refined timing of FrontBuffer rendering logic, etc.
+OVR_EXPORT ovrSensorState ovrHmd_GetSensorState(ovrHmd hmd, double absTime);
+
+// Returns information about a sensor.
+// Only valid after StartSensor.
+OVR_EXPORT ovrBool ovrHmd_GetSensorDesc(ovrHmd hmd, ovrSensorDesc* descOut);
+
+
+//-------------------------------------------------------------------------------------
+// ***** Graphics Setup
+
+// Fills in description about HMD; this is the same as filled in by ovrHmd_Create.
+OVR_EXPORT void ovrHmd_GetDesc(ovrHmd hmd, ovrHmdDesc* desc);
+
+// Calculates texture size recommended for rendering one eye within HMD, given FOV cone.
+// Higher FOV will generally require larger textures to maintain quality.
+// - pixelsPerDisplayPixel specifies that number of render target pixels per display
+// pixel at center of distortion; 1.0 is the default value. Lower values
+// can improve performance.
+OVR_EXPORT ovrSizei ovrHmd_GetFovTextureSize(ovrHmd hmd, ovrEyeType eye, ovrFovPort fov,
+ float pixelsPerDisplayPixel);
+
+
+
+//-------------------------------------------------------------------------------------
+// ***** Rendering API Thread Safety
+
+// All of rendering APIs, inclusing Configure and frame functions are *NOT
+// Thread Safe*. It is ok to use ConfigureRendering on one thread and handle
+// frames on another thread, but explicit synchronization must be done since
+// functions that depend on configured state are not reentrant.
+//
+// As an extra requirement, any of the following calls must be done on
+// the render thread, which is the same thread that calls ovrHmd_BeginFrame
+// or ovrHmd_BeginFrameTiming.
+// - ovrHmd_EndFrame
+// - ovrHmd_BeginEyeRender
+// - ovrHmd_EndEyeRender
+// - ovrHmd_GetFramePointTime
+// - ovrHmd_GetEyePose
+// - ovrHmd_GetEyeTimewarpMatrices
+
+
+//-------------------------------------------------------------------------------------
+// ***** SDK-Rendering Functions
+
+// These functions support rendering of distortion by the SDK through direct
+// access to the underlying rendering HW, such as D3D or GL.
+// This is the recommended approach, as it allows for better support or future
+// Oculus hardware and a range of low-level optimizations.
+
+
+// Configures rendering; fills in computed render parameters.
+// This function can be called multiple times to change rendering settings.
+// The users pass in two eye view descriptors that are used to
+// generate complete rendering information for each eye in eyeRenderDescOut[2].
+//
+// - apiConfig provides D3D/OpenGL specific parameters. Pass null
+// to shutdown rendering and release all resources.
+// - distortionCaps describe distortion settings that will be applied.
+//
+OVR_EXPORT ovrBool ovrHmd_ConfigureRendering( ovrHmd hmd,
+ const ovrRenderAPIConfig* apiConfig,
+ unsigned int hmdCaps,
+ unsigned int distortionCaps,
+ const ovrEyeDesc eyeDescIn[2],
+ ovrEyeRenderDesc eyeRenderDescOut[2] );
+
+
+// Begins a frame, returning timing and orientation information useful for simulation.
+// This should be called in the beginning of game rendering loop (on render thread).
+// This function relies on ovrHmd_BeginFrameTiming for some of its functionality.
+// Pass 0 for frame index if not using GetFrameTiming.
+OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrame(ovrHmd hmd, unsigned int frameIndex);
+
+// Ends frame, rendering textures to frame buffer. This may perform distortion and scaling
+// internally, assuming is it not delegated to another thread.
+// Must be called on the same thread as BeginFrame. Calls ovrHmd_BeginEndTiming internally.
+// *** This Function will to Present/SwapBuffers and potentially wait for GPU Sync ***.
+OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmd);
+
+
+// Marks beginning of eye rendering. Must be called on the same thread as BeginFrame.
+// This function uses ovrHmd_GetEyePose to predict sensor state that should be
+// used rendering the specified eye.
+// This combines current absolute time with prediction that is appropriate for this HMD.
+// It is ok to call ovrHmd_BeginEyeRender() on both eyes before calling ovrHmd_EndEyeRender.
+// If rendering one eye at a time, it is best to render eye specified by
+// 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.
+// 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.
+// 'renderPose' will typically be the value returned from ovrHmd_BeginEyeRender, but can
+// be different if different pose was used for rendering.
+OVR_EXPORT void ovrHmd_EndEyeRender(ovrHmd hmd, ovrEyeType eye,
+ ovrPosef renderPose, ovrTexture* eyeTexture);
+
+
+
+//-------------------------------------------------------------------------------------
+// ***** Game-Side Rendering Functions
+
+// These functions provide distortion data and render timing support necessary to allow
+// game rendering of distortion. Game-side rendering involves the following steps:
+//
+// 1. Setup ovrEyeDesc based on desired texture size and Fov.
+// Call ovrHmd_GetRenderDesc to get the necessary rendering parameters for each eye.
+//
+// 2. Use ovrHmd_CreateDistortionMesh to generate distortion mesh.
+//
+// 3. Use ovrHmd_BeginFrameTiming, ovrHmd_GetEyePose and ovrHmd_BeginFrameTiming
+// in the rendering loop to obtain timing and predicted view orientation for
+// each eye.
+// - If relying on timewarp, use ovr_WaitTillTime after rendering+flush, followed
+// by ovrHmd_GetEyeTimewarpMatrices to obtain timewarp matrices used
+// in distortion pixel shader to reduce latency.
+//
+
+// 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);
+
+
+// Describes a vertex used for distortion; this is intended to be converted into
+// the engine-specific format.
+// Some fields may be unused based on ovrDistortionCaps selected. TexG and TexB, for example,
+// are not used if chromatic correction is not requested.
+typedef struct ovrDistortionVertex_
+{
+ ovrVector2f Pos;
+ float TimeWarpFactor; // Lerp factor between time-warp matrices. Can be encoded in Pos.z.
+ float VignetteFactor; // Vignette fade factor. Can be encoded in Pos.w.
+ ovrVector2f TexR;
+ ovrVector2f TexG;
+ ovrVector2f TexB;
+} ovrDistortionVertex;
+
+// Describes a full set of distortion mesh data, filled in by ovrHmd_CreateDistortionMesh.
+// Contents of this data structure, if not null, should be freed by ovrHmd_DestroyDistortionMesh.
+typedef struct ovrDistortionMesh_
+{
+ ovrDistortionVertex* pVertexData;
+ unsigned short* pIndexData;
+ unsigned int VertexCount;
+ unsigned int IndexCount;
+} ovrDistortionMesh;
+
+// Generate distortion mesh per eye.
+// Distortion capabilities will depend on 'distortionCaps' flags; user should rely on
+// 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.
+// 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,
+ unsigned int distortionCaps,
+ ovrVector2f uvScaleOffsetOut[2],
+ ovrDistortionMesh *meshData );
+
+// Frees distortion mesh allocated by ovrHmd_GenerateDistortionMesh. meshData elements
+// are set to null and zeroes after the call.
+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,
+ ovrVector2f uvScaleOffsetOut[2] );
+
+
+// Thread-safe timing function for the main thread. Caller should increment frameIndex
+// with every frame and pass the index to RenderThread for processing.
+OVR_EXPORT ovrFrameTiming ovrHmd_GetFrameTiming(ovrHmd hmd, unsigned int frameIndex);
+
+// Called at the beginning of the frame on the Render Thread.
+// Pass frameIndex == 0 if ovrHmd_GetFrameTiming isn't being used. Otherwise,
+// pass the same frame index as was used for GetFrameTiming on the main thread.
+OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrameTiming(ovrHmd hmd, unsigned int frameIndex);
+
+// Marks the end of game-rendered frame, tracking the necessary timing information. This
+// function must be called immediately after Present/SwapBuffers + GPU sync. GPU sync is important
+// before this call to reduce latency and ensure proper timing.
+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);
+
+
+// Predicts and returns Pose that should be used rendering the specified eye.
+// Must be called between ovrHmd_BeginFrameTiming & ovrHmd_EndFrameTiming.
+OVR_EXPORT ovrPosef ovrHmd_GetEyePose(ovrHmd hmd, ovrEyeType eye);
+
+// Computes timewarp matrices used by distortion mesh shader, these are used to adjust
+// for orientation change since the last call to ovrHmd_GetEyePose for this eye.
+// The ovrDistortionVertex::TimeWarpFactor is used to blend between the matrices,
+// usually representing two different sides of the screen.
+// Must be called on the same thread as ovrHmd_BeginFrameTiming.
+OVR_EXPORT void ovrHmd_GetEyeTimewarpMatrices(ovrHmd hmd, ovrEyeType eye,
+ ovrPosef renderPose, ovrMatrix4f twmOut[2]);
+
+
+
+//-------------------------------------------------------------------------------------
+// ***** Stateless math setup functions
+
+// Used to generate projection from ovrEyeDesc::Fov.
+OVR_EXPORT ovrMatrix4f ovrMatrix4f_Projection( ovrFovPort fov,
+ float znear, float zfar, ovrBool rightHanded );
+
+// Used for 2D rendering, Y is down
+// orthoScale = 1.0f / pixelsPerTanAngleAtCenter
+// orthoDistance = distance from camera, such as 0.8m
+OVR_EXPORT ovrMatrix4f ovrMatrix4f_OrthoSubProjection(ovrMatrix4f projection, ovrVector2f orthoScale,
+ float orthoDistance, float eyeViewAdjustX);
+
+// Returns global, absolute high-resolution time in seconds. This is the same
+// value as used in sensor messages.
+OVR_EXPORT double ovr_GetTimeInSeconds();
+
+// Waits until the specified absolute time.
+OVR_EXPORT double ovr_WaitTillTime(double absTime);
+
+
+
+// -----------------------------------------------------------------------------------
+// ***** Latency Test interface
+
+// Does latency test processing and returns 'TRUE' if specified rgb color should
+// be used to clear the screen.
+OVR_EXPORT ovrBool ovrHmd_ProcessLatencyTest(ovrHmd hmd, unsigned char rgbColorOut[3]);
+
+// Returns non-null string once with latency test result, when it is available.
+// Buffer is valid until next call.
+OVR_EXPORT const char* ovrHmd_GetLatencyTestResult(ovrHmd hmd);
+
+// Returns latency for HMDs that support internal latency testing via the
+// pixel-read back method (-1 for invalid or N/A)
+OVR_EXPORT double ovrHmd_GetMeasuredLatencyTest2(ovrHmd hmd);
+
+
+// -----------------------------------------------------------------------------------
+// ***** Property Access
+
+// NOTICE: This is experimental part of API that is likely to go away or change.
+
+// These allow accessing different properties of the HMD and profile.
+// Some of the properties may go away with profile/HMD versions, so software should
+// use defaults and/or proper fallbacks.
+//
+
+// For now, access profile entries; this will change.
+#if !defined(OVR_KEY_USER)
+
+ #define OVR_KEY_USER "User"
+ #define OVR_KEY_NAME "Name"
+ #define OVR_KEY_GENDER "Gender"
+ #define OVR_KEY_PLAYER_HEIGHT "PlayerHeight"
+ #define OVR_KEY_EYE_HEIGHT "EyeHeight"
+ #define OVR_KEY_IPD "IPD"
+ #define OVR_KEY_NECK_TO_EYE_HORIZONTAL "NeckEyeHori"
+ #define OVR_KEY_NECK_TO_EYE_VERTICAL "NeckEyeVert"
+
+ #define OVR_DEFAULT_GENDER "Male"
+ #define OVR_DEFAULT_PLAYER_HEIGHT 1.778f
+ #define OVR_DEFAULT_EYE_HEIGHT 1.675f
+ #define OVR_DEFAULT_IPD 0.064f
+ #define OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL 0.12f
+ #define OVR_DEFAULT_NECK_TO_EYE_VERTICAL 0.12f
+#endif
+
+
+// Get float property. Returns first element if property is a float array.
+// Returns defaultValue if property doesn't exist.
+OVR_EXPORT float ovrHmd_GetFloat(ovrHmd hmd, const char* propertyName, float defaultVal);
+
+// Modify float property; false if property doesn't exist or is readonly.
+OVR_EXPORT ovrBool ovrHmd_SetFloat(ovrHmd hmd, const char* propertyName, float value);
+
+
+// Get float[] property. Returns the number of elements filled in, 0 if property doesn't exist.
+// Maximum of arraySize elements will be written.
+OVR_EXPORT unsigned int ovrHmd_GetFloatArray(ovrHmd hmd, const char* propertyName,
+ float values[], unsigned int arraySize);
+
+// Modify float[] property; false if property doesn't exist or is readonly.
+OVR_EXPORT ovrBool ovrHmd_SetFloatArray(ovrHmd hmd, const char* propertyName,
+ float values[], unsigned int arraySize);
+
+// Get string property. Returns first element if property is a string array.
+// Returns defaultValue if property doesn't exist.
+// String memory is guaranteed to exist until next call to GetString or GetStringArray, or HMD is destroyed.
+OVR_EXPORT const char* ovrHmd_GetString(ovrHmd hmd, const char* propertyName,
+ const char* defaultVal);
+
+// Returns array size of a property, 0 if property doesn't exist.
+// Can be used to check existence of a property.
+OVR_EXPORT unsigned int ovrHmd_GetArraySize(ovrHmd hmd, const char* propertyName);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+
+#endif // OVR_CAPI_h
diff --git a/LibOVR/Src/OVR_CAPI_D3D.h b/LibOVR/Src/OVR_CAPI_D3D.h
new file mode 100644
index 0000000..75c383a
--- /dev/null
+++ b/LibOVR/Src/OVR_CAPI_D3D.h
@@ -0,0 +1,156 @@
+/************************************************************************************
+
+Filename : OVR_CAPI_D3D.h
+Content : D3D specific structures used by the CAPI interface.
+Created : November 7, 2013
+Authors : Michael Antonov
+
+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_CAPI_D3D_h
+#define OVR_CAPI_D3D_h
+
+#include "OVR_CAPI.h"
+
+#ifndef OVR_D3D_VERSION
+#error Please define OVR_D3D_VERSION to 9 or 10 or 11 before including OVR_CAPI_D3D.h
+#endif
+
+
+#if defined(OVR_D3D_VERSION) && (OVR_D3D_VERSION == 11)
+
+//-----------------------------------------------------------------------------------
+// ***** D3D11 Specific
+
+#include <d3d11.h>
+
+// Used to configure slave D3D rendering (i.e. for devices created externally).
+struct ovrD3D11ConfigData
+{
+ // General device settings.
+ ovrRenderAPIConfigHeader Header;
+ ID3D11Device* pDevice;
+ ID3D11DeviceContext* pDeviceContext;
+ ID3D11RenderTargetView* pBackBufferRT;
+ IDXGISwapChain* pSwapChain;
+};
+
+union ovrD3D11Config
+{
+ ovrRenderAPIConfig Config;
+ ovrD3D11ConfigData D3D11;
+};
+
+// Used to pass D3D11 eye texture data to ovrHmd_EndFrame.
+struct ovrD3D11TextureData
+{
+ // General device settings.
+ ovrTextureHeader Header;
+ ID3D11Texture2D* pTexture;
+ ID3D11ShaderResourceView* pSRView;
+};
+
+union ovrD3D11Texture
+{
+ ovrTexture Texture;
+ ovrD3D11TextureData D3D11;
+};
+
+
+
+#elif defined(OVR_D3D_VERSION) && (OVR_D3D_VERSION == 10)
+
+//-----------------------------------------------------------------------------------
+// ***** D3D10 Specific
+
+// Used to configure slave D3D rendering (i.e. for devices created externally).
+struct ovrD3D10ConfigData
+{
+ // General device settings.
+ ovrRenderAPIConfigHeader Header;
+ ID3D10Device* pDevice;
+ void* Unused;
+ ID3D10RenderTargetView* pBackBufferRT;
+ IDXGISwapChain* pSwapChain;
+};
+
+union ovrD3D10Config
+{
+ ovrRenderAPIConfig Config;
+ ovrD3D10ConfigData D3D10;
+};
+
+// Used to pass D3D10 eye texture data to ovrHmd_EndFrame.
+struct ovrD3D10TextureData
+{
+ // General device settings.
+ ovrTextureHeader Header;
+ ID3D10Texture2D* pTexture;
+ ID3D10ShaderResourceView* pSRView;
+};
+
+union ovrD3D10Texture
+{
+ ovrTexture Texture;
+ ovrD3D10TextureData D3D10;
+};
+
+#elif defined(OVR_D3D_VERSION) && (OVR_D3D_VERSION == 9)
+
+//-----------------------------------------------------------------------------------
+// ***** D3D9 Specific
+
+// Used to configure D3D9 rendering
+struct ovrD3D9ConfigData
+{
+ // General device settings.
+ ovrRenderAPIConfigHeader Header;
+
+ IDirect3DDevice9 * pDevice;
+ ///ID3D10RenderTargetView* pBackBufferRT;
+ ///IDXGISwapChain* pSwapChain;
+};
+
+union ovrD3D9Config
+{
+ ovrRenderAPIConfig Config;
+ ovrD3D9ConfigData D3D9;
+};
+
+// Used to pass D3D9 eye texture data to ovrHmd_EndFrame.
+struct ovrD3D9TextureData
+{
+ // General device settings.
+ ovrTextureHeader Header;
+ IDirect3DTexture9 * pTexture;
+ ///ID3D10ShaderResourceView* pSRView;
+};
+
+union ovrD3D9Texture
+{
+ ovrTexture Texture;
+ ovrD3D9TextureData D3D9;
+};
+
+
+
+#endif
+
+
+#endif // OVR_CAPI_h
diff --git a/LibOVR/Src/OVR_CAPI_GL.h b/LibOVR/Src/OVR_CAPI_GL.h
new file mode 100644
index 0000000..c042b5d
--- /dev/null
+++ b/LibOVR/Src/OVR_CAPI_GL.h
@@ -0,0 +1,59 @@
+/************************************************************************************
+
+Filename : OVR_CAPI_GL.h
+Content : GL specific structures used by the CAPI interface.
+Created : November 7, 2013
+Authors : Lee Cooper
+
+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_h
+#define OVR_CAPI_GL_h
+
+#include "OVR_CAPI.h"
+
+//-----------------------------------------------------------------------------------
+// ***** GL Specific
+
+#if defined(OVR_OS_WIN32)
+#include <GL/gl.h>
+#include <GL/wglext.h>
+#endif
+
+
+// Used to configure slave GL rendering (i.e. for devices created externally).
+typedef struct ovrGLConfigData_s
+{
+ // General device settings.
+ ovrRenderAPIConfigHeader Header;
+ HWND Window;
+ HGLRC WglContext;
+ HDC GdiDc;
+} ovrGLConfigData;
+
+union ovrGLConfig
+{
+ ovrRenderAPIConfig Config;
+ ovrGLConfigData OGL;
+};
+
+// Used to pass GL eye texture data to ovrHmd_EndFrame.
+typedef struct ovrGLTextureData_s
+{
+ // General device settings.
+ ovrTextureHeader Header;
+ GLuint TexId;
+} ovrGLTextureData;
+
+typedef union ovrGLTexture_s
+{
+ ovrTexture Texture;
+ ovrGLTextureData OGL;
+} ovrGLTexture;
+
+#endif // OVR_CAPI_GL_h
diff --git a/LibOVR/Src/OVR_Common_HMDDevice.cpp b/LibOVR/Src/OVR_Common_HMDDevice.cpp
new file mode 100644
index 0000000..b4ef177
--- /dev/null
+++ b/LibOVR/Src/OVR_Common_HMDDevice.cpp
@@ -0,0 +1,383 @@
+/************************************************************************************
+
+Filename : OVR_Common_HMDDevice.cpp
+Content :
+Created :
+Authors :
+
+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.
+
+*************************************************************************************/
+
+// Should be #included from the relevant OVR_YourPlatformHere_HMDDevice.cpp
+
+#include "Kernel/OVR_Alg.h"
+
+//-------------------------------------------------------------------------------------
+// ***** HMDDeviceCreateDesc
+
+DeviceBase* HMDDeviceCreateDesc::NewDeviceInstance()
+{
+ return new HMDDevice(this);
+}
+
+void HMDDeviceCreateDesc::SetScreenParameters(int x, int y,
+ int hres, int vres,
+ float hsize, float vsize,
+ float vCenterFromTopInMeters, float lensSeparationInMeters)
+{
+ Desktop.X = x;
+ Desktop.Y = y;
+ ResolutionInPixels = Sizei(hres, vres);
+ ScreenSizeInMeters = Sizef(hsize, vsize);
+ VCenterFromTopInMeters = vCenterFromTopInMeters;
+ LensSeparationInMeters = lensSeparationInMeters;
+
+ Contents |= Contents_Screen;
+}
+
+
+void HMDDeviceCreateDesc::SetDistortion(const float* dks)
+{
+ for (int i = 0; i < 4; i++)
+ DistortionK[i] = dks[i];
+ // TODO: add DistortionEqn
+ Contents |= Contents_Distortion;
+}
+
+HmdTypeEnum HMDDeviceCreateDesc::GetHmdType() const
+{
+ // Determine the HMD model
+ // The closest thing we have to a dependable model indicator are the
+ // the screen characteristics. Additionally we can check the sensor
+ // (on attached devices) to further refine our guess
+ HmdTypeEnum hmdType = HmdType_Unknown;
+
+ if ( ResolutionInPixels.w == 1280 )
+ {
+ if ( ScreenSizeInMeters.w > 0.1497f && ScreenSizeInMeters.w < 0.1498f )
+ hmdType = HmdType_DK1;
+ else
+ hmdType = HmdType_DKProto;
+ }
+ else if ( ResolutionInPixels.w == 1920 )
+ {
+ // DKHD protoypes, all 1920x1080
+ if ( ScreenSizeInMeters.w > 0.1209f && ScreenSizeInMeters.w < 0.1210f )
+ {
+ // Screen size 0.12096 x 0.06804
+ hmdType = HmdType_DKHDProto;
+ }
+ else if ( ScreenSizeInMeters.w > 0.1257f && ScreenSizeInMeters.w < 0.1258f )
+ {
+ // Screen size 0.125 x 0.071
+ // Could be a HmdType_DKHDProto566Mi, HmdType_CrystalCoveProto, or DK2
+ // - most likely the latter.
+ hmdType = HmdType_DK2;
+
+ // If available, check the sensor to determine exactly which variant this is
+ if (pDevice)
+ {
+ Ptr<SensorDevice> sensor = *((HMDDevice*)pDevice)->GetSensor();
+
+ SensorInfo sinfo;
+ if (sensor && sensor->GetDeviceInfo(&sinfo))
+ {
+ if (sinfo.ProductId == 1)
+ {
+ hmdType = HmdType_DKHDProto566Mi;
+ }
+ else
+ { // Crystal Cove uses 0.# firmware, DK2 uses 1.#
+ int firm_major = Alg::DecodeBCD((sinfo.Version >> 8) & 0x00ff);
+ int firm_minor = Alg::DecodeBCD(sinfo.Version & 0xff);
+ OVR_UNUSED(firm_minor);
+ if (firm_major == 0)
+ hmdType = HmdType_CrystalCoveProto;
+ else
+ hmdType = HmdType_DK2;
+ }
+ }
+ }
+ }
+ else if (ScreenSizeInMeters.w > 0.1295f && ScreenSizeInMeters.w < 0.1297f)
+ {
+ // Screen size 0.1296 x 0.0729
+ hmdType = HmdType_DKHD2Proto;
+ }
+ }
+
+ OVR_ASSERT( hmdType != HmdType_Unknown );
+ return hmdType;
+}
+
+bool HMDDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const
+{
+ if ((info->InfoClassType != Device_HMD) &&
+ (info->InfoClassType != Device_None))
+ return false;
+
+ HmdTypeEnum hmdType = GetHmdType();
+ char const* deviceName = "Oculus HMD";
+ switch (hmdType)
+ {
+ case HmdType_DKProto: deviceName = "Oculus Rift Prototype"; break;
+ case HmdType_DK1: deviceName = "Oculus Rift DK1"; break;
+ case HmdType_DKHDProto: deviceName = "Oculus Rift DKHD"; break;
+ case HmdType_DKHD2Proto: deviceName = "Oculus Rift DKHD2"; break;
+ 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;
+ }
+
+ info->ProductName = deviceName;
+ info->Manufacturer = "Oculus VR";
+ info->Type = Device_HMD;
+ info->Version = 0;
+
+ // Display detection.
+ if (info->InfoClassType == Device_HMD)
+ {
+ HMDInfo* hmdInfo = static_cast<HMDInfo*>(info);
+
+ hmdInfo->HmdType = hmdType;
+ hmdInfo->DesktopX = Desktop.X;
+ hmdInfo->DesktopY = Desktop.Y;
+ hmdInfo->ResolutionInPixels = ResolutionInPixels;
+ hmdInfo->ScreenSizeInMeters = ScreenSizeInMeters; // Includes ScreenGapSizeInMeters
+ hmdInfo->ScreenGapSizeInMeters = 0.0f;
+ hmdInfo->CenterFromTopInMeters = VCenterFromTopInMeters;
+ hmdInfo->LensSeparationInMeters = LensSeparationInMeters;
+ // TODO: any other information we get from the hardware itself should be added to this list
+
+ switch ( hmdInfo->HmdType )
+ {
+ case HmdType_DKProto:
+ // WARNING - estimated.
+ hmdInfo->Shutter.Type = HmdShutter_RollingTopToBottom;
+ hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 60.0f );
+ hmdInfo->Shutter.VsyncToFirstScanline = 0.000052f;
+ hmdInfo->Shutter.FirstScanlineToLastScanline = 0.016580f;
+ hmdInfo->Shutter.PixelSettleTime = 0.015f; // estimated.
+ hmdInfo->Shutter.PixelPersistence = hmdInfo->Shutter.VsyncToNextVsync; // Full persistence
+ break;
+ case HmdType_DK1:
+ // Data from specs.
+ hmdInfo->Shutter.Type = HmdShutter_RollingTopToBottom;
+ hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 60.0f );
+ hmdInfo->Shutter.VsyncToFirstScanline = 0.00018226f;
+ hmdInfo->Shutter.FirstScanlineToLastScanline = 0.01620089f;
+ hmdInfo->Shutter.PixelSettleTime = 0.017f; // estimated.
+ hmdInfo->Shutter.PixelPersistence = hmdInfo->Shutter.VsyncToNextVsync; // Full persistence
+ break;
+ case HmdType_DKHDProto:
+ // Data from specs.
+ hmdInfo->Shutter.Type = HmdShutter_RollingRightToLeft;
+ hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 60.0f );
+ hmdInfo->Shutter.VsyncToFirstScanline = 0.0000859f;
+ hmdInfo->Shutter.FirstScanlineToLastScanline = 0.0164948f;
+ hmdInfo->Shutter.PixelSettleTime = 0.012f; // estimated.
+ hmdInfo->Shutter.PixelPersistence = hmdInfo->Shutter.VsyncToNextVsync; // Full persistence
+ break;
+ case HmdType_DKHD2Proto:
+ // Data from specs.
+ hmdInfo->Shutter.Type = HmdShutter_RollingRightToLeft;
+ hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 60.0f );
+ hmdInfo->Shutter.VsyncToFirstScanline = 0.000052f;
+ hmdInfo->Shutter.FirstScanlineToLastScanline = 0.016580f;
+ hmdInfo->Shutter.PixelSettleTime = 0.015f; // estimated.
+ hmdInfo->Shutter.PixelPersistence = hmdInfo->Shutter.VsyncToNextVsync; // Full persistence
+ break;
+ case HmdType_DKHDProto566Mi:
+#if 0
+ // Low-persistence global shutter
+ hmdInfo->Shutter.Type = HmdShutter_Global;
+ hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 76.0f );
+ hmdInfo->Shutter.VsyncToFirstScanline = 0.0000273f + 0.0131033f; // Global shutter - first visible scan line is actually the last!
+ hmdInfo->Shutter.FirstScanlineToLastScanline = 0.000f; // Global shutter - all visible at once.
+ hmdInfo->Shutter.PixelSettleTime = 0.0f; // <100us
+ hmdInfo->Shutter.PixelPersistence = 0.18f * hmdInfo->Shutter.VsyncToNextVsync; // Confgurable - currently set to 18% of total frame.
+#else
+ // Low-persistence rolling shutter
+ hmdInfo->Shutter.Type = HmdShutter_RollingRightToLeft;
+ hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 76.0f );
+ hmdInfo->Shutter.VsyncToFirstScanline = 0.0000273f;
+ hmdInfo->Shutter.FirstScanlineToLastScanline = 0.0131033f;
+ hmdInfo->Shutter.PixelSettleTime = 0.0f; // <100us
+ hmdInfo->Shutter.PixelPersistence = 0.18f * hmdInfo->Shutter.VsyncToNextVsync; // Confgurable - currently set to 18% of total frame.
+#endif
+ break;
+ case HmdType_CrystalCoveProto:
+ // Low-persistence rolling shutter
+ hmdInfo->Shutter.Type = HmdShutter_RollingRightToLeft;
+ hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 76.0f );
+ hmdInfo->Shutter.VsyncToFirstScanline = 0.0000273f;
+ hmdInfo->Shutter.FirstScanlineToLastScanline = 0.0131033f;
+ hmdInfo->Shutter.PixelSettleTime = 0.0f; // <100us
+ hmdInfo->Shutter.PixelPersistence = 0.18f * hmdInfo->Shutter.VsyncToNextVsync; // Confgurable - currently set to 18% of total frame.
+ break;
+ case HmdType_DK2:
+ // Low-persistence rolling shutter
+ hmdInfo->Shutter.Type = HmdShutter_RollingRightToLeft;
+ hmdInfo->Shutter.VsyncToNextVsync = ( 1.0f / 76.0f );
+ hmdInfo->Shutter.VsyncToFirstScanline = 0.0000273f;
+ hmdInfo->Shutter.FirstScanlineToLastScanline = 0.0131033f;
+ hmdInfo->Shutter.PixelSettleTime = 0.0f; // <100us
+ hmdInfo->Shutter.PixelPersistence = 0.18f * hmdInfo->Shutter.VsyncToNextVsync; // Confgurable - currently set to 18% of total frame.
+ break;
+ default: OVR_ASSERT ( false ); break;
+ }
+
+
+ OVR_strcpy(hmdInfo->DisplayDeviceName, sizeof(hmdInfo->DisplayDeviceName),
+ DisplayDeviceName.ToCStr());
+#if defined(OVR_OS_WIN32)
+ // Nothing special for Win32.
+#elif defined(OVR_OS_MAC)
+ hmdInfo->DisplayId = DisplayId;
+#elif defined(OVR_OS_LINUX)
+ hmdInfo->DisplayId = DisplayId;
+#elif defined(OVR_OS_ANDROID)
+ hmdInfo->DisplayId = DisplayId;
+#else
+#error Unknown platform
+#endif
+
+ }
+
+ return true;
+}
+
+
+
+
+
+//-------------------------------------------------------------------------------------
+// ***** HMDDevice
+
+HMDDevice::HMDDevice(HMDDeviceCreateDesc* createDesc)
+ : OVR::DeviceImpl<OVR::HMDDevice>(createDesc, 0)
+{
+}
+HMDDevice::~HMDDevice()
+{
+}
+
+bool HMDDevice::Initialize(DeviceBase* parent)
+{
+ pParent = parent;
+ return true;
+}
+void HMDDevice::Shutdown()
+{
+ ProfileName.Clear();
+ pCachedProfile.Clear();
+ pParent.Clear();
+}
+
+Profile* HMDDevice::GetProfile()
+{
+ // Loads and returns a cached profile based on this device and current user
+ if (pCachedProfile == NULL)
+ {
+ ProfileManager* mgr = GetManager()->GetProfileManager();
+ const char* profile_name = GetProfileName();
+ if (profile_name && profile_name[0])
+ pCachedProfile = *mgr->GetProfile(this, profile_name);
+
+ if (pCachedProfile == NULL)
+ pCachedProfile = *mgr->GetDefaultProfile(this);
+
+ }
+ return pCachedProfile.GetPtr();
+}
+
+const char* HMDDevice::GetProfileName()
+{
+ if (ProfileName.IsEmpty())
+ { // If the profile name has not been initialized then
+ // retrieve the stored default user for this specific device
+ ProfileManager* mgr = GetManager()->GetProfileManager();
+ const char* name = mgr->GetDefaultUser(this);
+ ProfileName = name;
+ }
+
+ return ProfileName.ToCStr();
+}
+
+bool HMDDevice::SetProfileName(const char* name)
+{
+ if (ProfileName == name)
+ return true; // already set
+
+ // Flush the old profile
+ pCachedProfile.Clear();
+ if (!name)
+ {
+ ProfileName.Clear();
+ return false;
+ }
+
+ // Set the name and attempt to cache the profile
+ ProfileName = name;
+ if (GetProfile())
+ {
+ return true;
+ }
+ else
+ {
+ ProfileName.Clear();
+ return false;
+ }
+}
+
+OVR::SensorDevice* HMDDevice::GetSensor()
+{
+ // Just return first sensor found since we have no way to match it yet.
+
+ // Create DK2 sensor if it exists otherwise create first DK1 sensor.
+ SensorDevice* sensor = NULL;
+
+ DeviceEnumerator<SensorDevice> enumerator = GetManager()->EnumerateDevices<SensorDevice>();
+
+ while(enumerator.GetType() != Device_None)
+ {
+ SensorInfo info;
+ enumerator.GetDeviceInfo(&info);
+
+ if (info.ProductId == Device_Tracker2_ProductId)
+ {
+ sensor = enumerator.CreateDevice();
+ break;
+ }
+
+ enumerator.Next();
+ }
+
+ if (sensor == NULL)
+ {
+ sensor = GetManager()->EnumerateDevices<SensorDevice>().CreateDevice();
+ }
+
+ if (sensor)
+ {
+ sensor->SetCoordinateFrame(SensorDevice::Coord_HMD);
+ }
+
+ return sensor;
+}
diff --git a/LibOVR/Src/OVR_Device.h b/LibOVR/Src/OVR_Device.h
index d0a39d0..4ddc7a2 100644
--- a/LibOVR/Src/OVR_Device.h
+++ b/LibOVR/Src/OVR_Device.h
@@ -6,16 +6,16 @@ Content : Definition of HMD-related Device interfaces
Created : September 21, 2012
Authors : Michael Antonov
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -37,6 +37,7 @@ limitations under the License.
#include "Kernel/OVR_RefCount.h"
#include "Kernel/OVR_String.h"
+
namespace OVR {
// Declared externally
@@ -79,7 +80,7 @@ public:
virtual bool SupportsMessageType(MessageType) const { return true; }
private:
- UPInt Internal[4];
+ UPInt Internal[8];
};
@@ -112,12 +113,14 @@ public:
virtual DeviceBase* GetParent() const;
virtual DeviceManager* GetManager() const;
- virtual void SetMessageHandler(MessageHandler* handler);
- virtual MessageHandler* GetMessageHandler() const;
+ virtual void AddMessageHandler(MessageHandler* handler);
virtual DeviceType GetType() const;
virtual bool GetDeviceInfo(DeviceInfo* info) const;
+ // Returns true if device is connected and usable
+ virtual bool IsConnected();
+
// returns the MessageHandler's lock
Lock* GetHandlerLock() const;
protected:
@@ -138,25 +141,23 @@ class DeviceInfo
{
public:
DeviceInfo() : InfoClassType(Device_None), Type(Device_None), Version(0)
- { ProductName[0] = Manufacturer[0] = 0; }
-
- enum { MaxNameLength = 32 };
+ {}
// Type of device for which DeviceInfo is intended.
// This will be set to Device_HMD for HMDInfo structure, note that this may be
// different form the actual device type since (Device_None) is valid.
- const DeviceType InfoClassType;
+ const DeviceType InfoClassType;
// Type of device this describes. This must be the same as InfoClassType when
// InfoClassType != Device_None.
- DeviceType Type;
+ DeviceType Type;
// Name string describing the product: "Oculus Rift DK1", etc.
- char ProductName[MaxNameLength];
- char Manufacturer[MaxNameLength];
- unsigned Version;
+ String ProductName;
+ String Manufacturer;
+ unsigned Version;
protected:
DeviceInfo(DeviceType type) : InfoClassType(type), Type(type), Version(0)
- { ProductName[0] = Manufacturer[0] = 0; }
+ {}
void operator = (const DeviceInfo&) { OVR_ASSERT(0); } // Assignment not allowed.
};
@@ -318,35 +319,28 @@ protected:
class HMDInfo : public DeviceInfo
{
public:
- // Size of the entire screen, in pixels.
- unsigned HResolution, VResolution;
- // Physical dimensions of the active screen in meters. Can be used to calculate
- // projection center while considering IPD.
- float HScreenSize, VScreenSize;
- // Physical offset from the top of the screen to the eye center, in meters.
- // This will usually, but not necessarily be half of VScreenSize.
- float VScreenCenter;
- // Distance from the eye to screen surface, in meters.
- // Useful for calculating FOV and projection.
- float EyeToScreenDistance;
- // Distance between physical lens centers useful for calculating distortion center.
- float LensSeparationDistance;
- // Configured distance between the user's eye centers, in meters. Defaults to 0.064.
- float InterpupillaryDistance;
-
- // Radial distortion correction coefficients.
- // The distortion assumes that the input texture coordinates will be scaled
- // by the following equation:
- // uvResult = uvInput * (K0 + K1 * uvLength^2 + K2 * uvLength^4)
- // Where uvInput is the UV vector from the center of distortion in direction
- // of the mapped pixel, uvLength is the magnitude of that vector, and uvResult
- // the corresponding location after distortion.
- float DistortionK[4];
-
- float ChromaAbCorrection[4];
+ // Characteristics of the HMD screen and enclosure
+ HmdTypeEnum HmdType;
+ Size<int> ResolutionInPixels;
+ Size<float> ScreenSizeInMeters;
+ float ScreenGapSizeInMeters;
+ float CenterFromTopInMeters;
+ float LensSeparationInMeters;
+
+ // Timing & shutter data. All values in seconds.
+ struct ShutterInfo
+ {
+ HmdShutterTypeEnum Type;
+ float VsyncToNextVsync; // 1/framerate
+ float VsyncToFirstScanline; // for global shutter, vsync->shutter open.
+ float FirstScanlineToLastScanline; // for global shutter, will be zero.
+ float PixelSettleTime; // estimated.
+ float PixelPersistence; // Full persistence = 1/framerate.
+ } Shutter;
// Desktop coordinate position of the screen (can be negative; may not be present on all platforms)
- int DesktopX, DesktopY;
+ int DesktopX;
+ int DesktopY;
// Windows:
// "\\\\.\\DISPLAY3", etc. Can be used in EnumDisplaySettings/CreateDC.
@@ -356,43 +350,44 @@ public:
long DisplayId;
+ // Constructor initializes all values to 0s.
+ // To create a "virtualized" HMDInfo, use CreateDebugHMDInfo instead.
HMDInfo()
- : DeviceInfo(Device_HMD),
- HResolution(0), VResolution(0), HScreenSize(0), VScreenSize(0),
- VScreenCenter(0), EyeToScreenDistance(0),
- LensSeparationDistance(0), InterpupillaryDistance(0),
- DesktopX(0), DesktopY(0), DisplayId(0)
+ : DeviceInfo(Device_HMD),
+ HmdType(HmdType_None),
+ ResolutionInPixels(0),
+ ScreenSizeInMeters(0.0f),
+ ScreenGapSizeInMeters(0.0f),
+ CenterFromTopInMeters(0),
+ LensSeparationInMeters(0),
+ DisplayId(0)
{
+ DesktopX = 0;
+ DesktopY = 0;
DisplayDeviceName[0] = 0;
- memset(DistortionK, 0, sizeof(DistortionK));
- DistortionK[0] = 1;
- ChromaAbCorrection[0] = ChromaAbCorrection[2] = 1;
- ChromaAbCorrection[1] = ChromaAbCorrection[3] = 0;
+ Shutter.Type = HmdShutter_LAST;
+ Shutter.VsyncToNextVsync = 0.0f;
+ Shutter.VsyncToFirstScanline = 0.0f;
+ Shutter.FirstScanlineToLastScanline = 0.0f;
+ Shutter.PixelSettleTime = 0.0f;
+ Shutter.PixelPersistence = 0.0f;
}
// Operator = copies local fields only (base class must be correct already)
void operator = (const HMDInfo& src)
{
- HResolution = src.HResolution;
- VResolution = src.VResolution;
- HScreenSize = src.HScreenSize;
- VScreenSize = src.VScreenSize;
- VScreenCenter = src.VScreenCenter;
- EyeToScreenDistance = src.EyeToScreenDistance;
- LensSeparationDistance = src.LensSeparationDistance;
- InterpupillaryDistance = src.InterpupillaryDistance;
- DistortionK[0] = src.DistortionK[0];
- DistortionK[1] = src.DistortionK[1];
- DistortionK[2] = src.DistortionK[2];
- DistortionK[3] = src.DistortionK[3];
- ChromaAbCorrection[0] = src.ChromaAbCorrection[0];
- ChromaAbCorrection[1] = src.ChromaAbCorrection[1];
- ChromaAbCorrection[2] = src.ChromaAbCorrection[2];
- ChromaAbCorrection[3] = src.ChromaAbCorrection[3];
- DesktopX = src.DesktopX;
- DesktopY = src.DesktopY;
+ HmdType = src.HmdType;
+ ResolutionInPixels = src.ResolutionInPixels;
+ ScreenSizeInMeters = src.ScreenSizeInMeters;
+ ScreenGapSizeInMeters = src.ScreenGapSizeInMeters;
+ CenterFromTopInMeters = src.CenterFromTopInMeters;
+ LensSeparationInMeters = src.LensSeparationInMeters;
+ DesktopX = src.DesktopX;
+ DesktopY = src.DesktopY;
+ Shutter = src.Shutter;
memcpy(DisplayDeviceName, src.DisplayDeviceName, sizeof(DisplayDeviceName));
- DisplayId = src.DisplayId;
+
+ DisplayId = src.DisplayId;
}
bool IsSameDisplay(const HMDInfo& o) const
@@ -431,10 +426,10 @@ public:
// Requests the currently used profile. This profile affects the
// settings reported by HMDInfo.
- virtual Profile* GetProfile() const = 0;
+ virtual Profile* GetProfile() = 0;
// Obtains the currently used profile name. This is initialized to the default
// profile name, if any; it can then be changed per-device by SetProfileName.
- virtual const char* GetProfileName() const = 0;
+ virtual const char* GetProfileName() = 0;
// Sets the profile user name, changing the data returned by GetProfileInfo.
virtual bool SetProfileName(const char* name) = 0;
@@ -483,7 +478,6 @@ class SensorInfo : public DeviceInfo
public:
SensorInfo() : DeviceInfo(Device_Sensor), VendorId(0), ProductId(0)
{
- SerialNumber[0] = 0;
}
// HID Vendor and ProductId of the device.
@@ -492,12 +486,399 @@ public:
// MaxRanges report maximum sensor range values supported by HW.
SensorRange MaxRanges;
// Sensor (and display) serial number.
- char SerialNumber[20];
+ String SerialNumber;
private:
void operator = (const SensorInfo&) { OVR_ASSERT(0); } // Assignment not allowed.
};
+// Tracking settings (DK2).
+struct TrackingReport
+{
+ TrackingReport()
+ : CommandId(0), Pattern(0),
+ Enable(0), Autoincrement(0), UseCarrier(0),
+ SyncInput(0), VsyncLock(0), CustomPattern(0),
+ ExposureLength(0), FrameInterval(0),
+ VsyncOffset(0), DutyCycle(0)
+ {}
+
+ TrackingReport( UInt16 commandId,
+ UByte pattern,
+ bool enable,
+ bool autoincrement,
+ bool useCarrier,
+ bool syncInput,
+ bool vsyncLock,
+ bool customPattern,
+ UInt16 exposureLength,
+ UInt16 frameInterval,
+ UInt16 vsyncOffset,
+ UByte dutyCycle)
+ : CommandId(commandId), Pattern(pattern),
+ Enable(enable), Autoincrement(autoincrement), UseCarrier(useCarrier),
+ SyncInput(syncInput), VsyncLock(vsyncLock), CustomPattern(customPattern),
+ ExposureLength(exposureLength), FrameInterval(frameInterval),
+ VsyncOffset(vsyncOffset), DutyCycle(dutyCycle)
+ { }
+
+ UInt16 CommandId;
+ UByte Pattern; // Tracking LED pattern index.
+ bool Enable; // Enables the tracking LED exposure and updating.
+ bool Autoincrement; // Autoincrement pattern after each exposure.
+ bool UseCarrier; // Modulate tracking LEDs at 85kHz.
+ bool SyncInput; // Trigger LED exposure from wired sync signal.
+ bool VsyncLock; // Trigger LED exposure from panel Vsync.
+ bool CustomPattern; // Use custom LED sequence.
+ UInt16 ExposureLength; // Tracking LED illumination (and exposure) length in microseconds.
+ UInt16 FrameInterval; // LED exposure interval in microseconds when in
+ // 'internal timer' mode (when SyncInput = VsyncLock = false).
+ UInt16 VsyncOffset; // Exposure offset in microseconds from vsync when in
+ // 'vsync lock' mode (when VsyncLock = true).
+ UByte DutyCycle; // Duty cycle of 85kHz modulation when in 'use carrier' mode
+ // (when UseCarrier = true). 128 = 50% duty cycle.
+};
+
+// Display settings (DK2).
+struct DisplayReport
+{
+ enum ShutterTypeEnum
+ {
+ // These are not yet defined.
+ ShutterType_Default = 0,
+ };
+
+ enum CurrentLimitEnum
+ {
+ // These are not yet defined.
+ CurrentLimit_Default = 0,
+ };
+
+ DisplayReport()
+ : CommandId(0), Brightness(0),
+ ShutterType(ShutterType_Default), CurrentLimit(CurrentLimit_Default), UseRolling(0),
+ ReverseRolling(0), HighBrightness(0), SelfRefresh(0),
+ ReadPixel(0), DirectPentile(0),
+ Persistence(0), LightingOffset(0),
+ PixelSettle(0), TotalRows(0)
+ {}
+
+ DisplayReport( UInt16 commandId,
+ UByte brightness,
+ ShutterTypeEnum shutterType,
+ CurrentLimitEnum currentLimit,
+ bool useRolling,
+ bool reverseRolling,
+ bool highBrightness,
+ bool selfRefresh,
+ bool readPixel,
+ bool directPentile,
+ UInt16 persistence,
+ UInt16 lightingOffset,
+ UInt16 pixelSettle,
+ UInt16 totalRows)
+ : CommandId(commandId), Brightness(brightness),
+ ShutterType(shutterType), CurrentLimit(currentLimit), UseRolling(useRolling),
+ ReverseRolling(reverseRolling), HighBrightness(highBrightness), SelfRefresh(selfRefresh),
+ ReadPixel(readPixel), DirectPentile(directPentile),
+ Persistence(persistence), LightingOffset(lightingOffset),
+ PixelSettle(pixelSettle), TotalRows(totalRows)
+ { }
+
+ UInt16 CommandId;
+ UByte Brightness; // See 'DK2 Firmware Specification' document for a description of
+ ShutterTypeEnum ShutterType; // display settings.
+ CurrentLimitEnum CurrentLimit;
+ bool UseRolling;
+ bool ReverseRolling;
+ bool HighBrightness;
+ bool SelfRefresh;
+ bool ReadPixel;
+ bool DirectPentile;
+ UInt16 Persistence;
+ UInt16 LightingOffset;
+ UInt16 PixelSettle;
+ UInt16 TotalRows;
+};
+
+// MagCalibration matrix (DK2).
+struct MagCalibrationReport
+{
+ MagCalibrationReport()
+ : CommandId(0), Version(0), Calibration()
+ {}
+
+ MagCalibrationReport( UInt16 commandId,
+ UByte version,
+ const Matrix4f& calibration)
+ : CommandId(commandId), Version(version), Calibration(calibration)
+ { }
+
+ UInt16 CommandId;
+ UByte Version; // Version of the calibration procedure used to generate the calibration matrix.
+ Matrix4f Calibration; // Calibration matrix. Note only the first three rows are used by the feature report.
+};
+
+// PositionCalibration values (DK2).
+// - Sensor interface versions before 5 do not support Normal and Rotation.
+struct PositionCalibrationReport
+{
+ enum PositionTypeEnum
+ {
+ PositionType_LED = 0,
+ PositionType_IMU = 1
+ };
+
+ PositionCalibrationReport()
+ : CommandId(0), Version(0),
+ Position(0), Normal(0), Rotation(0),
+ PositionIndex(0), NumPositions(0), PositionType(PositionType_LED)
+ {}
+
+ PositionCalibrationReport(UInt16 commandId,
+ UByte version,
+ const Vector3f& position,
+ const Vector3f& normal,
+ float rotation,
+ UInt16 positionIndex,
+ UInt16 numPositions,
+ PositionTypeEnum positionType)
+ : CommandId(commandId), Version(version),
+ Position(position), Normal(normal), Rotation(rotation),
+ PositionIndex(positionIndex), NumPositions(numPositions), PositionType(positionType)
+ {
+ }
+
+ UInt16 CommandId;
+ UByte Version; // The version of the calibration procedure used to generate the stored positions.
+ Vector3d Position; // Position of the LED or inertial tracker in meters. This is relative to the
+ // 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.
+ 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
+ // the inertial tracker, all others are LED positions.
+ PositionTypeEnum PositionType; // The type of the item which has its position reported in the current report
+};
+
+// CustomPattern values (DK2).
+struct CustomPatternReport
+{
+ CustomPatternReport()
+ : CommandId(0), SequenceLength(0), Sequence(0),
+ LEDIndex(0), NumLEDs(0)
+ {}
+
+ CustomPatternReport(UInt16 commandId,
+ UByte sequenceLength,
+ UInt32 sequence,
+ UInt16 ledIndex,
+ UInt16 numLEDs)
+ : CommandId(commandId), SequenceLength(sequenceLength), Sequence(sequence),
+ LEDIndex(ledIndex), NumLEDs(numLEDs)
+ { }
+
+ UInt16 CommandId;
+ UByte SequenceLength; // See 'DK2 Firmware Specification' document for a description of
+ UInt32 Sequence; // LED custom patterns.
+ UInt16 LEDIndex;
+ UInt16 NumLEDs;
+};
+
+// KeepAliveMux settings (DK2).
+struct KeepAliveMuxReport
+{
+ KeepAliveMuxReport()
+ : CommandId(0), INReport(0), Interval(0)
+ {}
+
+ KeepAliveMuxReport( UInt16 commandId,
+ UByte inReport,
+ UInt16 interval)
+ : CommandId(commandId), INReport(inReport), Interval(interval)
+ { }
+
+ UInt16 CommandId;
+ UByte INReport; // Requested IN report type (1 = DK1, 11 = DK2).
+ UInt16 Interval; // Keep alive period in milliseconds.
+};
+
+// Manufacturing test result (DK2).
+struct ManufacturingReport
+{
+ ManufacturingReport()
+ : CommandId(0), NumStages(0), Stage(0),
+ StageLocation(0), StageTime(0), Result(0), StageVersion(0)
+ {}
+
+ ManufacturingReport( UInt16 commandId,
+ UByte numStages,
+ UByte stage,
+ UByte version,
+ UInt16 stageLocation,
+ UInt32 stageTime,
+ UInt32 result)
+ : CommandId(commandId), NumStages(numStages), Stage(stage),
+ StageLocation(stageLocation), StageTime(stageTime), Result(result), StageVersion(version)
+ { }
+
+ UInt16 CommandId;
+ UByte NumStages; // See 'DK2 Firmware Specification' document for a description of
+ UByte Stage; // manufacturing test results.
+ UByte StageVersion;
+ UInt16 StageLocation;
+ UInt32 StageTime;
+ UInt32 Result;
+};
+
+// UUID (DK2).
+struct UUIDReport
+{
+ static const int UUID_SIZE = 20;
+
+ UUIDReport()
+ : CommandId(0)
+ {
+ memset(UUIDValue, 0, sizeof(UUIDValue));
+ }
+
+ UUIDReport( UInt16 commandId,
+ UByte uuid[UUID_SIZE])
+ : CommandId(commandId)
+ {
+ for (int i=0; i<UUID_SIZE; i++)
+ {
+ UUIDValue[i] = uuid[i];
+ }
+ }
+
+ UInt16 CommandId;
+ UByte UUIDValue[UUID_SIZE]; // See 'DK2 Firmware Specification' document for
+ // a description of UUID.
+};
+
+// Lens Distortion (DK2).
+struct LensDistortionReport
+{
+ LensDistortionReport()
+ : CommandId(0),
+ NumDistortions(0),
+ DistortionIndex(0),
+ Bitmask(0),
+ LensType(0),
+ Version(0),
+ EyeRelief(0),
+ MaxR(0),
+ MetersPerTanAngleAtCenter(0)
+ {}
+
+ LensDistortionReport( UInt16 commandId,
+ UByte numDistortions,
+ UByte distortionIndex,
+ UByte bitmask,
+ UInt16 lensType,
+ UInt16 version,
+ UInt16 eyeRelief,
+ UInt16 kCoefficients[11],
+ UInt16 maxR,
+ UInt16 metersPerTanAngleAtCenter,
+ UInt16 chromaticAberration[4])
+ : CommandId(commandId),
+ NumDistortions(numDistortions),
+ DistortionIndex(distortionIndex),
+ Bitmask(bitmask),
+ LensType(lensType),
+ Version(version),
+ EyeRelief(eyeRelief),
+ MaxR(maxR),
+ MetersPerTanAngleAtCenter(metersPerTanAngleAtCenter)
+ {
+ memcpy(KCoefficients, kCoefficients, sizeof(KCoefficients));
+ memcpy(ChromaticAberration, chromaticAberration, sizeof(ChromaticAberration));
+ }
+
+ UInt16 CommandId;
+ UByte NumDistortions;
+ UByte DistortionIndex;
+ UByte Bitmask;
+ UInt16 LensType;
+ UInt16 Version;
+ UInt16 EyeRelief;
+ UInt16 KCoefficients[11];
+ UInt16 MaxR;
+ UInt16 MetersPerTanAngleAtCenter;
+ UInt16 ChromaticAberration[4];
+};
+
+// Temperature calibration result (DK2).
+struct TemperatureReport
+{
+ TemperatureReport()
+ : CommandId(0), Version(0),
+ NumBins(0), Bin(0), NumSamples(0), Sample(0),
+ TargetTemperature(0), ActualTemperature(0),
+ Time(0), Offset(0)
+ {}
+
+ TemperatureReport( UInt16 commandId,
+ UByte version,
+ UByte numBins,
+ UByte bin,
+ UByte numSamples,
+ UByte sample,
+ double targetTemperature,
+ double actualTemperature,
+ UInt32 time,
+ Vector3d offset)
+ : CommandId(commandId), Version(version),
+ NumBins(numBins), Bin(bin), NumSamples(numSamples), Sample(sample),
+ TargetTemperature(targetTemperature), ActualTemperature(actualTemperature),
+ Time(time), Offset(offset)
+ { }
+
+ UInt16 CommandId;
+ UByte Version; // See 'DK2 Firmware Specification' document for a description of
+ UByte NumBins; // temperature calibration data.
+ UByte Bin;
+ UByte NumSamples;
+ UByte Sample;
+ double TargetTemperature;
+ double ActualTemperature;
+ UInt32 Time; // Better hope nobody tries to use this in 2038
+ Vector3d Offset;
+};
+
+// Gyro autocalibration result (DK2).
+struct GyroOffsetReport
+{
+ enum VersionEnum
+ {
+ // These are not yet defined.
+ Version_NoOffset = 0,
+ Version_ShortAvg = 1,
+ Version_LongAvg = 2
+ };
+
+ GyroOffsetReport()
+ : CommandId(0), Version(Version_NoOffset),
+ Offset(0), Temperature(0)
+ {}
+
+ GyroOffsetReport( UInt16 commandId,
+ VersionEnum version,
+ Vector3d offset,
+ double temperature)
+ : CommandId(commandId), Version(version),
+ Offset(offset), Temperature(temperature)
+ {}
+
+ UInt16 CommandId;
+ VersionEnum Version;
+ Vector3d Offset;
+ double Temperature;
+};
//-------------------------------------------------------------------------------------
// ***** SensorDevice
@@ -519,7 +900,9 @@ public:
virtual DeviceType GetType() const { return Device_Sensor; }
-
+ virtual UByte GetDeviceInterfaceVersion() = 0;
+
+
// CoordinateFrame defines whether messages come in the coordinate frame
// of the sensor device or HMD, which has a different internal sensor.
// Sensors obtained form the HMD will automatically use HMD coordinates.
@@ -542,7 +925,7 @@ public:
// Returns currently set report rate, in Hz. If 0 - error occurred.
// Note, this value may be different from the one provided for SetReportRate. The return
// value will contain the actual rate.
- virtual unsigned GetReportRate() const = 0;
+ virtual unsigned GetReportRate() const = 0;
// Sets maximum range settings for the sensor described by SensorRange.
// The function will fail if you try to pass values outside Maximum supported
@@ -550,11 +933,52 @@ public:
// Pass waitFlag == true to wait for command completion. For waitFlag == true,
// returns true if the range was applied successfully (no HW error).
// For waitFlag = false, return 'true' means that command was enqueued successfully.
- virtual bool SetRange(const SensorRange& range, bool waitFlag = false) = 0;
+ virtual bool SetRange(const SensorRange& range, bool waitFlag = false) = 0;
// Return the current sensor range settings for the device. These may not exactly
// match the values applied through SetRange.
- virtual void GetRange(SensorRange* range) const = 0;
+ virtual void GetRange(SensorRange* range) const = 0;
+
+ // Return the factory calibration parameters for the IMU
+ virtual void GetFactoryCalibration(Vector3f* AccelOffset, Vector3f* GyroOffset,
+ Matrix4f* AccelMatrix, Matrix4f* GyroMatrix,
+ float* Temperature) = 0;
+ // Enable/disable onboard IMU calibration
+ // If set to false, the device will return raw values
+ virtual void SetOnboardCalibrationEnabled(bool enabled) = 0;
+
+ // Get/set feature reports added to DK2. See 'DK2 Firmware Specification' document for details.
+ virtual bool SetTrackingReport(const TrackingReport&) { return false; }
+ virtual bool GetTrackingReport(TrackingReport*) { return false; }
+
+ virtual bool SetDisplayReport(const DisplayReport&) { return false; }
+ virtual bool GetDisplayReport(DisplayReport*) { return false; }
+
+ virtual bool SetMagCalibrationReport(const MagCalibrationReport&) { return false; }
+ virtual bool GetMagCalibrationReport(MagCalibrationReport*) { return false; }
+
+ virtual bool SetPositionCalibrationReport(const PositionCalibrationReport&) { return false; }
+ virtual bool GetAllPositionCalibrationReports(Array<PositionCalibrationReport>*) { return false; }
+
+ virtual bool SetCustomPatternReport(const CustomPatternReport&) { return false; }
+ virtual bool GetCustomPatternReport(CustomPatternReport*) { return false; }
+
+ virtual bool SetKeepAliveMuxReport(const KeepAliveMuxReport&) { return false; }
+ virtual bool GetKeepAliveMuxReport(KeepAliveMuxReport*) { return false; }
+
+ virtual bool SetManufacturingReport(const ManufacturingReport&) { return false; }
+ virtual bool GetManufacturingReport(ManufacturingReport*) { return false; }
+
+ virtual bool SetUUIDReport(const UUIDReport&) { return false; }
+ virtual bool GetUUIDReport(UUIDReport*) { return false; }
+
+ virtual bool SetTemperatureReport(const TemperatureReport&) { return false; }
+ virtual bool GetAllTemperatureReports(Array<Array<TemperatureReport> >*) { return false; }
+
+ virtual bool GetGyroOffsetReport(GyroOffsetReport*) { return false; }
+
+ virtual bool SetLensDistortionReport(const LensDistortionReport&) { return false; }
+ virtual bool GetLensDistortionReport(LensDistortionReport*) { return false; }
};
//-------------------------------------------------------------------------------------
@@ -627,4 +1051,7 @@ public:
} // namespace OVR
+
+
+
#endif
diff --git a/LibOVR/Src/OVR_DeviceConstants.h b/LibOVR/Src/OVR_DeviceConstants.h
index d5c2418..6b40b7d 100644
--- a/LibOVR/Src/OVR_DeviceConstants.h
+++ b/LibOVR/Src/OVR_DeviceConstants.h
@@ -6,16 +6,16 @@ Content : Device constants
Created : February 5, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -42,9 +42,101 @@ enum DeviceType
Device_Sensor = 3,
Device_LatencyTester = 4,
Device_BootLoader = 5,
+ Device_Camera = 6,
+ Device_Display = 7,
Device_All = 0xFF // Set for enumeration only, to enumerate all device types.
};
+
+
+//-------------------------------------------------------------------------------------
+// Different lens distortion types supported by devices.
+//
+enum DistortionEqnType
+{
+ Distortion_No_Override = -1,
+ // These two are leagcy and deprecated.
+ Distortion_Poly4 = 0, // scale = (K0 + K1*r^2 + K2*r^4 + K3*r^6)
+ Distortion_RecipPoly4 = 1, // scale = 1/(K0 + K1*r^2 + K2*r^4 + K3*r^6)
+
+ // CatmullRom10 is the preferred distortion format.
+ Distortion_CatmullRom10 = 2, // scale = Catmull-Rom spline through points (1.0, K[1]...K[9])
+
+ Distortion_LAST // For ease of enumeration.
+};
+
+
+//-------------------------------------------------------------------------------------
+// HMD types.
+//
+enum HmdTypeEnum
+{
+ HmdType_None,
+
+ HmdType_DKProto, // First duct-tape model, never sold.
+ HmdType_DK1, // DevKit1 - on sale to developers.
+ HmdType_DKHDProto, // DKHD - shown at various shows, never sold.
+ HmdType_DKHD2Proto, // DKHD2, 5.85-inch panel, never sold.
+ HmdType_DKHDProto566Mi, // DKHD, 5.66-inch panel, never sold.
+ HmdType_CrystalCoveProto, // Crystal Cove, 5.66-inch panel, shown at shows but never sold.
+ HmdType_DK2,
+
+ // Reminder - this header file is public - codenames only!
+
+ HmdType_Unknown, // Used for unnamed HW lab experiments.
+
+ HmdType_LAST
+};
+
+
+//-------------------------------------------------------------------------------------
+// HMD shutter types.
+//
+enum HmdShutterTypeEnum
+{
+ HmdShutter_Global,
+ HmdShutter_RollingTopToBottom,
+ HmdShutter_RollingLeftToRight,
+ HmdShutter_RollingRightToLeft,
+ // TODO:
+ // color-sequential e.g. LCOS?
+ // alternate eyes?
+ // alternate columns?
+ // outside-in?
+
+ HmdShutter_LAST
+};
+
+
+
+//-------------------------------------------------------------------------------------
+// For headsets that use eye cups
+//
+enum EyeCupType
+{
+ // Public lenses
+ EyeCup_DK1A = 0,
+ EyeCup_DK1B = 1,
+ EyeCup_DK1C = 2,
+
+ EyeCup_DK2A = 3,
+
+ // Internal R&D codenames.
+ // Reminder - this header file is public - codenames only!
+ EyeCup_DKHD2A,
+ EyeCup_OrangeA,
+ EyeCup_RedA,
+ EyeCup_PinkA,
+ EyeCup_BlueA,
+ EyeCup_Delilah1A,
+ EyeCup_Delilah2A,
+ EyeCup_JamesA,
+ EyeCup_SunMandalaA,
+
+ EyeCup_LAST
+};
+
+
} // namespace OVR
#endif
diff --git a/LibOVR/Src/OVR_DeviceHandle.cpp b/LibOVR/Src/OVR_DeviceHandle.cpp
index 4a98897..cf6f05f 100644
--- a/LibOVR/Src/OVR_DeviceHandle.cpp
+++ b/LibOVR/Src/OVR_DeviceHandle.cpp
@@ -5,16 +5,16 @@ Content : Implementation of device handle class
Created : February 5, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/OVR_DeviceHandle.h b/LibOVR/Src/OVR_DeviceHandle.h
index e811d23..dd3e92b 100644
--- a/LibOVR/Src/OVR_DeviceHandle.h
+++ b/LibOVR/Src/OVR_DeviceHandle.h
@@ -6,16 +6,16 @@ Content : Handle to a device that was enumerated
Created : February 5, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/OVR_DeviceImpl.cpp b/LibOVR/Src/OVR_DeviceImpl.cpp
index 140598f..5b77708 100644
--- a/LibOVR/Src/OVR_DeviceImpl.cpp
+++ b/LibOVR/Src/OVR_DeviceImpl.cpp
@@ -5,16 +5,16 @@ Content : Partial back-end independent implementation of Device interfaces
Created : October 10, 2012
Authors : Michael Antonov
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -37,75 +37,6 @@ namespace OVR {
//-------------------------------------------------------------------------------------
-// ***** SharedLock
-
-// This is a general purpose globally shared Lock implementation that should probably be
-// moved to Kernel.
-// May in theory busy spin-wait if we hit contention on first lock creation,
-// but this shouldn't matter in practice since Lock* should be cached.
-
-
-enum { LockInitMarker = 0xFFFFFFFF };
-
-Lock* SharedLock::GetLockAddRef()
-{
- int oldUseCount;
-
- do {
- oldUseCount = UseCount;
- if (oldUseCount == LockInitMarker)
- continue;
-
- if (oldUseCount == 0)
- {
- // Initialize marker
- if (AtomicOps<int>::CompareAndSet_Sync(&UseCount, 0, LockInitMarker))
- {
- Construct<Lock>(Buffer);
- do { }
- while (!AtomicOps<int>::CompareAndSet_Sync(&UseCount, LockInitMarker, 1));
- return toLock();
- }
- continue;
- }
-
- } while (!AtomicOps<int>::CompareAndSet_NoSync(&UseCount, oldUseCount, oldUseCount + 1));
-
- return toLock();
-}
-
-void SharedLock::ReleaseLock(Lock* plock)
-{
- OVR_UNUSED(plock);
- OVR_ASSERT(plock == toLock());
-
- int oldUseCount;
-
- do {
- oldUseCount = UseCount;
- OVR_ASSERT(oldUseCount != LockInitMarker);
-
- if (oldUseCount == 1)
- {
- // Initialize marker
- if (AtomicOps<int>::CompareAndSet_Sync(&UseCount, 1, LockInitMarker))
- {
- Destruct<Lock>(toLock());
-
- do { }
- while (!AtomicOps<int>::CompareAndSet_Sync(&UseCount, LockInitMarker, 0));
-
- return;
- }
- continue;
- }
-
- } while (!AtomicOps<int>::CompareAndSet_NoSync(&UseCount, oldUseCount, oldUseCount - 1));
-}
-
-
-
-//-------------------------------------------------------------------------------------
// ***** MessageHandler
// Threading notes:
@@ -119,8 +50,13 @@ static SharedLock MessageHandlerSharedLock;
class MessageHandlerImpl
{
public:
+ enum
+ {
+ MaxHandlerRefsCount = 4
+ };
+
MessageHandlerImpl()
- : pLock(MessageHandlerSharedLock.GetLockAddRef())
+ : pLock(MessageHandlerSharedLock.GetLockAddRef()), HandlerRefsCount(0)
{
}
~MessageHandlerImpl()
@@ -136,14 +72,15 @@ public:
// This lock is held while calling a handler and when we are applied/
// removed from a device.
- Lock* pLock;
- // List of device we are applied to.
- List<MessageHandlerRef> UseList;
+ Lock* pLock;
+ // List of devices we are applied to.
+ int HandlerRefsCount;
+ MessageHandlerRef* pHandlerRefs[MaxHandlerRefsCount];
};
MessageHandlerRef::MessageHandlerRef(DeviceBase* device)
- : pLock(MessageHandlerSharedLock.GetLockAddRef()), pDevice(device), pHandler(0)
+ : pLock(MessageHandlerSharedLock.GetLockAddRef()), pDevice(device), HandlersCount(0)
{
}
@@ -151,41 +88,87 @@ MessageHandlerRef::~MessageHandlerRef()
{
{
Lock::Locker lockScope(pLock);
- if (pHandler)
- {
- pHandler = 0;
- RemoveNode();
- }
+
+ while (HandlersCount > 0)
+ removeHandler(0);
}
MessageHandlerSharedLock.ReleaseLock(pLock);
pLock = 0;
}
-void MessageHandlerRef::SetHandler(MessageHandler* handler)
+void MessageHandlerRef::Call(const Message& msg)
+{
+ Lock::Locker lockScope(pLock);
+
+ for (int i = 0; i < HandlersCount; i++)
+ pHandlers[i]->OnMessage(msg);
+}
+
+void MessageHandlerRef::AddHandler(MessageHandler* handler)
{
OVR_ASSERT(!handler ||
MessageHandlerImpl::FromHandler(handler)->pLock == pLock);
Lock::Locker lockScope(pLock);
- SetHandler_NTS(handler);
+ AddHandler_NTS(handler);
+}
+
+void MessageHandlerRef::AddHandler_NTS(MessageHandler* handler)
+{
+ OVR_ASSERT(handler != NULL);
+
+ OVR_ASSERT(HandlersCount < MaxHandlersCount);
+ for (int i = 0; i < HandlersCount; i++)
+ if (pHandlers[i] == handler)
+ // handler already installed - do nothing
+ return;
+ pHandlers[HandlersCount] = handler;
+ HandlersCount++;
+
+ MessageHandlerImpl* handlerImpl = MessageHandlerImpl::FromHandler(handler);
+ OVR_ASSERT(handlerImpl->HandlerRefsCount < MessageHandlerImpl::MaxHandlerRefsCount);
+ handlerImpl->pHandlerRefs[handlerImpl->HandlerRefsCount] = this;
+ handlerImpl->HandlerRefsCount++;
+
+ // TBD: Call notifier on device?
}
-void MessageHandlerRef::SetHandler_NTS(MessageHandler* handler)
-{
- if (pHandler != handler)
+bool MessageHandlerRef::RemoveHandler(MessageHandler* handler)
+{
+ Lock::Locker lockScope(pLock);
+
+ for (int i = 0; i < HandlersCount; i++)
{
- if (pHandler)
- RemoveNode();
- pHandler = handler;
+ if (pHandlers[i] == handler)
+ return removeHandler(i);
+ }
+ return false;
+}
- if (handler)
+bool MessageHandlerRef::removeHandler(int idx)
+{
+ OVR_ASSERT(idx < HandlersCount);
+
+ MessageHandlerImpl* handlerImpl = MessageHandlerImpl::FromHandler(pHandlers[idx]);
+ for (int i = 0; i < handlerImpl->HandlerRefsCount; i++)
+ if (handlerImpl->pHandlerRefs[i] == this)
{
- MessageHandlerImpl* handlerImpl = MessageHandlerImpl::FromHandler(handler);
- handlerImpl->UseList.PushBack(this);
+ handlerImpl->pHandlerRefs[i] = handlerImpl->pHandlerRefs[handlerImpl->HandlerRefsCount - 1];
+ handlerImpl->HandlerRefsCount--;
+
+ pHandlers[idx] = pHandlers[HandlersCount - 1];
+ HandlersCount--;
+
+ return true;
}
- // TBD: Call notifier on device?
- }
-}
+ // couldn't find a link in the opposite direction, assert in Debug
+ OVR_ASSERT(0);
+
+ pHandlers[idx] = pHandlers[HandlersCount - 1];
+ HandlersCount--;
+
+ return true;
+}
MessageHandler::MessageHandler()
{
@@ -198,7 +181,7 @@ MessageHandler::~MessageHandler()
MessageHandlerImpl* handlerImpl = MessageHandlerImpl::FromHandler(this);
{
Lock::Locker lockedScope(handlerImpl->pLock);
- OVR_ASSERT_LOG(handlerImpl->UseList.IsEmpty(),
+ OVR_ASSERT_LOG(handlerImpl->HandlerRefsCount == 0,
("~MessageHandler %p - Handler still active; call RemoveHandlerFromDevices", this));
}
@@ -209,19 +192,19 @@ bool MessageHandler::IsHandlerInstalled() const
{
const MessageHandlerImpl* handlerImpl = MessageHandlerImpl::FromHandler(this);
Lock::Locker lockedScope(handlerImpl->pLock);
- return handlerImpl->UseList.IsEmpty() != true;
-}
+ return handlerImpl->HandlerRefsCount > 0;
+}
void MessageHandler::RemoveHandlerFromDevices()
{
MessageHandlerImpl* handlerImpl = MessageHandlerImpl::FromHandler(this);
Lock::Locker lockedScope(handlerImpl->pLock);
- while(!handlerImpl->UseList.IsEmpty())
+ while (handlerImpl->HandlerRefsCount > 0)
{
- MessageHandlerRef* use = handlerImpl->UseList.GetFirst();
- use->SetHandler_NTS(0);
+ MessageHandlerRef* use = handlerImpl->pHandlerRefs[0];
+ use->RemoveHandler(this);
}
}
@@ -255,13 +238,9 @@ DeviceManager* DeviceBase::GetManager() const
return getDeviceCommon()->pCreateDesc->GetManagerImpl();
}
-void DeviceBase::SetMessageHandler(MessageHandler* handler)
-{
- getDeviceCommon()->HandlerRef.SetHandler(handler);
-}
-MessageHandler* DeviceBase::GetMessageHandler() const
+void DeviceBase::AddMessageHandler(MessageHandler* handler)
{
- return getDeviceCommon()->HandlerRef.GetHandler();
+ getDeviceCommon()->HandlerRef.AddHandler(handler);
}
DeviceType DeviceBase::GetType() const
@@ -276,6 +255,12 @@ bool DeviceBase::GetDeviceInfo(DeviceInfo* info) const
//return false;
}
+// Returns true if device is connected and usable
+bool DeviceBase::IsConnected()
+{
+ return getDeviceCommon()->ConnectedFlag;
+}
+
// returns the MessageHandler's lock
Lock* DeviceBase::GetHandlerLock() const
{
diff --git a/LibOVR/Src/OVR_DeviceImpl.h b/LibOVR/Src/OVR_DeviceImpl.h
index 7f85c78..80b227b 100644
--- a/LibOVR/Src/OVR_DeviceImpl.h
+++ b/LibOVR/Src/OVR_DeviceImpl.h
@@ -5,16 +5,16 @@ Content : Partial back-end independent implementation of Device interfaces
Created : October 10, 2012
Authors : Michael Antonov
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -43,61 +43,44 @@ class DeviceFactory;
enum
{
- Oculus_VendorId = 0x2833
-};
-
-//-------------------------------------------------------------------------------------
-// Globally shared Lock implementation used for MessageHandlers.
-
-class SharedLock
-{
-public:
- SharedLock() : UseCount(0) {}
-
- Lock* GetLockAddRef();
- void ReleaseLock(Lock* plock);
-
-private:
- Lock* toLock() { return (Lock*)Buffer; }
-
- // UseCount and max alignment.
- volatile int UseCount;
- UInt64 Buffer[(sizeof(Lock)+sizeof(UInt64)-1)/sizeof(UInt64)];
+ Oculus_VendorId = 0x2833,
+ Device_Tracker_ProductId = 0x0001,
+ Device_Tracker2_ProductId = 0x0021,
+ Device_KTracker_ProductId = 0x0010,
};
// Wrapper for MessageHandler that includes synchronization logic.
-// References to MessageHandlers are organized in a list to allow for them to
-// easily removed with MessageHandler::RemoveAllHandlers.
-class MessageHandlerRef : public ListNode<MessageHandlerRef>
-{
+class MessageHandlerRef
+{
+ enum
+ {
+ MaxHandlersCount = 4
+ };
public:
MessageHandlerRef(DeviceBase* device);
~MessageHandlerRef();
- void SetHandler(MessageHandler* hander);
-
+ bool HasHandlers() const { return HandlersCount > 0; };
+ void AddHandler(MessageHandler* handler);
+ // returns false if the handler is not found
+ bool RemoveHandler(MessageHandler* handler);
// Not-thread-safe version
- void SetHandler_NTS(MessageHandler* hander);
+ void AddHandler_NTS(MessageHandler* handler);
- void Call(const Message& msg)
- {
- Lock::Locker lockScope(pLock);
- if (pHandler)
- pHandler->OnMessage(msg);
- }
+ void Call(const Message& msg);
Lock* GetLock() const { return pLock; }
-
- // GetHandler() is not thread safe if used out of order across threads; nothing can be done
- // about that.
- MessageHandler* GetHandler() const { return pHandler; }
DeviceBase* GetDevice() const { return pDevice; }
private:
Lock* pLock; // Cached global handler lock.
DeviceBase* pDevice;
- MessageHandler* pHandler;
+
+ int HandlersCount;
+ MessageHandler* pHandlers[MaxHandlersCount];
+
+ bool removeHandler(int idx);
};
@@ -221,12 +204,15 @@ public:
AtomicInt<UInt32> RefCount;
Ptr<DeviceCreateDesc> pCreateDesc;
Ptr<DeviceBase> pParent;
+ volatile bool ConnectedFlag;
MessageHandlerRef HandlerRef;
DeviceCommon(DeviceCreateDesc* createDesc, DeviceBase* device, DeviceBase* parent)
- : RefCount(1), pCreateDesc(createDesc), pParent(parent), HandlerRef(device)
+ : RefCount(1), pCreateDesc(createDesc), pParent(parent),
+ ConnectedFlag(true), HandlerRef(device)
{
}
+ virtual ~DeviceCommon() {}
// Device reference counting delegates to Manager thread to actually kill devices.
void DeviceAddRef();
diff --git a/LibOVR/Src/OVR_DeviceMessages.h b/LibOVR/Src/OVR_DeviceMessages.h
index 6d525b3..0fe0a3c 100644
--- a/LibOVR/Src/OVR_DeviceMessages.h
+++ b/LibOVR/Src/OVR_DeviceMessages.h
@@ -6,16 +6,16 @@ Content : Definition of messages generated by devices
Created : February 5, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -35,10 +35,12 @@ limitations under the License.
#include "Kernel/OVR_Array.h"
#include "Kernel/OVR_Color.h"
+
namespace OVR {
class DeviceBase;
class DeviceHandle;
+class String;
#define OVR_MESSAGETYPE(devName, msgIndex) ((Device_##devName << 8) | msgIndex)
@@ -55,12 +57,17 @@ enum MessageType
Message_DeviceRemoved = OVR_MESSAGETYPE(Manager, 1), // Existing device has been plugged/unplugged.
// Sensor Messages
Message_BodyFrame = OVR_MESSAGETYPE(Sensor, 0), // Emitted by sensor at regular intervals.
+ Message_ExposureFrame = OVR_MESSAGETYPE(Sensor, 1),
+ Message_PixelRead = OVR_MESSAGETYPE(Sensor, 2),
+
// Latency Tester Messages
Message_LatencyTestSamples = OVR_MESSAGETYPE(LatencyTester, 0),
Message_LatencyTestColorDetected = OVR_MESSAGETYPE(LatencyTester, 1),
Message_LatencyTestStarted = OVR_MESSAGETYPE(LatencyTester, 2),
Message_LatencyTestButton = OVR_MESSAGETYPE(LatencyTester, 3),
-
+
+ Message_CameraFrame = OVR_MESSAGETYPE(Camera, 0),
+ Message_CameraAdded = OVR_MESSAGETYPE(Camera, 1),
};
//-------------------------------------------------------------------------------------
@@ -89,19 +96,37 @@ public:
// - Yaw is rotation around Y, positive for turning left.
// - Pitch is rotation around X, positive for pitching up.
+//-------------------------------------------------------------------------------------
+// ***** Sensor
+
class MessageBodyFrame : public Message
{
public:
MessageBodyFrame(DeviceBase* dev)
- : Message(Message_BodyFrame, dev), Temperature(0.0f), TimeDelta(0.0f)
+ : Message(Message_BodyFrame, dev), Temperature(0.0f), TimeDelta(0.0f), MagCalibrated(false)
{
}
Vector3f Acceleration; // Acceleration in m/s^2.
- Vector3f RotationRate; // Angular velocity in rad/s^2.
+ Vector3f RotationRate; // Angular velocity in rad/s.
Vector3f MagneticField; // Magnetic field strength in Gauss.
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
+ // device clock matching.
+ //
+ // Integration should use TimeDelta, but prediction into the future should derive
+ // the delta time from PredictToSeconds - AbsoluteTimeSeconds.
+ //
+ // This value will generally be <= the return from a call to ovr_GetTimeInSeconds(),
+ // but could be greater by under 1 ms due to system time update interrupt delays.
+ //
+ double AbsoluteTimeSeconds;
};
// Sent when we receive a device status changes (e.g.:
@@ -109,10 +134,36 @@ public:
class MessageDeviceStatus : public Message
{
public:
- MessageDeviceStatus(MessageType type, DeviceBase* dev, const DeviceHandle &hdev)
- : Message(type, dev), Handle(hdev) { }
+ MessageDeviceStatus(MessageType type, DeviceBase* dev, const DeviceHandle &hdev)
+ : Message(type, dev), Handle(hdev) { }
- DeviceHandle Handle;
+ DeviceHandle Handle;
+};
+
+class MessageExposureFrame : public Message
+{
+public:
+ MessageExposureFrame(DeviceBase* dev)
+ : Message(Message_ExposureFrame, dev),
+ CameraPattern(0), CameraFrameCount(0), CameraTimeSeconds(0) { }
+
+ UByte CameraPattern;
+ UInt32 CameraFrameCount;
+ double CameraTimeSeconds;
+};
+
+class MessagePixelRead : public Message
+{
+public:
+ MessagePixelRead(DeviceBase* dev)
+ : Message(Message_PixelRead, dev),
+ PixelReadValue(0), SensorTimeSeconds(0), FrameTimeSeconds(0) { }
+
+ UByte PixelReadValue;
+ UInt32 RawSensorTime;
+ UInt32 RawFrameTime;
+ double SensorTimeSeconds;
+ double FrameTimeSeconds;
};
//-------------------------------------------------------------------------------------
@@ -167,6 +218,50 @@ public:
};
+//-------------------------------------------------------------------------------------
+// ***** Camera
+
+// Sent by camera, frame.
+class MessageCameraFrame : public Message
+{
+public:
+ MessageCameraFrame(DeviceBase* dev)
+ : Message(Message_CameraFrame, dev)
+ {
+ LostFrames = 0;
+ }
+
+ void SetInfo(UInt32 frameNumber, double timeSeconds, UInt32 width, UInt32 height, UInt32 format)
+ {
+ FrameNumber = frameNumber;
+ ArrivalTimeSeconds = timeSeconds;
+ Width = width;
+ Height = height;
+ Format = format;
+ }
+
+ void SetData(const UByte* pdata, UInt32 sizeInBytes)
+ {
+ pFrameData = pdata;
+ FrameSizeInBytes = sizeInBytes;
+ }
+
+ UInt32 FrameNumber; // an index of the frame
+ double ArrivalTimeSeconds; // frame time in seconds, as recorded by the host computer
+ const UByte* pFrameData; // a ptr to frame data.
+ UInt32 FrameSizeInBytes; // size of the data in the pFrameData.
+ 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
+};
+
+// Sent when a new camera is connected
+class MessageCameraAdded : public Message
+{
+public:
+ MessageCameraAdded(DeviceBase* dev)
+ : Message(Message_CameraAdded, dev) { }
+};
} // namespace OVR
diff --git a/LibOVR/Src/OVR_HIDDevice.h b/LibOVR/Src/OVR_HIDDevice.h
index 7fc6fee..657758b 100644
--- a/LibOVR/Src/OVR_HIDDevice.h
+++ b/LibOVR/Src/OVR_HIDDevice.h
@@ -5,16 +5,16 @@ Content : Cross platform HID device interface.
Created : February 22, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -129,8 +129,8 @@ public:
virtual void OnInputReport(UByte* pData, UInt32 length)
{ OVR_UNUSED2(pData, length); }
- virtual UInt64 OnTicks(UInt64 ticksMks)
- { OVR_UNUSED1(ticksMks); return Timer::MksPerSecond * 1000; ; }
+ virtual double OnTicks(double tickSeconds)
+ { OVR_UNUSED1(tickSeconds); return 1000.0 ; }
enum HIDDeviceMessageType
{
diff --git a/LibOVR/Src/OVR_HIDDeviceBase.h b/LibOVR/Src/OVR_HIDDeviceBase.h
index 9d20dfc..7dfd6b4 100644
--- a/LibOVR/Src/OVR_HIDDeviceBase.h
+++ b/LibOVR/Src/OVR_HIDDeviceBase.h
@@ -6,16 +6,16 @@ Content : Definition of HID device interface.
Created : March 11, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/OVR_HIDDeviceImpl.h b/LibOVR/Src/OVR_HIDDeviceImpl.h
index 598adba..1399da6 100644
--- a/LibOVR/Src/OVR_HIDDeviceImpl.h
+++ b/LibOVR/Src/OVR_HIDDeviceImpl.h
@@ -5,16 +5,16 @@ Content : Implementation of HIDDevice.
Created : March 7, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -66,26 +66,21 @@ public:
MessageType handlerMessageType;
switch (messageType) {
case HIDDeviceMessage_DeviceAdded:
- handlerMessageType = Message_DeviceAdded;
+ handlerMessageType = Message_DeviceAdded;
+ DeviceImpl<B>::ConnectedFlag = true;
break;
case HIDDeviceMessage_DeviceRemoved:
- handlerMessageType = Message_DeviceRemoved;
+ handlerMessageType = Message_DeviceRemoved;
+ DeviceImpl<B>::ConnectedFlag = false;
break;
default: OVR_ASSERT(0); return;
}
// Do device notification.
- {
- Lock::Locker scopeLock(this->HandlerRef.GetLock());
-
- if (this->HandlerRef.GetHandler())
- {
- MessageDeviceStatus status(handlerMessageType, this, OVR::DeviceHandle(this->pCreateDesc));
- this->HandlerRef.GetHandler()->OnMessage(status);
- }
- }
+ MessageDeviceStatus status(handlerMessageType, this, OVR::DeviceHandle(this->pCreateDesc));
+ this->HandlerRef.Call(status);
// Do device manager notification.
DeviceManagerImpl* manager = this->GetManagerImpl();
@@ -128,9 +123,6 @@ public:
{
InternalDevice->SetHandler(NULL);
- // Remove the handler, if any.
- this->HandlerRef.SetHandler(0);
-
DeviceImpl<B>::pParent.Clear();
}
@@ -144,37 +136,21 @@ public:
return DeviceImpl<B>::pCreateDesc->GetManagerImpl()->GetHIDDeviceManager();
}
-
- struct WriteData
- {
- enum { BufferSize = 64 };
- UByte Buffer[64];
- UPInt Size;
-
- WriteData(UByte* data, UPInt size) : Size(size)
- {
- OVR_ASSERT(size <= BufferSize);
- memcpy(Buffer, data, size);
- }
- };
-
bool SetFeatureReport(UByte* data, UInt32 length)
{
- WriteData writeData(data, length);
-
// Push call with wait.
bool result = false;
ThreadCommandQueue* pQueue = this->GetManagerImpl()->GetThreadQueue();
- if (!pQueue->PushCallAndWaitResult(this, &HIDDeviceImpl::setFeatureReport, &result, writeData))
+ if (!pQueue->PushCallAndWaitResult(this, &HIDDeviceImpl::setFeatureReport, &result, data, length))
return false;
return result;
}
- bool setFeatureReport(const WriteData& data)
+ bool setFeatureReport(UByte* data, UInt32 length)
{
- return InternalDevice->SetFeatureReport((UByte*) data.Buffer, (UInt32) data.Size);
+ return InternalDevice->SetFeatureReport(data, length);
}
bool GetFeatureReport(UByte* data, UInt32 length)
@@ -193,6 +169,17 @@ public:
return InternalDevice->GetFeatureReport(data, length);
}
+ UByte GetDeviceInterfaceVersion()
+ {
+ UInt16 versionNumber = getHIDDesc()->VersionNumber;
+
+ // Our interface and hardware versions are represented as two BCD digits each.
+ // Interface version is in the last two digits.
+ UByte interfaceVersion = (UByte) ((versionNumber & 0x000F) >> 0) * 1 +
+ ((versionNumber & 0x00F0) >> 4) * 10;
+ return interfaceVersion;
+ }
+
protected:
HIDDevice* GetInternalDevice() const
{
diff --git a/LibOVR/Src/OVR_JSON.cpp b/LibOVR/Src/OVR_JSON.cpp
index 0625f6d..209a41f 100644
--- a/LibOVR/Src/OVR_JSON.cpp
+++ b/LibOVR/Src/OVR_JSON.cpp
@@ -30,16 +30,16 @@ Notes :
THE SOFTWARE.
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -949,6 +949,17 @@ void JSON::ReplaceItem(unsigned int index, JSON* new_item)
}
*/
+// Removes and frees the last child item
+void JSON::RemoveLast()
+{
+ JSON* child = Children.GetLast();
+ if (!Children.IsNull(child))
+ {
+ child->RemoveNode();
+ child->Release();
+ }
+}
+
// Helper function to simplify creation of a typed object
JSON* JSON::createHelper(JSONItemType itemType, double dval, const char* strVal)
{
@@ -973,6 +984,31 @@ void JSON::AddArrayElement(JSON *item)
Children.PushBack(item);
}
+// Inserts an element into a valid array position
+void JSON::InsertArrayElement(int index, JSON *item)
+{
+ if (!item)
+ return;
+
+ if (index == 0)
+ {
+ Children.PushFront(item);
+ return;
+ }
+
+ JSON* iter = Children.GetFirst();
+ int i=0;
+ while (iter && i<index)
+ {
+ iter = Children.GetNext(iter);
+ i++;
+ }
+
+ if (iter)
+ iter->InsertNodeBefore(item);
+ else
+ Children.PushBack(item);
+}
// Returns the size of an array
int JSON::GetArraySize()
@@ -1011,6 +1047,23 @@ const char* JSON::GetArrayString(int index)
}
}
+JSON* JSON::Copy()
+{
+ JSON* copy = new JSON(Type);
+ copy->Name = Name;
+ copy->Value = Value;
+ copy->dValue = dValue;
+
+ JSON* child = Children.GetFirst();
+ while (!Children.IsNull(child))
+ {
+ copy->Children.PushBack(child->Copy());
+ child = Children.GetNext(child);
+ }
+
+ return copy;
+}
+
//-----------------------------------------------------------------------------
// Loads and parses the given JSON file pathname and returns a JSON object tree.
// The returned object must be Released after use.
@@ -1051,7 +1104,7 @@ bool JSON::Save(const char* path)
if (text)
{
SPInt len = OVR_strlen(text);
- OVR_ASSERT(len < (SPInt)(int)len);
+ OVR_ASSERT(len <= (SPInt)(int)len);
int bytes = f.Write((UByte*)text, (int)len);
f.Close();
diff --git a/LibOVR/Src/OVR_JSON.h b/LibOVR/Src/OVR_JSON.h
index ece84be..7a2e939 100644
--- a/LibOVR/Src/OVR_JSON.h
+++ b/LibOVR/Src/OVR_JSON.h
@@ -7,16 +7,16 @@ Created : April 9, 2013
Author : Brant Lewis
Notes :
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -48,7 +48,6 @@ enum JSONItemType
JSON_Object = 6
};
-
//-----------------------------------------------------------------------------
// ***** JSON
@@ -90,7 +89,6 @@ public:
// Saves a JSON object to a file.
bool Save(const char* path);
-
// *** Object Member Access
// These provide access to child items of the list.
@@ -117,11 +115,13 @@ public:
void AddStringItem(const char* name, const char* s) { AddItem(name, CreateString(s)); }
// void ReplaceItem(unsigned index, JSON* new_item);
// void DeleteItem(unsigned index);
+ void RemoveLast();
// *** Array Element Access
// Add new elements to the end of array.
void AddArrayElement(JSON *item);
+ void InsertArrayElement(int index, JSON* item);
void AddArrayNumber(double n) { AddArrayElement(CreateNumber(n)); }
void AddArrayString(const char* s) { AddArrayElement(CreateString(s)); }
@@ -130,6 +130,7 @@ public:
double GetArrayNumber(int index);
const char* GetArrayString(int index);
+ JSON* Copy(); // Create a copy of this object
protected:
JSON(JSONItemType itemType = JSON_Object);
diff --git a/LibOVR/Src/OVR_LatencyTestImpl.cpp b/LibOVR/Src/OVR_LatencyTestImpl.cpp
index 209487c..9385a37 100644
--- a/LibOVR/Src/OVR_LatencyTestImpl.cpp
+++ b/LibOVR/Src/OVR_LatencyTestImpl.cpp
@@ -5,16 +5,16 @@ Content : Oculus Latency Tester device implementation.
Created : March 7, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -25,9 +25,12 @@ limitations under the License.
*************************************************************************************/
#include "OVR_LatencyTestImpl.h"
+#include "Kernel/OVR_Alg.h"
namespace OVR {
+using namespace Alg;
+
//-------------------------------------------------------------------------------------
// ***** Oculus Latency Tester specific packet data structures
@@ -36,18 +39,6 @@ enum {
LatencyTester_ProductId = 0x0101,
};
-// Reported data is little-endian now
-static UInt16 DecodeUInt16(const UByte* buffer)
-{
- return (UInt16(buffer[1]) << 8) | UInt16(buffer[0]);
-}
-
-/* Unreferenced
-static SInt16 DecodeSInt16(const UByte* buffer)
-{
- return (SInt16(buffer[1]) << 8) | SInt16(buffer[0]);
-}*/
-
static void UnpackSamples(const UByte* buffer, UByte* r, UByte* g, UByte* b)
{
*r = buffer[0];
@@ -355,8 +346,7 @@ struct LatencyTestStartTestImpl
UInt16 commandID = 1;
Buffer[0] = 8;
- Buffer[1] = UByte(commandID & 0xFF);
- Buffer[2] = UByte(commandID >> 8);
+ EncodeUInt16(Buffer+1, commandID);
Buffer[3] = TargetColor.R;
Buffer[4] = TargetColor.G;
Buffer[5] = TargetColor.B;
@@ -364,7 +354,7 @@ struct LatencyTestStartTestImpl
void Unpack()
{
-// UInt16 commandID = Buffer[1] | (UInt16(Buffer[2]) << 8);
+// UInt16 commandID = DecodeUInt16(Buffer+1);
TargetColor.R = Buffer[3];
TargetColor.G = Buffer[4];
TargetColor.B = Buffer[5];
@@ -388,19 +378,13 @@ struct LatencyTestDisplayImpl
{
Buffer[0] = 9;
Buffer[1] = Display.Mode;
- Buffer[2] = UByte(Display.Value & 0xFF);
- Buffer[3] = UByte((Display.Value >> 8) & 0xFF);
- Buffer[4] = UByte((Display.Value >> 16) & 0xFF);
- Buffer[5] = UByte((Display.Value >> 24) & 0xFF);
+ EncodeUInt32(Buffer+2, Display.Value);
}
void Unpack()
{
Display.Mode = Buffer[1];
- Display.Value = UInt32(Buffer[2]) |
- (UInt32(Buffer[3]) << 8) |
- (UInt32(Buffer[4]) << 16) |
- (UInt32(Buffer[5]) << 24);
+ Display.Value = DecodeUInt32(Buffer+2);
}
};
@@ -471,17 +455,17 @@ bool LatencyTestDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const
(info->InfoClassType != Device_None))
return false;
- OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength, HIDDesc.Product.ToCStr());
- OVR_strcpy(info->Manufacturer, DeviceInfo::MaxNameLength, HIDDesc.Manufacturer.ToCStr());
- info->Type = Device_LatencyTester;
+ info->Type = Device_LatencyTester;
+ info->ProductName = HIDDesc.Product;
+ info->Manufacturer = HIDDesc.Manufacturer;
+ info->Version = HIDDesc.VersionNumber;
if (info->InfoClassType == Device_LatencyTester)
{
SensorInfo* sinfo = (SensorInfo*)info;
sinfo->VendorId = HIDDesc.VendorId;
sinfo->ProductId = HIDDesc.ProductId;
- sinfo->Version = HIDDesc.VersionNumber;
- OVR_strcpy(sinfo->SerialNumber, sizeof(sinfo->SerialNumber),HIDDesc.SerialNumber.ToCStr());
+ sinfo->SerialNumber = HIDDesc.SerialNumber;
}
return true;
}
@@ -712,7 +696,7 @@ void LatencyTestDeviceImpl::onLatencyTestSamplesMessage(LatencyTestSamplesMessag
// Call OnMessage() within a lock to avoid conflicts with handlers.
Lock::Locker scopeLock(HandlerRef.GetLock());
- if (HandlerRef.GetHandler())
+ if (HandlerRef.HasHandlers())
{
MessageLatencyTestSamples samples(this);
for (UByte i = 0; i < s.SampleCount; i++)
@@ -720,7 +704,7 @@ void LatencyTestDeviceImpl::onLatencyTestSamplesMessage(LatencyTestSamplesMessag
samples.Samples.PushBack(Color(s.Samples[i].Value[0], s.Samples[i].Value[1], s.Samples[i].Value[2]));
}
- HandlerRef.GetHandler()->OnMessage(samples);
+ HandlerRef.Call(samples);
}
}
@@ -734,14 +718,14 @@ void LatencyTestDeviceImpl::onLatencyTestColorDetectedMessage(LatencyTestColorDe
// Call OnMessage() within a lock to avoid conflicts with handlers.
Lock::Locker scopeLock(HandlerRef.GetLock());
- if (HandlerRef.GetHandler())
+ if (HandlerRef.HasHandlers())
{
MessageLatencyTestColorDetected detected(this);
detected.Elapsed = s.Elapsed;
detected.DetectedValue = Color(s.TriggerValue[0], s.TriggerValue[1], s.TriggerValue[2]);
detected.TargetValue = Color(s.TargetValue[0], s.TargetValue[1], s.TargetValue[2]);
- HandlerRef.GetHandler()->OnMessage(detected);
+ HandlerRef.Call(detected);
}
}
@@ -755,12 +739,12 @@ void LatencyTestDeviceImpl::onLatencyTestStartedMessage(LatencyTestStartedMessag
// Call OnMessage() within a lock to avoid conflicts with handlers.
Lock::Locker scopeLock(HandlerRef.GetLock());
- if (HandlerRef.GetHandler())
+ if (HandlerRef.HasHandlers())
{
MessageLatencyTestStarted started(this);
started.TargetValue = Color(ts.TargetValue[0], ts.TargetValue[1], ts.TargetValue[2]);
- HandlerRef.GetHandler()->OnMessage(started);
+ HandlerRef.Call(started);
}
}
@@ -774,11 +758,11 @@ void LatencyTestDeviceImpl::onLatencyTestButtonMessage(LatencyTestButtonMessage*
// Call OnMessage() within a lock to avoid conflicts with handlers.
Lock::Locker scopeLock(HandlerRef.GetLock());
- if (HandlerRef.GetHandler())
+ if (HandlerRef.HasHandlers())
{
MessageLatencyTestButton button(this);
- HandlerRef.GetHandler()->OnMessage(button);
+ HandlerRef.Call(button);
}
}
diff --git a/LibOVR/Src/OVR_LatencyTestImpl.h b/LibOVR/Src/OVR_LatencyTestImpl.h
index bab0180..21ef331 100644
--- a/LibOVR/Src/OVR_LatencyTestImpl.h
+++ b/LibOVR/Src/OVR_LatencyTestImpl.h
@@ -5,16 +5,16 @@ Content : Latency Tester specific implementation.
Created : March 7, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/OVR_Linux_DeviceManager.cpp b/LibOVR/Src/OVR_Linux_DeviceManager.cpp
deleted file mode 100644
index 298534b..0000000
--- a/LibOVR/Src/OVR_Linux_DeviceManager.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-/************************************************************************************
-
-Filename : OVR_Linux_DeviceManager.h
-Content : Linux implementation of DeviceManager.
-Created :
-Authors :
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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 "OVR_Linux_DeviceManager.h"
-
-// Sensor & HMD Factories
-#include "OVR_LatencyTestImpl.h"
-#include "OVR_SensorImpl.h"
-#include "OVR_Linux_HIDDevice.h"
-#include "OVR_Linux_HMDDevice.h"
-
-#include "Kernel/OVR_Timer.h"
-#include "Kernel/OVR_Std.h"
-#include "Kernel/OVR_Log.h"
-
-namespace OVR { namespace Linux {
-
-
-//-------------------------------------------------------------------------------------
-// **** Linux::DeviceManager
-
-DeviceManager::DeviceManager()
-{
-}
-
-DeviceManager::~DeviceManager()
-{
-}
-
-bool DeviceManager::Initialize(DeviceBase*)
-{
- if (!DeviceManagerImpl::Initialize(0))
- return false;
-
- pThread = *new DeviceManagerThread();
- if (!pThread || !pThread->Start())
- return false;
-
- // Wait for the thread to be fully up and running.
- pThread->StartupEvent.Wait();
-
- // Do this now that we know the thread's run loop.
- HidDeviceManager = *HIDDeviceManager::CreateInternal(this);
-
- pCreateDesc->pDevice = this;
- LogText("OVR::DeviceManager - initialized.\n");
- return true;
-}
-
-void DeviceManager::Shutdown()
-{
- LogText("OVR::DeviceManager - shutting down.\n");
-
- // Set Manager shutdown marker variable; this prevents
- // any existing DeviceHandle objects from accessing device.
- pCreateDesc->pLock->pManager = 0;
-
- // Push for thread shutdown *WITH NO WAIT*.
- // This will have the following effect:
- // - Exit command will get enqueued, which will be executed later on the thread itself.
- // - Beyond this point, this DeviceManager object may be deleted by our caller.
- // - Other commands, such as CreateDevice, may execute before ExitCommand, but they will
- // fail gracefully due to pLock->pManager == 0. Future commands can't be enqued
- // after pManager is null.
- // - Once ExitCommand executes, ThreadCommand::Run loop will exit and release the last
- // reference to the thread object.
- pThread->PushExitCommand(false);
- pThread.Clear();
-
- DeviceManagerImpl::Shutdown();
-}
-
-ThreadCommandQueue* DeviceManager::GetThreadQueue()
-{
- return pThread;
-}
-
-ThreadId DeviceManager::GetThreadId() const
-{
- return pThread->GetThreadId();
-}
-
-bool DeviceManager::GetDeviceInfo(DeviceInfo* info) const
-{
- if ((info->InfoClassType != Device_Manager) &&
- (info->InfoClassType != Device_None))
- return false;
-
- info->Type = Device_Manager;
- info->Version = 0;
- OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength, "DeviceManager");
- OVR_strcpy(info->Manufacturer,DeviceInfo::MaxNameLength, "Oculus VR, Inc.");
- return true;
-}
-
-DeviceEnumerator<> DeviceManager::EnumerateDevicesEx(const DeviceEnumerationArgs& args)
-{
- // TBD: Can this be avoided in the future, once proper device notification is in place?
- pThread->PushCall((DeviceManagerImpl*)this,
- &DeviceManager::EnumerateAllFactoryDevices, true);
-
- return DeviceManagerImpl::EnumerateDevicesEx(args);
-}
-
-
-//-------------------------------------------------------------------------------------
-// ***** DeviceManager Thread
-
-DeviceManagerThread::DeviceManagerThread()
- : Thread(ThreadStackSize)
-{
- int result = pipe(CommandFd);
- OVR_ASSERT(!result);
-
- AddSelectFd(NULL, CommandFd[0]);
-}
-
-DeviceManagerThread::~DeviceManagerThread()
-{
- if (CommandFd[0])
- {
- RemoveSelectFd(NULL, CommandFd[0]);
- close(CommandFd[0]);
- close(CommandFd[1]);
- }
-}
-
-bool DeviceManagerThread::AddSelectFd(Notifier* notify, int fd)
-{
- struct pollfd pfd;
- pfd.fd = fd;
- pfd.events = POLLIN|POLLHUP|POLLERR;
- pfd.revents = 0;
-
- FdNotifiers.PushBack(notify);
- PollFds.PushBack(pfd);
-
- OVR_ASSERT(FdNotifiers.GetSize() == PollFds.GetSize());
- return true;
-}
-
-bool DeviceManagerThread::RemoveSelectFd(Notifier* notify, int fd)
-{
- // [0] is reserved for thread commands with notify of null, but we still
- // can use this function to remove it.
- for (UPInt i = 0; i < FdNotifiers.GetSize(); i++)
- {
- if ((FdNotifiers[i] == notify) && (PollFds[i].fd == fd))
- {
- FdNotifiers.RemoveAt(i);
- PollFds.RemoveAt(i);
- return true;
- }
- }
- return false;
-}
-
-
-
-int DeviceManagerThread::Run()
-{
- ThreadCommand::PopBuffer command;
-
- SetThreadName("OVR::DeviceManagerThread");
- LogText("OVR::DeviceManagerThread - running (ThreadId=%p).\n", GetThreadId());
-
- // Signal to the parent thread that initialization has finished.
- StartupEvent.SetEvent();
-
- while(!IsExiting())
- {
- // PopCommand will reset event on empty queue.
- if (PopCommand(&command))
- {
- command.Execute();
- }
- else
- {
- bool commands = 0;
- do
- {
- int waitMs = -1;
-
- // If devices have time-dependent logic registered, get the longest wait
- // allowed based on current ticks.
- if (!TicksNotifiers.IsEmpty())
- {
- UInt64 ticksMks = Timer::GetTicks();
- int waitAllowed;
-
- for (UPInt j = 0; j < TicksNotifiers.GetSize(); j++)
- {
- waitAllowed = (int)(TicksNotifiers[j]->OnTicks(ticksMks) / Timer::MksPerMs);
- if (waitAllowed < waitMs)
- waitMs = waitAllowed;
- }
- }
-
- // wait until there is data available on one of the devices or the timeout expires
- int n = poll(&PollFds[0], PollFds.GetSize(), waitMs);
-
- if (n > 0)
- {
- // Iterate backwards through the list so the ordering will not be
- // affected if the called object gets removed during the callback
- // Also, the HID data streams are located toward the back of the list
- // and servicing them first will allow a disconnect to be handled
- // and cleaned directly at the device first instead of the general HID monitor
- for (int i=PollFds.GetSize()-1; i>=0; i--)
- {
- if (PollFds[i].revents & POLLERR)
- {
- OVR_DEBUG_LOG(("poll: error on [%d]: %d", i, PollFds[i].fd));
- }
- else if (PollFds[i].revents & POLLIN)
- {
- if (FdNotifiers[i])
- FdNotifiers[i]->OnEvent(i, PollFds[i].fd);
- else if (i == 0) // command
- {
- char dummy[128];
- read(PollFds[i].fd, dummy, 128);
- commands = 1;
- }
- }
-
- if (PollFds[i].revents & POLLHUP)
- PollFds[i].events = 0;
-
- if (PollFds[i].revents != 0)
- {
- n--;
- if (n == 0)
- break;
- }
- }
- }
- } while (PollFds.GetSize() > 0 && !commands);
- }
- }
-
- LogText("OVR::DeviceManagerThread - exiting (ThreadId=%p).\n", GetThreadId());
- return 0;
-}
-
-bool DeviceManagerThread::AddTicksNotifier(Notifier* notify)
-{
- TicksNotifiers.PushBack(notify);
- return true;
-}
-
-bool DeviceManagerThread::RemoveTicksNotifier(Notifier* notify)
-{
- for (UPInt i = 0; i < TicksNotifiers.GetSize(); i++)
- {
- if (TicksNotifiers[i] == notify)
- {
- TicksNotifiers.RemoveAt(i);
- return true;
- }
- }
- return false;
-}
-
-} // namespace Linux
-
-
-//-------------------------------------------------------------------------------------
-// ***** Creation
-
-
-// Creates a new DeviceManager and initializes OVR.
-DeviceManager* DeviceManager::Create()
-{
- if (!System::IsInitialized())
- {
- // Use custom message, since Log is not yet installed.
- OVR_DEBUG_STATEMENT(Log::GetDefaultLog()->
- LogMessage(Log_Debug, "DeviceManager::Create failed - OVR::System not initialized"); );
- return 0;
- }
-
- Ptr<Linux::DeviceManager> manager = *new Linux::DeviceManager;
-
- if (manager)
- {
- if (manager->Initialize(0))
- {
- manager->AddFactory(&LatencyTestDeviceFactory::Instance);
- manager->AddFactory(&SensorDeviceFactory::Instance);
- manager->AddFactory(&Linux::HMDDeviceFactory::Instance);
-
- manager->AddRef();
- }
- else
- {
- manager.Clear();
- }
-
- }
-
- return manager.GetPtr();
-}
-
-
-} // namespace OVR
-
diff --git a/LibOVR/Src/OVR_Linux_DeviceManager.h b/LibOVR/Src/OVR_Linux_DeviceManager.h
deleted file mode 100644
index 101f871..0000000
--- a/LibOVR/Src/OVR_Linux_DeviceManager.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/************************************************************************************
-
-Filename : OVR_Linux_DeviceManager.h
-Content : Linux-specific DeviceManager header.
-Created :
-Authors :
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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_Linux_DeviceManager_h
-#define OVR_Linux_DeviceManager_h
-
-#include "OVR_DeviceImpl.h"
-
-#include <unistd.h>
-#include <sys/poll.h>
-
-
-namespace OVR { namespace Linux {
-
-class DeviceManagerThread;
-
-//-------------------------------------------------------------------------------------
-// ***** Linux DeviceManager
-
-class DeviceManager : public DeviceManagerImpl
-{
-public:
- DeviceManager();
- ~DeviceManager();
-
- // Initialize/Shutdowncreate and shutdown manger thread.
- virtual bool Initialize(DeviceBase* parent);
- virtual void Shutdown();
-
- virtual ThreadCommandQueue* GetThreadQueue();
- virtual ThreadId GetThreadId() const;
-
- virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args);
-
- virtual bool GetDeviceInfo(DeviceInfo* info) const;
-
- Ptr<DeviceManagerThread> pThread;
-};
-
-//-------------------------------------------------------------------------------------
-// ***** Device Manager Background Thread
-
-class DeviceManagerThread : public Thread, public ThreadCommandQueue
-{
- friend class DeviceManager;
- enum { ThreadStackSize = 64 * 1024 };
-public:
- DeviceManagerThread();
- ~DeviceManagerThread();
-
- virtual int Run();
-
- // ThreadCommandQueue notifications for CommandEvent handling.
- virtual void OnPushNonEmpty_Locked() { write(CommandFd[1], this, 1); }
- virtual void OnPopEmpty_Locked() { }
-
- class Notifier
- {
- public:
- // Called when I/O is received
- virtual void OnEvent(int i, int fd) = 0;
-
- // Called when timing ticks are updated.
- // Returns the largest number of microseconds this function can
- // wait till next call.
- virtual UInt64 OnTicks(UInt64 ticksMks)
- {
- OVR_UNUSED1(ticksMks);
- return Timer::MksPerSecond * 1000;
- }
- };
-
- // Add I/O notifier
- bool AddSelectFd(Notifier* notify, int fd);
- bool RemoveSelectFd(Notifier* notify, int fd);
-
- // Add notifier that will be called at regular intervals.
- bool AddTicksNotifier(Notifier* notify);
- bool RemoveTicksNotifier(Notifier* notify);
-
-private:
-
- bool threadInitialized() { return CommandFd[0] != 0; }
-
- // pipe used to signal commands
- int CommandFd[2];
-
- Array<struct pollfd> PollFds;
- Array<Notifier*> FdNotifiers;
-
- Event StartupEvent;
-
- // Ticks notifiers - used for time-dependent events such as keep-alive.
- Array<Notifier*> TicksNotifiers;
-};
-
-}} // namespace Linux::OVR
-
-#endif // OVR_Linux_DeviceManager_h
diff --git a/LibOVR/Src/OVR_Linux_HIDDevice.cpp b/LibOVR/Src/OVR_Linux_HIDDevice.cpp
deleted file mode 100644
index ed4db0e..0000000
--- a/LibOVR/Src/OVR_Linux_HIDDevice.cpp
+++ /dev/null
@@ -1,815 +0,0 @@
-/************************************************************************************
-Filename : OVR_Linux_HIDDevice.cpp
-Content : Linux HID device implementation.
-Created : February 26, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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 "OVR_Linux_HIDDevice.h"
-
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <linux/hidraw.h>
-#include "OVR_HIDDeviceImpl.h"
-
-namespace OVR { namespace Linux {
-
-static const UInt32 MAX_QUEUED_INPUT_REPORTS = 5;
-
-//-------------------------------------------------------------------------------------
-// **** Linux::DeviceManager
-//-----------------------------------------------------------------------------
-HIDDeviceManager::HIDDeviceManager(DeviceManager* manager) : DevManager(manager)
-{
- UdevInstance = NULL;
- HIDMonitor = NULL;
- HIDMonHandle = -1;
-}
-
-//-----------------------------------------------------------------------------
-HIDDeviceManager::~HIDDeviceManager()
-{
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDeviceManager::initializeManager()
-{
- if (HIDMonitor)
- {
- return true;
- }
-
- // Create a udev_monitor handle to watch for device changes (hot-plug detection)
- HIDMonitor = udev_monitor_new_from_netlink(UdevInstance, "udev");
- if (HIDMonitor == NULL)
- {
- return false;
- }
-
- udev_monitor_filter_add_match_subsystem_devtype(HIDMonitor, "hidraw", NULL); // filter for hidraw only
-
- int err = udev_monitor_enable_receiving(HIDMonitor);
- if (err)
- {
- udev_monitor_unref(HIDMonitor);
- HIDMonitor = NULL;
- return false;
- }
-
- // Get the file descriptor (fd) for the monitor.
- HIDMonHandle = udev_monitor_get_fd(HIDMonitor);
- if (HIDMonHandle < 0)
- {
- udev_monitor_unref(HIDMonitor);
- HIDMonitor = NULL;
- return false;
- }
-
- // This file handle will be polled along-side with the device hid handles for changes
- // Add the handle to the polling list
- if (!DevManager->pThread->AddSelectFd(this, HIDMonHandle))
- {
- close(HIDMonHandle);
- HIDMonHandle = -1;
-
- udev_monitor_unref(HIDMonitor);
- HIDMonitor = NULL;
- return false;
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDeviceManager::Initialize()
-{
- // Get a udev library handle. This handle must stay active during the
- // duration the lifetime of device monitoring handles
- UdevInstance = udev_new();
- if (!UdevInstance)
- return false;
-
- return initializeManager();
-}
-
-//-----------------------------------------------------------------------------
-void HIDDeviceManager::Shutdown()
-{
- OVR_ASSERT_LOG((UdevInstance), ("Should have called 'Initialize' before 'Shutdown'."));
-
- if (HIDMonitor)
- {
- DevManager->pThread->RemoveSelectFd(this, HIDMonHandle);
- close(HIDMonHandle);
- HIDMonHandle = -1;
-
- udev_monitor_unref(HIDMonitor);
- HIDMonitor = NULL;
- }
-
- udev_unref(UdevInstance); // release the library
-
- LogText("OVR::Linux::HIDDeviceManager - shutting down.\n");
-}
-
-//-------------------------------------------------------------------------------
-bool HIDDeviceManager::AddNotificationDevice(HIDDevice* device)
-{
- NotificationDevices.PushBack(device);
- return true;
-}
-
-//-------------------------------------------------------------------------------
-bool HIDDeviceManager::RemoveNotificationDevice(HIDDevice* device)
-{
- for (UPInt i = 0; i < NotificationDevices.GetSize(); i++)
- {
- if (NotificationDevices[i] == device)
- {
- NotificationDevices.RemoveAt(i);
- return true;
- }
- }
- return false;
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDeviceManager::getIntProperty(udev_device* device,
- const char* propertyName,
- SInt32* pResult)
-{
- const char* str = udev_device_get_sysattr_value(device, propertyName);
- if (str)
- {
- *pResult = strtol(str, NULL, 16);
- return true;
- }
- else
- {
- *pResult = 0;
- return true;
- }
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDeviceManager::initVendorProductVersion(udev_device* device, HIDDeviceDesc* pDevDesc)
-{
- SInt32 result;
- if (getIntProperty(device, "idVendor", &result))
- pDevDesc->VendorId = result;
- else
- return false;
-
- if (getIntProperty(device, "idProduct", &result))
- pDevDesc->ProductId = result;
- else
- return false;
-
- if (getIntProperty(device, "bcdDevice", &result))
- pDevDesc->VersionNumber = result;
- else
- return false;
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDeviceManager::getStringProperty(udev_device* device,
- const char* propertyName,
- OVR::String* pResult)
-{
- // Get the attribute in UTF8
- const char* str = udev_device_get_sysattr_value(device, propertyName);
- if (str)
- { // Copy the string into the return value
- *pResult = String(str);
- return true;
- }
- else
- {
- return false;
- }
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor)
-{
-
- if (!initializeManager())
- {
- return false;
- }
-
- // Get a list of hid devices
- udev_enumerate* devices = udev_enumerate_new(UdevInstance);
- udev_enumerate_add_match_subsystem(devices, "hidraw");
- udev_enumerate_scan_devices(devices);
-
- udev_list_entry* entry = udev_enumerate_get_list_entry(devices);
-
- // Search each device for the matching vid/pid
- while (entry != NULL)
- {
- // Get the device file name
- const char* sysfs_path = udev_list_entry_get_name(entry);
- udev_device* hid; // The device's HID udev node.
- hid = udev_device_new_from_syspath(UdevInstance, sysfs_path);
- const char* dev_path = udev_device_get_devnode(hid);
-
- // Get the USB device
- hid = udev_device_get_parent_with_subsystem_devtype(hid, "usb", "usb_device");
- if (hid)
- {
- HIDDeviceDesc devDesc;
-
- // Check the VID/PID for a match
- if (dev_path &&
- initVendorProductVersion(hid, &devDesc) &&
- enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId))
- {
- devDesc.Path = dev_path;
- getFullDesc(hid, &devDesc);
-
- // Look for the device to check if it is already opened.
- Ptr<DeviceCreateDesc> existingDevice = DevManager->FindHIDDevice(devDesc, true);
- // if device exists and it is opened then most likely the device open()
- // will fail; therefore, we just set Enumerated to 'true' and continue.
- if (existingDevice && existingDevice->pDevice)
- {
- existingDevice->Enumerated = true;
- }
- else
- { // open the device temporarily for startup communication
- int device_handle = open(dev_path, O_RDWR);
- if (device_handle >= 0)
- {
- // Construct minimal device that the visitor callback can get feature reports from
- Linux::HIDDevice device(this, device_handle);
- enumVisitor->Visit(device, devDesc);
-
- close(device_handle); // close the file handle
- }
- }
- }
-
- udev_device_unref(hid);
- entry = udev_list_entry_get_next(entry);
- }
- }
-
- // Free the enumerator and udev objects
- udev_enumerate_unref(devices);
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-OVR::HIDDevice* HIDDeviceManager::Open(const String& path)
-{
- Ptr<Linux::HIDDevice> device = *new Linux::HIDDevice(this);
-
- if (device->HIDInitialize(path))
- {
- device->AddRef();
- return device;
- }
-
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDeviceManager::getFullDesc(udev_device* device, HIDDeviceDesc* desc)
-{
-
- if (!initVendorProductVersion(device, desc))
- {
- return false;
- }
-
- if (!getStringProperty(device, "serial", &(desc->SerialNumber)))
- {
- return false;
- }
-
- getStringProperty(device, "manufacturer", &(desc->Manufacturer));
- getStringProperty(device, "product", &(desc->Product));
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDeviceManager::GetDescriptorFromPath(const char* dev_path, HIDDeviceDesc* desc)
-{
- if (!initializeManager())
- {
- return false;
- }
-
- // Search for the udev device from the given pathname so we can
- // have a handle to query device properties
-
- udev_enumerate* devices = udev_enumerate_new(UdevInstance);
- udev_enumerate_add_match_subsystem(devices, "hidraw");
- udev_enumerate_scan_devices(devices);
-
- udev_list_entry* entry = udev_enumerate_get_list_entry(devices);
-
- bool success = false;
- // Search for the device with the matching path
- while (entry != NULL)
- {
- // Get the device file name
- const char* sysfs_path = udev_list_entry_get_name(entry);
- udev_device* hid; // The device's HID udev node.
- hid = udev_device_new_from_syspath(UdevInstance, sysfs_path);
- const char* path = udev_device_get_devnode(hid);
-
- if (OVR_strcmp(dev_path, path) == 0)
- { // Found the device so lets collect the device descriptor
-
- // Get the USB device
- hid = udev_device_get_parent_with_subsystem_devtype(hid, "usb", "usb_device");
- if (hid)
- {
- desc->Path = dev_path;
- success = getFullDesc(hid, desc);
- }
-
- }
-
- udev_device_unref(hid);
- entry = udev_list_entry_get_next(entry);
- }
-
- // Free the enumerator
- udev_enumerate_unref(devices);
-
- return success;
-}
-
-//-----------------------------------------------------------------------------
-void HIDDeviceManager::OnEvent(int i, int fd)
-{
- // There is a device status change
- udev_device* hid = udev_monitor_receive_device(HIDMonitor);
- if (hid)
- {
- const char* dev_path = udev_device_get_devnode(hid);
- const char* action = udev_device_get_action(hid);
-
- HIDDeviceDesc device_info;
- device_info.Path = dev_path;
-
- MessageType notify_type;
- if (OVR_strcmp(action, "add") == 0)
- {
- notify_type = Message_DeviceAdded;
-
- // Retrieve the device info. This can only be done on a connected
- // device and is invalid for a disconnected device
-
- // Get the USB device
- hid = udev_device_get_parent_with_subsystem_devtype(hid, "usb", "usb_device");
- if (!hid)
- {
- return;
- }
-
- getFullDesc(hid, &device_info);
- }
- else if (OVR_strcmp(action, "remove") == 0)
- {
- notify_type = Message_DeviceRemoved;
- }
- else
- {
- return;
- }
-
- bool error = false;
- bool deviceFound = false;
- for (UPInt i = 0; i < NotificationDevices.GetSize(); i++)
- {
- if (NotificationDevices[i] &&
- NotificationDevices[i]->OnDeviceNotification(notify_type, &device_info, &error))
- {
- // The notification was for an existing device
- deviceFound = true;
- break;
- }
- }
-
- if (notify_type == Message_DeviceAdded && !deviceFound)
- {
- DevManager->DetectHIDDevice(device_info);
- }
-
- udev_device_unref(hid);
- }
-}
-
-//=============================================================================
-// Linux::HIDDevice
-//=============================================================================
-HIDDevice::HIDDevice(HIDDeviceManager* manager)
- : HIDManager(manager), InMinimalMode(false)
-{
- DeviceHandle = -1;
-}
-
-//-----------------------------------------------------------------------------
-// This is a minimal constructor used during enumeration for us to pass
-// a HIDDevice to the visit function (so that it can query feature reports).
-HIDDevice::HIDDevice(HIDDeviceManager* manager, int device_handle)
-: HIDManager(manager), DeviceHandle(device_handle), InMinimalMode(true)
-{
-}
-
-//-----------------------------------------------------------------------------
-HIDDevice::~HIDDevice()
-{
- if (!InMinimalMode)
- {
- HIDShutdown();
- }
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDevice::HIDInitialize(const String& path)
-{
- const char* hid_path = path.ToCStr();
- if (!openDevice(hid_path))
- {
- LogText("OVR::Linux::HIDDevice - Failed to open HIDDevice: %s", hid_path);
- return false;
- }
-
- HIDManager->DevManager->pThread->AddTicksNotifier(this);
- HIDManager->AddNotificationDevice(this);
-
- LogText("OVR::Linux::HIDDevice - Opened '%s'\n"
- " Manufacturer:'%s' Product:'%s' Serial#:'%s'\n",
- DevDesc.Path.ToCStr(),
- DevDesc.Manufacturer.ToCStr(), DevDesc.Product.ToCStr(),
- DevDesc.SerialNumber.ToCStr());
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDevice::initInfo()
-{
- // Device must have been successfully opened.
- OVR_ASSERT(DeviceHandle >= 0);
-
- int desc_size = 0;
- hidraw_report_descriptor rpt_desc;
- memset(&rpt_desc, 0, sizeof(rpt_desc));
-
- // get report descriptor size
- int r = ioctl(DeviceHandle, HIDIOCGRDESCSIZE, &desc_size);
- if (r < 0)
- {
- OVR_ASSERT_LOG(false, ("Failed to get report descriptor size."));
- return false;
- }
-
- // Get the report descriptor
- rpt_desc.size = desc_size;
- r = ioctl(DeviceHandle, HIDIOCGRDESC, &rpt_desc);
- if (r < 0)
- {
- OVR_ASSERT_LOG(false, ("Failed to get report descriptor."));
- return false;
- }
-
- /*
- // Get report lengths.
- SInt32 bufferLength;
- bool getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxInputReportSizeKey), &bufferLength);
- OVR_ASSERT(getResult);
- InputReportBufferLength = (UInt16) bufferLength;
-
- getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxOutputReportSizeKey), &bufferLength);
- OVR_ASSERT(getResult);
- OutputReportBufferLength = (UInt16) bufferLength;
-
- getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxFeatureReportSizeKey), &bufferLength);
- OVR_ASSERT(getResult);
- FeatureReportBufferLength = (UInt16) bufferLength;
-
-
- if (ReadBufferSize < InputReportBufferLength)
- {
- OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer."));
- return false;
- }
-
- // Get device desc.
- if (!HIDManager->getFullDesc(Device, &DevDesc))
- {
- OVR_ASSERT_LOG(false, ("Failed to get device desc while initializing device."));
- return false;
- }
-
- return true;
- */
-
- // Get report lengths.
-// TODO: hard-coded for now. Need to interpret these values from the report descriptor
- InputReportBufferLength = 62;
- OutputReportBufferLength = 0;
- FeatureReportBufferLength = 69;
-
- if (ReadBufferSize < InputReportBufferLength)
- {
- OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer."));
- return false;
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDevice::openDevice(const char* device_path)
-{
- // First fill out the device descriptor
- if (!HIDManager->GetDescriptorFromPath(device_path, &DevDesc))
- {
- return false;
- }
-
- // Now open the device
- DeviceHandle = open(device_path, O_RDWR);
- if (DeviceHandle < 0)
- {
- OVR_DEBUG_LOG(("Failed 'CreateHIDFile' while opening device, error = 0x%X.", errno));
- DeviceHandle = -1;
- return false;
- }
-
- // fill out some values from the feature report descriptor
- if (!initInfo())
- {
- OVR_ASSERT_LOG(false, ("Failed to get HIDDevice info."));
-
- close(DeviceHandle);
- DeviceHandle = -1;
- return false;
- }
-
- // Add the device to the polling list
- if (!HIDManager->DevManager->pThread->AddSelectFd(this, DeviceHandle))
- {
- OVR_ASSERT_LOG(false, ("Failed to initialize polling for HIDDevice."));
-
- close(DeviceHandle);
- DeviceHandle = -1;
- return false;
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-void HIDDevice::HIDShutdown()
-{
-
- HIDManager->DevManager->pThread->RemoveTicksNotifier(this);
- HIDManager->RemoveNotificationDevice(this);
-
- if (DeviceHandle >= 0) // Device may already have been closed if unplugged.
- {
- closeDevice(false);
- }
-
- LogText("OVR::Linux::HIDDevice - HIDShutdown '%s'\n", DevDesc.Path.ToCStr());
-}
-
-//-----------------------------------------------------------------------------
-void HIDDevice::closeDevice(bool wasUnplugged)
-{
- OVR_ASSERT(DeviceHandle >= 0);
-
-
- HIDManager->DevManager->pThread->RemoveSelectFd(this, DeviceHandle);
-
- close(DeviceHandle); // close the file handle
- DeviceHandle = -1;
-
- LogText("OVR::Linux::HIDDevice - HID Device Closed '%s'\n", DevDesc.Path.ToCStr());
-}
-
-//-----------------------------------------------------------------------------
-void HIDDevice::closeDeviceOnIOError()
-{
- LogText("OVR::Linux::HIDDevice - Lost connection to '%s'\n", DevDesc.Path.ToCStr());
- closeDevice(false);
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDevice::SetFeatureReport(UByte* data, UInt32 length)
-{
-
- if (DeviceHandle < 0)
- return false;
-
- UByte reportID = data[0];
-
- if (reportID == 0)
- {
- // Not using reports so remove from data packet.
- data++;
- length--;
- }
-
- int r = ioctl(DeviceHandle, HIDIOCSFEATURE(length), data);
- return (r >= 0);
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDevice::GetFeatureReport(UByte* data, UInt32 length)
-{
- if (DeviceHandle < 0)
- return false;
-
- int r = ioctl(DeviceHandle, HIDIOCGFEATURE(length), data);
- return (r >= 0);
-}
-
-//-----------------------------------------------------------------------------
-UInt64 HIDDevice::OnTicks(UInt64 ticksMks)
-{
- if (Handler)
- {
- return Handler->OnTicks(ticksMks);
- }
-
- return DeviceManagerThread::Notifier::OnTicks(ticksMks);
-}
-
-//-----------------------------------------------------------------------------
-void HIDDevice::OnEvent(int i, int fd)
-{
- // We have data to read from the device
- int bytes = read(fd, ReadBuffer, ReadBufferSize);
- if (bytes >= 0)
- {
-// TODO: I need to handle partial messages and package reconstruction
- if (Handler)
- {
- Handler->OnInputReport(ReadBuffer, bytes);
- }
- }
- else
- { // Close the device on read error.
- closeDeviceOnIOError();
- }
-}
-
-//-----------------------------------------------------------------------------
-bool HIDDevice::OnDeviceNotification(MessageType messageType,
- HIDDeviceDesc* device_info,
- bool* error)
-{
- const char* device_path = device_info->Path.ToCStr();
-
- if (messageType == Message_DeviceAdded && DeviceHandle < 0)
- {
- // Is this the correct device?
- if (!(device_info->VendorId == DevDesc.VendorId
- && device_info->ProductId == DevDesc.ProductId
- && device_info->SerialNumber == DevDesc.SerialNumber))
- {
- return false;
- }
-
- // A closed device has been re-added. Try to reopen.
- if (!openDevice(device_path))
- {
- LogError("OVR::Linux::HIDDevice - Failed to reopen a device '%s' that was re-added.\n",
- device_path);
- *error = true;
- return true;
- }
-
- LogText("OVR::Linux::HIDDevice - Reopened device '%s'\n", device_path);
-
- if (Handler)
- {
- Handler->OnDeviceMessage(HIDHandler::HIDDeviceMessage_DeviceAdded);
- }
- }
- else if (messageType == Message_DeviceRemoved)
- {
- // Is this the correct device?
- // For disconnected device, the device description will be invalid so
- // checking the path is the only way to match them
- if (DevDesc.Path.CompareNoCase(device_path) != 0)
- {
- return false;
- }
-
- if (DeviceHandle >= 0)
- {
- closeDevice(true);
- }
-
- if (Handler)
- {
- Handler->OnDeviceMessage(HIDHandler::HIDDeviceMessage_DeviceRemoved);
- }
- }
- else
- {
- OVR_ASSERT(0);
- }
-
- *error = false;
- return true;
-}
-
-//-----------------------------------------------------------------------------
-HIDDeviceManager* HIDDeviceManager::CreateInternal(Linux::DeviceManager* devManager)
-{
-
- if (!System::IsInitialized())
- {
- // Use custom message, since Log is not yet installed.
- OVR_DEBUG_STATEMENT(Log::GetDefaultLog()->
- LogMessage(Log_Debug, "HIDDeviceManager::Create failed - OVR::System not initialized"); );
- return 0;
- }
-
- Ptr<Linux::HIDDeviceManager> manager = *new Linux::HIDDeviceManager(devManager);
-
- if (manager)
- {
- if (manager->Initialize())
- {
- manager->AddRef();
- }
- else
- {
- manager.Clear();
- }
- }
-
- return manager.GetPtr();
-}
-
-} // namespace Linux
-
-//-------------------------------------------------------------------------------------
-// ***** Creation
-
-// Creates a new HIDDeviceManager and initializes OVR.
-HIDDeviceManager* HIDDeviceManager::Create()
-{
- OVR_ASSERT_LOG(false, ("Standalone mode not implemented yet."));
-
- if (!System::IsInitialized())
- {
- // Use custom message, since Log is not yet installed.
- OVR_DEBUG_STATEMENT(Log::GetDefaultLog()->
- LogMessage(Log_Debug, "HIDDeviceManager::Create failed - OVR::System not initialized"); );
- return 0;
- }
-
- Ptr<Linux::HIDDeviceManager> manager = *new Linux::HIDDeviceManager(NULL);
-
- if (manager)
- {
- if (manager->Initialize())
- {
- manager->AddRef();
- }
- else
- {
- manager.Clear();
- }
- }
-
- return manager.GetPtr();
-}
-
-} // namespace OVR
diff --git a/LibOVR/Src/OVR_Linux_HIDDevice.h b/LibOVR/Src/OVR_Linux_HIDDevice.h
deleted file mode 100644
index 0f4c7f0..0000000
--- a/LibOVR/Src/OVR_Linux_HIDDevice.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/************************************************************************************
-Filename : OVR_Linux_HIDDevice.h
-Content : Linux HID device implementation.
-Created : June 13, 2013
-Authors : Brant Lewis
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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_LINUX_HIDDevice_h
-#define OVR_LINUX_HIDDevice_h
-
-#include "OVR_HIDDevice.h"
-#include "OVR_Linux_DeviceManager.h"
-#include <libudev.h>
-
-namespace OVR { namespace Linux {
-
-class HIDDeviceManager;
-
-//-------------------------------------------------------------------------------------
-// ***** Linux HIDDevice
-
-class HIDDevice : public OVR::HIDDevice, public DeviceManagerThread::Notifier
-{
-private:
- friend class HIDDeviceManager;
-
-public:
- HIDDevice(HIDDeviceManager* manager);
-
- // This is a minimal constructor used during enumeration for us to pass
- // a HIDDevice to the visit function (so that it can query feature reports).
- HIDDevice(HIDDeviceManager* manager, int device_handle);
-
- virtual ~HIDDevice();
-
- bool HIDInitialize(const String& path);
- void HIDShutdown();
-
- virtual bool SetFeatureReport(UByte* data, UInt32 length);
- virtual bool GetFeatureReport(UByte* data, UInt32 length);
-
- // DeviceManagerThread::Notifier
- void OnEvent(int i, int fd);
- UInt64 OnTicks(UInt64 ticksMks);
-
- bool OnDeviceNotification(MessageType messageType,
- HIDDeviceDesc* device_info,
- bool* error);
-
-private:
- bool initInfo();
- bool openDevice(const char* dev_path);
- void closeDevice(bool wasUnplugged);
- void closeDeviceOnIOError();
- bool setupDevicePluggedInNotification();
-
- bool InMinimalMode;
- HIDDeviceManager* HIDManager;
- int DeviceHandle; // file handle to the device
- HIDDeviceDesc DevDesc;
-
- enum { ReadBufferSize = 96 };
- UByte ReadBuffer[ReadBufferSize];
-
- UInt16 InputReportBufferLength;
- UInt16 OutputReportBufferLength;
- UInt16 FeatureReportBufferLength;
-};
-
-
-//-------------------------------------------------------------------------------------
-// ***** Linux HIDDeviceManager
-
-class HIDDeviceManager : public OVR::HIDDeviceManager, public DeviceManagerThread::Notifier
-{
- friend class HIDDevice;
-
-public:
- HIDDeviceManager(Linux::DeviceManager* Manager);
- virtual ~HIDDeviceManager();
-
- virtual bool Initialize();
- virtual void Shutdown();
-
- virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor);
- virtual OVR::HIDDevice* Open(const String& path);
-
- static HIDDeviceManager* CreateInternal(DeviceManager* manager);
-
- void OnEvent(int i, int fd);
-
-private:
- bool initializeManager();
- bool initVendorProductVersion(udev_device* device, HIDDeviceDesc* pDevDesc);
- bool getPath(udev_device* device, String* pPath);
- bool getIntProperty(udev_device* device, const char* key, int32_t* pResult);
- bool getStringProperty(udev_device* device,
- const char* propertyName,
- OVR::String* pResult);
- bool getFullDesc(udev_device* device, HIDDeviceDesc* desc);
- bool GetDescriptorFromPath(const char* dev_path, HIDDeviceDesc* desc);
-
- bool AddNotificationDevice(HIDDevice* device);
- bool RemoveNotificationDevice(HIDDevice* device);
-
- DeviceManager* DevManager;
-
- udev* UdevInstance; // a handle to the udev library instance
- udev_monitor* HIDMonitor;
- int HIDMonHandle; // the udev_monitor file handle
-
- Array<HIDDevice*> NotificationDevices;
-};
-
-}} // namespace OVR::Linux
-
-#endif // OVR_Linux_HIDDevice_h
diff --git a/LibOVR/Src/OVR_Linux_HMDDevice.cpp b/LibOVR/Src/OVR_Linux_HMDDevice.cpp
deleted file mode 100644
index 633e665..0000000
--- a/LibOVR/Src/OVR_Linux_HMDDevice.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-/************************************************************************************
-
-Filename : OVR_Linux_HMDDevice.h
-Content : Linux HMDDevice implementation
-Created : June 17, 2013
-Authors : Brant Lewis
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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 "OVR_Linux_HMDDevice.h"
-
-#include "OVR_Linux_DeviceManager.h"
-
-#include "OVR_Profile.h"
-
-#include <X11/Xlib.h>
-#include <X11/extensions/Xinerama.h>
-
-namespace OVR { namespace Linux {
-
-//-------------------------------------------------------------------------------------
-
-HMDDeviceCreateDesc::HMDDeviceCreateDesc(DeviceFactory* factory, const String& displayDeviceName, long dispId)
- : DeviceCreateDesc(factory, Device_HMD),
- DisplayDeviceName(displayDeviceName),
- DesktopX(0), DesktopY(0), Contents(0), EyeToScreenDistance(0),
- HResolution(0), VResolution(0), HScreenSize(0), VScreenSize(0),
- DisplayId(dispId)
-{
- DeviceId = DisplayDeviceName;
- for (int i=0; i<4; i++)
- DistortionK[i] = 0;
-}
-
-HMDDeviceCreateDesc::HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other)
- : DeviceCreateDesc(other.pFactory, Device_HMD),
- DeviceId(other.DeviceId), DisplayDeviceName(other.DisplayDeviceName),
- DesktopX(other.DesktopX), DesktopY(other.DesktopY), Contents(other.Contents),
- HResolution(other.HResolution), VResolution(other.VResolution),
- HScreenSize(other.HScreenSize), VScreenSize(other.VScreenSize),
- DisplayId(other.DisplayId), EyeToScreenDistance(other.EyeToScreenDistance)
-{
- for (int i=0; i<4; i++)
- DistortionK[i] = other.DistortionK[i];
-}
-
-HMDDeviceCreateDesc::MatchResult HMDDeviceCreateDesc::MatchDevice(const DeviceCreateDesc& other,
- DeviceCreateDesc** pcandidate) const
-{
- if ((other.Type != Device_HMD) || (other.pFactory != pFactory))
- return Match_None;
-
- // There are several reasons we can come in here:
- // a) Matching this HMD Monitor created desc to OTHER HMD Monitor desc
- // - Require exact device DeviceId/DeviceName match
- // b) Matching SensorDisplayInfo created desc to OTHER HMD Monitor desc
- // - This DeviceId is empty; becomes candidate
- // c) Matching this HMD Monitor created desc to SensorDisplayInfo desc
- // - This other.DeviceId is empty; becomes candidate
-
- const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other;
-
- if ((DeviceId == s2.DeviceId) &&
- (DisplayId == s2.DisplayId))
- {
- // Non-null DeviceId may match while size is different if screen size was overwritten
- // by SensorDisplayInfo in prior iteration.
- if (!DeviceId.IsEmpty() ||
- ((HScreenSize == s2.HScreenSize) &&
- (VScreenSize == s2.VScreenSize)) )
- {
- *pcandidate = 0;
- return Match_Found;
- }
- }
-
-
- // DisplayInfo takes precedence, although we try to match it first.
- if ((HResolution == s2.HResolution) &&
- (VResolution == s2.VResolution) &&
- (HScreenSize == s2.HScreenSize) &&
- (VScreenSize == s2.VScreenSize))
- {
- if (DeviceId.IsEmpty() && !s2.DeviceId.IsEmpty())
- {
- *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this);
- return Match_Candidate;
- }
-
- *pcandidate = 0;
- return Match_Found;
- }
-
- // SensorDisplayInfo may override resolution settings, so store as candidate.
- if (s2.DeviceId.IsEmpty())
- {
- *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this);
- return Match_Candidate;
- }
- // OTHER HMD Monitor desc may initialize DeviceName/Id
- else if (DeviceId.IsEmpty())
- {
- *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this);
- return Match_Candidate;
- }
-
- return Match_None;
-}
-
-
-bool HMDDeviceCreateDesc::UpdateMatchedCandidate(const DeviceCreateDesc& other,
- bool* newDeviceFlag)
-{
- // This candidate was the the "best fit" to apply sensor DisplayInfo to.
- OVR_ASSERT(other.Type == Device_HMD);
-
- const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other;
-
- // Force screen size on resolution from SensorDisplayInfo.
- // We do this because USB detection is more reliable as compared to HDMI EDID,
- // which may be corrupted by splitter reporting wrong monitor
- if (s2.DeviceId.IsEmpty())
- {
- HScreenSize = s2.HScreenSize;
- VScreenSize = s2.VScreenSize;
- Contents |= Contents_Screen;
-
- if (s2.Contents & HMDDeviceCreateDesc::Contents_Distortion)
- {
- memcpy(DistortionK, s2.DistortionK, sizeof(float)*4);
- Contents |= Contents_Distortion;
- }
- DeviceId = s2.DeviceId;
- DisplayId = s2.DisplayId;
- DisplayDeviceName = s2.DisplayDeviceName;
- if (newDeviceFlag) *newDeviceFlag = true;
- }
- else if (DeviceId.IsEmpty())
- {
- DeviceId = s2.DeviceId;
- DisplayId = s2.DisplayId;
- DisplayDeviceName = s2.DisplayDeviceName;
-
- // ScreenSize and Resolution are NOT assigned here, since they may have
- // come from a sensor DisplayInfo (which has precedence over HDMI).
-
- if (newDeviceFlag) *newDeviceFlag = true;
- }
- else
- {
- if (newDeviceFlag) *newDeviceFlag = false;
- }
-
- return true;
-}
-
-bool HMDDeviceCreateDesc::MatchDevice(const String& path)
-{
- return DeviceId.CompareNoCase(path) == 0;
-}
-
-//-------------------------------------------------------------------------------------
-// ***** HMDDeviceFactory
-
-HMDDeviceFactory HMDDeviceFactory::Instance;
-
-void HMDDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor)
-{
- // For now we'll assume the Rift DK1 is attached in extended monitor mode. Ultimately we need to
- // use XFree86 to enumerate X11 screens in case the Rift is attached as a separate screen. We also
- // need to be able to read the EDID manufacturer product code to be able to differentiate between
- // Rift models.
-
- bool foundHMD = false;
-
- Display* display = XOpenDisplay(NULL);
- if (display && XineramaIsActive(display))
- {
- int numberOfScreens;
- XineramaScreenInfo* screens = XineramaQueryScreens(display, &numberOfScreens);
-
- for (int i = 0; i < numberOfScreens; i++)
- {
- XineramaScreenInfo screenInfo = screens[i];
-
- if (screenInfo.width == 1280 && screenInfo.height == 800)
- {
- String deviceName = "OVR0001";
-
- HMDDeviceCreateDesc hmdCreateDesc(this, deviceName, i);
- hmdCreateDesc.SetScreenParameters(screenInfo.x_org, screenInfo.y_org, 1280, 800, 0.14976f, 0.0936f);
-
- OVR_DEBUG_LOG_TEXT(("DeviceManager - HMD Found %s - %d\n",
- deviceName.ToCStr(), i));
-
- // Notify caller about detected device. This will call EnumerateAddDevice
- // if the this is the first time device was detected.
- visitor.Visit(hmdCreateDesc);
- foundHMD = true;
- break;
- }
- }
-
- XFree(screens);
- }
-
-
- // Real HMD device is not found; however, we still may have a 'fake' HMD
- // device created via SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo.
- // Need to find it and set 'Enumerated' to true to avoid Removal notification.
- if (!foundHMD)
- {
- Ptr<DeviceCreateDesc> hmdDevDesc = getManager()->FindDevice("", Device_HMD);
- if (hmdDevDesc)
- hmdDevDesc->Enumerated = true;
- }
-}
-
-DeviceBase* HMDDeviceCreateDesc::NewDeviceInstance()
-{
- return new HMDDevice(this);
-}
-
-bool HMDDeviceCreateDesc::Is7Inch() const
-{
- return (strstr(DeviceId.ToCStr(), "OVR0001") != 0) || (Contents & Contents_7Inch);
-}
-
-Profile* HMDDeviceCreateDesc::GetProfileAddRef() const
-{
- // Create device may override profile name, so get it from there is possible.
- ProfileManager* profileManager = GetManagerImpl()->GetProfileManager();
- ProfileType profileType = GetProfileType();
- const char * profileName = pDevice ?
- ((HMDDevice*)pDevice)->GetProfileName() :
- profileManager->GetDefaultProfileName(profileType);
-
- return profileName ?
- profileManager->LoadProfile(profileType, profileName) :
- profileManager->GetDeviceDefaultProfile(profileType);
-}
-
-
-bool HMDDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const
-{
- if ((info->InfoClassType != Device_HMD) &&
- (info->InfoClassType != Device_None))
- return false;
-
- bool is7Inch = Is7Inch();
-
- OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength,
- is7Inch ? "Oculus Rift DK1" :
- ((HResolution >= 1920) ? "Oculus Rift DK HD" : "Oculus Rift DK1-Prototype") );
- OVR_strcpy(info->Manufacturer, DeviceInfo::MaxNameLength, "Oculus VR");
- info->Type = Device_HMD;
- info->Version = 0;
-
- // Display detection.
- if (info->InfoClassType == Device_HMD)
- {
- HMDInfo* hmdInfo = static_cast<HMDInfo*>(info);
-
- hmdInfo->DesktopX = DesktopX;
- hmdInfo->DesktopY = DesktopY;
- hmdInfo->HResolution = HResolution;
- hmdInfo->VResolution = VResolution;
- hmdInfo->HScreenSize = HScreenSize;
- hmdInfo->VScreenSize = VScreenSize;
- hmdInfo->VScreenCenter = VScreenSize * 0.5f;
- hmdInfo->InterpupillaryDistance = 0.064f; // Default IPD; should be configurable.
- hmdInfo->LensSeparationDistance = 0.0635f;
-
- // Obtain IPD from profile.
- Ptr<Profile> profile = *GetProfileAddRef();
-
- if (profile)
- {
- hmdInfo->InterpupillaryDistance = profile->GetIPD();
- // TBD: Switch on EyeCup type.
- }
-
- if (Contents & Contents_Distortion)
- {
- memcpy(hmdInfo->DistortionK, DistortionK, sizeof(float)*4);
- hmdInfo->EyeToScreenDistance = EyeToScreenDistance;
- }
- else
- {
- if (is7Inch)
- {
- // 7" screen.
- hmdInfo->DistortionK[0] = 1.0f;
- hmdInfo->DistortionK[1] = 0.22f;
- hmdInfo->DistortionK[2] = 0.24f;
- hmdInfo->EyeToScreenDistance = 0.041f;
- }
- else
- {
- hmdInfo->DistortionK[0] = 1.0f;
- hmdInfo->DistortionK[1] = 0.18f;
- hmdInfo->DistortionK[2] = 0.115f;
-
- if (HResolution == 1920)
- hmdInfo->EyeToScreenDistance = 0.040f;
- else
- hmdInfo->EyeToScreenDistance = 0.0387f;
- }
- }
-
- hmdInfo->ChromaAbCorrection[0] = 0.996f;
- hmdInfo->ChromaAbCorrection[1] = -0.004f;
- hmdInfo->ChromaAbCorrection[2] = 1.014f;
- hmdInfo->ChromaAbCorrection[3] = 0.0f;
-
- OVR_strcpy(hmdInfo->DisplayDeviceName, sizeof(hmdInfo->DisplayDeviceName),
- DisplayDeviceName.ToCStr());
- hmdInfo->DisplayId = DisplayId;
- }
-
- return true;
-}
-
-//-------------------------------------------------------------------------------------
-// ***** HMDDevice
-
-HMDDevice::HMDDevice(HMDDeviceCreateDesc* createDesc)
- : OVR::DeviceImpl<OVR::HMDDevice>(createDesc, 0)
-{
-}
-HMDDevice::~HMDDevice()
-{
-}
-
-bool HMDDevice::Initialize(DeviceBase* parent)
-{
- pParent = parent;
-
- // Initialize user profile to default for device.
- ProfileManager* profileManager = GetManager()->GetProfileManager();
- ProfileName = profileManager->GetDefaultProfileName(getDesc()->GetProfileType());
-
- return true;
-}
-void HMDDevice::Shutdown()
-{
- ProfileName.Clear();
- pCachedProfile.Clear();
- pParent.Clear();
-}
-
-Profile* HMDDevice::GetProfile() const
-{
- if (!pCachedProfile)
- pCachedProfile = *getDesc()->GetProfileAddRef();
- return pCachedProfile.GetPtr();
-}
-
-const char* HMDDevice::GetProfileName() const
-{
- return ProfileName.ToCStr();
-}
-
-bool HMDDevice::SetProfileName(const char* name)
-{
- pCachedProfile.Clear();
- if (!name)
- {
- ProfileName.Clear();
- return 0;
- }
- if (GetManager()->GetProfileManager()->HasProfile(getDesc()->GetProfileType(), name))
- {
- ProfileName = name;
- return true;
- }
- return false;
-}
-
-OVR::SensorDevice* HMDDevice::GetSensor()
-{
- // Just return first sensor found since we have no way to match it yet.
- OVR::SensorDevice* sensor = GetManager()->EnumerateDevices<SensorDevice>().CreateDevice();
- if (sensor)
- sensor->SetCoordinateFrame(SensorDevice::Coord_HMD);
- return sensor;
-}
-
-}} // namespace OVR::Linux
-
-
diff --git a/LibOVR/Src/OVR_Linux_HMDDevice.h b/LibOVR/Src/OVR_Linux_HMDDevice.h
deleted file mode 100644
index b5c4bf1..0000000
--- a/LibOVR/Src/OVR_Linux_HMDDevice.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/************************************************************************************
-
-Filename : OVR_Linux_HMDDevice.h
-Content : Linux HMDDevice implementation
-Created : June 17, 2013
-Authors : Brant Lewis
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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_Linux_HMDDevice_h
-#define OVR_Linux_HMDDevice_h
-
-#include "OVR_Linux_DeviceManager.h"
-#include "OVR_Profile.h"
-
-namespace OVR { namespace Linux {
-
-class HMDDevice;
-
-//-------------------------------------------------------------------------------------
-
-// HMDDeviceFactory enumerates attached Oculus HMD devices.
-//
-// This is currently done by matching monitor device strings.
-
-class HMDDeviceFactory : public DeviceFactory
-{
-public:
- static HMDDeviceFactory Instance;
-
- // Enumerates devices, creating and destroying relevant objects in manager.
- virtual void EnumerateDevices(EnumerateVisitor& visitor);
-
-protected:
- DeviceManager* getManager() const { return (DeviceManager*) pManager; }
-};
-
-
-class HMDDeviceCreateDesc : public DeviceCreateDesc
-{
- friend class HMDDevice;
-
-protected:
- enum
- {
- Contents_Screen = 1,
- Contents_Distortion = 2,
- Contents_7Inch = 4,
- };
- String DeviceId;
- String DisplayDeviceName;
- int DesktopX, DesktopY;
- unsigned Contents;
- unsigned HResolution, VResolution;
- float HScreenSize, VScreenSize;
- long DisplayId;
- float DistortionK[4];
- float EyeToScreenDistance;
-
-public:
- HMDDeviceCreateDesc(DeviceFactory* factory, const String& displayDeviceName, long dispId);
- HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other);
-
- virtual DeviceCreateDesc* Clone() const
- {
- return new HMDDeviceCreateDesc(*this);
- }
-
- virtual DeviceBase* NewDeviceInstance();
-
- virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
- DeviceCreateDesc**) const;
-
- // Matches device by path.
- virtual bool MatchDevice(const String& path);
-
- virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&, bool* newDeviceFlag = NULL);
-
- virtual bool GetDeviceInfo(DeviceInfo* info) const;
-
- // Requests the currently used default profile. This profile affects the
- // settings reported by HMDInfo.
- Profile* GetProfileAddRef() const;
-
- ProfileType GetProfileType() const
- {
- return (HResolution >= 1920) ? Profile_RiftDKHD : Profile_RiftDK1;
- }
-
-
- void SetScreenParameters(int x, int y, unsigned hres, unsigned vres, float hsize, float vsize)
- {
- DesktopX = x;
- DesktopY = y;
- HResolution = hres;
- VResolution = vres;
- HScreenSize = hsize;
- VScreenSize = vsize;
- Contents |= Contents_Screen;
- }
- void SetDistortion(float eye2screen, const float* dks)
- {
- EyeToScreenDistance = eye2screen;
-
- for (int i = 0; i < 4; i++)
- DistortionK[i] = dks[i];
- Contents |= Contents_Distortion;
- }
-
- void Set7Inch() { Contents |= Contents_7Inch; }
-
- bool Is7Inch() const;
-};
-
-
-//-------------------------------------------------------------------------------------
-
-// HMDDevice represents an Oculus HMD device unit. An instance of this class
-// is typically created from the DeviceManager.
-// After HMD device is created, we its sensor data can be obtained by
-// first creating a Sensor object and then wrappig it in SensorFusion.
-
-class HMDDevice : public DeviceImpl<OVR::HMDDevice>
-{
-public:
- HMDDevice(HMDDeviceCreateDesc* createDesc);
- ~HMDDevice();
-
- virtual bool Initialize(DeviceBase* parent);
- virtual void Shutdown();
-
- // Requests the currently used default profile. This profile affects the
- // settings reported by HMDInfo.
- virtual Profile* GetProfile() const;
- virtual const char* GetProfileName() const;
- virtual bool SetProfileName(const char* name);
-
- // Query associated sensor.
- virtual OVR::SensorDevice* GetSensor();
-
-protected:
- HMDDeviceCreateDesc* getDesc() const { return (HMDDeviceCreateDesc*)pCreateDesc.GetPtr(); }
-
- // User name for the profile used with this device.
- String ProfileName;
- mutable Ptr<Profile> pCachedProfile;
-};
-
-
-}} // namespace OVR::Linux
-
-#endif // OVR_Linux_HMDDevice_h
-
diff --git a/LibOVR/Src/OVR_Linux_SensorDevice.cpp b/LibOVR/Src/OVR_Linux_SensorDevice.cpp
deleted file mode 100644
index 376e4d4..0000000
--- a/LibOVR/Src/OVR_Linux_SensorDevice.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/************************************************************************************
-
-Filename : OVR_Linux_SensorDevice.cpp
-Content : Linux SensorDevice implementation
-Created : June 13, 2013
-Authors : Brant Lewis
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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 "OVR_Linux_HMDDevice.h"
-#include "OVR_SensorImpl.h"
-#include "OVR_DeviceImpl.h"
-
-namespace OVR { namespace OSX {
-
-} // namespace OSX
-
-//-------------------------------------------------------------------------------------
-void SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo( const SensorDisplayInfoImpl& displayInfo,
- DeviceFactory::EnumerateVisitor& visitor)
-{
-
- Linux::HMDDeviceCreateDesc hmdCreateDesc(&Linux::HMDDeviceFactory::Instance, "", 0);
-
- hmdCreateDesc.SetScreenParameters( 0, 0,
- displayInfo.HResolution, displayInfo.VResolution,
- displayInfo.HScreenSize, displayInfo.VScreenSize);
-
- if ((displayInfo.DistortionType & SensorDisplayInfoImpl::Mask_BaseFmt) & SensorDisplayInfoImpl::Base_Distortion)
- hmdCreateDesc.SetDistortion(displayInfo.EyeToScreenDistance[0], displayInfo.DistortionK);
- if (displayInfo.HScreenSize > 0.14f)
- hmdCreateDesc.Set7Inch();
-
- visitor.Visit(hmdCreateDesc);
-}
-
-} // namespace OVR
-
-
diff --git a/LibOVR/Src/OVR_OSX_DeviceManager.cpp b/LibOVR/Src/OVR_OSX_DeviceManager.cpp
deleted file mode 100644
index 1e1f6d6..0000000
--- a/LibOVR/Src/OVR_OSX_DeviceManager.cpp
+++ /dev/null
@@ -1,360 +0,0 @@
-/************************************************************************************
-
-Filename : OVR_OSX_DeviceManager.cpp
-Content : OSX specific DeviceManager implementation.
-Created : March 14, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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 "OVR_OSX_DeviceManager.h"
-
-// Sensor & HMD Factories
-#include "OVR_LatencyTestImpl.h"
-#include "OVR_SensorImpl.h"
-#include "OVR_OSX_HMDDevice.h"
-#include "OVR_OSX_HIDDevice.h"
-
-#include "Kernel/OVR_Timer.h"
-#include "Kernel/OVR_Std.h"
-#include "Kernel/OVR_Log.h"
-
-#include <IOKit/hid/IOHIDManager.h>
-#include <IOKit/hid/IOHIDKeys.h>
-
-
-namespace OVR { namespace OSX {
-
-//-------------------------------------------------------------------------------------
-// **** OSX::DeviceManager
-
-DeviceManager::DeviceManager()
-{
-}
-
-DeviceManager::~DeviceManager()
-{
- OVR_DEBUG_LOG(("OSX::DeviceManager::~DeviceManager was called"));
-}
-
-bool DeviceManager::Initialize(DeviceBase*)
-{
- if (!DeviceManagerImpl::Initialize(0))
- return false;
-
- // Start the background thread.
- pThread = *new DeviceManagerThread();
- if (!pThread || !pThread->Start())
- return false;
-
- // Wait for the thread to be fully up and running.
- pThread->StartupEvent.Wait();
-
- // Do this now that we know the thread's run loop.
- HidDeviceManager = *HIDDeviceManager::CreateInternal(this);
-
- CGDisplayRegisterReconfigurationCallback(displayReconfigurationCallBack, this);
-
- pCreateDesc->pDevice = this;
- LogText("OVR::DeviceManager - initialized.\n");
-
- return true;
-}
-
-void DeviceManager::Shutdown()
-{
- LogText("OVR::DeviceManager - shutting down.\n");
-
- CGDisplayRemoveReconfigurationCallback(displayReconfigurationCallBack, this);
-
- // Set Manager shutdown marker variable; this prevents
- // any existing DeviceHandle objects from accessing device.
- pCreateDesc->pLock->pManager = 0;
-
- // Push for thread shutdown *WITH NO WAIT*.
- // This will have the following effect:
- // - Exit command will get enqueued, which will be executed later on the thread itself.
- // - Beyond this point, this DeviceManager object may be deleted by our caller.
- // - Other commands, such as CreateDevice, may execute before ExitCommand, but they will
- // fail gracefully due to pLock->pManager == 0. Future commands can't be enqued
- // after pManager is null.
- // - Once ExitCommand executes, ThreadCommand::Run loop will exit and release the last
- // reference to the thread object.
- pThread->Shutdown();
- pThread.Clear();
-
- DeviceManagerImpl::Shutdown();
-}
-
-ThreadCommandQueue* DeviceManager::GetThreadQueue()
-{
- return pThread;
-}
-
-ThreadId DeviceManager::GetThreadId() const
-{
- return pThread->GetThreadId();
-}
-
-bool DeviceManager::GetDeviceInfo(DeviceInfo* info) const
-{
- if ((info->InfoClassType != Device_Manager) &&
- (info->InfoClassType != Device_None))
- return false;
-
- info->Type = Device_Manager;
- info->Version = 0;
- OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength, "DeviceManager");
- OVR_strcpy(info->Manufacturer,DeviceInfo::MaxNameLength, "Oculus VR, Inc.");
- return true;
-}
-
-DeviceEnumerator<> DeviceManager::EnumerateDevicesEx(const DeviceEnumerationArgs& args)
-{
- // TBD: Can this be avoided in the future, once proper device notification is in place?
- pThread->PushCall((DeviceManagerImpl*)this,
- &DeviceManager::EnumerateAllFactoryDevices, true);
-
- return DeviceManagerImpl::EnumerateDevicesEx(args);
-}
-
-void DeviceManager::displayReconfigurationCallBack (CGDirectDisplayID display,
- CGDisplayChangeSummaryFlags flags,
- void *userInfo)
-{
- DeviceManager* manager = reinterpret_cast<DeviceManager*>(userInfo);
- OVR_UNUSED(manager);
-
- if (flags & kCGDisplayAddFlag)
- {
- LogText("Display Added, id = %d\n", int(display));
- manager->EnumerateDevices<HMDDevice>();
- }
- else if (flags & kCGDisplayRemoveFlag)
- {
- LogText("Display Removed, id = %d\n", int(display));
- manager->EnumerateDevices<HMDDevice>();
- }
-}
-
-//-------------------------------------------------------------------------------------
-// ***** DeviceManager Thread
-
-DeviceManagerThread::DeviceManagerThread()
- : Thread(ThreadStackSize)
-{
-}
-
-DeviceManagerThread::~DeviceManagerThread()
-{
-}
-
-int DeviceManagerThread::Run()
-{
-
- SetThreadName("OVR::DeviceManagerThread");
- LogText("OVR::DeviceManagerThread - running (ThreadId=0x%p).\n", GetThreadId());
-
- // Store out the run loop ref.
- RunLoop = CFRunLoopGetCurrent();
-
- // Create a 'source' to enable us to signal the run loop to process the command queue.
- CFRunLoopSourceContext sourceContext;
- memset(&sourceContext, 0, sizeof(sourceContext));
- sourceContext.version = 0;
- sourceContext.info = this;
- sourceContext.perform = &staticCommandQueueSourceCallback;
-
- CommandQueueSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0 , &sourceContext);
-
- CFRunLoopAddSource(RunLoop, CommandQueueSource, kCFRunLoopDefaultMode);
-
-
- // Signal to the parent thread that initialization has finished.
- StartupEvent.SetEvent();
-
-
- ThreadCommand::PopBuffer command;
-
- while(!IsExiting())
- {
- // PopCommand will reset event on empty queue.
- if (PopCommand(&command))
- {
- command.Execute();
- }
- else
- {
- SInt32 exitReason = 0;
- do {
-
- UInt32 waitMs = INT_MAX;
-
- // If devices have time-dependent logic registered, get the longest wait
- // allowed based on current ticks.
- if (!TicksNotifiers.IsEmpty())
- {
- UInt64 ticksMks = Timer::GetTicks();
- UInt32 waitAllowed;
-
- for (UPInt j = 0; j < TicksNotifiers.GetSize(); j++)
- {
- waitAllowed = (UInt32)(TicksNotifiers[j]->OnTicks(ticksMks) / Timer::MksPerMs);
- if (waitAllowed < waitMs)
- waitMs = waitAllowed;
- }
- }
-
- // Enter blocking run loop. We may continue until we timeout in which
- // case it's time to service the ticks. Or if commands arrive in the command
- // queue then the source callback will call 'CFRunLoopStop' causing this
- // to return.
- CFTimeInterval blockInterval = 0.001 * (double) waitMs;
- exitReason = CFRunLoopRunInMode(kCFRunLoopDefaultMode, blockInterval, false);
-
- if (exitReason == kCFRunLoopRunFinished)
- {
- // Maybe this will occur during shutdown?
- break;
- }
- else if (exitReason == kCFRunLoopRunStopped )
- {
- // Commands need processing or we're being shutdown.
- break;
- }
- else if (exitReason == kCFRunLoopRunTimedOut)
- {
- // Timed out so that we can service our ticks callbacks.
- continue;
- }
- else if (exitReason == kCFRunLoopRunHandledSource)
- {
- // Should never occur since the last param when we call
- // 'CFRunLoopRunInMode' is false.
- OVR_ASSERT(false);
- break;
- }
- else
- {
- OVR_ASSERT_LOG(false, ("CFRunLoopRunInMode returned unexpected code"));
- break;
- }
- }
- while(true);
- }
- }
-
-
- CFRunLoopRemoveSource(RunLoop, CommandQueueSource, kCFRunLoopDefaultMode);
- CFRelease(CommandQueueSource);
-
- LogText("OVR::DeviceManagerThread - exiting (ThreadId=0x%p).\n", GetThreadId());
-
- return 0;
-}
-
-void DeviceManagerThread::staticCommandQueueSourceCallback(void* pContext)
-{
- DeviceManagerThread* pThread = (DeviceManagerThread*) pContext;
- pThread->commandQueueSourceCallback();
-}
-
-void DeviceManagerThread::commandQueueSourceCallback()
-{
- CFRunLoopStop(RunLoop);
-}
-
-bool DeviceManagerThread::AddTicksNotifier(Notifier* notify)
-{
- TicksNotifiers.PushBack(notify);
- return true;
-}
-
-bool DeviceManagerThread::RemoveTicksNotifier(Notifier* notify)
-{
- for (UPInt i = 0; i < TicksNotifiers.GetSize(); i++)
- {
- if (TicksNotifiers[i] == notify)
- {
- TicksNotifiers.RemoveAt(i);
- return true;
- }
- }
- return false;
-}
-
-void DeviceManagerThread::Shutdown()
-{
- // Push for thread shutdown *WITH NO WAIT*.
- // This will have the following effect:
- // - Exit command will get enqueued, which will be executed later on the thread itself.
- // - Beyond this point, this DeviceManager object may be deleted by our caller.
- // - Other commands, such as CreateDevice, may execute before ExitCommand, but they will
- // fail gracefully due to pLock->pManager == 0. Future commands can't be enqued
- // after pManager is null.
- // - Once ExitCommand executes, ThreadCommand::Run loop will exit and release the last
- // reference to the thread object.
- PushExitCommand(false);
-
- // make sure CFRunLoopRunInMode is woken up
- CFRunLoopSourceSignal(CommandQueueSource);
- CFRunLoopWakeUp(RunLoop);
-}
-
-} // namespace OSX
-
-
-//-------------------------------------------------------------------------------------
-// ***** Creation
-
-// Creates a new DeviceManager and initializes OVR.
-DeviceManager* DeviceManager::Create()
-{
-
- if (!System::IsInitialized())
- {
- // Use custom message, since Log is not yet installed.
- OVR_DEBUG_STATEMENT(Log::GetDefaultLog()->
- LogMessage(Log_Debug, "DeviceManager::Create failed - OVR::System not initialized"); );
- return 0;
- }
-
- Ptr<OSX::DeviceManager> manager = *new OSX::DeviceManager;
-
- if (manager)
- {
- if (manager->Initialize(0))
- {
- manager->AddFactory(&LatencyTestDeviceFactory::Instance);
- manager->AddFactory(&SensorDeviceFactory::Instance);
- manager->AddFactory(&OSX::HMDDeviceFactory::Instance);
-
- manager->AddRef();
- }
- else
- {
- manager.Clear();
- }
- }
-
- return manager.GetPtr();
-}
-
-} // namespace OVR
diff --git a/LibOVR/Src/OVR_OSX_DeviceManager.h b/LibOVR/Src/OVR_OSX_DeviceManager.h
deleted file mode 100644
index ff6a577..0000000
--- a/LibOVR/Src/OVR_OSX_DeviceManager.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/************************************************************************************
-
-Filename : OVR_OSX_DeviceManager.h
-Content : OSX specific DeviceManager header.
-Created : March 14, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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_OSX_DeviceManager_h
-#define OVR_OSX_DeviceManager_h
-
-#include "OVR_DeviceImpl.h"
-
-#include "Kernel/OVR_Timer.h"
-
-#include <IOKit/hid/IOHIDManager.h>
-#include <CoreGraphics/CGDirectDisplay.h>
-#include <CoreGraphics/CGDisplayConfiguration.h>
-
-
-namespace OVR { namespace OSX {
-
-class DeviceManagerThread;
-
-//-------------------------------------------------------------------------------------
-// ***** OSX DeviceManager
-
-class DeviceManager : public DeviceManagerImpl
-{
-public:
- DeviceManager();
- ~DeviceManager();
-
- // Initialize/Shutdown manager thread.
- virtual bool Initialize(DeviceBase* parent);
- virtual void Shutdown();
-
- virtual ThreadCommandQueue* GetThreadQueue();
- virtual ThreadId GetThreadId() const;
-
- virtual DeviceEnumerator<> EnumerateDevicesEx(const DeviceEnumerationArgs& args);
-
- virtual bool GetDeviceInfo(DeviceInfo* info) const;
-
-protected:
- static void displayReconfigurationCallBack (CGDirectDisplayID display,
- CGDisplayChangeSummaryFlags flags,
- void *userInfo);
-
-public: // data
- Ptr<DeviceManagerThread> pThread;
-};
-
-//-------------------------------------------------------------------------------------
-// ***** Device Manager Background Thread
-
-class DeviceManagerThread : public Thread, public ThreadCommandQueue
-{
- friend class DeviceManager;
- enum { ThreadStackSize = 32 * 1024 };
-public:
- DeviceManagerThread();
- ~DeviceManagerThread();
-
- virtual int Run();
-
- // ThreadCommandQueue notifications for CommandEvent handling.
- virtual void OnPushNonEmpty_Locked()
- {
- CFRunLoopSourceSignal(CommandQueueSource);
- CFRunLoopWakeUp(RunLoop);
- }
-
- virtual void OnPopEmpty_Locked() {}
-
-
- // Notifier used for different updates (EVENT or regular timing or messages).
- class Notifier
- {
- public:
-
- // Called when timing ticks are updated. // Returns the largest number of microseconds
- // this function can wait till next call.
- virtual UInt64 OnTicks(UInt64 ticksMks)
- { OVR_UNUSED1(ticksMks); return Timer::MksPerSecond * 1000; }
- };
-
- // Add notifier that will be called at regular intervals.
- bool AddTicksNotifier(Notifier* notify);
- bool RemoveTicksNotifier(Notifier* notify);
-
- CFRunLoopRef GetRunLoop()
- { return RunLoop; }
-
- void Shutdown();
-private:
- CFRunLoopRef RunLoop;
-
- CFRunLoopSourceRef CommandQueueSource;
-
- static void staticCommandQueueSourceCallback(void* pContext);
- void commandQueueSourceCallback();
-
- Event StartupEvent;
-
- // Ticks notifiers. Used for time-dependent events such as keep-alive.
- Array<Notifier*> TicksNotifiers;
-};
-
-}} // namespace OSX::OVR
-
-#endif // OVR_OSX_DeviceManager_h
diff --git a/LibOVR/Src/OVR_OSX_HIDDevice.cpp b/LibOVR/Src/OVR_OSX_HIDDevice.cpp
deleted file mode 100644
index 38b1b3e..0000000
--- a/LibOVR/Src/OVR_OSX_HIDDevice.cpp
+++ /dev/null
@@ -1,923 +0,0 @@
-/************************************************************************************
-Filename : OVR_OSX_HIDDevice.cpp
-Content : OSX HID device implementation.
-Created : February 26, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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 "OVR_OSX_HIDDevice.h"
-
-#include <IOKit/usb/IOUSBLib.h>
-
-namespace OVR { namespace OSX {
-
-static const UInt32 MAX_QUEUED_INPUT_REPORTS = 5;
-
-//-------------------------------------------------------------------------------------
-// **** OSX::DeviceManager
-
-HIDDeviceManager::HIDDeviceManager(DeviceManager* manager)
- : DevManager(manager)
-{
- HIDManager = NULL;
-}
-
-HIDDeviceManager::~HIDDeviceManager()
-{
-}
-
-CFRunLoopRef HIDDeviceManager::getRunLoop()
-{
- if (DevManager != NULL)
- {
- return DevManager->pThread->GetRunLoop();
- }
-
- return CFRunLoopGetCurrent();
-}
-
-bool HIDDeviceManager::initializeManager()
-{
- if (HIDManager != NULL)
- {
- return true;
- }
-
- HIDManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
-
- if (!HIDManager)
- {
- return false;
- }
-
- // Create a Matching Dictionary
- CFMutableDictionaryRef matchDict =
- CFDictionaryCreateMutable(kCFAllocatorDefault,
- 2,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
-
- // Specify a device manufacturer in the Matching Dictionary
- UInt32 vendorId = Oculus_VendorId;
- CFNumberRef vendorIdRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendorId);
- CFDictionarySetValue(matchDict,
- CFSTR(kIOHIDVendorIDKey),
- vendorIdRef);
- // Register the Matching Dictionary to the HID Manager
- IOHIDManagerSetDeviceMatching(HIDManager, matchDict);
- CFRelease(vendorIdRef);
- CFRelease(matchDict);
-
- // Register a callback for USB device detection with the HID Manager
- IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, &staticDeviceMatchingCallback, this);
-
- IOHIDManagerScheduleWithRunLoop(HIDManager, getRunLoop(), kCFRunLoopDefaultMode);
-
- return true;
-}
-
-bool HIDDeviceManager::Initialize()
-{
- return initializeManager();
-}
-
-void HIDDeviceManager::Shutdown()
-{
- OVR_ASSERT_LOG(HIDManager, ("Should have called 'Initialize' before 'Shutdown'."));
- CFRelease(HIDManager);
-
- LogText("OVR::OSX::HIDDeviceManager - shutting down.\n");
-}
-
-bool HIDDeviceManager::getIntProperty(IOHIDDeviceRef device, CFStringRef propertyName, SInt32* pResult)
-{
-
- CFTypeRef ref = IOHIDDeviceGetProperty(device, propertyName);
-
- if (!ref)
- {
- return false;
- }
-
- if (CFGetTypeID(ref) != CFNumberGetTypeID())
- {
- return false;
- }
-
- CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, pResult);
-
- return true;
-}
-
-bool HIDDeviceManager::initVendorProductVersion(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc)
-{
-
- if (!getVendorId(device, &(pDevDesc->VendorId)))
- {
- return false;
- }
-
- if (!getProductId(device, &(pDevDesc->ProductId)))
- {
- return false;
- }
-
- SInt32 result;
- if (!getIntProperty(device, CFSTR(kIOHIDVersionNumberKey), &result))
- {
- return false;
- }
- pDevDesc->VersionNumber = result;
-
- return true;
-}
-
-bool HIDDeviceManager::initUsage(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc)
-{
-
- SInt32 result;
-
- if (!getIntProperty(device, CFSTR(kIOHIDPrimaryUsagePageKey), &result))
- {
- return false;
- }
-
- pDevDesc->UsagePage = result;
-
-
- if (!getIntProperty(device, CFSTR(kIOHIDPrimaryUsageKey), &result))
- {
- return false;
- }
-
- pDevDesc->Usage = result;
-
- return true;
-}
-
-bool HIDDeviceManager::initSerialNumber(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc)
-{
- return getSerialNumberString(device, &(pDevDesc->SerialNumber));
-}
-
-bool HIDDeviceManager::initStrings(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc)
-{
-
- // Regardless of whether they fail we'll try and get the remaining.
- getStringProperty(device, CFSTR(kIOHIDManufacturerKey), &(pDevDesc->Manufacturer));
- getStringProperty(device, CFSTR(kIOHIDProductKey), &(pDevDesc->Product));
-
- return true;
-}
-
-bool HIDDeviceManager::getStringProperty(IOHIDDeviceRef device,
- CFStringRef propertyName,
- String* pResult)
-{
-
- CFStringRef str = (CFStringRef) IOHIDDeviceGetProperty(device, propertyName);
-
- if (!str)
- {
- return false;
- }
-
- CFIndex length = CFStringGetLength(str);
- CFRange range = CFRangeMake(0, length);
-
- // Test the conversion first to get required buffer size.
- CFIndex bufferLength;
- CFIndex numberOfChars = CFStringGetBytes(str,
- range,
- kCFStringEncodingUTF8,
- (char) '?',
- FALSE,
- NULL,
- 0,
- &bufferLength);
-
- if (numberOfChars == 0)
- {
- return false;
- }
-
- // Now allocate buffer.
- char* buffer = new char[bufferLength+1];
-
- numberOfChars = CFStringGetBytes(str,
- range,
- kCFStringEncodingUTF8,
- (char) '?',
- FALSE,
- (UInt8*) buffer,
- bufferLength,
- NULL);
- OVR_ASSERT_LOG(numberOfChars != 0, ("CFStringGetBytes failed."));
-
- buffer[bufferLength] = '\0';
- *pResult = String(buffer);
-
- return true;
-}
-
-bool HIDDeviceManager::getVendorId(IOHIDDeviceRef device, UInt16* pResult)
-{
- SInt32 result;
-
- if (!getIntProperty(device, CFSTR(kIOHIDVendorIDKey), &result))
- {
- return false;
- }
-
- *pResult = result;
-
- return true;
-}
-
-bool HIDDeviceManager::getProductId(IOHIDDeviceRef device, UInt16* pResult)
-{
- SInt32 result;
-
- if (!getIntProperty(device, CFSTR(kIOHIDProductIDKey), &result))
- {
- return false;
- }
-
- *pResult = result;
-
- return true;
-}
-
-bool HIDDeviceManager::getLocationId(IOHIDDeviceRef device, SInt32* pResult)
-{
- SInt32 result;
-
- if (!getIntProperty(device, CFSTR(kIOHIDLocationIDKey), &result))
- {
- return false;
- }
-
- *pResult = result;
-
- return true;
-}
-
-bool HIDDeviceManager::getSerialNumberString(IOHIDDeviceRef device, String* pResult)
-{
-
- if (!getStringProperty(device, CFSTR(kIOHIDSerialNumberKey), pResult))
- {
- return false;
- }
-
- return true;
-}
-
-bool HIDDeviceManager::getPath(IOHIDDeviceRef device, String* pPath)
-{
-
- String transport;
- if (!getStringProperty(device, CFSTR(kIOHIDTransportKey), &transport))
- {
- return false;
- }
-
- UInt16 vendorId;
- if (!getVendorId(device, &vendorId))
- {
- return false;
- }
-
- UInt16 productId;
- if (!getProductId(device, &productId))
- {
- return false;
- }
-
- String serialNumber;
- if (!getSerialNumberString(device, &serialNumber))
- {
- return false;
- }
-
-
- StringBuffer buffer;
- buffer.AppendFormat("%s:vid=%04hx:pid=%04hx:ser=%s",
- transport.ToCStr(),
- vendorId,
- productId,
- serialNumber.ToCStr());
-
- *pPath = String(buffer);
-
- return true;
-}
-
-bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor)
-{
- if (!initializeManager())
- {
- return false;
- }
-
-
- CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager);
- if (!deviceSet)
- return false;
-
- CFIndex deviceCount = CFSetGetCount(deviceSet);
-
- // Allocate a block of memory and read the set into it.
- IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount);
- CFSetGetValues(deviceSet, (const void **) devices);
-
-
- // Iterate over devices.
- for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
- {
- IOHIDDeviceRef hidDev = devices[deviceIndex];
-
- if (!hidDev)
- {
- continue;
- }
-
- HIDDeviceDesc devDesc;
-
- if (getPath(hidDev, &(devDesc.Path)) &&
- initVendorProductVersion(hidDev, &devDesc) &&
- enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId) &&
- initUsage(hidDev, &devDesc))
- {
- initStrings(hidDev, &devDesc);
- initSerialNumber(hidDev, &devDesc);
-
- // Look for the device to check if it is already opened.
- Ptr<DeviceCreateDesc> existingDevice = DevManager->FindHIDDevice(devDesc, true);
- // if device exists and it is opened then most likely the CreateHIDFile
- // will fail; therefore, we just set Enumerated to 'true' and continue.
- if (existingDevice && existingDevice->pDevice)
- {
- existingDevice->Enumerated = true;
- continue;
- }
-
- // open the device temporarily for startup communication
- if (IOHIDDeviceOpen(hidDev, kIOHIDOptionsTypeSeizeDevice) == kIOReturnSuccess)
- {
- // Construct minimal device that the visitor callback can get feature reports from.
- OSX::HIDDevice device(this, hidDev);
-
- enumVisitor->Visit(device, devDesc);
-
- IOHIDDeviceClose(hidDev, kIOHIDOptionsTypeSeizeDevice);
- }
- }
- }
-
- OVR_FREE(devices);
- CFRelease(deviceSet);
-
- return true;
-}
-
-OVR::HIDDevice* HIDDeviceManager::Open(const String& path)
-{
-
- Ptr<OSX::HIDDevice> device = *new OSX::HIDDevice(this);
-
- if (!device->HIDInitialize(path))
- {
- return NULL;
- }
-
- device->AddRef();
-
- return device;
-}
-
-bool HIDDeviceManager::getFullDesc(IOHIDDeviceRef device, HIDDeviceDesc* desc)
-{
-
- if (!initVendorProductVersion(device, desc))
- {
- return false;
- }
-
- if (!initUsage(device, desc))
- {
- return false;
- }
-
- if (!initSerialNumber(device, desc))
- {
- return false;
- }
-
- initStrings(device, desc);
-
- return true;
-}
-
-// New USB device specified in the matching dictionary has been added (callback function)
-void HIDDeviceManager::staticDeviceMatchingCallback(void *inContext,
- IOReturn inResult,
- void *inSender,
- IOHIDDeviceRef inIOHIDDeviceRef)
-{
- HIDDeviceManager* hidMgr = static_cast<HIDDeviceManager*>(inContext);
- HIDDeviceDesc hidDevDesc;
- hidMgr->getPath(inIOHIDDeviceRef, &hidDevDesc.Path);
- hidMgr->getFullDesc(inIOHIDDeviceRef, &hidDevDesc);
-
- hidMgr->DevManager->DetectHIDDevice(hidDevDesc);
-}
-
-//-------------------------------------------------------------------------------------
-// **** OSX::HIDDevice
-
-HIDDevice::HIDDevice(HIDDeviceManager* manager)
- : HIDManager(manager), InMinimalMode(false)
-{
- Device = NULL;
- RepluggedNotificationPort = 0;
-}
-
-// This is a minimal constructor used during enumeration for us to pass
-// a HIDDevice to the visit function (so that it can query feature reports).
-HIDDevice::HIDDevice(HIDDeviceManager* manager, IOHIDDeviceRef device)
-: HIDManager(manager), Device(device), InMinimalMode(true)
-{
- RepluggedNotificationPort = 0;
-}
-
-HIDDevice::~HIDDevice()
-{
- if (!InMinimalMode)
- {
- HIDShutdown();
- }
-}
-
-bool HIDDevice::HIDInitialize(const String& path)
-{
-
- DevDesc.Path = path;
-
- if (!openDevice())
- {
- LogText("OVR::OSX::HIDDevice - Failed to open HIDDevice: %s", path.ToCStr());
- return false;
- }
-
- // Setup notification for when a device is unplugged and plugged back in.
- if (!setupDevicePluggedInNotification())
- {
- LogText("OVR::OSX::HIDDevice - Failed to setup notification for when device plugged back in.");
- closeDevice(false);
- return false;
- }
-
- HIDManager->DevManager->pThread->AddTicksNotifier(this);
-
-
- LogText("OVR::OSX::HIDDevice - Opened '%s'\n"
- " Manufacturer:'%s' Product:'%s' Serial#:'%s'\n",
- DevDesc.Path.ToCStr(),
- DevDesc.Manufacturer.ToCStr(), DevDesc.Product.ToCStr(),
- DevDesc.SerialNumber.ToCStr());
-
- return true;
-}
-
-bool HIDDevice::initInfo()
-{
- // Device must have been successfully opened.
- OVR_ASSERT(Device);
-
-
- // Get report lengths.
- SInt32 bufferLength;
- bool getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxInputReportSizeKey), &bufferLength);
- OVR_ASSERT(getResult);
- InputReportBufferLength = (UInt16) bufferLength;
-
- getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxOutputReportSizeKey), &bufferLength);
- OVR_ASSERT(getResult);
- OutputReportBufferLength = (UInt16) bufferLength;
-
- getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxFeatureReportSizeKey), &bufferLength);
- OVR_ASSERT(getResult);
- FeatureReportBufferLength = (UInt16) bufferLength;
-
-
- if (ReadBufferSize < InputReportBufferLength)
- {
- OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer."));
- return false;
- }
-
- // Get device desc.
- if (!HIDManager->getFullDesc(Device, &DevDesc))
- {
- OVR_ASSERT_LOG(false, ("Failed to get device desc while initializing device."));
- return false;
- }
-
- return true;
-}
-
-void HIDDevice::staticDeviceAddedCallback(void* pContext, io_iterator_t iterator)
-{
- HIDDevice* pDevice = (HIDDevice*) pContext;
- pDevice->deviceAddedCallback(iterator);
-}
-
-void HIDDevice::deviceAddedCallback(io_iterator_t iterator)
-{
-
- if (Device == NULL)
- {
- if (openDevice())
- {
- LogText("OVR::OSX::HIDDevice - Reopened device : %s", DevDesc.Path.ToCStr());
-
- Ptr<DeviceCreateDesc> existingHIDDev = HIDManager->DevManager->FindHIDDevice(DevDesc, true);
- if (existingHIDDev && existingHIDDev->pDevice)
- {
- HIDManager->DevManager->CallOnDeviceAdded(existingHIDDev);
- }
- }
- }
-
- // Reset callback.
- while (IOIteratorNext(iterator))
- ;
-}
-
-bool HIDDevice::openDevice()
-{
-
- // Have to iterate through devices again to generate paths.
- CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager->HIDManager);
- CFIndex deviceCount = CFSetGetCount(deviceSet);
-
- // Allocate a block of memory and read the set into it.
- IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount);
- CFSetGetValues(deviceSet, (const void **) devices);
-
-
- // Iterate over devices.
- IOHIDDeviceRef device = NULL;
-
- for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
- {
- IOHIDDeviceRef tmpDevice = devices[deviceIndex];
-
- if (!tmpDevice)
- {
- continue;
- }
-
- String path;
- if (!HIDManager->getPath(tmpDevice, &path))
- {
- continue;
- }
-
- if (path == DevDesc.Path)
- {
- device = tmpDevice;
- break;
- }
- }
-
-
- OVR_FREE(devices);
-
- if (!device)
- {
- CFRelease(deviceSet);
- return false;
- }
-
- // Attempt to open device.
- if (IOHIDDeviceOpen(device, kIOHIDOptionsTypeSeizeDevice)
- != kIOReturnSuccess)
- {
- CFRelease(deviceSet);
- return false;
- }
-
- // Retain the device before we release the set.
- CFRetain(device);
- CFRelease(deviceSet);
-
-
- Device = device;
-
-
- if (!initInfo())
- {
- IOHIDDeviceClose(Device, kIOHIDOptionsTypeSeizeDevice);
- CFRelease(Device);
- Device = NULL;
- return false;
- }
-
-
- // Setup the Run Loop and callbacks.
- IOHIDDeviceScheduleWithRunLoop(Device,
- HIDManager->getRunLoop(),
- kCFRunLoopDefaultMode);
-
- IOHIDDeviceRegisterInputReportCallback(Device,
- ReadBuffer,
- ReadBufferSize,
- staticHIDReportCallback,
- this);
-
- IOHIDDeviceRegisterRemovalCallback(Device,
- staticDeviceRemovedCallback,
- this);
-
- return true;
-}
-
-void HIDDevice::HIDShutdown()
-{
-
- HIDManager->DevManager->pThread->RemoveTicksNotifier(this);
-
- if (Device != NULL) // Device may already have been closed if unplugged.
- {
- closeDevice(false);
- }
-
- IOObjectRelease(RepluggedNotification);
- if (RepluggedNotificationPort)
- IONotificationPortDestroy(RepluggedNotificationPort);
-
- LogText("OVR::OSX::HIDDevice - HIDShutdown '%s'\n", DevDesc.Path.ToCStr());
-}
-
-bool HIDDevice::setupDevicePluggedInNotification()
-{
-
- // Setup notification when devices are plugged in.
- RepluggedNotificationPort = IONotificationPortCreate(kIOMasterPortDefault);
-
- CFRunLoopSourceRef notificationRunLoopSource =
- IONotificationPortGetRunLoopSource(RepluggedNotificationPort);
-
- CFRunLoopAddSource(HIDManager->getRunLoop(),
- notificationRunLoopSource,
- kCFRunLoopDefaultMode);
-
- CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
-
- // Have to specify vendorId and productId. Doesn't seem to accept additional
- // things like serial number.
- SInt32 vendorId = DevDesc.VendorId;
- CFNumberRef numberRef = CFNumberCreate(kCFAllocatorDefault,
- kCFNumberSInt32Type,
- &vendorId);
- CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef);
- CFRelease(numberRef);
-
- SInt32 deviceProductId = DevDesc.ProductId;
- numberRef = CFNumberCreate(kCFAllocatorDefault,
- kCFNumberSInt32Type,
- &deviceProductId);
- CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef);
- CFRelease(numberRef);
-
- kern_return_t result =
- IOServiceAddMatchingNotification(RepluggedNotificationPort,
- kIOMatchedNotification,
- matchingDict,
- staticDeviceAddedCallback,
- this,
- &RepluggedNotification);
-
- if (result != KERN_SUCCESS)
- {
- CFRelease(RepluggedNotificationPort);
- RepluggedNotificationPort = 0;
- return false;
- }
-
- // Iterate through to arm.
- while (IOIteratorNext(RepluggedNotification))
- {
- }
-
- return true;
-}
-
-void HIDDevice::closeDevice(bool wasUnplugged)
-{
- OVR_ASSERT(Device != NULL);
-
- if (!wasUnplugged)
- {
- // Clear the registered callbacks.
- IOHIDDeviceRegisterInputReportCallback(Device,
- ReadBuffer,
- InputReportBufferLength,
- NULL,
- this);
-
- IOHIDDeviceRegisterRemovalCallback(Device, NULL, this);
-
- IOHIDDeviceUnscheduleFromRunLoop(Device,
- HIDManager->getRunLoop(),
- kCFRunLoopDefaultMode);
- IOHIDDeviceClose(Device, kIOHIDOptionsTypeNone);
- }
-
- CFRelease(Device);
- Device = NULL;
-
- LogText("OVR::OSX::HIDDevice - HID Device Closed '%s'\n", DevDesc.Path.ToCStr());
-}
-
-void HIDDevice::staticHIDReportCallback(void* pContext,
- IOReturn result,
- void* pSender,
- IOHIDReportType reportType,
- uint32_t reportId,
- uint8_t* pReport,
- CFIndex reportLength)
-{
- HIDDevice* pDevice = (HIDDevice*) pContext;
- return pDevice->hidReportCallback(pReport, (UInt32)reportLength);
-}
-
-void HIDDevice::hidReportCallback(UByte* pData, UInt32 length)
-{
-
- // We got data.
- if (Handler)
- {
- Handler->OnInputReport(pData, length);
- }
-}
-
-void HIDDevice::staticDeviceRemovedCallback(void* pContext, IOReturn result, void* pSender)
-{
- HIDDevice* pDevice = (HIDDevice*) pContext;
- pDevice->deviceRemovedCallback();
-}
-
-void HIDDevice::deviceRemovedCallback()
-{
- Ptr<HIDDevice> _this(this); // prevent from release
-
- Ptr<DeviceCreateDesc> existingHIDDev = HIDManager->DevManager->FindHIDDevice(DevDesc, true);
- if (existingHIDDev && existingHIDDev->pDevice)
- {
- HIDManager->DevManager->CallOnDeviceRemoved(existingHIDDev);
- }
- closeDevice(true);
-}
-
-CFStringRef HIDDevice::generateRunLoopModeString(IOHIDDeviceRef device)
-{
- const UInt32 safeBuffSize = 256;
- char nameBuff[safeBuffSize];
- OVR_sprintf(nameBuff, safeBuffSize, "%016lX", device);
-
- return CFStringCreateWithCString(NULL, nameBuff, kCFStringEncodingASCII);
-}
-
-bool HIDDevice::SetFeatureReport(UByte* data, UInt32 length)
-{
-
- if (!Device)
- return false;
-
- UByte reportID = data[0];
-
- if (reportID == 0)
- {
- // Not using reports so remove from data packet.
- data++;
- length--;
- }
-
- IOReturn result = IOHIDDeviceSetReport( Device,
- kIOHIDReportTypeFeature,
- reportID,
- data,
- length);
-
- return (result == kIOReturnSuccess);
-}
-
-bool HIDDevice::GetFeatureReport(UByte* data, UInt32 length)
-{
- if (!Device)
- return false;
-
- CFIndex bufferLength = length;
-
- // Report id is in first byte of the buffer.
- IOReturn result = IOHIDDeviceGetReport(Device, kIOHIDReportTypeFeature, data[0], data, &bufferLength);
-
- return (result == kIOReturnSuccess);
-}
-
-UInt64 HIDDevice::OnTicks(UInt64 ticksMks)
-{
-
- if (Handler)
- {
- return Handler->OnTicks(ticksMks);
- }
-
- return DeviceManagerThread::Notifier::OnTicks(ticksMks);
-}
-
-HIDDeviceManager* HIDDeviceManager::CreateInternal(OSX::DeviceManager* devManager)
-{
-
- if (!System::IsInitialized())
- {
- // Use custom message, since Log is not yet installed.
- OVR_DEBUG_STATEMENT(Log::GetDefaultLog()->
- LogMessage(Log_Debug, "HIDDeviceManager::Create failed - OVR::System not initialized"); );
- return 0;
- }
-
- Ptr<OSX::HIDDeviceManager> manager = *new OSX::HIDDeviceManager(devManager);
-
- if (manager)
- {
- if (manager->Initialize())
- {
- manager->AddRef();
- }
- else
- {
- manager.Clear();
- }
- }
-
- return manager.GetPtr();
-}
-
-} // namespace OSX
-
-//-------------------------------------------------------------------------------------
-// ***** Creation
-
-// Creates a new HIDDeviceManager and initializes OVR.
-HIDDeviceManager* HIDDeviceManager::Create()
-{
- OVR_ASSERT_LOG(false, ("Standalone mode not implemented yet."));
-
- if (!System::IsInitialized())
- {
- // Use custom message, since Log is not yet installed.
- OVR_DEBUG_STATEMENT(Log::GetDefaultLog()->
- LogMessage(Log_Debug, "HIDDeviceManager::Create failed - OVR::System not initialized"); );
- return 0;
- }
-
- Ptr<OSX::HIDDeviceManager> manager = *new OSX::HIDDeviceManager(NULL);
-
- if (manager)
- {
- if (manager->Initialize())
- {
- manager->AddRef();
- }
- else
- {
- manager.Clear();
- }
- }
-
- return manager.GetPtr();
-}
-
-} // namespace OVR
diff --git a/LibOVR/Src/OVR_OSX_HIDDevice.h b/LibOVR/Src/OVR_OSX_HIDDevice.h
deleted file mode 100644
index e2fac31..0000000
--- a/LibOVR/Src/OVR_OSX_HIDDevice.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/************************************************************************************
-Filename : OVR_OSX_HIDDevice.h
-Content : OSX HID device implementation.
-Created : February 26, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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_OSX_HIDDevice_h
-#define OVR_OSX_HIDDevice_h
-
-#include "OVR_HIDDevice.h"
-
-#include "OVR_OSX_DeviceManager.h"
-
-#include <IOKit/IOKitLib.h>
-
-namespace OVR { namespace OSX {
-
-class HIDDeviceManager;
-
-//-------------------------------------------------------------------------------------
-// ***** OSX HIDDevice
-
-class HIDDevice : public OVR::HIDDevice, public DeviceManagerThread::Notifier
-{
-private:
- friend class HIDDeviceManager;
-
-public:
- HIDDevice(HIDDeviceManager* manager);
-
- // This is a minimal constructor used during enumeration for us to pass
- // a HIDDevice to the visit function (so that it can query feature reports).
- HIDDevice(HIDDeviceManager* manager, IOHIDDeviceRef device);
-
- virtual ~HIDDevice();
-
- bool HIDInitialize(const String& path);
- void HIDShutdown();
-
- virtual bool SetFeatureReport(UByte* data, UInt32 length);
- virtual bool GetFeatureReport(UByte* data, UInt32 length);
-
- bool Write(UByte* data, UInt32 length);
-
- bool Read(UByte* pData, UInt32 length, UInt32 timeoutMilliS);
- bool ReadBlocking(UByte* pData, UInt32 length);
-
-
- // DeviceManagerThread::Notifier
- UInt64 OnTicks(UInt64 ticksMks);
-
-private:
- bool initInfo();
- bool openDevice();
- void closeDevice(bool wasUnplugged);
- bool setupDevicePluggedInNotification();
- CFStringRef generateRunLoopModeString(IOHIDDeviceRef device);
-
- static void staticHIDReportCallback(void* pContext,
- IOReturn result,
- void* pSender,
- IOHIDReportType reportType,
- uint32_t reportId,
- uint8_t* pReport,
- CFIndex reportLength);
- void hidReportCallback(UByte* pData, UInt32 length);
-
- static void staticDeviceRemovedCallback(void* pContext,
- IOReturn result,
- void* pSender);
- void deviceRemovedCallback();
-
- static void staticDeviceAddedCallback(void* pContext,
- io_iterator_t iterator);
- void deviceAddedCallback(io_iterator_t iterator);
-
- bool InMinimalMode;
- HIDDeviceManager* HIDManager;
- IOHIDDeviceRef Device;
- HIDDeviceDesc DevDesc;
-
- enum { ReadBufferSize = 96 };
- UByte ReadBuffer[ReadBufferSize];
-
- UInt16 InputReportBufferLength;
- UInt16 OutputReportBufferLength;
- UInt16 FeatureReportBufferLength;
-
- IONotificationPortRef RepluggedNotificationPort;
- io_iterator_t RepluggedNotification;
-};
-
-
-//-------------------------------------------------------------------------------------
-// ***** OSX HIDDeviceManager
-
-class HIDDeviceManager : public OVR::HIDDeviceManager
-{
- friend class HIDDevice;
-
-public:
- HIDDeviceManager(OSX::DeviceManager* Manager);
- virtual ~HIDDeviceManager();
-
- virtual bool Initialize();
- virtual void Shutdown();
-
- virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor);
- virtual OVR::HIDDevice* Open(const String& path);
-
- static HIDDeviceManager* CreateInternal(DeviceManager* manager);
-
-private:
- CFRunLoopRef getRunLoop();
- bool initializeManager();
- bool initVendorProductVersion(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc);
- bool initUsage(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc);
- bool initStrings(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc);
- bool initSerialNumber(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc);
- bool getVendorId(IOHIDDeviceRef device, UInt16* pResult);
- bool getProductId(IOHIDDeviceRef device, UInt16* pResult);
- bool getLocationId(IOHIDDeviceRef device, SInt32* pResult);
- bool getSerialNumberString(IOHIDDeviceRef device, String* pResult);
- bool getPath(IOHIDDeviceRef device, String* pPath);
- bool getIntProperty(IOHIDDeviceRef device, CFStringRef key, int32_t* pResult);
- bool getStringProperty(IOHIDDeviceRef device, CFStringRef propertyName, String* pResult);
- bool getFullDesc(IOHIDDeviceRef device, HIDDeviceDesc* desc);
-
- static void staticDeviceMatchingCallback(void *inContext,
- IOReturn inResult,
- void *inSender,
- IOHIDDeviceRef inIOHIDDeviceRef);
-
- DeviceManager* DevManager;
-
- IOHIDManagerRef HIDManager;
-};
-
-}} // namespace OVR::OSX
-
-#endif // OVR_OSX_HIDDevice_h
diff --git a/LibOVR/Src/OVR_OSX_HMDDevice.cpp b/LibOVR/Src/OVR_OSX_HMDDevice.cpp
deleted file mode 100644
index 214a2e7..0000000
--- a/LibOVR/Src/OVR_OSX_HMDDevice.cpp
+++ /dev/null
@@ -1,417 +0,0 @@
-/************************************************************************************
-
-Filename : OVR_OSX_HMDDevice.cpp
-Content : OSX Interface to HMD - detects HMD display
-Created : September 21, 2012
-Authors : Michael Antonov
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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 "OVR_OSX_HMDDevice.h"
-#include <CoreGraphics/CGDirectDisplay.h>
-#include <CoreGraphics/CGDisplayConfiguration.h>
-#include <CoreFoundation/CoreFoundation.h>
-#include <CoreFoundation/CFString.h>
-#include <IOKit/graphics/IOGraphicsLib.h>
-
-namespace OVR { namespace OSX {
-
-//-------------------------------------------------------------------------------------
-
-HMDDeviceCreateDesc::HMDDeviceCreateDesc(DeviceFactory* factory,
- UInt32 vend, UInt32 prod, const String& displayDeviceName, long dispId)
- : DeviceCreateDesc(factory, Device_HMD),
- DisplayDeviceName(displayDeviceName),
- DesktopX(0), DesktopY(0), Contents(0), EyeToScreenDistance(0),
- HResolution(0), VResolution(0), HScreenSize(0), VScreenSize(0),
- DisplayId(dispId)
-{
- /* //??????????
- char idstring[9];
- idstring[0] = 'A'-1+((vend>>10) & 31);
- idstring[1] = 'A'-1+((vend>>5) & 31);
- idstring[2] = 'A'-1+((vend>>0) & 31);
- snprintf(idstring+3, 5, "%04d", prod);
- DeviceId = idstring;*/
- DeviceId = DisplayDeviceName;
-
- for (int i=0; i<4; i++)
- DistortionK[i] = 0;
-}
-
-HMDDeviceCreateDesc::HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other)
- : DeviceCreateDesc(other.pFactory, Device_HMD),
- DeviceId(other.DeviceId), DisplayDeviceName(other.DisplayDeviceName),
- DesktopX(other.DesktopX), DesktopY(other.DesktopY), Contents(other.Contents),
- HResolution(other.HResolution), VResolution(other.VResolution),
- HScreenSize(other.HScreenSize), VScreenSize(other.VScreenSize),
- DisplayId(other.DisplayId), EyeToScreenDistance(other.EyeToScreenDistance)
-{
- for (int i=0; i<4; i++)
- DistortionK[i] = other.DistortionK[i];
-}
-
-HMDDeviceCreateDesc::MatchResult HMDDeviceCreateDesc::MatchDevice(const DeviceCreateDesc& other,
- DeviceCreateDesc** pcandidate) const
-{
- if ((other.Type != Device_HMD) || (other.pFactory != pFactory))
- return Match_None;
-
- // There are several reasons we can come in here:
- // a) Matching this HMD Monitor created desc to OTHER HMD Monitor desc
- // - Require exact device DeviceId/DeviceName match
- // b) Matching SensorDisplayInfo created desc to OTHER HMD Monitor desc
- // - This DeviceId is empty; becomes candidate
- // c) Matching this HMD Monitor created desc to SensorDisplayInfo desc
- // - This other.DeviceId is empty; becomes candidate
-
- const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other;
-
- if ((DeviceId == s2.DeviceId) &&
- (DisplayId == s2.DisplayId))
- {
- // Non-null DeviceId may match while size is different if screen size was overwritten
- // by SensorDisplayInfo in prior iteration.
- if (!DeviceId.IsEmpty() ||
- ((HScreenSize == s2.HScreenSize) &&
- (VScreenSize == s2.VScreenSize)) )
- {
- *pcandidate = 0;
- return Match_Found;
- }
- }
-
-
- // DisplayInfo takes precedence, although we try to match it first.
- if ((HResolution == s2.HResolution) &&
- (VResolution == s2.VResolution) &&
- (HScreenSize == s2.HScreenSize) &&
- (VScreenSize == s2.VScreenSize))
- {
- if (DeviceId.IsEmpty() && !s2.DeviceId.IsEmpty())
- {
- *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this);
- return Match_Candidate;
- }
-
- *pcandidate = 0;
- return Match_Found;
- }
-
- // SensorDisplayInfo may override resolution settings, so store as candidiate.
- if (s2.DeviceId.IsEmpty() && s2.DisplayId == 0)
- {
- *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this);
- return Match_Candidate;
- }
- // OTHER HMD Monitor desc may initialize DeviceName/Id
- else if (DeviceId.IsEmpty() && DisplayId == 0)
- {
- *pcandidate = const_cast<DeviceCreateDesc*>((const DeviceCreateDesc*)this);
- return Match_Candidate;
- }
-
- return Match_None;
-}
-
-
-bool HMDDeviceCreateDesc::UpdateMatchedCandidate(const DeviceCreateDesc& other, bool* newDeviceFlag)
-{
- // This candidate was the the "best fit" to apply sensor DisplayInfo to.
- OVR_ASSERT(other.Type == Device_HMD);
-
- const HMDDeviceCreateDesc& s2 = (const HMDDeviceCreateDesc&) other;
-
- // Force screen size on resolution from SensorDisplayInfo.
- // We do this because USB detection is more reliable as compared to HDMI EDID,
- // which may be corrupted by splitter reporting wrong monitor
- if (s2.DeviceId.IsEmpty() && s2.DisplayId == 0)
- {
- // disconnected HMD: replace old descriptor by the 'fake' one.
- HScreenSize = s2.HScreenSize;
- VScreenSize = s2.VScreenSize;
- Contents |= Contents_Screen;
-
- if (s2.Contents & HMDDeviceCreateDesc::Contents_Distortion)
- {
- memcpy(DistortionK, s2.DistortionK, sizeof(float)*4);
- Contents |= Contents_Distortion;
- }
- DeviceId = s2.DeviceId;
- DisplayId = s2.DisplayId;
- DisplayDeviceName = s2.DisplayDeviceName;
- if (newDeviceFlag) *newDeviceFlag = true;
- }
- else if (DeviceId.IsEmpty())
- {
- // This branch is executed when 'fake' HMD descriptor is being replaced by
- // the real one.
- DeviceId = s2.DeviceId;
- DisplayId = s2.DisplayId;
- DisplayDeviceName = s2.DisplayDeviceName;
- if (newDeviceFlag) *newDeviceFlag = true;
- }
- else
- {
- if (newDeviceFlag) *newDeviceFlag = false;
- }
-
- return true;
-}
-
-
-//-------------------------------------------------------------------------------------
-
-
-//-------------------------------------------------------------------------------------
-// ***** HMDDeviceFactory
-
-HMDDeviceFactory HMDDeviceFactory::Instance;
-
-void HMDDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor)
-{
- CGDirectDisplayID Displays[32];
- uint32_t NDisplays = 0;
- CGGetOnlineDisplayList(32, Displays, &NDisplays);
-
- for (int i = 0; i < NDisplays; i++)
- {
- io_service_t port = CGDisplayIOServicePort(Displays[i]);
- CFDictionaryRef DispInfo = IODisplayCreateInfoDictionary(port, kIODisplayMatchingInfo);
-
- uint32_t vendor = CGDisplayVendorNumber(Displays[i]);
- uint32_t product = CGDisplayModelNumber(Displays[i]);
- unsigned mwidth = (unsigned)CGDisplayPixelsWide(Displays[i]);
- unsigned mheight = (unsigned)CGDisplayPixelsHigh(Displays[i]);
- CGRect desktop = CGDisplayBounds(Displays[i]);
-
- if (vendor == 16082 && ( (product == 1)||(product == 2) ) ) // 7" or HD
- {
- char idstring[9];
- idstring[0] = 'A'-1+((vendor>>10) & 31);
- idstring[1] = 'A'-1+((vendor>>5) & 31);
- idstring[2] = 'A'-1+((vendor>>0) & 31);
- snprintf(idstring+3, 5, "%04d", product);
-
- HMDDeviceCreateDesc hmdCreateDesc(this, vendor, product, idstring, Displays[i]);
-
- if (product == 2)
- {
- hmdCreateDesc.SetScreenParameters(desktop.origin.x, desktop.origin.y,
- mwidth, mheight, 0.12096f, 0.06804f);
- }
- else
- {
- if (hmdCreateDesc.Is7Inch())
- {
- // Physical dimension of SLA screen.
- hmdCreateDesc.SetScreenParameters(desktop.origin.x, desktop.origin.y,
- mwidth, mheight, 0.14976f, 0.0936f);
- }
- else
- {
- hmdCreateDesc.SetScreenParameters(desktop.origin.x, desktop.origin.y,
- mwidth, mheight, 0.12096f, 0.0756f);
- }
- }
-
- OVR_DEBUG_LOG_TEXT(("DeviceManager - HMD Found %x:%x\n", vendor, product));
-
- // Notify caller about detected device. This will call EnumerateAddDevice
- // if the this is the first time device was detected.
- visitor.Visit(hmdCreateDesc);
- }
- CFRelease(DispInfo);
- }
-}
-
-DeviceBase* HMDDeviceCreateDesc::NewDeviceInstance()
-{
- return new HMDDevice(this);
-}
-
-bool HMDDeviceCreateDesc::Is7Inch() const
-{
- return (strstr(DeviceId.ToCStr(), "OVR0001") != 0) || (Contents & Contents_7Inch);
-}
-
-Profile* HMDDeviceCreateDesc::GetProfileAddRef() const
-{
- // Create device may override profile name, so get it from there is possible.
- ProfileManager* profileManager = GetManagerImpl()->GetProfileManager();
- ProfileType profileType = GetProfileType();
- const char * profileName = pDevice ?
- ((HMDDevice*)pDevice)->GetProfileName() :
- profileManager->GetDefaultProfileName(profileType);
-
- return profileName ?
- profileManager->LoadProfile(profileType, profileName) :
- profileManager->GetDeviceDefaultProfile(profileType);
-}
-
-bool HMDDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const
-{
- if ((info->InfoClassType != Device_HMD) &&
- (info->InfoClassType != Device_None))
- return false;
-
- bool is7Inch = Is7Inch();
-
- OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength,
- is7Inch ? "Oculus Rift DK1" :
- ((HResolution >= 1920) ? "Oculus Rift DK HD" : "Oculus Rift DK1-Prototype") );
- OVR_strcpy(info->Manufacturer, DeviceInfo::MaxNameLength, "Oculus VR");
- info->Type = Device_HMD;
- info->Version = 0;
-
- // Display detection.
- if (info->InfoClassType == Device_HMD)
- {
- HMDInfo* hmdInfo = static_cast<HMDInfo*>(info);
-
- hmdInfo->DesktopX = DesktopX;
- hmdInfo->DesktopY = DesktopY;
- hmdInfo->HResolution = HResolution;
- hmdInfo->VResolution = VResolution;
- hmdInfo->HScreenSize = HScreenSize;
- hmdInfo->VScreenSize = VScreenSize;
- hmdInfo->VScreenCenter = VScreenSize * 0.5f;
- hmdInfo->InterpupillaryDistance = 0.064f; // Default IPD; should be configurable.
- hmdInfo->LensSeparationDistance = 0.0635f;
-
- // Obtain IPD from profile.
- Ptr<Profile> profile = *GetProfileAddRef();
-
- if (profile)
- {
- hmdInfo->InterpupillaryDistance = profile->GetIPD();
- // TBD: Switch on EyeCup type.
- }
-
- if (Contents & Contents_Distortion)
- {
- memcpy(hmdInfo->DistortionK, DistortionK, sizeof(float)*4);
- hmdInfo->EyeToScreenDistance = EyeToScreenDistance;
- }
- else
- {
- if (is7Inch)
- {
- // 7" screen.
- hmdInfo->DistortionK[0] = 1.0f;
- hmdInfo->DistortionK[1] = 0.22f;
- hmdInfo->DistortionK[2] = 0.24f;
- hmdInfo->EyeToScreenDistance = 0.041f;
- }
- else
- {
- hmdInfo->DistortionK[0] = 1.0f;
- hmdInfo->DistortionK[1] = 0.18f;
- hmdInfo->DistortionK[2] = 0.115f;
-
- if (HResolution == 1920)
- hmdInfo->EyeToScreenDistance = 0.040f;
- else
- hmdInfo->EyeToScreenDistance = 0.0387f;
- }
- }
-
- hmdInfo->ChromaAbCorrection[0] = 0.996f;
- hmdInfo->ChromaAbCorrection[1] = -0.004f;
- hmdInfo->ChromaAbCorrection[2] = 1.014f;
- hmdInfo->ChromaAbCorrection[3] = 0.0f;
-
- OVR_strcpy(hmdInfo->DisplayDeviceName, sizeof(hmdInfo->DisplayDeviceName),
- DisplayDeviceName.ToCStr());
- hmdInfo->DisplayId = DisplayId;
- }
-
- return true;
-}
-
-//-------------------------------------------------------------------------------------
-// ***** HMDDevice
-
-HMDDevice::HMDDevice(HMDDeviceCreateDesc* createDesc)
- : OVR::DeviceImpl<OVR::HMDDevice>(createDesc, 0)
-{
-}
-HMDDevice::~HMDDevice()
-{
-}
-
-bool HMDDevice::Initialize(DeviceBase* parent)
-{
- pParent = parent;
-
- // Initialize user profile to default for device.
- ProfileManager* profileManager = GetManager()->GetProfileManager();
- ProfileName = profileManager->GetDefaultProfileName(getDesc()->GetProfileType());
-
- return true;
-}
-void HMDDevice::Shutdown()
-{
- ProfileName.Clear();
- pCachedProfile.Clear();
- pParent.Clear();
-}
-
-Profile* HMDDevice::GetProfile() const
-{
- if (!pCachedProfile)
- pCachedProfile = *getDesc()->GetProfileAddRef();
- return pCachedProfile.GetPtr();
-}
-
-const char* HMDDevice::GetProfileName() const
-{
- return ProfileName.ToCStr();
-}
-
-bool HMDDevice::SetProfileName(const char* name)
-{
- pCachedProfile.Clear();
- if (!name)
- {
- ProfileName.Clear();
- return 0;
- }
- if (GetManager()->GetProfileManager()->HasProfile(getDesc()->GetProfileType(), name))
- {
- ProfileName = name;
- return true;
- }
- return false;
-}
-
-OVR::SensorDevice* HMDDevice::GetSensor()
-{
- // Just return first sensor found since we have no way to match it yet.
- OVR::SensorDevice* sensor = GetManager()->EnumerateDevices<SensorDevice>().CreateDevice();
- if (sensor)
- sensor->SetCoordinateFrame(SensorDevice::Coord_HMD);
- return sensor;
-}
-
-
-}} // namespace OVR::OSX
-
-
diff --git a/LibOVR/Src/OVR_OSX_HMDDevice.h b/LibOVR/Src/OVR_OSX_HMDDevice.h
deleted file mode 100644
index d92aa1f..0000000
--- a/LibOVR/Src/OVR_OSX_HMDDevice.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/************************************************************************************
-
-Filename : OVR_OSX_HMDDevice.h
-Content : OSX HMDDevice implementation
-Created : September 21, 2012
-Authors : Michael Antonov
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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_OSX_HMDDevice_h
-#define OVR_OSX_HMDDevice_h
-
-#include "OVR_DeviceImpl.h"
-#include <Kernel/OVR_String.h>
-#include "OVR_Profile.h"
-
-namespace OVR { namespace OSX {
-
-class HMDDevice;
-
-
-//-------------------------------------------------------------------------------------
-
-// HMDDeviceFactory enumerates attached Oculus HMD devices.
-//
-// This is currently done by matching monitor device strings.
-
-class HMDDeviceFactory : public DeviceFactory
-{
-public:
- static HMDDeviceFactory Instance;
-
- // Enumerates devices, creating and destroying relevant objects in manager.
- virtual void EnumerateDevices(EnumerateVisitor& visitor);
-
-protected:
- DeviceManager* getManager() const { return (DeviceManager*) pManager; }
-};
-
-
-class HMDDeviceCreateDesc : public DeviceCreateDesc
-{
- friend class HMDDevice;
-
-protected:
- enum
- {
- Contents_Screen = 1,
- Contents_Distortion = 2,
- Contents_7Inch = 4,
- };
-
-public:
-
- HMDDeviceCreateDesc(DeviceFactory* factory,
- UInt32 vendor, UInt32 product, const String& displayDeviceName, long dispId);
- HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other);
-
- virtual DeviceCreateDesc* Clone() const
- {
- return new HMDDeviceCreateDesc(*this);
- }
-
- virtual DeviceBase* NewDeviceInstance();
-
- virtual MatchResult MatchDevice(const DeviceCreateDesc& other,
- DeviceCreateDesc**) const;
-
- virtual bool UpdateMatchedCandidate(const DeviceCreateDesc&, bool* newDeviceFlag = NULL);
-
- virtual bool GetDeviceInfo(DeviceInfo* info) const;
-
- // Requests the currently used default profile. This profile affects the
- // settings reported by HMDInfo.
- Profile* GetProfileAddRef() const;
-
- ProfileType GetProfileType() const
- {
- return (HResolution >= 1920) ? Profile_RiftDKHD : Profile_RiftDK1;
- }
-
- void SetScreenParameters(int x, int y, unsigned hres, unsigned vres, float hsize, float vsize)
- {
- DesktopX = x;
- DesktopY = y;
- HResolution = hres;
- VResolution = vres;
- HScreenSize = hsize;
- VScreenSize = vsize;
- Contents |= Contents_Screen;
- }
-
- void SetDistortion(float eye2screen, const float* dks)
- {
- EyeToScreenDistance = eye2screen;
-
- for (int i = 0; i < 4; i++)
- DistortionK[i] = dks[i];
- Contents |= Contents_Distortion;
- }
-
- void Set7Inch() { Contents |= Contents_7Inch; }
-
- bool Is7Inch() const;
-
-protected:
- String DeviceId;
- String DisplayDeviceName;
- int DesktopX, DesktopY;
- unsigned Contents;
- unsigned HResolution, VResolution;
- float HScreenSize, VScreenSize;
- long DisplayId;
- float DistortionK[4];
- float EyeToScreenDistance;
-};
-
-
-//-------------------------------------------------------------------------------------
-
-// HMDDevice represents an Oculus HMD device unit. An instance of this class
-// is typically created from the DeviceManager.
-// After HMD device is created, we its sensor data can be obtained by
-// first creating a Sensor object and then wrappig it in SensorFusion.
-
-class HMDDevice : public DeviceImpl<OVR::HMDDevice>
-{
-public:
- HMDDevice(HMDDeviceCreateDesc* createDesc);
- ~HMDDevice();
-
- virtual bool Initialize(DeviceBase* parent);
- virtual void Shutdown();
-
-
- // Requests the currently used default profile. This profile affects the
- // settings reported by HMDInfo.
- virtual Profile* GetProfile() const;
- virtual const char* GetProfileName() const;
- virtual bool SetProfileName(const char* name);
-
- // Query associated sensor.
- virtual OVR::SensorDevice* GetSensor();
-
-protected:
- HMDDeviceCreateDesc* getDesc() const { return (HMDDeviceCreateDesc*)pCreateDesc.GetPtr(); }
-
- // User name for the profile used with this device.
- String ProfileName;
- mutable Ptr<Profile> pCachedProfile;
-};
-
-
-}} // namespace OVR::OSX
-
-#endif // OVR_OSX_HMDDevice_h
-
diff --git a/LibOVR/Src/OVR_OSX_SensorDevice.cpp b/LibOVR/Src/OVR_OSX_SensorDevice.cpp
deleted file mode 100644
index bee648d..0000000
--- a/LibOVR/Src/OVR_OSX_SensorDevice.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/************************************************************************************
-
-Filename : OVR_OSX_SensorDevice.cpp
-Content : OSX SensorDevice implementation
-Created : March 14, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR 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-2.0
-
-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 "OVR_OSX_HMDDevice.h"
-#include "OVR_SensorImpl.h"
-#include "OVR_DeviceImpl.h"
-
-namespace OVR { namespace OSX {
-
-} // namespace OSX
-
-//-------------------------------------------------------------------------------------
-void SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo( const SensorDisplayInfoImpl& displayInfo,
- DeviceFactory::EnumerateVisitor& visitor)
-{
-
- OSX::HMDDeviceCreateDesc hmdCreateDesc(&OSX::HMDDeviceFactory::Instance, 1, 1, "", 0);
-
- hmdCreateDesc.SetScreenParameters( 0, 0,
- displayInfo.HResolution, displayInfo.VResolution,
- displayInfo.HScreenSize, displayInfo.VScreenSize);
-
- if ((displayInfo.DistortionType & SensorDisplayInfoImpl::Mask_BaseFmt) & SensorDisplayInfoImpl::Base_Distortion)
- hmdCreateDesc.SetDistortion(displayInfo.EyeToScreenDistance[0], displayInfo.DistortionK);
- if (displayInfo.HScreenSize > 0.14f)
- hmdCreateDesc.Set7Inch();
-
- visitor.Visit(hmdCreateDesc);
-}
-
-} // namespace OVR
-
-
diff --git a/LibOVR/Src/OVR_Profile.cpp b/LibOVR/Src/OVR_Profile.cpp
index fdac5d7..1fa8eb4 100644
--- a/LibOVR/Src/OVR_Profile.cpp
+++ b/LibOVR/Src/OVR_Profile.cpp
@@ -12,16 +12,16 @@ Notes :
can be accomplished in game via the Profile API or by the official Oculus Configuration
Utility.
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -32,6 +32,7 @@ limitations under the License.
************************************************************************************/
#include "OVR_Profile.h"
+#include "OVR_Device.h"
#include "OVR_JSON.h"
#include "Kernel/OVR_Types.h"
#include "Kernel/OVR_SysFile.h"
@@ -51,8 +52,10 @@ limitations under the License.
#endif
-#define PROFILE_VERSION 1.0
-#define MAX_PROFILE_MAJOR_VERSION 1
+
+#define PROFILE_VERSION 2.0
+#define MAX_PROFILE_MAJOR_VERSION 2
+#define MAX_DEVICE_PROFILE_MAJOR_VERSION 1
namespace OVR {
@@ -127,28 +130,143 @@ String GetBaseOVRPath(bool create_dir)
return path;
}
-String GetProfilePath(bool create_dir)
+String ProfileManager::GetProfilePath(bool create_dir)
{
String path = GetBaseOVRPath(create_dir);
- path += "/Profiles.json";
+ path += "/ProfileDB.json";
return path;
}
+bool ProfileManager::GetDeviceTags(const DeviceBase* device, String& product, String& serial)
+{
+ product = "";
+ serial = "";
+
+ if (device && device->GetType() == Device_HMD)
+ {
+ HMDDevice* hmd = (HMDDevice*)device;
+
+ Ptr<SensorDevice> sensor = *(hmd->GetSensor());
+ if (sensor)
+ {
+ SensorInfo sinfo;
+ sensor->GetDeviceInfo(&sinfo);
+ serial = sinfo.SerialNumber; // get the serial number
+
+ // Derive the product tag from the HMD product name
+ HMDInfo hmdinfo;
+ hmd->GetDeviceInfo(&hmdinfo);
+
+ const char* product_name = NULL;
+
+ // If the HMD is unrecognized then use the name stamped into the
+ // sensor firmware
+ if (hmdinfo.HmdType == HmdType_None || hmdinfo.Type == HmdType_Unknown)
+ product_name = sinfo.ProductName.ToCStr();
+ else
+ product_name = hmdinfo.ProductName.ToCStr();
+
+ // First strip off "Oculus"
+ const char* oculus = strstr(product_name, "Oculus ");
+ if (oculus)
+ product_name = oculus + OVR_strlen("Oculus ");
+ // And remove spaces from the name
+ for (const char* s=product_name; *s != 0; s++)
+ {
+ if (*s != ' ')
+ product.AppendChar(*s);
+ }
+ }
+ }
+
+ return (!product.IsEmpty() && !serial.IsEmpty());
+}
+
+static JSON* FindTaggedData(JSON* data, const char** tag_names, const char** qtags, int num_qtags)
+{
+ if (data == NULL || !(data->Name == "TaggedData") || data->Type != JSON_Array)
+ return NULL;
+
+ JSON* tagged_item = data->GetFirstItem();
+ while (tagged_item)
+ {
+ JSON* tags = tagged_item->GetItemByName("tags");
+ if (tags->Type == JSON_Array && num_qtags == tags->GetArraySize())
+ { // Check for a full tag match on each item
+ int num_matches = 0;
+
+ for (int k=0; k<num_qtags; k++)
+ {
+ JSON* tag = tags->GetFirstItem();
+ while (tag)
+ {
+ JSON* tagval = tag->GetFirstItem();
+ if (tagval && tagval->Name == tag_names[k])
+ {
+ if (tagval->Value == qtags[k])
+ num_matches++;
+ break;
+ }
+ tag = tags->GetNextItem(tag);
+ }
+ }
+
+ // if all tags were matched then copy the values into this Profile
+ if (num_matches == num_qtags)
+ {
+ JSON* vals = tagged_item->GetItemByName("vals");
+ return vals;
+ }
+ }
+
+ tagged_item = data->GetNextItem(tagged_item);
+ }
+
+ return NULL;
+}
+
+static void FilterTaggedData(JSON* data, const char* tag_name, const char* qtag, Array<JSON*>& items)
+{
+ if (data == NULL || !(data->Name == "TaggedData") || data->Type != JSON_Array)
+ return;
+
+ JSON* tagged_item = data->GetFirstItem();
+ while (tagged_item)
+ {
+ JSON* tags = tagged_item->GetItemByName("tags");
+ if (tags->Type == JSON_Array)
+ { // Check for a tag match on the requested tag
+
+ JSON* tag = tags->GetFirstItem();
+ while (tag)
+ {
+ JSON* tagval = tag->GetFirstItem();
+ if (tagval && tagval->Name == tag_name)
+ {
+ if (tagval->Value == qtag)
+ { // Add this item to the output list
+ items.PushBack(tagged_item);
+ }
+ break;
+ }
+ tag = tags->GetNextItem(tag);
+ }
+ }
+
+ tagged_item = data->GetNextItem(tagged_item);
+ }
+}
+
//-----------------------------------------------------------------------------
// ***** ProfileManager
ProfileManager::ProfileManager()
{
Changed = false;
- CacheDevice = Profile_Unknown;
}
ProfileManager::~ProfileManager()
{
- // If the profiles have been altered then write out the profile file
- if (Changed)
- SaveCache();
-
ClearCache();
}
@@ -157,49 +275,50 @@ ProfileManager* ProfileManager::Create()
return new ProfileManager();
}
-Profile* ProfileManager::CreateProfileObject(const char* user,
- ProfileType device,
- const char** device_name)
+// Clear the local profile cache
+void ProfileManager::ClearCache()
{
Lock::Locker lockScope(&ProfileLock);
-
- Profile* profile = NULL;
- switch (device)
+ //ProfileCache.Clear();
+ if (ProfileCache)
{
- case Profile_GenericHMD:
- *device_name = NULL;
- profile = new HMDProfile(Profile_GenericHMD, user);
- break;
- case Profile_RiftDK1:
- *device_name = "RiftDK1";
- profile = new RiftDK1Profile(user);
- break;
- case Profile_RiftDKHD:
- *device_name = "RiftDKHD";
- profile = new RiftDKHDProfile(user);
- break;
- case Profile_Unknown:
- break;
+ //ProfileCache->Release();
+ ProfileCache = NULL;
}
-
- return profile;
+ Changed = false;
}
-
-// Clear the local profile cache
-void ProfileManager::ClearCache()
+// Returns a profile with all system default values
+Profile* ProfileManager::GetDefaultProfile(const DeviceBase* device)
{
- Lock::Locker lockScope(&ProfileLock);
+ // In the absence of any data, set some reasonable profile defaults.
+ // However, this is not future proof and developers should still
+ // provide reasonable default values for queried fields.
+ Profile* profile = CreateProfile();
+ profile->SetValue(OVR_KEY_USER, "default");
+ profile->SetValue(OVR_KEY_NAME, "Default");
+ profile->SetValue(OVR_KEY_GENDER, OVR_DEFAULT_GENDER);
+ profile->SetFloatValue(OVR_KEY_PLAYER_HEIGHT, OVR_DEFAULT_PLAYER_HEIGHT);
+ profile->SetFloatValue(OVR_KEY_EYE_HEIGHT, 1.675f);
+ profile->SetFloatValue(OVR_KEY_IPD, OVR_DEFAULT_IPD);
+ float dist[2] = {OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL, OVR_DEFAULT_NECK_TO_EYE_VERTICAL};
+ profile->SetFloatValues(OVR_KEY_NECK_TO_EYE_DISTANCE, dist, 2);
+ //profile->SetFloatValue(OVR_KEY_NECK_TO_EYE_VERTICAL, 0.12f);
+
+ // TODO: Provide device specific defaults
+ OVR_UNUSED(device);
+
+ // DK1 default
+ //profile->SetValue("EyeCup", "A");
- ProfileCache.Clear();
- CacheDevice = Profile_Unknown;
+ return profile;
}
// Poplulates the local profile cache. This occurs on the first access of the profile
// data. All profile operations are performed against the local cache until the
// ProfileManager is released or goes out of scope at which time the cache is serialized
// to disk.
-void ProfileManager::LoadCache(ProfileType device)
+void ProfileManager::LoadCache(bool create)
{
Lock::Locker lockScope(&ProfileLock);
@@ -208,27 +327,75 @@ void ProfileManager::LoadCache(ProfileType device)
String path = GetProfilePath(false);
Ptr<JSON> root = *JSON::Load(path);
- if (!root || root->GetItemCount() < 3)
- return;
+ if (root == NULL)
+ {
+ path = GetBaseOVRPath(false) + "/Profiles.json"; // look for legacy profile
+ root = *JSON::Load(path);
+
+ if (root == NULL)
+ {
+ if (create)
+ { // Generate a skeleton profile database
+ root = *JSON::CreateObject();
+ root->AddNumberItem("Oculus Profile Version", 2.0);
+ root->AddItem("Users", JSON::CreateArray());
+ root->AddItem("TaggedData", JSON::CreateArray());
+ ProfileCache = root;
+ }
+
+ return;
+ }
- // First read the file type and version to make sure this is a valid file
- JSON* item0 = root->GetFirstItem();
- JSON* item1 = root->GetNextItem(item0);
- JSON* item2 = root->GetNextItem(item1);
+ // Verify the legacy version
+ JSON* version_item = root->GetFirstItem();
+ if (version_item->Name == "Oculus Profile Version")
+ {
+ int major = atoi(version_item->Value.ToCStr());
+ if (major != 1)
+ return; // don't use the file on unsupported major version number
+ }
+ else
+ {
+ return; // invalid file
+ }
- if (item0->Name == "Oculus Profile Version")
- {
- int major = atoi(item0->Value.ToCStr());
- if (major > MAX_PROFILE_MAJOR_VERSION)
- return; // don't parse the file on unsupported major version number
+ // Convert the legacy format to the new database format
+ LoadV1Profiles(root);
}
else
{
- return;
+ // Verify the file format and version
+ JSON* version_item = root->GetFirstItem();
+ if (version_item->Name == "Oculus Profile Version")
+ {
+ int major = atoi(version_item->Value.ToCStr());
+ if (major != 2)
+ return; // don't use the file on unsupported major version number
+ }
+ else
+ {
+ return; // invalid file
+ }
+
+ ProfileCache = root; // store the database contents for traversal
}
+}
+
+void ProfileManager::LoadV1Profiles(JSON* v1)
+{
+ JSON* item0 = v1->GetFirstItem();
+ JSON* item1 = v1->GetNextItem(item0);
+ JSON* item2 = v1->GetNextItem(item1);
- DefaultProfile = item1->Value;
+ // Create the new profile database
+ Ptr<JSON> root = *JSON::CreateObject();
+ root->AddNumberItem("Oculus Profile Version", 2.0);
+ root->AddItem("Users", JSON::CreateArray());
+ root->AddItem("TaggedData", JSON::CreateArray());
+ ProfileCache = root;
+ const char* default_dk1_user = item1->Value;
+
// Read the number of profiles
int profileCount = (int)item2->dValue;
JSON* profileItem = item2;
@@ -253,585 +420,1098 @@ void ProfileManager::LoadCache(ProfileType device)
{
return; // invalid field
}
+
+ // Read the user profile fields
+ if (CreateUser(profileName, profileName))
+ {
+ const char* tag_names[2] = {"User", "Product"};
+ const char* tags[2];
+ tags[0] = profileName;
- const char* deviceName = 0;
- bool deviceFound = false;
- Ptr<Profile> profile = *CreateProfileObject(profileName, device, &deviceName);
+ Ptr<Profile> user_profile = *CreateProfile();
+ user_profile->SetValue(OVR_KEY_NAME, profileName);
- // Read the base profile fields.
- if (profile)
- {
- while (item = profileItem->GetNextItem(item), item)
+ float neckeye[2] = { 0, 0 };
+
+ item = profileItem->GetNextItem(item);
+ while (item)
{
if (item->Type != JSON_Object)
{
- profile->ParseProperty(item->Name, item->Value);
+ if (item->Name == OVR_KEY_PLAYER_HEIGHT)
+ { // Add an explicit eye height
+
+ }
+ if (item->Name == "NeckEyeHori")
+ neckeye[0] = (float)item->dValue;
+ else if (item->Name == "NeckEyeVert")
+ neckeye[1] = (float)item->dValue;
+ else
+ user_profile->SetValue(item);
}
else
- { // Search for the matching device to get device specific fields
- if (!deviceFound && deviceName && OVR_strcmp(item->Name, deviceName) == 0)
- {
- deviceFound = true;
+ {
+ // Add the user/device tag values
+ const char* device_name = item->Name.ToCStr();
+ Ptr<Profile> device_profile = *CreateProfile();
- for (JSON* deviceItem = item->GetFirstItem(); deviceItem;
- deviceItem = item->GetNextItem(deviceItem))
- {
- profile->ParseProperty(deviceItem->Name, deviceItem->Value);
- }
+ JSON* device_item = item->GetFirstItem();
+ while (device_item)
+ {
+ device_profile->SetValue(device_item);
+ device_item = item->GetNextItem(device_item);
}
+
+ tags[1] = device_name;
+ SetTaggedProfile(tag_names, tags, 2, device_profile);
}
+
+ item = profileItem->GetNextItem(item);
}
- }
- // Add the new profile
- ProfileCache.PushBack(profile);
+ // Add an explicit eye-height field
+ float player_height = user_profile->GetFloatValue(OVR_KEY_PLAYER_HEIGHT,
+ OVR_DEFAULT_PLAYER_HEIGHT);
+ if (player_height > 0)
+ {
+ char gender[16];
+ user_profile->GetValue(OVR_KEY_GENDER, gender, 16);
+
+ const float EYE_TO_HEADTOP_RATIO = 0.44538f;
+ const float MALE_AVG_HEAD_HEIGHT = 0.232f;
+ const float FEMALE_AVG_HEAD_HEIGHT = 0.218f;
+
+ // compute distance from top of skull to the eye
+ float head_height;
+ if (OVR_strcmp(gender, "Female") == 0)
+ head_height = FEMALE_AVG_HEAD_HEIGHT;
+ else
+ head_height = MALE_AVG_HEAD_HEIGHT;
+
+ float skull = EYE_TO_HEADTOP_RATIO * head_height;
+ float eye_height = player_height - skull;
+
+ user_profile->SetFloatValue(OVR_KEY_EYE_HEIGHT, eye_height);
+ }
+
+ // Convert NeckEye values to an array
+ if (neckeye[0] > 0 && neckeye[1] > 0)
+ user_profile->SetFloatValues(OVR_KEY_NECK_TO_EYE_DISTANCE, neckeye, 2);
+
+ // Add the user tag values
+ SetTaggedProfile(tag_names, tags, 1, user_profile);
+ }
}
}
- CacheDevice = device;
+ // since V1 profiles were only for DK1, the assign the user to all DK1's
+ const char* tag_names[1] = { "Product" };
+ const char* tags[1] = { "RiftDK1" };
+ Ptr<Profile> product_profile = *CreateProfile();
+ product_profile->SetValue("DefaultUser", default_dk1_user);
+ SetTaggedProfile(tag_names, tags, 1, product_profile);
}
+// Returns the number of stored profiles for this device type
+int ProfileManager::GetUserCount()
+{
+ Lock::Locker lockScope(&ProfileLock);
+
+ if (ProfileCache == NULL)
+ { // Load the cache
+ LoadCache(false);
+ if (ProfileCache == NULL)
+ return 0;
+ }
+
+ JSON* users = ProfileCache->GetItemByName("Users");
+ if (users == NULL)
+ return 0;
+
+ return users->GetItemCount();
+}
-// Serializes the profiles to disk.
-void ProfileManager::SaveCache()
+bool ProfileManager::CreateUser(const char* user, const char* name)
{
- String path = GetProfilePath(true);
-
Lock::Locker lockScope(&ProfileLock);
- Ptr<JSON> oldroot = *JSON::Load(path);
- if (oldroot)
- {
- if (oldroot->GetItemCount() >= 3)
- {
- JSON* item0 = oldroot->GetFirstItem();
- JSON* item1 = oldroot->GetNextItem(item0);
- oldroot->GetNextItem(item1);
+ if (ProfileCache == NULL)
+ { // Load the cache
+ LoadCache(true);
+ if (ProfileCache == NULL)
+ return false;
+ }
- if (item0->Name == "Oculus Profile Version")
- {
- int major = atoi(item0->Value.ToCStr());
- if (major > MAX_PROFILE_MAJOR_VERSION)
- oldroot.Clear(); // don't use the file on unsupported major version number
- }
- else
+ JSON* users = ProfileCache->GetItemByName("Users");
+ if (users == NULL)
+ { // Generate the User section
+ users = JSON::CreateArray();
+ ProfileCache->AddItem("Users", users);
+//TODO: Insert this before the TaggedData
+ }
+
+ // Search for the pre-existence of this user
+ JSON* user_item = users->GetFirstItem();
+ int index = 0;
+ while (user_item)
+ {
+ JSON* userid = user_item->GetItemByName("User");
+ int compare = OVR_strcmp(user, userid->Value);
+ if (compare == 0)
+ { // The user already exists so simply update the fields
+ JSON* name_item = user_item->GetItemByName("Name");
+ if (name_item && OVR_strcmp(name, name_item->Value) != 0)
{
- oldroot.Clear();
+ name_item->Value = name;
+ Changed = true;
}
+ return true;
}
- else
- {
- oldroot.Clear();
+ else if (compare < 0)
+ { // A new user should be placed before this item
+ break;
}
+
+ user_item = users->GetNextItem(user_item);
+ index++;
}
-
- // Create a new json root
- Ptr<JSON> root = *JSON::CreateObject();
- root->AddNumberItem("Oculus Profile Version", PROFILE_VERSION);
- root->AddStringItem("CurrentProfile", DefaultProfile);
- root->AddNumberItem("ProfileCount", (double) ProfileCache.GetSize());
- // Generate a JSON subtree for each profile
- for (unsigned int i=0; i<ProfileCache.GetSize(); i++)
- {
- Profile* profile = ProfileCache[i];
+ // Create and fill the user struct
+ JSON* new_user = JSON::CreateObject();
+ new_user->AddStringItem(OVR_KEY_USER, user);
+ new_user->AddStringItem(OVR_KEY_NAME, name);
+ // user_item->AddStringItem("Password", password);
- // Write the base profile information
- JSON* json_profile = JSON::CreateObject();
- json_profile->Name = "Profile";
- json_profile->AddStringItem("Name", profile->Name);
- const char* gender;
- switch (profile->GetGender())
- {
- case Profile::Gender_Male: gender = "Male"; break;
- case Profile::Gender_Female: gender = "Female"; break;
- default: gender = "Unspecified";
- }
- json_profile->AddStringItem("Gender", gender);
- json_profile->AddNumberItem("PlayerHeight", profile->PlayerHeight);
- json_profile->AddNumberItem("IPD", profile->IPD);
+ if (user_item == NULL)
+ users->AddArrayElement(new_user);
+ else
+ users->InsertArrayElement(index, new_user);
- const char* device_name = NULL;
- // Create a device-specific subtree for the cached device
- if (profile->Type == Profile_RiftDK1)
- {
- device_name = "RiftDK1";
-
- RiftDK1Profile* rift = (RiftDK1Profile*)profile;
- JSON* json_rift = JSON::CreateObject();
- json_profile->AddItem(device_name, json_rift);
+ Changed = true;
+ return true;
+}
- const char* eyecup = "A";
- switch (rift->EyeCups)
- {
- case EyeCup_A: eyecup = "A"; break;
- case EyeCup_B: eyecup = "B"; break;
- case EyeCup_C: eyecup = "C"; break;
- }
- json_rift->AddStringItem("EyeCup", eyecup);
- json_rift->AddNumberItem("LL", rift->LL);
- json_rift->AddNumberItem("LR", rift->LR);
- json_rift->AddNumberItem("RL", rift->RL);
- json_rift->AddNumberItem("RR", rift->RR);
- }
- else if (profile->Type == Profile_RiftDKHD)
- {
- device_name = "RiftDKHD";
-
- RiftDKHDProfile* rift = (RiftDKHDProfile*)profile;
- JSON* json_rift = JSON::CreateObject();
- json_profile->AddItem(device_name, json_rift);
+// Returns the user id of a specific user in the list. The returned
+// memory is locally allocated and should not be stored or deleted. Returns NULL
+// if the index is invalid
+const char* ProfileManager::GetUser(unsigned int index)
+{
+ Lock::Locker lockScope(&ProfileLock);
- const char* eyecup = "A";
- switch (rift->EyeCups)
- {
- case EyeCup_A: eyecup = "A"; break;
- case EyeCup_B: eyecup = "B"; break;
- case EyeCup_C: eyecup = "C"; break;
- }
- json_rift->AddStringItem("EyeCup", eyecup);
- //json_rift->AddNumberItem("LL", rift->LL);
- //json_rift->AddNumberItem("LR", rift->LR);
- //json_rift->AddNumberItem("RL", rift->RL);
- //json_rift->AddNumberItem("RR", rift->RR);
- }
-
- // There may be multiple devices stored per user, but only a single
- // device is represented by this root. We don't want to overwrite
- // the other devices so we need to examine the older root
- // and merge previous devices into new json root
- if (oldroot)
+ if (ProfileCache == NULL)
+ { // Load the cache
+ LoadCache(false);
+ if (ProfileCache == NULL)
+ return NULL;
+ }
+
+ JSON* users = ProfileCache->GetItemByName("Users");
+
+ if (users && index < users->GetItemCount())
+ {
+ JSON* user_item = users->GetItemByIndex(index);
+ if (user_item)
{
- JSON* old_profile = oldroot->GetFirstItem();
- while (old_profile)
+ JSON* user = user_item->GetFirstItem();
+ if (user)
{
- if (old_profile->Name == "Profile")
- {
- JSON* profile_name = old_profile->GetItemByName("Name");
- if (profile_name && OVR_strcmp(profile->Name, profile_name->Value) == 0)
- { // Now that we found the user in the older root, add all the
- // object children to the new root - except for the one for the
- // current device
- JSON* old_item = old_profile->GetFirstItem();
- while (old_item)
- {
- if (old_item->Type == JSON_Object
- && (device_name == NULL || OVR_strcmp(old_item->Name, device_name) != 0))
- {
- JSON* old_device = old_item;
- old_item = old_profile->GetNextItem(old_item);
-
- // remove the node from the older root to avoid multiple reference
- old_device->RemoveNode();
- // add the node pointer to the new root
- json_profile->AddItem(old_device->Name, old_device);
- }
- else
- {
- old_item = old_profile->GetNextItem(old_item);
- }
- }
-
- break;
- }
- }
-
- old_profile = oldroot->GetNextItem(old_profile);
+ JSON* userid = user_item->GetItemByName(OVR_KEY_USER);
+ if (userid)
+ return userid->Value.ToCStr();
}
}
-
- // Add the completed user profile to the new root
- root->AddItem("Profile", json_profile);
}
+
- // Save the profile to disk
- root->Save(path);
+ return NULL;
}
-// Returns the number of stored profiles for this device type
-int ProfileManager::GetProfileCount(ProfileType device)
+bool ProfileManager::RemoveUser(const char* user)
{
Lock::Locker lockScope(&ProfileLock);
- if (CacheDevice == Profile_Unknown)
- LoadCache(device);
+ if (ProfileCache == NULL)
+ { // Load the cache
+ LoadCache(false);
+ if (ProfileCache == NULL)
+ return true;
+ }
+
+ JSON* users = ProfileCache->GetItemByName("Users");
+ if (users == NULL)
+ return true;
+
+ // Remove this user from the User table
+ JSON* user_item = users->GetFirstItem();
+ while (user_item)
+ {
+ JSON* userid = user_item->GetItemByName("User");
+ if (OVR_strcmp(user, userid->Value) == 0)
+ { // Delete the user entry
+ user_item->RemoveNode();
+ user_item->Release();
+ Changed = true;
+ break;
+ }
+
+ user_item = users->GetNextItem(user_item);
+ }
+
+ // Now remove all data entries with this user tag
+ JSON* tagged_data = ProfileCache->GetItemByName("TaggedData");
+ Array<JSON*> user_items;
+ FilterTaggedData(tagged_data, "User", user, user_items);
+ for (unsigned int i=0; i<user_items.GetSize(); i++)
+ {
+ user_items[i]->RemoveNode();
+ user_items[i]->Release();
+ Changed = true;
+ }
+
+ return Changed;
+}
- return (int)ProfileCache.GetSize();
+Profile* ProfileManager::CreateProfile()
+{
+ Profile* profile = new Profile();
+ return profile;
}
-// Returns the profile name of a specific profile in the list. The returned
-// memory is locally allocated and should not be stored or deleted. Returns NULL
-// if the index is invalid
-const char* ProfileManager::GetProfileName(ProfileType device, unsigned int index)
+// Returns the name of the profile that is marked as the current default user.
+const char* ProfileManager::GetDefaultUser(const DeviceBase* device)
{
- Lock::Locker lockScope(&ProfileLock);
+ const char* tag_names[2] = {"Product", "Serial"};
+ const char* tags[2];
- if (CacheDevice == Profile_Unknown)
- LoadCache(device);
+ String product;
+ String serial;
+ if (!GetDeviceTags(device, product, serial))
+ return NULL;
- if (index < ProfileCache.GetSize())
- {
- Profile* profile = ProfileCache[index];
- OVR_strcpy(NameBuff, Profile::MaxNameLen, profile->Name);
- return NameBuff;
- }
- else
+ const char* product_str = product.IsEmpty() ? NULL : product.ToCStr();
+ const char* serial_str = serial.IsEmpty() ? NULL : serial.ToCStr();
+
+ if (product_str && serial_str)
{
- return NULL;
+ tags[0] = product_str;
+ tags[1] = serial_str;
+ // Look for a default user on this specific device
+ Ptr<Profile> p = *GetTaggedProfile(tag_names, tags, 2);
+ if (p == NULL)
+ { // Look for a default user on this product
+ p = *GetTaggedProfile(tag_names, tags, 1);
+ }
+
+ if (p)
+ {
+ const char* user = p->GetValue("DefaultUser");
+ if (user != NULL && user[0] != 0)
+ {
+ TempBuff = user;
+ return TempBuff.ToCStr();
+ }
+ }
}
+
+ return NULL;
}
-bool ProfileManager::HasProfile(ProfileType device, const char* name)
+//-----------------------------------------------------------------------------
+bool ProfileManager::SetDefaultUser(const DeviceBase* device, const char* user)
{
- Lock::Locker lockScope(&ProfileLock);
+ const char* tag_names[2] = {"Product", "Serial"};
+ const char* tags[2];
+
+ String product;
+ String serial;
+ if (!GetDeviceTags(device, product, serial))
+ return NULL;
- if (CacheDevice == Profile_Unknown)
- LoadCache(device);
+ const char* product_str = product.IsEmpty() ? NULL : product.ToCStr();
+ const char* serial_str = serial.IsEmpty() ? NULL : serial.ToCStr();
- for (unsigned i = 0; i< ProfileCache.GetSize(); i++)
+ if (product_str && serial_str)
{
- if (ProfileCache[i] && OVR_strcmp(ProfileCache[i]->Name, name) == 0)
- return true;
+ tags[0] = product_str;
+ tags[1] = serial_str;
+
+ Ptr<Profile> p = *CreateProfile();
+ p->SetValue("DefaultUser", user);
+ return SetTaggedProfile(tag_names, tags, 2, p);
}
+
return false;
}
-
-// Returns a specific profile object in the list. The returned memory should be
-// encapsulated in a Ptr<> object or released after use. Returns NULL if the index
-// is invalid
-Profile* ProfileManager::LoadProfile(ProfileType device, unsigned int index)
+//-----------------------------------------------------------------------------
+Profile* ProfileManager::GetTaggedProfile(const char** tag_names, const char** tags, int num_tags)
{
Lock::Locker lockScope(&ProfileLock);
- if (CacheDevice == Profile_Unknown)
- LoadCache(device);
+ if (ProfileCache == NULL)
+ { // Load the cache
+ LoadCache(false);
+ if (ProfileCache == NULL)
+ return NULL;
+ }
- if (index < ProfileCache.GetSize())
- {
- Profile* profile = ProfileCache[index];
- return profile->Clone();
+ JSON* tagged_data = ProfileCache->GetItemByName("TaggedData");
+ OVR_ASSERT(tagged_data);
+ if (tagged_data == NULL)
+ return false;
+
+ Profile* profile = new Profile();
+
+ JSON* vals = FindTaggedData(tagged_data, tag_names, tags, num_tags);
+ if (vals)
+ {
+ JSON* item = vals->GetFirstItem();
+ while (item)
+ {
+ //printf("Add %s, %s\n", item->Name.ToCStr(), item->Value.ToCStr());
+ //profile->Settings.Set(item->Name, item->Value);
+ profile->SetValue(item);
+ item = vals->GetNextItem(item);
+ }
+
+ return profile;
}
else
{
+ profile->Release();
return NULL;
}
}
-// Returns a profile object for a particular device and user name. The returned
-// memory should be encapsulated in a Ptr<> object or released after use. Returns
-// NULL if the profile is not found
-Profile* ProfileManager::LoadProfile(ProfileType device, const char* user)
+//-----------------------------------------------------------------------------
+bool ProfileManager::SetTaggedProfile(const char** tag_names, const char** tags, int num_tags, Profile* profile)
{
- if (user == NULL)
- return NULL;
-
Lock::Locker lockScope(&ProfileLock);
-
- if (CacheDevice == Profile_Unknown)
- LoadCache(device);
- for (unsigned int i=0; i<ProfileCache.GetSize(); i++)
- {
- if (OVR_strcmp(user, ProfileCache[i]->Name) == 0)
- { // Found the requested user profile
- Profile* profile = ProfileCache[i];
- return profile->Clone();
+ if (ProfileCache == NULL)
+ { // Load the cache
+ LoadCache(true);
+ if (ProfileCache == NULL)
+ return false; // TODO: Generate a new profile DB
+ }
+
+ JSON* tagged_data = ProfileCache->GetItemByName("TaggedData");
+ OVR_ASSERT(tagged_data);
+ if (tagged_data == NULL)
+ return false;
+
+ // Get the cached tagged data section
+ JSON* vals = FindTaggedData(tagged_data, tag_names, tags, num_tags);
+ if (vals == NULL)
+ {
+ JSON* tagged_item = JSON::CreateObject();
+ JSON* taglist = JSON::CreateArray();
+ for (int i=0; i<num_tags; i++)
+ {
+ JSON* k = JSON::CreateObject();
+ k->AddStringItem(tag_names[i], tags[i]);
+ taglist->AddArrayElement(k);
}
+
+ vals = JSON::CreateObject();
+
+ tagged_item->AddItem("tags", taglist);
+ tagged_item->AddItem("vals", vals);
+ tagged_data->AddArrayElement(tagged_item);
}
- return NULL;
-}
+ // Now add or update each profile setting in cache
+ for (unsigned int i=0; i<profile->Values.GetSize(); i++)
+ {
+ JSON* value = profile->Values[i];
+
+ bool found = false;
+ JSON* item = vals->GetFirstItem();
+ while (item)
+ {
+ if (value->Name == item->Name)
+ {
+ // Don't allow a pre-existing type to be overridden
+ OVR_ASSERT(value->Type == item->Type);
+
+ if (value->Type == item->Type)
+ { // Check for the same value
+ if (value->Type == JSON_Array)
+ { // Update each array item
+ if (item->GetArraySize() == value->GetArraySize())
+ { // Update each value (assumed to be basic types and not array of objects)
+ JSON* value_element = value->GetFirstItem();
+ JSON* item_element = item->GetFirstItem();
+ while (item_element && value_element)
+ {
+ if (value_element->Type == JSON_String)
+ {
+ if (item_element->Value != value_element->Value)
+ { // Overwrite the changed value and mark for file update
+ item_element->Value = value_element->Value;
+ Changed = true;
+ }
+ }
+ else {
+ if (item_element->dValue != value_element->dValue)
+ { // Overwrite the changed value and mark for file update
+ item_element->dValue = value_element->dValue;
+ Changed = true;
+ }
+ }
+
+ value_element = value->GetNextItem(value_element);
+ item_element = item->GetNextItem(item_element);
+ }
+ }
+ else
+ { // if the array size changed, simply create a new one
+// TODO: Create the new array
+ }
+ }
+ else if (value->Type == JSON_String)
+ {
+ if (item->Value != value->Value)
+ { // Overwrite the changed value and mark for file update
+ item->Value = value->Value;
+ Changed = true;
+ }
+ }
+ else {
+ if (item->dValue != value->dValue)
+ { // Overwrite the changed value and mark for file update
+ item->dValue = value->dValue;
+ Changed = true;
+ }
+ }
+ }
+ else
+ {
+ return false;
+ }
-// Returns a profile with all system default values
-Profile* ProfileManager::GetDeviceDefaultProfile(ProfileType device)
-{
- const char* device_name = NULL;
- return CreateProfileObject("default", device, &device_name);
+ found = true;
+ break;
+ }
+
+ item = vals->GetNextItem(item);
+ }
+
+ if (!found)
+ { // Add the new value
+ if (value->Type == JSON_String)
+ vals->AddStringItem(value->Name, value->Value);
+ else if (value->Type == JSON_Bool)
+ vals->AddBoolItem(value->Name, (value->dValue != 0));
+ else if (value->Type == JSON_Array)
+ vals->AddItem(value->Name, value->Copy());
+ else
+ vals->AddNumberItem(value->Name, value->dValue);
+
+ Changed = true;
+ }
+ }
+
+ return true;
}
-// Returns the name of the profile that is marked as the current default user.
-const char* ProfileManager::GetDefaultProfileName(ProfileType device)
+//-----------------------------------------------------------------------------
+Profile* ProfileManager::GetProfile(const DeviceBase* device, const char* user)
{
Lock::Locker lockScope(&ProfileLock);
- if (CacheDevice == Profile_Unknown)
- LoadCache(device);
+ if (ProfileCache == NULL)
+ { // Load the cache
+ LoadCache(false);
+ if (ProfileCache == NULL)
+ return NULL;
+ }
+
+ Profile* profile = new Profile();
- if (ProfileCache.GetSize() > 0)
+ if (device)
{
- OVR_strcpy(NameBuff, Profile::MaxNameLen, DefaultProfile);
- return NameBuff;
+ if (!profile->LoadDeviceProfile(device) && (user == NULL))
+ {
+ profile->Release();
+ return NULL;
+ }
}
- else
+
+ if (user)
{
- return NULL;
+ String product;
+ String serial;
+ GetDeviceTags(device, product, serial);
+
+ const char* product_str = product.IsEmpty() ? NULL : product.ToCStr();
+ const char* serial_str = serial.IsEmpty() ? NULL : serial.ToCStr();
+
+ if (!profile->LoadProfile(ProfileCache.GetPtr(), user, product_str, serial_str))
+ {
+ profile->Release();
+ return NULL;
+ }
}
+
+ return profile;
+}
+
+//-----------------------------------------------------------------------------
+// ***** Profile
+
+Profile::~Profile()
+{
+ ValMap.Clear();
+ for (unsigned int i=0; i<Values.GetSize(); i++)
+ Values[i]->Release();
+
+ Values.Clear();
}
-// Marks a particular user as the current default user.
-bool ProfileManager::SetDefaultProfileName(ProfileType device, const char* name)
+bool Profile::Close()
{
- Lock::Locker lockScope(&ProfileLock);
+ // TODO:
+ return true;
+}
- if (CacheDevice == Profile_Unknown)
- LoadCache(device);
-// TODO: I should verify that the user is valid
- if (ProfileCache.GetSize() > 0)
+//-----------------------------------------------------------------------------
+void Profile::CopyItems(JSON* root, String prefix)
+{
+ JSON* item = root->GetFirstItem();
+ while (item)
{
- DefaultProfile = name;
- Changed = true;
- return true;
+ String item_name;
+ if (prefix.IsEmpty())
+ item_name = item->Name;
+ else
+ item_name = prefix + "." + item->Name;
+
+ if (item->Type == JSON_Object)
+ { // recursively copy the children
+
+ CopyItems(item, item_name);
+ }
+ else
+ {
+ //Settings.Set(item_name, item->Value);
+ SetValue(item);
+ }
+
+ item = root->GetNextItem(item);
+ }
+}
+
+//-----------------------------------------------------------------------------
+bool Profile::LoadDeviceFile(unsigned int device_id, const char* serial)
+{
+ if (serial[0] == 0)
+ return false;
+
+ String path = GetBaseOVRPath(false);
+ path += "/Devices.json";
+
+ // Load the device profiles
+ Ptr<JSON> root = *JSON::Load(path);
+ if (root == NULL)
+ return false;
+
+ // Quick sanity check of the file type and format before we parse it
+ JSON* version = root->GetFirstItem();
+ if (version && version->Name == "Oculus Device Profile Version")
+ {
+ int major = atoi(version->Value.ToCStr());
+ if (major > MAX_DEVICE_PROFILE_MAJOR_VERSION)
+ return false; // don't parse the file on unsupported major version number
}
else
{
return false;
+ }
+
+
+ JSON* device = root->GetNextItem(version);
+ while (device)
+ {
+ if (device->Name == "Device")
+ {
+ JSON* product_item = device->GetItemByName("ProductID");
+ JSON* serial_item = device->GetItemByName("Serial");
+ if (product_item && serial_item
+ && (product_item->dValue == device_id) && (serial_item->Value == serial))
+ {
+ // found the entry for this device so recursively copy all the settings to the profile
+ CopyItems(device, "");
+ return true;
+ }
+ }
+
+ device = root->GetNextItem(device);
}
+
+ return false;
}
+//-----------------------------------------------------------------------------
+static int BCDByte(unsigned int byte)
+{
+ int digit1 = (byte >> 4) & 0x000f;
+ int digit2 = byte & 0x000f;
+ int decimal = digit1 * 10 + digit2;
+ return decimal;
+}
-// Saves a new or existing profile. Returns true on success or false on an
-// invalid or failed save.
-bool ProfileManager::Save(const Profile* profile)
+//-----------------------------------------------------------------------------
+bool Profile::LoadDeviceProfile(const DeviceBase* device)
{
- Lock::Locker lockScope(&ProfileLock);
+ bool success = false;
+ if (device == NULL)
+ return false;
- if (OVR_strcmp(profile->Name, "default") == 0)
- return false; // don't save a default profile
+ SensorDevice* sensor = NULL;
- // TODO: I should also verify that this profile type matches the current cache
- if (CacheDevice == Profile_Unknown)
- LoadCache(profile->Type);
+ if (device->GetType() == Device_HMD)
+ {
+ // Convert the HMD device to Sensor
+ sensor = ((HMDDevice*)device)->GetSensor();
+ device = sensor;
+ if (device == NULL)
+ return false;
+ }
- // Look for the pre-existence of this profile
- bool added = false;
- for (unsigned int i=0; i<ProfileCache.GetSize(); i++)
+ if (device->GetType() == Device_Sensor)
{
- int compare = OVR_strcmp(profile->Name, ProfileCache[i]->Name);
-
- if (compare == 0)
- {
- // TODO: I should do a proper field comparison to avoid unnecessary
- // overwrites and file saves
-
- // Replace the previous instance with the new profile
- ProfileCache[i] = *profile->Clone();
- added = true;
- Changed = true;
- break;
+ SensorDevice* sensor = (SensorDevice*)device;
+
+ SensorInfo sinfo;
+ sensor->GetDeviceInfo(&sinfo);
+
+ int dev_major = BCDByte((sinfo.Version >> 8) & 0x00ff);
+ OVR_UNUSED(dev_major);
+ int dev_minor = BCDByte(sinfo.Version & 0xff);
+
+ if (dev_minor > 18)
+ { // If the firmware supports hardware stored profiles then grab the device profile
+ // from the sensor
+ // TBD: Implement this
+ }
+ else
+ {
+ // Grab the model and serial number from the device and use it to access the device
+ // profile file stored on the local machine
+ success = LoadDeviceFile(sinfo.ProductId, sinfo.SerialNumber);
}
}
- if (!added)
- {
- ProfileCache.PushBack(*profile->Clone());
- if (ProfileCache.GetSize() == 1)
- CacheDevice = profile->Type;
-
- Changed = true;
- }
+ if (sensor)
+ sensor->Release(); // release the sensor handle
- return true;
+ return success;
}
-// Removes an existing profile. Returns true if the profile was found and deleted
-// and returns false otherwise.
-bool ProfileManager::Delete(const Profile* profile)
+//-----------------------------------------------------------------------------
+bool Profile::LoadUser(JSON* root,
+ const char* user,
+ const char* model_name,
+ const char* device_serial)
{
- Lock::Locker lockScope(&ProfileLock);
+ if (user == NULL)
+ return false;
- if (OVR_strcmp(profile->Name, "default") == 0)
- return false; // don't delete a default profile
+ // For legacy files, convert to old style names
+ //if (model_name && OVR_strcmp(model_name, "Oculus Rift DK1") == 0)
+ // model_name = "RiftDK1";
+
+ bool user_found = false;
+ JSON* data = root->GetItemByName("TaggedData");
+ if (data)
+ {
+ const char* tag_names[3];
+ const char* tags[3];
+ tag_names[0] = "User";
+ tags[0] = user;
+ int num_tags = 1;
+
+ if (model_name)
+ {
+ tag_names[num_tags] = "Product";
+ tags[num_tags] = model_name;
+ num_tags++;
+ }
- if (CacheDevice == Profile_Unknown)
- LoadCache(profile->Type);
+ if (device_serial)
+ {
+ tag_names[num_tags] = "Serial";
+ tags[num_tags] = device_serial;
+ num_tags++;
+ }
- // Look for the existence of this profile
- for (unsigned int i=0; i<ProfileCache.GetSize(); i++)
- {
- if (OVR_strcmp(profile->Name, ProfileCache[i]->Name) == 0)
- {
- if (OVR_strcmp(profile->Name, DefaultProfile) == 0)
- DefaultProfile.Clear();
-
- ProfileCache.RemoveAt(i);
- Changed = true;
- return true;
+ // Retrieve all tag permutations
+ for (int combos=1; combos<=num_tags; combos++)
+ {
+ for (int i=0; i<(num_tags - combos + 1); i++)
+ {
+ JSON* vals = FindTaggedData(data, tag_names+i, tags+i, combos);
+ if (vals)
+ {
+ if (i==0) // This tag-combination contains a user match
+ user_found = true;
+
+ // Add the values to the Profile. More specialized multi-tag values
+ // will take precedence over and overwrite generalized ones
+ // For example: ("Me","RiftDK1").IPD would overwrite ("Me").IPD
+ JSON* item = vals->GetFirstItem();
+ while (item)
+ {
+ //printf("Add %s, %s\n", item->Name.ToCStr(), item->Value.ToCStr());
+ //Settings.Set(item->Name, item->Value);
+ SetValue(item);
+ item = vals->GetNextItem(item);
+ }
+ }
+ }
}
}
- return false;
-}
+ if (user_found)
+ SetValue(OVR_KEY_USER, user);
+ return user_found;
+}
//-----------------------------------------------------------------------------
-// ***** Profile
-
-Profile::Profile(ProfileType device, const char* name)
+bool Profile::LoadProfile(JSON* root,
+ const char* user,
+ const char* device_model,
+ const char* device_serial)
{
- Type = device;
- Gender = Gender_Unspecified;
- PlayerHeight = 1.778f; // 5'10" inch man
- IPD = 0.064f;
- OVR_strcpy(Name, MaxNameLen, name);
+ if (!LoadUser(root, user, device_model, device_serial))
+ return false;
+
+ return true;
}
-bool Profile::ParseProperty(const char* prop, const char* sval)
+//-----------------------------------------------------------------------------
+char* Profile::GetValue(const char* key, char* val, int val_length) const
{
- if (OVR_strcmp(prop, "Name") == 0)
+ JSON* value = NULL;
+ if (ValMap.Get(key, &value))
{
- OVR_strcpy(Name, MaxNameLen, sval);
- return true;
+ OVR_strcpy(val, val_length, value->Value.ToCStr());
+ return val;
}
- else if (OVR_strcmp(prop, "Gender") == 0)
+ else
{
- if (OVR_strcmp(sval, "Male") == 0)
- Gender = Gender_Male;
- else if (OVR_strcmp(sval, "Female") == 0)
- Gender = Gender_Female;
- else
- Gender = Gender_Unspecified;
-
- return true;
+ val[0] = 0;
+ return NULL;
}
- else if (OVR_strcmp(prop, "PlayerHeight") == 0)
+}
+
+//-----------------------------------------------------------------------------
+const char* Profile::GetValue(const char* key)
+{
+ // Non-reentrant query. The returned buffer can only be used until the next call
+ // to GetValue()
+ JSON* value = NULL;
+ if (ValMap.Get(key, &value))
{
- PlayerHeight = (float)atof(sval);
- return true;
+ TempVal = value->Value;
+ return TempVal.ToCStr();
}
- else if (OVR_strcmp(prop, "IPD") == 0)
+ else
{
- IPD = (float)atof(sval);
- return true;
+ return NULL;
}
-
- return false;
}
+//-----------------------------------------------------------------------------
+int Profile::GetNumValues(const char* key) const
+{
+ JSON* value = NULL;
+ if (ValMap.Get(key, &value))
+ {
+ if (value->Type == JSON_Array)
+ return value->GetArraySize();
+ else
+ return 1;
+ }
+ else
+ return 0;
+}
-// Computes the eye height from the metric head height
-float Profile::GetEyeHeight()
+//-----------------------------------------------------------------------------
+bool Profile::GetBoolValue(const char* key, bool default_val) const
{
- const float EYE_TO_HEADTOP_RATIO = 0.44538f;
- const float MALE_AVG_HEAD_HEIGHT = 0.232f;
- const float FEMALE_AVG_HEAD_HEIGHT = 0.218f;
-
- // compute distance from top of skull to the eye
- float head_height;
- if (Gender == Gender_Female)
- head_height = FEMALE_AVG_HEAD_HEIGHT;
+ JSON* value = NULL;
+ if (ValMap.Get(key, &value) && value->Type == JSON_Bool)
+ return (value->dValue != 0);
else
- head_height = MALE_AVG_HEAD_HEIGHT;
+ return default_val;
+}
- float skull = EYE_TO_HEADTOP_RATIO * head_height;
+//-----------------------------------------------------------------------------
+int Profile::GetIntValue(const char* key, int default_val) const
+{
+ JSON* value = NULL;
+ if (ValMap.Get(key, &value) && value->Type == JSON_Number)
+ return (int)(value->dValue);
+ else
+ return default_val;
+}
- float eye_height = PlayerHeight - skull;
- return eye_height;
+//-----------------------------------------------------------------------------
+float Profile::GetFloatValue(const char* key, float default_val) const
+{
+ JSON* value = NULL;
+ if (ValMap.Get(key, &value) && value->Type == JSON_Number)
+ return (float)(value->dValue);
+ else
+ return default_val;
}
//-----------------------------------------------------------------------------
-// ***** HMDProfile
+int Profile::GetFloatValues(const char* key, float* values, int num_vals) const
+{
+ JSON* value = NULL;
+ if (ValMap.Get(key, &value) && value->Type == JSON_Array)
+ {
+ int val_count = Alg::Min(value->GetArraySize(), num_vals);
+ JSON* item = value->GetFirstItem();
+ int count=0;
+ while (item && count < val_count)
+ {
+ if (item->Type == JSON_Number)
+ values[count] = (float)item->dValue;
+ else
+ break;
+
+ count++;
+ item = value->GetNextItem(item);
+ }
+
+ return count;
+ }
+ else
+ {
+ return 0;
+ }
+}
-HMDProfile::HMDProfile(ProfileType type, const char* name) : Profile(type, name)
+//-----------------------------------------------------------------------------
+double Profile::GetDoubleValue(const char* key, double default_val) const
{
- LL = 0;
- LR = 0;
- RL = 0;
- RR = 0;
+ JSON* value = NULL;
+ if (ValMap.Get(key, &value) && value->Type == JSON_Number)
+ return value->dValue;
+ else
+ return default_val;
}
-bool HMDProfile::ParseProperty(const char* prop, const char* sval)
+//-----------------------------------------------------------------------------
+int Profile::GetDoubleValues(const char* key, double* values, int num_vals) const
{
- if (OVR_strcmp(prop, "LL") == 0)
+ JSON* value = NULL;
+ if (ValMap.Get(key, &value) && value->Type == JSON_Array)
{
- LL = atoi(sval);
- return true;
+ int val_count = Alg::Min(value->GetArraySize(), num_vals);
+ JSON* item = value->GetFirstItem();
+ int count=0;
+ while (item && count < val_count)
+ {
+ if (item->Type == JSON_Number)
+ values[count] = item->dValue;
+ else
+ break;
+
+ count++;
+ item = value->GetNextItem(item);
+ }
+
+ return count;
}
- else if (OVR_strcmp(prop, "LR") == 0)
+ else
{
- LR = atoi(sval);
- return true;
+ return 0;
}
- else if (OVR_strcmp(prop, "RL") == 0)
+}
+
+//-----------------------------------------------------------------------------
+void Profile::SetValue(JSON* val)
+{
+ if (val->Type == JSON_Number)
+ SetDoubleValue(val->Name, val->dValue);
+ else if (val->Type == JSON_Bool)
+ SetBoolValue(val->Name, (val->dValue != 0));
+ else if (val->Type == JSON_String)
+ SetValue(val->Name, val->Value);
+ else if (val->Type == JSON_Array)
{
- RL = atoi(sval);
- return true;
+ if (val == NULL)
+ return;
+
+ // Create a copy of the array
+ JSON* value = val->Copy();
+ Values.PushBack(value);
+ ValMap.Set(value->Name, value);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void Profile::SetValue(const char* key, const char* val)
+{
+ if (key == NULL || val == NULL)
+ return;
+
+ JSON* value = NULL;
+ if (ValMap.Get(key, &value))
+ {
+ value->Value = val;
}
- else if (OVR_strcmp(prop, "RR") == 0)
+ else
{
- RR = atoi(sval);
- return true;
+ value = JSON::CreateString(val);
+ value->Name = key;
+
+ Values.PushBack(value);
+ ValMap.Set(key, value);
}
-
- return Profile::ParseProperty(prop, sval);
}
-Profile* HMDProfile::Clone() const
+//-----------------------------------------------------------------------------
+void Profile::SetBoolValue(const char* key, bool val)
{
- HMDProfile* profile = new HMDProfile(*this);
- return profile;
+ if (key == NULL)
+ return;
+
+ JSON* value = NULL;
+ if (ValMap.Get(key, &value))
+ {
+ value->dValue = val;
+ }
+ else
+ {
+ value = JSON::CreateBool(val);
+ value->Name = key;
+
+ Values.PushBack(value);
+ ValMap.Set(key, value);
+ }
}
//-----------------------------------------------------------------------------
-// ***** RiftDK1Profile
+void Profile::SetIntValue(const char* key, int val)
+{
+ SetDoubleValue(key, val);
+}
-RiftDK1Profile::RiftDK1Profile(const char* name) : HMDProfile(Profile_RiftDK1, name)
+//-----------------------------------------------------------------------------
+void Profile::SetFloatValue(const char* key, float val)
{
- EyeCups = EyeCup_A;
+ SetDoubleValue(key, val);
}
-bool RiftDK1Profile::ParseProperty(const char* prop, const char* sval)
+//-----------------------------------------------------------------------------
+void Profile::SetFloatValues(const char* key, const float* vals, int num_vals)
{
- if (OVR_strcmp(prop, "EyeCup") == 0)
+ JSON* value = NULL;
+ int val_count = 0;
+ if (ValMap.Get(key, &value))
{
- switch (sval[0])
+ if (value->Type == JSON_Array)
{
- case 'C': EyeCups = EyeCup_C; break;
- case 'B': EyeCups = EyeCup_B; break;
- default: EyeCups = EyeCup_A; break;
+ // truncate the existing array if fewer entries provided
+ int num_existing_vals = value->GetArraySize();
+ for (int i=num_vals; i<num_existing_vals; i++)
+ value->RemoveLast();
+
+ JSON* item = value->GetFirstItem();
+ while (item && val_count < num_vals)
+ {
+ if (item->Type == JSON_Number)
+ item->dValue = vals[val_count];
+
+ item = value->GetNextItem(item);
+ val_count++;
+ }
+ }
+ else
+ {
+ return; // Maybe we should change the data type?
}
- return true;
}
-
- return HMDProfile::ParseProperty(prop, sval);
-}
+ else
+ {
+ value = JSON::CreateArray();
+ value->Name = key;
-Profile* RiftDK1Profile::Clone() const
-{
- RiftDK1Profile* profile = new RiftDK1Profile(*this);
- return profile;
+ Values.PushBack(value);
+ ValMap.Set(key, value);
+ }
+
+ for (val_count; val_count < num_vals; val_count++)
+ value->AddArrayNumber(vals[val_count]);
}
//-----------------------------------------------------------------------------
-// ***** RiftDKHDProfile
-
-RiftDKHDProfile::RiftDKHDProfile(const char* name) : HMDProfile(Profile_RiftDKHD, name)
+void Profile::SetDoubleValue(const char* key, double val)
{
- EyeCups = EyeCup_A;
+ JSON* value = NULL;
+ if (ValMap.Get(key, &value))
+ {
+ value->dValue = val;
+ }
+ else
+ {
+ value = JSON::CreateNumber(val);
+ value->Name = key;
+
+ Values.PushBack(value);
+ ValMap.Set(key, value);
+ }
}
-bool RiftDKHDProfile::ParseProperty(const char* prop, const char* sval)
+//-----------------------------------------------------------------------------
+void Profile::SetDoubleValues(const char* key, const double* vals, int num_vals)
{
- if (OVR_strcmp(prop, "EyeCup") == 0)
+ JSON* value = NULL;
+ int val_count = 0;
+ if (ValMap.Get(key, &value))
{
- switch (sval[0])
+ if (value->Type == JSON_Array)
{
- case 'C': EyeCups = EyeCup_C; break;
- case 'B': EyeCups = EyeCup_B; break;
- default: EyeCups = EyeCup_A; break;
+ // truncate the existing array if fewer entries provided
+ int num_existing_vals = value->GetArraySize();
+ for (int i=num_vals; i<num_existing_vals; i++)
+ value->RemoveLast();
+
+ JSON* item = value->GetFirstItem();
+ while (item && val_count < num_vals)
+ {
+ if (item->Type == JSON_Number)
+ item->dValue = vals[val_count];
+
+ item = value->GetNextItem(item);
+ val_count++;
+ }
+ }
+ else
+ {
+ return; // Maybe we should change the data type?
}
- return true;
}
-
- return HMDProfile::ParseProperty(prop, sval);
-}
+ else
+ {
+ value = JSON::CreateArray();
+ value->Name = key;
-Profile* RiftDKHDProfile::Clone() const
-{
- RiftDKHDProfile* profile = new RiftDKHDProfile(*this);
- return profile;
+ Values.PushBack(value);
+ ValMap.Set(key, value);
+ }
+
+ for (val_count; val_count < num_vals; val_count++)
+ value->AddArrayNumber(vals[val_count]);
}
} // OVR
diff --git a/LibOVR/Src/OVR_Profile.h b/LibOVR/Src/OVR_Profile.h
index 9e2f9f3..e34820a 100644
--- a/LibOVR/Src/OVR_Profile.h
+++ b/LibOVR/Src/OVR_Profile.h
@@ -11,16 +11,16 @@ Notes :
can be accomplished in game via the Profile API or by the official Oculus Configuration
Utility.
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -33,22 +33,17 @@ limitations under the License.
#ifndef OVR_Profile_h
#define OVR_Profile_h
+#include "OVR_DeviceConstants.h"
#include "Kernel/OVR_String.h"
#include "Kernel/OVR_RefCount.h"
#include "Kernel/OVR_Array.h"
+#include "Kernel/OVR_StringHash.h"
namespace OVR {
-// Defines the profile object for each device type
-enum ProfileType
-{
- Profile_Unknown = 0,
- Profile_GenericHMD = 10,
- Profile_RiftDK1 = 11,
- Profile_RiftDKHD = 12,
-};
-
class Profile;
+class DeviceBase;
+class JSON;
// -----------------------------------------------------------------------------
// ***** ProfileManager
@@ -69,183 +64,137 @@ class Profile;
// { // Retrieve the current profile settings
// }
// } // Profile will be destroyed and any disk I/O completed when going out of scope
-
class ProfileManager : public RefCountBase<ProfileManager>
{
protected:
// Synchronize ProfileManager access since it may be accessed from multiple threads,
// as it's shared through DeviceManager.
- Lock ProfileLock;
- Array<Ptr<Profile> > ProfileCache;
- ProfileType CacheDevice;
- String DefaultProfile;
- bool Changed;
- char NameBuff[32];
+ Lock ProfileLock;
+ Ptr<JSON> ProfileCache;
+ bool Changed;
+ String TempBuff;
public:
static ProfileManager* Create();
- // Static interface functions
- int GetProfileCount(ProfileType device);
- const char* GetProfileName(ProfileType device, unsigned int index);
- bool HasProfile(ProfileType device, const char* name);
- Profile* LoadProfile(ProfileType device, unsigned int index);
- Profile* LoadProfile(ProfileType device, const char* name);
- Profile* GetDeviceDefaultProfile(ProfileType device);
- const char* GetDefaultProfileName(ProfileType device);
- bool SetDefaultProfileName(ProfileType device, const char* name);
- bool Save(const Profile* profile);
- bool Delete(const Profile* profile);
-
+ int GetUserCount();
+ const char* GetUser(unsigned int index);
+ bool CreateUser(const char* user, const char* name);
+ bool RemoveUser(const char* user);
+ const char* GetDefaultUser(const DeviceBase* device);
+ bool SetDefaultUser(const DeviceBase* device, const char* user);
+
+ virtual Profile* CreateProfile();
+ Profile* GetProfile(const DeviceBase* device, const char* user);
+ Profile* GetDefaultProfile(const DeviceBase* device);
+ Profile* GetTaggedProfile(const char** key_names, const char** keys, int num_keys);
+ bool SetTaggedProfile(const char** key_names, const char** keys, int num_keys, Profile* profile);
+
+ bool GetDeviceTags(const DeviceBase* device, String& product, String& serial);
+
protected:
ProfileManager();
~ProfileManager();
- void LoadCache(ProfileType device);
- void SaveCache();
+ String GetProfilePath(bool create_dir);
+ void LoadCache(bool create);
void ClearCache();
- Profile* CreateProfileObject(const char* user,
- ProfileType device,
- const char** device_name);
+ void LoadV1Profiles(JSON* v1);
+
+
};
+
//-------------------------------------------------------------------
// ***** Profile
// The base profile for all users. This object is not created directly.
// Instead derived device objects provide add specific device members to
// the base profile
-
class Profile : public RefCountBase<Profile>
{
-public:
- enum { MaxNameLen = 32 };
-
- enum GenderType
- {
- Gender_Unspecified = 0,
- Gender_Male = 1,
- Gender_Female = 2
- };
-
- ProfileType Type; // The type of device profile
- char Name[MaxNameLen]; // The name given to this profile
-
protected:
- GenderType Gender; // The gender of the user
- float PlayerHeight; // The height of the user in meters
- float IPD; // Distance between eyes in meters
+ OVR::Hash<String, JSON*, String::HashFunctor> ValMap;
+ OVR::Array<JSON*> Values;
+ OVR::String TempVal;
public:
- virtual Profile* Clone() const = 0;
-
- // These are properties which are intrinsic to the user and affect scene setup
- GenderType GetGender() { return Gender; };
- float GetPlayerHeight() { return PlayerHeight; };
- float GetIPD() { return IPD; };
- float GetEyeHeight();
-
- void SetGender(GenderType gender) { Gender = gender; };
- void SetPlayerHeight(float height) { PlayerHeight = height; };
- void SetIPD(float ipd) { IPD = ipd; };
-
-protected:
- Profile(ProfileType type, const char* name);
+ ~Profile();
+
+ int GetNumValues(const char* key) const;
+ const char* GetValue(const char* key);
+ char* GetValue(const char* key, char* val, int val_length) const;
+ bool GetBoolValue(const char* key, bool default_val) const;
+ int GetIntValue(const char* key, int default_val) const;
+ float GetFloatValue(const char* key, float default_val) const;
+ int GetFloatValues(const char* key, float* values, int num_vals) const;
+ double GetDoubleValue(const char* key, double default_val) const;
+ int GetDoubleValues(const char* key, double* values, int num_vals) const;
+
+ void SetValue(const char* key, const char* val);
+ void SetBoolValue(const char* key, bool val);
+ void SetIntValue(const char* key, int val);
+ void SetFloatValue(const char* key, float val);
+ void SetFloatValues(const char* key, const float* vals, int num_vals);
+ void SetDoubleValue(const char* key, double val);
+ void SetDoubleValues(const char* key, const double* vals, int num_vals);
- virtual bool ParseProperty(const char* prop, const char* sval);
-
- friend class ProfileManager;
-};
-
-//-----------------------------------------------------------------------------
-// ***** HMDProfile
-
-// The generic HMD profile is used for properties that are common to all headsets
-class HMDProfile : public Profile
-{
-protected:
- // FOV extents in pixels measured by a user
- int LL; // left eye outer extent
- int LR; // left eye inner extent
- int RL; // right eye inner extent
- int RR; // right eye outer extent
-
-public:
- virtual Profile* Clone() const;
-
- void SetLL(int val) { LL = val; };
- void SetLR(int val) { LR = val; };
- void SetRL(int val) { RL = val; };
- void SetRR(int val) { RR = val; };
-
- int GetLL() { return LL; };
- int GetLR() { return LR; };
- int GetRL() { return RL; };
- int GetRR() { return RR; };
+ bool Close();
protected:
- HMDProfile(ProfileType type, const char* name);
+ Profile() {};
- virtual bool ParseProperty(const char* prop, const char* sval);
-
- friend class ProfileManager;
-};
-
-// For headsets that use eye cups
-enum EyeCupType
-{
- EyeCup_A = 0,
- EyeCup_B = 1,
- EyeCup_C = 2
-};
-
-//-----------------------------------------------------------------------------
-// ***** RiftDK1Profile
-
-// This profile is specific to the Rift Dev Kit 1 and contains overrides specific
-// to that device and lens cup settings.
-class RiftDK1Profile : public HMDProfile
-{
-protected:
- EyeCupType EyeCups; // Which eye cup does the player use
-
-public:
- virtual Profile* Clone() const;
-
- EyeCupType GetEyeCup() { return EyeCups; };
- void SetEyeCup(EyeCupType cup) { EyeCups = cup; };
-
-protected:
- RiftDK1Profile(const char* name);
-
- virtual bool ParseProperty(const char* prop, const char* sval);
-
- friend class ProfileManager;
-};
-
-//-----------------------------------------------------------------------------
-// ***** RiftDKHDProfile
-
-// This profile is specific to the Rift HD Dev Kit and contains overrides specific
-// to that device and lens cup settings.
-class RiftDKHDProfile : public HMDProfile
-{
-protected:
- EyeCupType EyeCups; // Which eye cup does the player use
-
-public:
- virtual Profile* Clone() const;
+
+ void SetValue(JSON* val);
- EyeCupType GetEyeCup() { return EyeCups; };
- void SetEyeCup(EyeCupType cup) { EyeCups = cup; };
+
+ static bool LoadProfile(const DeviceBase* device,
+ const char* user,
+ Profile** profile);
+ void CopyItems(JSON* root, String prefix);
+
+ bool LoadDeviceFile(unsigned int device_id, const char* serial);
+ bool LoadDeviceProfile(const DeviceBase* device);
-protected:
- RiftDKHDProfile(const char* name);
+ bool LoadProfile(JSON* root,
+ const char* user,
+ const char* device_model,
+ const char* device_serial);
- virtual bool ParseProperty(const char* prop, const char* sval);
+ bool LoadUser(JSON* root,
+ const char* user,
+ const char* device_name,
+ const char* device_serial);
+
friend class ProfileManager;
};
+// # defined() check for CAPI compatibility near term that re-defines these
+// for now. To be unified.
+#if !defined(OVR_KEY_USER)
+
+#define OVR_KEY_USER "User"
+#define OVR_KEY_NAME "Name"
+#define OVR_KEY_GENDER "Gender"
+#define OVR_KEY_PLAYER_HEIGHT "PlayerHeight"
+#define OVR_KEY_EYE_HEIGHT "EyeHeight"
+#define OVR_KEY_IPD "IPD"
+#define OVR_KEY_NECK_TO_EYE_DISTANCE "NeckEyeDistance"
+#define OVR_KEY_EYE_RELIEF_DIAL "EyeReliefDial"
+#define OVR_KEY_EYE_TO_NOSE_DISTANCE "EyeToNoseDist"
+#define OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE "MaxEyeToPlateDist"
+#define OVR_KEY_EYE_CUP "EyeCup"
+#define OVR_KEY_CUSTOM_EYE_RENDER "CustomEyeRender"
+
+#define OVR_DEFAULT_GENDER "Male"
+#define OVR_DEFAULT_PLAYER_HEIGHT 1.778f
+#define OVR_DEFAULT_EYE_HEIGHT 1.675f
+#define OVR_DEFAULT_IPD 0.064f
+#define OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL 0.09f
+#define OVR_DEFAULT_NECK_TO_EYE_VERTICAL 0.15f
+#define OVR_DEFAULT_EYE_RELIEF_DIAL 3
+
+#endif // OVR_KEY_USER
String GetBaseOVRPath(bool create_dir);
diff --git a/LibOVR/Src/OVR_Sensor2Impl.cpp b/LibOVR/Src/OVR_Sensor2Impl.cpp
new file mode 100644
index 0000000..fa5d6e9
--- /dev/null
+++ b/LibOVR/Src/OVR_Sensor2Impl.cpp
@@ -0,0 +1,1128 @@
+/************************************************************************************
+
+Filename : OVR_Sensor2Impl.cpp
+Content : DK2 sensor device specific implementation.
+Created : January 21, 2013
+Authors : Lee Cooper
+
+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 "OVR_Sensor2Impl.h"
+#include "OVR_SensorImpl_Common.h"
+#include "OVR_Sensor2ImplUtil.h"
+#include "Kernel/OVR_Alg.h"
+
+//extern FILE *SF_LOG_fp;
+
+namespace OVR {
+
+//-------------------------------------------------------------------------------------
+// ***** Oculus Sensor2-specific packet data structures
+
+enum {
+ Sensor2_VendorId = Oculus_VendorId,
+ Sensor2_ProductId = 0x0021,
+
+ Sensor2_BootLoader = 0x1001,
+
+ Sensor2_DefaultReportRate = 1000, // Hz
+};
+
+
+// Messages we care for
+enum Tracker2MessageType
+{
+ Tracker2Message_None = 0,
+ Tracker2Message_Sensors = 11,
+ Tracker2Message_Unknown = 0x100,
+ Tracker2Message_SizeError = 0x101,
+};
+
+
+struct Tracker2Sensors
+{
+ UInt16 LastCommandID;
+ UByte NumSamples;
+ UInt16 RunningSampleCount; // Named 'SampleCount' in the firmware docs.
+ SInt16 Temperature;
+ UInt32 SampleTimestamp;
+ TrackerSample Samples[2];
+ SInt16 MagX, MagY, MagZ;
+ UInt16 FrameCount;
+ UInt32 FrameTimestamp;
+ UByte FrameID;
+ UByte CameraPattern;
+ UInt16 CameraFrameCount; // Named 'CameraCount' in the firmware docs.
+ UInt32 CameraTimestamp;
+
+ Tracker2MessageType Decode(const UByte* buffer, int size)
+ {
+ if (size < 64)
+ return Tracker2Message_SizeError;
+
+ LastCommandID = DecodeUInt16(buffer + 1);
+ NumSamples = buffer[3];
+ RunningSampleCount = DecodeUInt16(buffer + 4);
+ Temperature = DecodeSInt16(buffer + 6);
+ SampleTimestamp = DecodeUInt32(buffer + 8);
+
+ // Only unpack as many samples as there actually are.
+ UByte iterationCount = (NumSamples > 1) ? 2 : NumSamples;
+
+ for (UByte i = 0; i < iterationCount; i++)
+ {
+ UnpackSensor(buffer + 12 + 16 * i, &Samples[i].AccelX, &Samples[i].AccelY, &Samples[i].AccelZ);
+ UnpackSensor(buffer + 20 + 16 * i, &Samples[i].GyroX, &Samples[i].GyroY, &Samples[i].GyroZ);
+ }
+
+ MagX = DecodeSInt16(buffer + 44);
+ MagY = DecodeSInt16(buffer + 46);
+ MagZ = DecodeSInt16(buffer + 48);
+
+ FrameCount = DecodeUInt16(buffer + 50);
+
+ FrameTimestamp = DecodeUInt32(buffer + 52);
+ FrameID = buffer[56];
+ CameraPattern = buffer[57];
+ CameraFrameCount = DecodeUInt16(buffer + 58);
+ CameraTimestamp = DecodeUInt32(buffer + 60);
+
+ return Tracker2Message_Sensors;
+ }
+};
+
+struct Tracker2Message
+{
+ Tracker2MessageType Type;
+ Tracker2Sensors Sensors;
+};
+
+// Sensor reports data in the following coordinate system:
+// Accelerometer: 10^-4 m/s^2; X forward, Y right, Z Down.
+// Gyro: 10^-4 rad/s; X positive roll right, Y positive pitch up; Z positive yaw right.
+
+
+// We need to convert it to the following RHS coordinate system:
+// X right, Y Up, Z Back (out of screen)
+//
+Vector3f AccelFromBodyFrameUpdate(const Tracker2Sensors& update, UByte sampleNumber)
+{
+ const TrackerSample& sample = update.Samples[sampleNumber];
+ float ax = (float)sample.AccelX;
+ float ay = (float)sample.AccelY;
+ float az = (float)sample.AccelZ;
+
+ return Vector3f(ax, ay, az) * 0.0001f;
+}
+
+
+Vector3f MagFromBodyFrameUpdate(const Tracker2Sensors& update)
+{
+ return Vector3f( (float)update.MagX, (float)update.MagY, (float)update.MagZ) * 0.0001f;
+}
+
+Vector3f EulerFromBodyFrameUpdate(const Tracker2Sensors& update, UByte sampleNumber)
+{
+ const TrackerSample& sample = update.Samples[sampleNumber];
+ float gx = (float)sample.GyroX;
+ float gy = (float)sample.GyroY;
+ float gz = (float)sample.GyroZ;
+
+ return Vector3f(gx, gy, gz) * 0.0001f;
+}
+
+bool Sensor2DeviceImpl::decodeTracker2Message(Tracker2Message* message, UByte* buffer, int size)
+{
+ memset(message, 0, sizeof(Tracker2Message));
+
+ if (size < 4)
+ {
+ message->Type = Tracker2Message_SizeError;
+ return false;
+ }
+
+ switch (buffer[0])
+ {
+ case Tracker2Message_Sensors:
+ message->Type = message->Sensors.Decode(buffer, size);
+ break;
+
+ default:
+ message->Type = Tracker2Message_Unknown;
+ break;
+ }
+
+ return (message->Type < Tracker2Message_Unknown) && (message->Type != Tracker2Message_None);
+}
+
+//-------------------------------------------------------------------------------------
+// ***** Sensor2Device
+
+Sensor2DeviceImpl::Sensor2DeviceImpl(SensorDeviceCreateDesc* createDesc)
+ : SensorDeviceImpl(createDesc),
+ LastNumSamples(0),
+ LastRunningSampleCount(0),
+ FullCameraFrameCount(0),
+ LastCameraTime("C"),
+ LastFrameTime("F"),
+ LastSensorTime("S"),
+ LastFrameTimestamp(0)
+{
+ // 15 samples ok in min-window for DK2 since it uses microsecond clock.
+ TimeFilter = SensorTimeFilter(SensorTimeFilter::Settings(15));
+
+ pCalibration = new SensorCalibration(this);
+}
+
+Sensor2DeviceImpl::~Sensor2DeviceImpl()
+{
+ delete pCalibration;
+}
+
+void Sensor2DeviceImpl::openDevice()
+{
+
+ // Read the currently configured range from sensor.
+ SensorRangeImpl sr(SensorRange(), 0);
+
+ if (GetInternalDevice()->GetFeatureReport(sr.Buffer, SensorRangeImpl::PacketSize))
+ {
+ sr.Unpack();
+ sr.GetSensorRange(&CurrentRange);
+ }
+
+ // Read the currently configured calibration from sensor.
+ SensorFactoryCalibrationImpl sc;
+ if (GetInternalDevice()->GetFeatureReport(sc.Buffer, SensorFactoryCalibrationImpl::PacketSize))
+ {
+ sc.Unpack();
+ AccelCalibrationOffset = sc.AccelOffset;
+ GyroCalibrationOffset = sc.GyroOffset;
+ AccelCalibrationMatrix = sc.AccelMatrix;
+ GyroCalibrationMatrix = sc.GyroMatrix;
+ CalibrationTemperature = sc.Temperature;
+ }
+
+ // If the sensor has "DisplayInfo" data, use HMD coordinate frame by default.
+ SensorDisplayInfoImpl displayInfo;
+ if (GetInternalDevice()->GetFeatureReport(displayInfo.Buffer, SensorDisplayInfoImpl::PacketSize))
+ {
+ displayInfo.Unpack();
+ Coordinates = (displayInfo.DistortionType & SensorDisplayInfoImpl::Mask_BaseFmt) ?
+ Coord_HMD : Coord_Sensor;
+ }
+ Coordinates = Coord_HMD; // TODO temporary to force it behave
+
+ // Read/Apply sensor config.
+ setCoordinateFrame(Coordinates);
+ setReportRate(Sensor2_DefaultReportRate);
+ setOnboardCalibrationEnabled(false);
+
+ // Must send DK2 keep-alive. Set Keep-alive at 10 seconds.
+ KeepAliveMuxReport keepAlive;
+ keepAlive.CommandId = 0;
+ keepAlive.INReport = 11;
+ keepAlive.Interval = 10 * 1000;
+
+ // Device creation is done from background thread so we don't need to add this to the command queue.
+ KeepAliveMuxImpl keepAliveImpl(keepAlive);
+ GetInternalDevice()->SetFeatureReport(keepAliveImpl.Buffer, KeepAliveMuxImpl::PacketSize);
+
+ // Read the temperature data from the device
+ pCalibration->Initialize();
+}
+
+bool Sensor2DeviceImpl::SetTrackingReport(const TrackingReport& data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::setTrackingReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::setTrackingReport(const TrackingReport& data)
+{
+ TrackingImpl ci(data);
+ return GetInternalDevice()->SetFeatureReport(ci.Buffer, TrackingImpl::PacketSize);
+}
+
+bool Sensor2DeviceImpl::GetTrackingReport(TrackingReport* data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::getTrackingReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::getTrackingReport(TrackingReport* data)
+{
+ TrackingImpl ci;
+ if (GetInternalDevice()->GetFeatureReport(ci.Buffer, TrackingImpl::PacketSize))
+ {
+ ci.Unpack();
+ *data = ci.Settings;
+ return true;
+ }
+
+ return false;
+}
+
+bool Sensor2DeviceImpl::SetDisplayReport(const DisplayReport& data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::setDisplayReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::setDisplayReport(const DisplayReport& data)
+{
+ DisplayImpl di(data);
+ return GetInternalDevice()->SetFeatureReport(di.Buffer, DisplayImpl::PacketSize);
+}
+
+bool Sensor2DeviceImpl::GetDisplayReport(DisplayReport* data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::getDisplayReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::getDisplayReport(DisplayReport* data)
+{
+ DisplayImpl di;
+ if (GetInternalDevice()->GetFeatureReport(di.Buffer, DisplayImpl::PacketSize))
+ {
+ di.Unpack();
+ *data = di.Settings;
+ return true;
+ }
+
+ return false;
+}
+
+bool Sensor2DeviceImpl::SetMagCalibrationReport(const MagCalibrationReport& data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::setMagCalibrationReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::setMagCalibrationReport(const MagCalibrationReport& data)
+{
+ MagCalibrationImpl mci(data);
+ return GetInternalDevice()->SetFeatureReport(mci.Buffer, MagCalibrationImpl::PacketSize);
+}
+
+bool Sensor2DeviceImpl::GetMagCalibrationReport(MagCalibrationReport* data)
+{
+ // direct call if we are already on the device manager thread
+ if (GetCurrentThreadId() == GetManagerImpl()->GetThreadId())
+ {
+ return getMagCalibrationReport(data);
+ }
+
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::getMagCalibrationReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::getMagCalibrationReport(MagCalibrationReport* data)
+{
+ MagCalibrationImpl mci;
+ if (GetInternalDevice()->GetFeatureReport(mci.Buffer, MagCalibrationImpl::PacketSize))
+ {
+ mci.Unpack();
+ *data = mci.Settings;
+ return true;
+ }
+
+ return false;
+}
+
+bool Sensor2DeviceImpl::SetPositionCalibrationReport(const PositionCalibrationReport& data)
+{
+ Lock::Locker lock(&IndexedReportLock);
+
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::setPositionCalibrationReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::setPositionCalibrationReport(const PositionCalibrationReport& data)
+{
+ UByte version = GetDeviceInterfaceVersion();
+ if (version < 5)
+ {
+ PositionCalibrationImpl_Pre5 pci(data);
+ return GetInternalDevice()->SetFeatureReport(pci.Buffer, PositionCalibrationImpl_Pre5::PacketSize);
+ }
+
+ PositionCalibrationImpl pci(data);
+ 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();
+ if (version < 5)
+ {
+ PositionCalibrationImpl_Pre5 pci;
+ if (GetInternalDevice()->GetFeatureReport(pci.Buffer, PositionCalibrationImpl_Pre5::PacketSize))
+ {
+ pci.Unpack();
+ *data = pci.Settings;
+ return true;
+ }
+
+ return false;
+ }
+
+ PositionCalibrationImpl pci;
+ if (GetInternalDevice()->GetFeatureReport(pci.Buffer, PositionCalibrationImpl::PacketSize))
+ {
+ pci.Unpack();
+ *data = pci.Settings;
+ return true;
+ }
+
+ return false;
+}
+
+bool Sensor2DeviceImpl::GetAllPositionCalibrationReports(Array<PositionCalibrationReport>* data)
+{
+ Lock::Locker lock(&IndexedReportLock);
+
+ PositionCalibrationReport pc;
+ bool result = GetPositionCalibrationReport(&pc);
+ if (!result)
+ return false;
+
+ int positions = pc.NumPositions;
+ data->Clear();
+ data->Resize(positions);
+
+ for (int i = 0; i < positions; i++)
+ {
+ result = GetPositionCalibrationReport(&pc);
+ if (!result)
+ return false;
+ OVR_ASSERT(pc.NumPositions == positions);
+
+ (*data)[pc.PositionIndex] = pc;
+ // IMU should be the last one
+ OVR_ASSERT(pc.PositionType == (pc.PositionIndex == positions - 1) ?
+ PositionCalibrationReport::PositionType_IMU : PositionCalibrationReport::PositionType_LED);
+ }
+ return true;
+}
+
+bool Sensor2DeviceImpl::SetCustomPatternReport(const CustomPatternReport& data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::setCustomPatternReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::setCustomPatternReport(const CustomPatternReport& data)
+{
+ CustomPatternImpl cpi(data);
+ return GetInternalDevice()->SetFeatureReport(cpi.Buffer, CustomPatternImpl::PacketSize);
+}
+
+bool Sensor2DeviceImpl::GetCustomPatternReport(CustomPatternReport* data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::getCustomPatternReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::getCustomPatternReport(CustomPatternReport* data)
+{
+ CustomPatternImpl cpi;
+ if (GetInternalDevice()->GetFeatureReport(cpi.Buffer, CustomPatternImpl::PacketSize))
+ {
+ cpi.Unpack();
+ *data = cpi.Settings;
+ return true;
+ }
+
+ return false;
+}
+
+bool Sensor2DeviceImpl::SetManufacturingReport(const ManufacturingReport& data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::setManufacturingReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::setManufacturingReport(const ManufacturingReport& data)
+{
+ ManufacturingImpl mi(data);
+ return GetInternalDevice()->SetFeatureReport(mi.Buffer, ManufacturingImpl::PacketSize);
+}
+
+bool Sensor2DeviceImpl::GetManufacturingReport(ManufacturingReport* data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::getManufacturingReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::getManufacturingReport(ManufacturingReport* data)
+{
+ ManufacturingImpl mi;
+ if (GetInternalDevice()->GetFeatureReport(mi.Buffer, ManufacturingImpl::PacketSize))
+ {
+ mi.Unpack();
+ *data = mi.Settings;
+ return true;
+ }
+
+ return false;
+}
+
+bool Sensor2DeviceImpl::SetLensDistortionReport(const LensDistortionReport& data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::setLensDistortionReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::setLensDistortionReport(const LensDistortionReport& data)
+{
+ LensDistortionImpl ui(data);
+ return GetInternalDevice()->SetFeatureReport(ui.Buffer, LensDistortionImpl::PacketSize);
+}
+
+bool Sensor2DeviceImpl::GetLensDistortionReport(LensDistortionReport* data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::getLensDistortionReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::getLensDistortionReport(LensDistortionReport* data)
+{
+ LensDistortionImpl ui;
+ if (GetInternalDevice()->GetFeatureReport(ui.Buffer, LensDistortionImpl::PacketSize))
+ {
+ ui.Unpack();
+ *data = ui.Settings;
+ return true;
+ }
+
+ return false;
+}
+
+bool Sensor2DeviceImpl::SetUUIDReport(const UUIDReport& data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::setUUIDReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::setUUIDReport(const UUIDReport& data)
+{
+ UUIDImpl ui(data);
+ return GetInternalDevice()->SetFeatureReport(ui.Buffer, UUIDImpl::PacketSize);
+}
+
+bool Sensor2DeviceImpl::GetUUIDReport(UUIDReport* data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::getUUIDReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::getUUIDReport(UUIDReport* data)
+{
+ UUIDImpl ui;
+ if (GetInternalDevice()->GetFeatureReport(ui.Buffer, UUIDImpl::PacketSize))
+ {
+ ui.Unpack();
+ *data = ui.Settings;
+ return true;
+ }
+
+ return false;
+}
+
+bool Sensor2DeviceImpl::SetKeepAliveMuxReport(const KeepAliveMuxReport& data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::setKeepAliveMuxReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::setKeepAliveMuxReport(const KeepAliveMuxReport& data)
+{
+ KeepAliveMuxImpl kami(data);
+ return GetInternalDevice()->SetFeatureReport(kami.Buffer, KeepAliveMuxImpl::PacketSize);
+}
+
+bool Sensor2DeviceImpl::GetKeepAliveMuxReport(KeepAliveMuxReport* data)
+{
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::getKeepAliveMuxReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::getKeepAliveMuxReport(KeepAliveMuxReport* data)
+{
+ KeepAliveMuxImpl kami;
+ if (GetInternalDevice()->GetFeatureReport(kami.Buffer, KeepAliveMuxImpl::PacketSize))
+ {
+ kami.Unpack();
+ *data = kami.Settings;
+ return true;
+ }
+
+ return false;
+}
+
+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())
+ {
+ return setTemperatureReport(data);
+ }
+
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::setTemperatureReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::setTemperatureReport(const TemperatureReport& data)
+{
+ TemperatureImpl ti(data);
+ return GetInternalDevice()->SetFeatureReport(ti.Buffer, TemperatureImpl::PacketSize);
+}
+
+bool Sensor2DeviceImpl::GetTemperatureReport(TemperatureReport* data)
+{
+ Lock::Locker lock(&IndexedReportLock);
+
+ // direct call if we are already on the device manager thread
+ if (GetCurrentThreadId() == GetManagerImpl()->GetThreadId())
+ {
+ return getTemperatureReport(data);
+ }
+
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::getTemperatureReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::GetAllTemperatureReports(Array<Array<TemperatureReport> >* data)
+{
+ Lock::Locker lock(&IndexedReportLock);
+
+ TemperatureReport t;
+ bool result = GetTemperatureReport(&t);
+ if (!result)
+ return false;
+
+ int bins = t.NumBins, samples = t.NumSamples;
+ data->Clear();
+ data->Resize(bins);
+ for (int i = 0; i < bins; i++)
+ (*data)[i].Resize(samples);
+
+ for (int i = 0; i < bins; i++)
+ for (int j = 0; j < samples; j++)
+ {
+ result = GetTemperatureReport(&t);
+ if (!result)
+ return false;
+ OVR_ASSERT(t.NumBins == bins && t.NumSamples == samples);
+
+ (*data)[t.Bin][t.Sample] = t;
+ }
+ 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
+ if (GetCurrentThreadId() == GetManagerImpl()->GetThreadId())
+ {
+ return getGyroOffsetReport(data);
+ }
+
+ bool result;
+ if (!GetManagerImpl()->GetThreadQueue()->
+ PushCallAndWaitResult(this, &Sensor2DeviceImpl::getGyroOffsetReport, &result, data))
+ {
+ return false;
+ }
+
+ return result;
+}
+
+bool Sensor2DeviceImpl::getGyroOffsetReport(GyroOffsetReport* data)
+{
+ GyroOffsetImpl goi;
+ if (GetInternalDevice()->GetFeatureReport(goi.Buffer, GyroOffsetImpl::PacketSize))
+ {
+ goi.Unpack();
+ *data = goi.Settings;
+ return true;
+ }
+
+ return false;
+}
+
+void Sensor2DeviceImpl::onTrackerMessage(Tracker2Message* message)
+{
+ if (message->Type != Tracker2Message_Sensors)
+ return;
+
+ const float sampleIntervalTimeUnit = (1.0f / 1000.f);
+ double scaledSampleIntervalTimeUnit = sampleIntervalTimeUnit;
+ Tracker2Sensors& s = message->Sensors;
+
+ double absoluteTimeSeconds = 0.0;
+
+ if (SequenceValid)
+ {
+ UInt32 runningSampleCountDelta;
+
+ if (s.RunningSampleCount < LastRunningSampleCount)
+ {
+ // The running sample count on the device rolled around the 16 bit counter
+ // (expect to happen about once per minute), so RunningSampleCount
+ // needs a high word increment.
+ runningSampleCountDelta = ((((int)s.RunningSampleCount) + 0x10000) - (int)LastRunningSampleCount);
+ }
+ else
+ {
+ runningSampleCountDelta = (s.RunningSampleCount - LastRunningSampleCount);
+ }
+
+ absoluteTimeSeconds = LastSensorTime.TimeSeconds;
+ scaledSampleIntervalTimeUnit = TimeFilter.ScaleTimeUnit(sampleIntervalTimeUnit);
+
+ // If we missed a small number of samples, replicate the last sample.
+ if ((runningSampleCountDelta > LastNumSamples) && (runningSampleCountDelta <= 254))
+ {
+ if (HandlerRef.HasHandlers())
+ {
+ MessageBodyFrame sensors(this);
+
+ sensors.AbsoluteTimeSeconds = absoluteTimeSeconds - s.NumSamples * scaledSampleIntervalTimeUnit;
+ sensors.TimeDelta = (float) ((runningSampleCountDelta - LastNumSamples) * scaledSampleIntervalTimeUnit);
+ sensors.Acceleration = LastAcceleration;
+ sensors.RotationRate = LastRotationRate;
+ sensors.MagneticField = LastMagneticField;
+ sensors.Temperature = LastTemperature;
+
+ pCalibration->Apply(sensors);
+ HandlerRef.Call(sensors);
+ }
+ }
+ }
+ else
+ {
+ LastAcceleration = Vector3f(0);
+ LastRotationRate = Vector3f(0);
+ LastMagneticField= Vector3f(0);
+ LastTemperature = 0;
+ SequenceValid = true;
+ }
+
+ LastNumSamples = s.NumSamples;
+ LastRunningSampleCount = s.RunningSampleCount;
+
+ if (HandlerRef.HasHandlers())
+ {
+ MessageBodyFrame sensors(this);
+ UByte iterations = s.NumSamples;
+
+ if (s.NumSamples > 2)
+ {
+ iterations = 2;
+ sensors.TimeDelta = (float) ((s.NumSamples - 1) * scaledSampleIntervalTimeUnit);
+ }
+ else
+ {
+ sensors.TimeDelta = (float) scaledSampleIntervalTimeUnit;
+ }
+
+ for (UByte i = 0; i < iterations; i++)
+ {
+ sensors.AbsoluteTimeSeconds = absoluteTimeSeconds - ( iterations - 1 - i ) * scaledSampleIntervalTimeUnit;
+ sensors.Acceleration = AccelFromBodyFrameUpdate(s, i);
+ sensors.RotationRate = EulerFromBodyFrameUpdate(s, i);
+ sensors.MagneticField= MagFromBodyFrameUpdate(s);
+ sensors.Temperature = s.Temperature * 0.01f;
+
+ pCalibration->Apply(sensors);
+ HandlerRef.Call(sensors);
+
+ // TimeDelta for the last two sample is always fixed.
+ sensors.TimeDelta = (float) scaledSampleIntervalTimeUnit;
+ }
+
+ // Send pixel read only when frame timestamp changes.
+ if (LastFrameTimestamp != s.FrameTimestamp)
+ {
+ MessagePixelRead pixelRead(this);
+ // Prepare message for pixel read
+ pixelRead.PixelReadValue = s.FrameID;
+ pixelRead.RawFrameTime = s.FrameTimestamp;
+ pixelRead.RawSensorTime = s.SampleTimestamp;
+ pixelRead.SensorTimeSeconds = LastSensorTime.TimeSeconds;
+ pixelRead.FrameTimeSeconds = LastFrameTime.TimeSeconds;
+
+ HandlerRef.Call(pixelRead);
+ LastFrameTimestamp = s.FrameTimestamp;
+ }
+
+ UInt16 lowFrameCount = (UInt16) FullCameraFrameCount;
+ // Send message only when frame counter changes
+ if (lowFrameCount != s.CameraFrameCount)
+ {
+ // check for the rollover in the counter
+ if (s.CameraFrameCount < lowFrameCount)
+ FullCameraFrameCount += 0x10000;
+ // update the low bits
+ FullCameraFrameCount = (FullCameraFrameCount & ~0xFFFF) | s.CameraFrameCount;
+
+ MessageExposureFrame vision(this);
+ vision.CameraPattern = s.CameraPattern;
+ vision.CameraFrameCount = FullCameraFrameCount;
+ vision.CameraTimeSeconds = LastCameraTime.TimeSeconds;
+
+ HandlerRef.Call(vision);
+ }
+
+ LastAcceleration = sensors.Acceleration;
+ LastRotationRate = sensors.RotationRate;
+ LastMagneticField= sensors.MagneticField;
+ LastTemperature = sensors.Temperature;
+
+ //LastPixelRead = pixelRead.PixelReadValue;
+ //LastPixelReadTimeStamp = LastFrameTime;
+ }
+ else
+ {
+ if (s.NumSamples != 0)
+ {
+ UByte i = (s.NumSamples > 1) ? 1 : 0;
+ LastAcceleration = AccelFromBodyFrameUpdate(s, i);
+ LastRotationRate = EulerFromBodyFrameUpdate(s, i);
+ LastMagneticField = MagFromBodyFrameUpdate(s);
+ LastTemperature = s.Temperature * 0.01f;
+ }
+ }
+}
+
+// Helper function to handle wrap-around of timestamps from Tracker2Message and convert them
+// to system time.
+// - Any timestamps that didn't increment keep their old system time.
+// - This is a bit tricky since we don't know which one of timestamps has most recent time.
+// - The first timestamp must be the IMU one; we assume that others can't be too much ahead of it
+
+void UpdateDK2Timestamps(SensorTimeFilter& tf,
+ SensorTimestampMapping** timestamps, UInt32 *rawValues, int count)
+{
+ int updateIndices[4];
+ int updateCount = 0;
+ int i;
+ double now = Timer::GetSeconds();
+
+ OVR_ASSERT(count <= sizeof(updateIndices)/sizeof(int));
+
+ // Update timestamp wrapping for any values that changed.
+ for (i = 0; i < count; i++)
+ {
+ UInt32 lowMks = (UInt32)timestamps[i]->TimestampMks; // Low 32-bits are raw old timestamp.
+
+ if (rawValues[i] != lowMks)
+ {
+ if (i == 0)
+ {
+ // Only check for rollover in the IMU timestamp
+ if (rawValues[i] < lowMks)
+ {
+ LogText("Timestamp %d rollover, was: %u, now: %u\n", i, lowMks, rawValues[i]);
+ timestamps[i]->TimestampMks += 0x100000000;
+ }
+ // Update the low bits
+ timestamps[i]->TimestampMks = (timestamps[i]->TimestampMks & 0xFFFFFFFF00000000) | rawValues[i];
+ }
+ else
+ {
+ // Take the high bits from the main timestamp first (not a typo in the first argument!)
+ timestamps[i]->TimestampMks =
+ (timestamps[0]->TimestampMks & 0xFFFFFFFF00000000) | rawValues[i];
+ // Now force it into the reasonable range around the expanded main timestamp
+ if (timestamps[i]->TimestampMks > timestamps[0]->TimestampMks + 0x1000000)
+ timestamps[i]->TimestampMks -= 0x100000000;
+ else if (timestamps[i]->TimestampMks + 0x100000000 < timestamps[0]->TimestampMks + 0x1000000)
+ timestamps[i]->TimestampMks += 0x100000000;
+ }
+
+ updateIndices[updateCount] = i;
+ updateCount++;
+ }
+ }
+
+
+ // TBD: Simplify. Update indices should no longer be needed with new TimeFilter accepting
+ // previous values.
+ // We might want to have multi-element checking time roll-over.
+
+ static const double mksToSec = 1.0 / 1000000.0;
+
+ for (int i = 0; i < updateCount; i++)
+ {
+ SensorTimestampMapping& ts = *timestamps[updateIndices[i]];
+
+ ts.TimeSeconds = tf.SampleToSystemTime(((double)ts.TimestampMks) * mksToSec,
+ now, ts.TimeSeconds, ts.DebugTag);
+ }
+}
+
+
+void Sensor2DeviceImpl::OnInputReport(UByte* pData, UInt32 length)
+{
+ bool processed = false;
+ if (!processed)
+ {
+ Tracker2Message message;
+ if (decodeTracker2Message(&message, pData, length))
+ {
+ processed = true;
+
+ // Process microsecond timestamps from DK2 tracker.
+ // Mapped and raw values must correspond to one another in each array.
+ // IMU timestamp must be the first one!
+ SensorTimestampMapping* tsMaps[3] =
+ {
+ &LastSensorTime,
+ &LastCameraTime,
+ &LastFrameTime
+ };
+ UInt32 tsRawMks[3] =
+ {
+ message.Sensors.SampleTimestamp,
+ message.Sensors.CameraTimestamp,
+ message.Sensors.FrameTimestamp
+ };
+ // Handle wrap-around and convert samples to system time for any samples that changed.
+ UpdateDK2Timestamps(TimeFilter, tsMaps, tsRawMks, sizeof(tsRawMks)/sizeof(tsRawMks[0]));
+
+ onTrackerMessage(&message);
+
+ /*
+ if (SF_LOG_fp)
+ {
+ static UInt32 lastFrameTs = 0;
+ static UInt32 lastCameraTs = 0;
+
+ if ((lastFrameTs != message.Sensors.FrameTimestamp) ||
+ (lastCameraTs = message.Sensors.CameraTimestamp))
+ fprintf(SF_LOG_fp, "msg cameraTs: 0x%X frameTs: 0x%X sensorTs: 0x%X\n",
+ message.Sensors.CameraTimestamp, message.Sensors.FrameTimestamp,
+ message.Sensors.SampleTimestamp);
+
+ lastFrameTs = message.Sensors.FrameTimestamp;
+ lastCameraTs = message.Sensors.CameraTimestamp;
+ }
+ */
+
+#if 0
+ // Checks for DK2 firmware bug.
+ static unsigned SLastSampleTime = 0;
+ if ((SLastSampleTime > message.Sensors.SampleTimestamp) && message.Sensors.SampleTimestamp > 1000000 )
+ {
+ fprintf(SF_LOG_fp, "*** Sample Timestamp Wrap! ***\n");
+ OVR_ASSERT (SLastSampleTime <= message.Sensors.SampleTimestamp);
+ }
+ SLastSampleTime = message.Sensors.SampleTimestamp;
+
+ static unsigned SLastCameraTime = 0;
+ if ((SLastCameraTime > message.Sensors.CameraTimestamp) && message.Sensors.CameraTimestamp > 1000000 )
+ {
+ fprintf(SF_LOG_fp, "*** Camera Timestamp Wrap! ***\n");
+ OVR_ASSERT (SLastCameraTime <= message.Sensors.CameraTimestamp);
+ }
+ SLastCameraTime = message.Sensors.CameraTimestamp;
+
+ static unsigned SLastFrameTime = 0;
+ if ((SLastFrameTime > message.Sensors.FrameTimestamp) && message.Sensors.FrameTimestamp > 1000000 )
+ {
+ fprintf(SF_LOG_fp, "*** Frame Timestamp Wrap! ***\n");
+ OVR_ASSERT (SLastFrameTime <= message.Sensors.FrameTimestamp);
+ }
+ SLastFrameTime = message.Sensors.FrameTimestamp;
+#endif
+ }
+ }
+}
+
+double Sensor2DeviceImpl::OnTicks(double tickSeconds)
+{
+
+ if (tickSeconds >= NextKeepAliveTickSeconds)
+ {
+ // Must send DK2 keep-alive. Set Keep-alive at 10 seconds.
+ KeepAliveMuxReport keepAlive;
+ keepAlive.CommandId = 0;
+ keepAlive.INReport = 11;
+ keepAlive.Interval = 10 * 1000;
+
+ // Device creation is done from background thread so we don't need to add this to the command queue.
+ KeepAliveMuxImpl keepAliveImpl(keepAlive);
+ GetInternalDevice()->SetFeatureReport(keepAliveImpl.Buffer, KeepAliveMuxImpl::PacketSize);
+
+ // Emit keep-alive every few seconds.
+ double keepAliveDelta = 3.0; // Use 3-second interval.
+ NextKeepAliveTickSeconds = tickSeconds + keepAliveDelta;
+ }
+ return NextKeepAliveTickSeconds - tickSeconds;
+}
+
+} // namespace OVR
diff --git a/LibOVR/Src/OVR_Sensor2Impl.h b/LibOVR/Src/OVR_Sensor2Impl.h
new file mode 100644
index 0000000..12da869
--- /dev/null
+++ b/LibOVR/Src/OVR_Sensor2Impl.h
@@ -0,0 +1,157 @@
+/************************************************************************************
+
+Filename : OVR_Sensor2Impl.h
+Content : DK2 sensor device specific implementation.
+Created : January 21, 2013
+Authors : Lee Cooper
+
+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_Sensor2Impl_h
+#define OVR_Sensor2Impl_h
+
+#include "OVR_SensorImpl.h"
+#include "OVR_SensorCalibration.h"
+
+namespace OVR {
+
+struct Tracker2Message;
+
+//-------------------------------------------------------------------------------------
+// Used to convert DK2 Mks timestamps to system TimeSeconds
+struct SensorTimestampMapping
+{
+ UInt64 TimestampMks;
+ double TimeSeconds;
+ const char* DebugTag;
+
+ SensorTimestampMapping(const char* debugTag)
+ : TimestampMks(0), TimeSeconds(0.0), DebugTag(debugTag) { }
+};
+
+//-------------------------------------------------------------------------------------
+// ***** OVR::Sensor2DeviceImpl
+
+// Oculus Sensor2 interface.
+class Sensor2DeviceImpl : public SensorDeviceImpl
+{
+public:
+ Sensor2DeviceImpl(SensorDeviceCreateDesc* createDesc);
+ ~Sensor2DeviceImpl();
+
+ // HIDDevice::Notifier interface.
+ virtual void OnInputReport(UByte* pData, UInt32 length);
+ virtual double OnTicks(double tickSeconds);
+
+ // Get/set feature reports added for DK2. See 'DK2 Firmware Specification' document details.
+ virtual bool SetTrackingReport(const TrackingReport& data);
+ virtual bool GetTrackingReport(TrackingReport* data);
+
+ virtual bool SetDisplayReport(const DisplayReport& data);
+ virtual bool GetDisplayReport(DisplayReport* data);
+
+ virtual bool SetMagCalibrationReport(const MagCalibrationReport& data);
+ 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);
+ virtual bool GetCustomPatternReport(CustomPatternReport* data);
+
+ virtual bool SetKeepAliveMuxReport(const KeepAliveMuxReport& data);
+ virtual bool GetKeepAliveMuxReport(KeepAliveMuxReport* data);
+
+ virtual bool SetManufacturingReport(const ManufacturingReport& data);
+ virtual bool GetManufacturingReport(ManufacturingReport* data);
+
+ virtual bool SetUUIDReport(const UUIDReport& data);
+ 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);
+
+ virtual bool SetLensDistortionReport(const LensDistortionReport& data);
+ virtual bool GetLensDistortionReport(LensDistortionReport* data);
+
+protected:
+ virtual void openDevice();
+
+ bool decodeTracker2Message(Tracker2Message* message, UByte* buffer, int size);
+
+ bool setTrackingReport(const TrackingReport& data);
+ bool getTrackingReport(TrackingReport* data);
+
+ bool setDisplayReport(const DisplayReport& data);
+ bool getDisplayReport(DisplayReport* data);
+
+ bool setMagCalibrationReport(const MagCalibrationReport& data);
+ bool getMagCalibrationReport(MagCalibrationReport* data);
+
+ bool setPositionCalibrationReport(const PositionCalibrationReport& data);
+ bool getPositionCalibrationReport(PositionCalibrationReport* data);
+
+ bool setCustomPatternReport(const CustomPatternReport& data);
+ bool getCustomPatternReport(CustomPatternReport* data);
+
+ bool setKeepAliveMuxReport(const KeepAliveMuxReport& data);
+ bool getKeepAliveMuxReport(KeepAliveMuxReport* data);
+
+ bool setManufacturingReport(const ManufacturingReport& data);
+ bool getManufacturingReport(ManufacturingReport* data);
+
+ bool setUUIDReport(const UUIDReport& data);
+ bool getUUIDReport(UUIDReport* data);
+
+ bool setTemperatureReport(const TemperatureReport& data);
+ bool getTemperatureReport(TemperatureReport* data);
+
+ bool getGyroOffsetReport(GyroOffsetReport* data);
+
+ bool setLensDistortionReport(const LensDistortionReport& data);
+ bool getLensDistortionReport(LensDistortionReport* data);
+
+ // Called for decoded messages
+ void onTrackerMessage(Tracker2Message* message);
+
+ UByte LastNumSamples;
+ UInt16 LastRunningSampleCount;
+ UInt32 FullCameraFrameCount;
+
+ SensorTimestampMapping LastCameraTime;
+ SensorTimestampMapping LastFrameTime;
+ SensorTimestampMapping LastSensorTime;
+ // Record last frame timestamp to know when to send pixelRead messages.
+ UInt32 LastFrameTimestamp;
+
+ SensorCalibration *pCalibration;
+
+ // This lock is used to protect operations with auto-incrementing indices
+ // (see TemperatureReport and PositionCalibrationReport)
+ Lock IndexedReportLock;
+};
+
+} // namespace OVR
+
+#endif // OVR_Sensor2Impl_h
diff --git a/LibOVR/Src/OVR_Sensor2ImplUtil.h b/LibOVR/Src/OVR_Sensor2ImplUtil.h
new file mode 100644
index 0000000..ffe9b6a
--- /dev/null
+++ b/LibOVR/Src/OVR_Sensor2ImplUtil.h
@@ -0,0 +1,676 @@
+/************************************************************************************
+
+Filename : OVR_Sensor2ImplUtil.h
+Content : DK2 sensor device feature report utils.
+Created : January 27, 2014
+Authors : Lee Cooper
+
+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_Sensor2ImplUtil_h
+#define OVR_Sensor2ImplUtil_h
+
+#include "OVR_Device.h"
+#include "OVR_SensorImpl_Common.h"
+#include "Kernel/OVR_Alg.h"
+
+namespace OVR {
+
+using namespace Alg;
+
+// Tracking feature report.
+struct TrackingImpl
+{
+ enum { PacketSize = 13 };
+ UByte Buffer[PacketSize];
+
+ TrackingReport Settings;
+
+ TrackingImpl()
+ {
+ for (int i=0; i<PacketSize; i++)
+ {
+ Buffer[i] = 0;
+ }
+
+ Buffer[0] = 12;
+ }
+
+ TrackingImpl(const TrackingReport& settings)
+ : Settings(settings)
+ {
+ Pack();
+ }
+
+ void Pack()
+ {
+
+ Buffer[0] = 12;
+ EncodeUInt16 ( Buffer+1, Settings.CommandId );
+ Buffer[3] = Settings.Pattern;
+ Buffer[4] = UByte(Settings.Enable << 0 |
+ Settings.Autoincrement << 1 |
+ Settings.UseCarrier << 2 |
+ Settings.SyncInput << 3 |
+ Settings.VsyncLock << 4 |
+ Settings.CustomPattern << 5);
+ Buffer[5] = 0;
+ EncodeUInt16 ( Buffer+6, Settings.ExposureLength );
+ EncodeUInt16 ( Buffer+8, Settings.FrameInterval );
+ EncodeUInt16 ( Buffer+10, Settings.VsyncOffset );
+ Buffer[12] = Settings.DutyCycle;
+ }
+
+ void Unpack()
+ {
+ Settings.CommandId = DecodeUInt16(Buffer+1);
+ Settings.Pattern = Buffer[3];
+ Settings.Enable = (Buffer[4] & 0x01) != 0;
+ Settings.Autoincrement = (Buffer[4] & 0x02) != 0;
+ Settings.UseCarrier = (Buffer[4] & 0x04) != 0;
+ Settings.SyncInput = (Buffer[4] & 0x08) != 0;
+ Settings.VsyncLock = (Buffer[4] & 0x10) != 0;
+ Settings.CustomPattern = (Buffer[4] & 0x20) != 0;
+ Settings.ExposureLength = DecodeUInt16(Buffer+6);
+ Settings.FrameInterval = DecodeUInt16(Buffer+8);
+ Settings.VsyncOffset = DecodeUInt16(Buffer+10);
+ Settings.DutyCycle = Buffer[12];
+ }
+};
+
+// Display feature report.
+struct DisplayImpl
+{
+ enum { PacketSize = 16 };
+ UByte Buffer[PacketSize];
+
+ DisplayReport Settings;
+
+ DisplayImpl()
+ {
+ for (int i=0; i<PacketSize; i++)
+ {
+ Buffer[i] = 0;
+ }
+
+ Buffer[0] = 13;
+ }
+
+ DisplayImpl(const DisplayReport& settings)
+ : Settings(settings)
+ {
+ Pack();
+ }
+
+ void Pack()
+ {
+
+ Buffer[0] = 13;
+ EncodeUInt16 ( Buffer+1, Settings.CommandId );
+ Buffer[3] = Settings.Brightness;
+ Buffer[4] = UByte( (Settings.ShutterType & 0x0F) |
+ (Settings.CurrentLimit & 0x03) << 4 |
+ (Settings.UseRolling ? 0x40 : 0) |
+ (Settings.ReverseRolling ? 0x80 : 0));
+ Buffer[5] = UByte( (Settings.HighBrightness ? 0x01 : 0) |
+ (Settings.SelfRefresh ? 0x02 : 0) |
+ (Settings.ReadPixel ? 0x04 : 0) |
+ (Settings.DirectPentile ? 0x08 : 0));
+ EncodeUInt16 ( Buffer+8, Settings.Persistence );
+ EncodeUInt16 ( Buffer+10, Settings.LightingOffset );
+ EncodeUInt16 ( Buffer+12, Settings.PixelSettle );
+ EncodeUInt16 ( Buffer+14, Settings.TotalRows );
+ }
+
+ void Unpack()
+ {
+
+ Settings.CommandId = DecodeUInt16(Buffer+1);
+ Settings.Brightness = Buffer[3];
+ Settings.ShutterType = DisplayReport::ShutterTypeEnum(Buffer[4] & 0x0F);
+ Settings.CurrentLimit = DisplayReport::CurrentLimitEnum((Buffer[4] >> 4) & 0x02);
+ Settings.UseRolling = (Buffer[4] & 0x40) != 0;
+ Settings.ReverseRolling = (Buffer[4] & 0x80) != 0;
+ Settings.HighBrightness = (Buffer[5] & 0x01) != 0;
+ Settings.SelfRefresh = (Buffer[5] & 0x02) != 0;
+ Settings.ReadPixel = (Buffer[5] & 0x04) != 0;
+ Settings.DirectPentile = (Buffer[5] & 0x08) != 0;
+ Settings.Persistence = DecodeUInt16(Buffer+8);
+ Settings.LightingOffset = DecodeUInt16(Buffer+10);
+ Settings.PixelSettle = DecodeUInt16(Buffer+12);
+ Settings.TotalRows = DecodeUInt16(Buffer+14);
+ }
+};
+
+// MagCalibration feature report.
+struct MagCalibrationImpl
+{
+ enum { PacketSize = 52 };
+ UByte Buffer[PacketSize];
+
+ MagCalibrationReport Settings;
+
+ MagCalibrationImpl()
+ {
+ memset(Buffer, 0, sizeof(Buffer));
+ Buffer[0] = 14;
+ }
+
+ MagCalibrationImpl(const MagCalibrationReport& settings)
+ : Settings(settings)
+ {
+ Pack();
+ }
+
+ void Pack()
+ {
+ Buffer[0] = 14;
+ EncodeUInt16(Buffer+1, Settings.CommandId);
+ Buffer[3] = Settings.Version;
+
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 4; j++)
+ {
+ SInt32 value = SInt32(Settings.Calibration.M[i][j] * 1e4f);
+ EncodeSInt32(Buffer + 4 + 4 * (4 * i + j), value);
+ }
+ }
+
+ void Unpack()
+ {
+ Settings.CommandId = DecodeUInt16(Buffer+1);
+ Settings.Version = Buffer[3];
+
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 4; j++)
+ {
+ SInt32 value = DecodeSInt32(Buffer + 4 + 4 * (4 * i + j));
+ Settings.Calibration.M[i][j] = (float)value * 1e-4f;
+ }
+ }
+};
+
+//-------------------------------------------------------------------------------------
+// PositionCalibration feature report.
+// - Sensor interface versions before 5 do not support Normal and Rotation.
+
+struct PositionCalibrationImpl
+{
+ enum { PacketSize = 30 };
+ UByte Buffer[PacketSize];
+
+ PositionCalibrationReport Settings;
+
+ PositionCalibrationImpl()
+ {
+ for (int i=0; i<PacketSize; i++)
+ {
+ Buffer[i] = 0;
+ }
+
+ Buffer[0] = 15;
+ }
+
+ PositionCalibrationImpl(const PositionCalibrationReport& settings)
+ : Settings(settings)
+ {
+ Pack();
+ }
+
+ void Pack()
+ {
+
+ Buffer[0] = 15;
+ EncodeUInt16(Buffer+1, Settings.CommandId);
+ Buffer[3] = Settings.Version;
+
+ Vector3d position = Settings.Position * 1e6;
+ EncodeSInt32(Buffer+4, (SInt32) position.x);
+ EncodeSInt32(Buffer+8, (SInt32) position.y);
+ EncodeSInt32(Buffer+12, (SInt32) position.z);
+
+ Vector3d normal = Settings.Normal * 1e6;
+ EncodeSInt16(Buffer+16, (SInt16) normal.x);
+ EncodeSInt16(Buffer+18, (SInt16) normal.y);
+ EncodeSInt16(Buffer+20, (SInt16) normal.z);
+
+ double rotation = Settings.Rotation * 1e4;
+ EncodeSInt16(Buffer+22, (SInt16) rotation);
+
+ EncodeUInt16(Buffer+24, Settings.PositionIndex);
+ EncodeUInt16(Buffer+26, Settings.NumPositions);
+ EncodeUInt16(Buffer+28, UInt16(Settings.PositionType));
+ }
+
+ void Unpack()
+ {
+ Settings.CommandId = DecodeUInt16(Buffer+1);
+ Settings.Version = Buffer[3];
+
+ Settings.Position.x = DecodeSInt32(Buffer + 4) * 1e-6;
+ Settings.Position.y = DecodeSInt32(Buffer + 8) * 1e-6;
+ Settings.Position.z = DecodeSInt32(Buffer + 12) * 1e-6;
+
+ Settings.Normal.x = DecodeSInt16(Buffer + 16) * 1e-6;
+ Settings.Normal.y = DecodeSInt16(Buffer + 18) * 1e-6;
+ Settings.Normal.z = DecodeSInt16(Buffer + 20) * 1e-6;
+
+ Settings.Rotation = DecodeSInt16(Buffer + 22) * 1e-4;
+
+ Settings.PositionIndex = DecodeUInt16(Buffer + 24);
+ Settings.NumPositions = DecodeUInt16(Buffer + 26);
+
+ Settings.PositionType = PositionCalibrationReport::PositionTypeEnum(DecodeUInt16(Buffer + 28));
+ }
+};
+
+struct PositionCalibrationImpl_Pre5
+{
+ enum { PacketSize = 22 };
+ UByte Buffer[PacketSize];
+
+ PositionCalibrationReport Settings;
+
+ PositionCalibrationImpl_Pre5()
+ {
+ for (int i=0; i<PacketSize; i++)
+ {
+ Buffer[i] = 0;
+ }
+
+ Buffer[0] = 15;
+ }
+
+ PositionCalibrationImpl_Pre5(const PositionCalibrationReport& settings)
+ : Settings(settings)
+ {
+ Pack();
+ }
+
+ void Pack()
+ {
+
+ Buffer[0] = 15;
+ EncodeUInt16(Buffer+1, Settings.CommandId);
+ Buffer[3] = Settings.Version;
+
+ Vector3d position = Settings.Position * 1e6;
+ EncodeSInt32(Buffer+4 , (SInt32) position.x);
+ EncodeSInt32(Buffer+8 , (SInt32) position.y);
+ EncodeSInt32(Buffer+12, (SInt32) position.z);
+
+ EncodeUInt16(Buffer+16, Settings.PositionIndex);
+ EncodeUInt16(Buffer+18, Settings.NumPositions);
+ EncodeUInt16(Buffer+20, UInt16(Settings.PositionType));
+ }
+
+ void Unpack()
+ {
+
+ Settings.CommandId = DecodeUInt16(Buffer+1);
+ Settings.Version = Buffer[3];
+
+ Settings.Position.x = DecodeSInt32(Buffer + 4) * 1e-6;
+ Settings.Position.y = DecodeSInt32(Buffer + 8) * 1e-6;
+ Settings.Position.z = DecodeSInt32(Buffer + 12) * 1e-6;
+
+ Settings.PositionIndex = DecodeUInt16(Buffer + 16);
+ Settings.NumPositions = DecodeUInt16(Buffer + 18);
+ Settings.PositionType = PositionCalibrationReport::PositionTypeEnum(DecodeUInt16(Buffer + 20));
+ }
+};
+
+// CustomPattern feature report.
+struct CustomPatternImpl
+{
+ enum { PacketSize = 12 };
+ UByte Buffer[PacketSize];
+
+ CustomPatternReport Settings;
+
+ CustomPatternImpl()
+ {
+ for (int i=0; i<PacketSize; i++)
+ {
+ Buffer[i] = 0;
+ }
+
+ Buffer[0] = 16;
+ }
+
+ CustomPatternImpl(const CustomPatternReport& settings)
+ : Settings(settings)
+ {
+ Pack();
+ }
+
+ void Pack()
+ {
+
+ Buffer[0] = 16;
+ EncodeUInt16(Buffer+1, Settings.CommandId);
+ Buffer[3] = Settings.SequenceLength;
+ EncodeUInt32(Buffer+4 , Settings.Sequence);
+ EncodeUInt16(Buffer+8 , Settings.LEDIndex);
+ EncodeUInt16(Buffer+10, Settings.NumLEDs);
+ }
+
+ void Unpack()
+ {
+ Settings.CommandId = DecodeUInt16(Buffer+1);
+ Settings.SequenceLength = Buffer[3];
+ Settings.Sequence = DecodeUInt32(Buffer+4);
+ Settings.LEDIndex = DecodeUInt16(Buffer+8);
+ Settings.NumLEDs = DecodeUInt16(Buffer+10);
+ }
+};
+
+// Manufacturing feature report.
+struct ManufacturingImpl
+{
+ enum { PacketSize = 16 };
+ UByte Buffer[PacketSize];
+
+ ManufacturingReport Settings;
+
+ ManufacturingImpl()
+ {
+ memset(Buffer, 0, sizeof(Buffer));
+ Buffer[0] = 18;
+ }
+
+ ManufacturingImpl(const ManufacturingReport& settings)
+ : Settings(settings)
+ {
+ Pack();
+ }
+
+ void Pack()
+ {
+ Buffer[0] = 18;
+ EncodeUInt16(Buffer+1, Settings.CommandId);
+ Buffer[3] = Settings.NumStages;
+ Buffer[4] = Settings.Stage;
+ Buffer[5] = Settings.StageVersion;
+ EncodeUInt16(Buffer+6, Settings.StageLocation);
+ EncodeUInt32(Buffer+8, Settings.StageTime);
+ EncodeUInt32(Buffer+12, Settings.Result);
+ }
+
+ void Unpack()
+ {
+ Settings.CommandId = DecodeUInt16(Buffer+1);
+ Settings.NumStages = Buffer[3];
+ Settings.Stage = Buffer[4];
+ Settings.StageVersion = Buffer[5];
+ Settings.StageLocation = DecodeUInt16(Buffer+6);
+ Settings.StageTime = DecodeUInt32(Buffer+8);
+ Settings.Result = DecodeUInt32(Buffer+12);
+ }
+};
+
+// UUID feature report.
+struct UUIDImpl
+{
+ enum { PacketSize = 23 };
+ UByte Buffer[PacketSize];
+
+ UUIDReport Settings;
+
+ UUIDImpl()
+ {
+ memset(Buffer, 0, sizeof(Buffer));
+ Buffer[0] = 19;
+ }
+
+ UUIDImpl(const UUIDReport& settings)
+ : Settings(settings)
+ {
+ Pack();
+ }
+
+ void Pack()
+ {
+ Buffer[0] = 19;
+ EncodeUInt16(Buffer+1, Settings.CommandId);
+ for (int i = 0; i < 20; ++i)
+ Buffer[3 + i] = Settings.UUIDValue[i];
+ }
+
+ void Unpack()
+ {
+ Settings.CommandId = DecodeUInt16(Buffer+1);
+ for (int i = 0; i < 20; ++i)
+ Settings.UUIDValue[i] = Buffer[3 + i];
+ }
+};
+
+// LensDistortion feature report.
+struct LensDistortionImpl
+{
+ enum { PacketSize = 64 };
+ UByte Buffer[PacketSize];
+
+ LensDistortionReport Settings;
+
+ LensDistortionImpl()
+ {
+ memset(Buffer, 0, sizeof(Buffer));
+ Buffer[0] = 22;
+ }
+
+ LensDistortionImpl(const LensDistortionReport& settings)
+ : Settings(settings)
+ {
+ Pack();
+ }
+
+ void Pack()
+ {
+ Buffer[0] = 19;
+ EncodeUInt16(Buffer+1, Settings.CommandId);
+
+ Buffer[3] = Settings.NumDistortions;
+ Buffer[4] = Settings.DistortionIndex;
+ Buffer[5] = Settings.Bitmask;
+ EncodeUInt16(Buffer+6, Settings.LensType);
+ EncodeUInt16(Buffer+8, Settings.Version);
+ EncodeUInt16(Buffer+10, Settings.EyeRelief);
+
+ for (int i = 0; i < 11; ++i)
+ EncodeUInt16(Buffer+12+2*i, Settings.KCoefficients[i]);
+
+ EncodeUInt16(Buffer+34, Settings.MaxR);
+ EncodeUInt16(Buffer+36, Settings.MetersPerTanAngleAtCenter);
+
+ for (int i = 0; i < 4; ++i)
+ EncodeUInt16(Buffer+38+2*i, Settings.ChromaticAberration[i]);
+ }
+
+ void Unpack()
+ {
+ Settings.CommandId = DecodeUInt16(Buffer+1);
+
+ Settings.NumDistortions = Buffer[3];
+ Settings.DistortionIndex = Buffer[4];
+ Settings.Bitmask = Buffer[5];
+ Settings.LensType = DecodeUInt16(Buffer+6);
+ Settings.Version = DecodeUInt16(Buffer+8);
+ Settings.EyeRelief = DecodeUInt16(Buffer+10);
+
+ for (int i = 0; i < 11; ++i)
+ Settings.KCoefficients[i] = DecodeUInt16(Buffer+12+2*i);
+
+ Settings.MaxR = DecodeUInt16(Buffer+34);
+ Settings.MetersPerTanAngleAtCenter = DecodeUInt16(Buffer+36);
+
+ for (int i = 0; i < 4; ++i)
+ Settings.ChromaticAberration[i] = DecodeUInt16(Buffer+38+2*i);
+ }
+};
+
+// KeepAliveMux feature report.
+struct KeepAliveMuxImpl
+{
+ enum { PacketSize = 6 };
+ UByte Buffer[PacketSize];
+
+ KeepAliveMuxReport Settings;
+
+ KeepAliveMuxImpl()
+ {
+ memset(Buffer, 0, sizeof(Buffer));
+ Buffer[0] = 17;
+ }
+
+ KeepAliveMuxImpl(const KeepAliveMuxReport& settings)
+ : Settings(settings)
+ {
+ Pack();
+ }
+
+ void Pack()
+ {
+ Buffer[0] = 17;
+ EncodeUInt16(Buffer+1, Settings.CommandId);
+ Buffer[3] = Settings.INReport;
+ EncodeUInt16(Buffer+4, Settings.Interval);
+ }
+
+ void Unpack()
+ {
+ Settings.CommandId = DecodeUInt16(Buffer+1);
+ Settings.INReport = Buffer[3];
+ Settings.Interval = DecodeUInt16(Buffer+4);
+ }
+};
+
+// Temperature feature report.
+struct TemperatureImpl
+{
+ enum { PacketSize = 24 };
+ UByte Buffer[PacketSize];
+
+ TemperatureReport Settings;
+
+ TemperatureImpl()
+ {
+ memset(Buffer, 0, sizeof(Buffer));
+ Buffer[0] = 20;
+ }
+
+ TemperatureImpl(const TemperatureReport& settings)
+ : Settings(settings)
+ {
+ Pack();
+ }
+
+ void Pack()
+ {
+
+ Buffer[0] = 20;
+ EncodeUInt16(Buffer + 1, Settings.CommandId);
+ Buffer[3] = Settings.Version;
+
+ Buffer[4] = Settings.NumBins;
+ Buffer[5] = Settings.Bin;
+ Buffer[6] = Settings.NumSamples;
+ Buffer[7] = Settings.Sample;
+
+ EncodeSInt16(Buffer + 8 , SInt16(Settings.TargetTemperature * 1e2));
+ EncodeSInt16(Buffer + 10, SInt16(Settings.ActualTemperature * 1e2));
+
+ EncodeUInt32(Buffer + 12, Settings.Time);
+
+ Vector3d offset = Settings.Offset * 1e4;
+ PackSensor(Buffer + 16, (SInt16) offset.x, (SInt16) offset.y, (SInt16) offset.z);
+ }
+
+ void Unpack()
+ {
+ Settings.CommandId = DecodeUInt16(Buffer + 1);
+ Settings.Version = Buffer[3];
+
+ Settings.NumBins = Buffer[4];
+ Settings.Bin = Buffer[5];
+ Settings.NumSamples = Buffer[6];
+ Settings.Sample = Buffer[7];
+
+ Settings.TargetTemperature = DecodeSInt16(Buffer + 8) * 1e-2;
+ Settings.ActualTemperature = DecodeSInt16(Buffer + 10) * 1e-2;
+
+ Settings.Time = DecodeUInt32(Buffer + 12);
+
+ SInt32 x, y, z;
+ UnpackSensor(Buffer + 16, &x, &y, &z);
+ Settings.Offset = Vector3d(x, y, z) * 1e-4;
+ }
+};
+
+// GyroOffset feature report.
+struct GyroOffsetImpl
+{
+ enum { PacketSize = 18 };
+ UByte Buffer[PacketSize];
+
+ GyroOffsetReport Settings;
+
+ GyroOffsetImpl()
+ {
+ memset(Buffer, 0, sizeof(Buffer));
+ Buffer[0] = 21;
+ }
+
+ GyroOffsetImpl(const GyroOffsetReport& settings)
+ : Settings(settings)
+ {
+ Pack();
+ }
+
+ void Pack()
+ {
+
+ Buffer[0] = 21;
+ Buffer[1] = UByte(Settings.CommandId & 0xFF);
+ Buffer[2] = UByte(Settings.CommandId >> 8);
+ Buffer[3] = UByte(Settings.Version);
+
+ Vector3d offset = Settings.Offset * 1e4;
+ PackSensor(Buffer + 4, (SInt32) offset.x, (SInt32) offset.y, (SInt32) offset.z);
+
+ EncodeSInt16(Buffer + 16, SInt16(Settings.Temperature * 1e2));
+ }
+
+ void Unpack()
+ {
+ Settings.CommandId = DecodeUInt16(Buffer + 1);
+ Settings.Version = GyroOffsetReport::VersionEnum(Buffer[3]);
+
+ SInt32 x, y, z;
+ UnpackSensor(Buffer + 4, &x, &y, &z);
+ Settings.Offset = Vector3d(x, y, z) * 1e-4f;
+
+ Settings.Temperature = DecodeSInt16(Buffer + 16) * 1e-2;
+ }
+};
+
+} // namespace OVR
+
+#endif // OVR_Sensor2ImplUtil_h
diff --git a/LibOVR/Src/OVR_SensorCalibration.cpp b/LibOVR/Src/OVR_SensorCalibration.cpp
new file mode 100644
index 0000000..665898b
--- /dev/null
+++ b/LibOVR/Src/OVR_SensorCalibration.cpp
@@ -0,0 +1,276 @@
+/************************************************************************************
+
+Filename : OVR_SensorCalibration.cpp
+Content : Calibration data implementation for the IMU messages
+Created : January 28, 2014
+Authors : Max Katsev
+
+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 "OVR_SensorCalibration.h"
+#include "Kernel/OVR_Log.h"
+#include <time.h>
+
+namespace OVR {
+
+using namespace Alg;
+
+const UByte VERSION = 2;
+const UByte MAX_COMPAT_VERSION = 15;
+
+SensorCalibration::SensorCalibration(SensorDevice* pSensor)
+ : MagCalibrated(false), GyroAutoTemperature(0), GyroFilter(6000)
+{
+ this->pSensor = pSensor;
+};
+
+void SensorCalibration::Initialize()
+{
+ // read factory calibration
+ pSensor->GetFactoryCalibration(&AccelOffset, &GyroAutoOffset, &AccelMatrix, &GyroMatrix, &GyroAutoTemperature);
+
+ // if the headset has an autocalibrated offset, prefer it over the factory defaults
+ GyroOffsetReport gyroReport;
+ bool result = pSensor->GetGyroOffsetReport(&gyroReport);
+ if (result && gyroReport.Version != GyroOffsetReport::Version_NoOffset)
+ {
+ GyroAutoOffset = (Vector3f) gyroReport.Offset;
+ GyroAutoTemperature = (float) gyroReport.Temperature;
+ }
+
+ // read the temperature tables and prepare the interpolation structures
+ result = pSensor->GetAllTemperatureReports(&temperatureReports);
+ OVR_ASSERT(result);
+ for (int i = 0; i < 3; i++)
+ Interpolators[i].Initialize(temperatureReports, i);
+
+ // read the mag calibration
+ MagCalibrationReport report;
+ result = pSensor->GetMagCalibrationReport(&report);
+ MagCalibrated = result && report.Version > 0;
+ MagMatrix = report.Calibration;
+ if (!MagCalibrated)
+ {
+ // OVR_ASSERT(false);
+ LogError("Magnetometer calibration not found!\n");
+ }
+}
+
+void SensorCalibration::Apply(MessageBodyFrame& msg)
+{
+ AutocalibrateGyro(msg);
+
+ // compute the interpolated offset
+ Vector3f gyroOffset;
+ for (int i = 0; i < 3; i++)
+ gyroOffset[i] = (float) Interpolators[i].GetOffset(msg.Temperature, GyroAutoTemperature, GyroAutoOffset[i]);
+
+ // apply calibration
+ msg.RotationRate = GyroMatrix.Transform(msg.RotationRate - gyroOffset);
+ 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)
+{
+ const float alpha = 0.4f;
+ // 1.25f is a scaling factor related to conversion from per-axis comparison to length comparison
+ const float absLimit = 1.25f * 0.349066f;
+ const float noiseLimit = 1.25f * 0.03f;
+
+ Vector3f gyro = msg.RotationRate;
+ // do a moving average to reject short term noise
+ Vector3f avg = (GyroFilter.IsEmpty()) ? gyro : gyro * alpha + GyroFilter.PeekBack() * (1 - alpha);
+
+ // Make sure the absolute value is below what is likely motion
+ // Make sure it is close enough to the current average that it is probably noise and not motion
+ if (avg.Length() >= absLimit || (avg - GyroFilter.Mean()).Length() >= noiseLimit)
+ GyroFilter.Clear();
+ GyroFilter.PushBack(avg);
+
+ // if had a reasonable number of samples already use it for the current offset
+ if (GyroFilter.GetSize() > GyroFilter.GetCapacity() / 2)
+ {
+ GyroAutoOffset = GyroFilter.Mean();
+ GyroAutoTemperature = msg.Temperature;
+ // After ~6 seconds of no motion, use the average as the new zero rate offset
+ if (GyroFilter.IsFull())
+ StoreAutoOffset();
+ }
+}
+
+void SensorCalibration::StoreAutoOffset()
+{
+ const double maxDeltaT = 2.5;
+ const double minExtraDeltaT = 0.5;
+ const UInt32 minDelay = 24 * 3600; // 1 day in seconds
+
+ // 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))
+ 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++)
+ {
+ // if the version is newer - do nothing
+ if (temperatureReports[binIdx][i].Version > VERSION)
+ return;
+ if (temperatureReports[binIdx][i].Time > temperatureReports[binIdx][newestIdx].Time)
+ newestIdx = i;
+ if (temperatureReports[binIdx][i].Time < temperatureReports[binIdx][oldestIdx].Time)
+ oldestIdx = i;
+ }
+ 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);
+
+ bool writeSuccess = false;
+ UInt32 now = (UInt32) time(0);
+ if (now - newestReport.Time > minDelay)
+ {
+ // only write a new sample if the temperature is close enough
+ if (Abs(GyroAutoTemperature - oldestReport.TargetTemperature) < maxDeltaT)
+ {
+ oldestReport.Time = now;
+ oldestReport.ActualTemperature = GyroAutoTemperature;
+ oldestReport.Offset = (Vector3d) GyroAutoOffset;
+ oldestReport.Version = VERSION;
+ writeSuccess = pSensor->SetTemperatureReport(oldestReport);
+ OVR_ASSERT(writeSuccess);
+ }
+ }
+ else
+ {
+ // if the newest sample is too recent - _update_ it if significantly closer to the target temp
+ if (Abs(GyroAutoTemperature - newestReport.TargetTemperature) + minExtraDeltaT
+ < Abs(newestReport.ActualTemperature - newestReport.TargetTemperature))
+ {
+ // (do not update the time!)
+ newestReport.ActualTemperature = GyroAutoTemperature;
+ newestReport.Offset = (Vector3d) GyroAutoOffset;
+ newestReport.Version = VERSION;
+ writeSuccess = pSensor->SetTemperatureReport(newestReport);
+ OVR_ASSERT(writeSuccess);
+ }
+ }
+
+ // update the interpolators with the new data
+ // this is not particularly expensive call and would only happen rarely
+ // 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);
+}
+
+void OffsetInterpolator::Initialize(Array<Array<TemperatureReport> > const& temperatureReports, int coord)
+{
+ int bins = (int) temperatureReports.GetSize();
+ Temperatures.Clear();
+ Temperatures.Reserve(bins);
+ Values.Clear();
+ Values.Reserve(bins);
+
+ 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];
+ if (report.Version > 0 && report.Version <= MAX_COMPAT_VERSION)
+ {
+ Temperatures.PushBack(report.ActualTemperature);
+ Values.PushBack(report.Offset[coord]);
+ }
+ }
+}
+
+double OffsetInterpolator::GetOffset(double targetTemperature, double autoTemperature, double autoValue)
+{
+ const double autoRangeExtra = 1.0;
+ const double minInterpolationDist = 0.5;
+
+ // difference between current and autocalibrated temperature adjusted for preference over historical data
+ const double adjustedDeltaT = Abs(autoTemperature - targetTemperature) - autoRangeExtra;
+
+ int count = (int) Temperatures.GetSize();
+ // handle special cases when we don't have enough data for proper interpolation
+ if (count == 0)
+ return autoValue;
+ if (count == 1)
+ {
+ if (adjustedDeltaT < Abs(Temperatures[0] - targetTemperature))
+ return autoValue;
+ else
+ return Values[0];
+ }
+
+ // first, find the interval that contains targetTemperature
+ // if all points are on the same side of targetTemperature, find the adjacent interval
+ int l;
+ if (targetTemperature < Temperatures[1])
+ l = 0;
+ else if (targetTemperature >= Temperatures[count - 2])
+ l = count - 2;
+ else
+ for (l = 1; l < count - 2; l++)
+ if (Temperatures[l] <= targetTemperature && targetTemperature < Temperatures[l+1])
+ break;
+ int u = l + 1;
+
+ // extend the interval if it's too small and the interpolation is unreliable
+ if (Temperatures[u] - Temperatures[l] < minInterpolationDist)
+ {
+ if (l > 0
+ && (u == count - 1 || Temperatures[u] - Temperatures[l - 1] < Temperatures[u + 1] - Temperatures[l]))
+ l--;
+ else if (u < count - 1)
+ u++;
+ }
+
+ // verify correctness
+ OVR_ASSERT(l >= 0 && u < count);
+ OVR_ASSERT(l == 0 || Temperatures[l] <= targetTemperature);
+ OVR_ASSERT(u == count - 1 || targetTemperature < Temperatures[u]);
+ OVR_ASSERT((l == 0 && u == count - 1) || Temperatures[u] - Temperatures[l] > minInterpolationDist);
+ OVR_ASSERT(Temperatures[l] <= Temperatures[u]);
+
+ // perform the interpolation
+ double slope;
+ if (Temperatures[u] - Temperatures[l] >= minInterpolationDist)
+ slope = (Values[u] - Values[l]) / (Temperatures[u] - Temperatures[l]);
+ else
+ // avoid a badly conditioned problem
+ slope = 0;
+ if (adjustedDeltaT < Abs(Temperatures[u] - targetTemperature))
+ // use the autocalibrated value, if it's close
+ return autoValue + slope * (targetTemperature - autoTemperature);
+ else
+ return Values[u] + slope * (targetTemperature - Temperatures[u]);
+}
+
+} // namespace OVR
diff --git a/LibOVR/Src/OVR_SensorCalibration.h b/LibOVR/Src/OVR_SensorCalibration.h
new file mode 100644
index 0000000..2c437b4
--- /dev/null
+++ b/LibOVR/Src/OVR_SensorCalibration.h
@@ -0,0 +1,77 @@
+/************************************************************************************
+
+Filename : OVR_SensorCalibration.h
+Content : Calibration data implementation for the IMU messages
+Created : January 28, 2014
+Authors : Max Katsev
+
+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_SensorCalibration_h
+#define OVR_SensorCalibration_h
+
+#include "OVR_Device.h"
+#include "OVR_SensorFilter.h"
+
+namespace OVR {
+
+class OffsetInterpolator
+{
+public:
+ void Initialize(Array<Array<TemperatureReport> > const& temperatureReports, int coord);
+ double GetOffset(double targetTemperature, double autoTemperature, double autoValue);
+
+ Array<double> Temperatures;
+ Array<double> Values;
+};
+
+class SensorCalibration : public NewOverrideBase
+{
+public:
+ SensorCalibration(SensorDevice* pSensor);
+
+ // Load data from the HW and perform the necessary preprocessing
+ void Initialize();
+ // Apply the calibration
+ void Apply(MessageBodyFrame& msg);
+
+protected:
+ void StoreAutoOffset();
+ void AutocalibrateGyro(MessageBodyFrame const& msg);
+
+ SensorDevice* pSensor;
+
+ // Factory calibration data
+ bool MagCalibrated;
+ Matrix4f AccelMatrix, GyroMatrix, MagMatrix;
+ Vector3f AccelOffset;
+
+ // Temperature based data
+ Array<Array<TemperatureReport> > temperatureReports;
+ OffsetInterpolator Interpolators[3];
+
+ // Autocalibration data
+ SensorFilterf GyroFilter;
+ Vector3f GyroAutoOffset;
+ float GyroAutoTemperature;
+};
+
+} // namespace OVR
+#endif //OVR_SensorCalibration_h
diff --git a/LibOVR/Src/OVR_SensorFilter.cpp b/LibOVR/Src/OVR_SensorFilter.cpp
index 38caa5e..2c660ae 100644
--- a/LibOVR/Src/OVR_SensorFilter.cpp
+++ b/LibOVR/Src/OVR_SensorFilter.cpp
@@ -2,20 +2,20 @@
PublicHeader: OVR.h
Filename : OVR_SensorFilter.cpp
-Content : Basic filtering of sensor data
+Content : Basic filtering of sensor this->Data
Created : March 7, 2013
Authors : Steve LaValle, Anna Yershova, Max Katsev
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -29,95 +29,66 @@ limitations under the License.
namespace OVR {
-Vector3f SensorFilter::Median() const
+template <typename T>
+Vector3<T> SensorFilter<T>::Median() const
{
- int half_window = Count / 2;
- float* sortx = (float*) OVR_ALLOC(Count * sizeof(float));
- float* sorty = (float*) OVR_ALLOC(Count * sizeof(float));
- float* sortz = (float*) OVR_ALLOC(Count * sizeof(float));
- float resultx = 0.0f, resulty = 0.0f, resultz = 0.0f;
+ Vector3<T> result;
+ T* slice = (T*) OVR_ALLOC(this->ElemCount * sizeof(T));
- for (int i = 0; i < Count; i++)
+ for (int coord = 0; coord < 3; coord++)
{
- sortx[i] = Elements[i].x;
- sorty[i] = Elements[i].y;
- sortz[i] = Elements[i].z;
+ for (int i = 0; i < this->ElemCount; i++)
+ slice[i] = this->Data[i][coord];
+ result[coord] = Alg::Median(ArrayAdaptor(slice, this->ElemCount));
}
- for (int j = 0; j <= half_window; j++)
- {
- int minx = j;
- int miny = j;
- int minz = j;
- for (int k = j + 1; k < Count; k++)
- {
- if (sortx[k] < sortx[minx]) minx = k;
- if (sorty[k] < sorty[miny]) miny = k;
- if (sortz[k] < sortz[minz]) minz = k;
- }
- const float tempx = sortx[j];
- const float tempy = sorty[j];
- const float tempz = sortz[j];
- sortx[j] = sortx[minx];
- sortx[minx] = tempx;
-
- sorty[j] = sorty[miny];
- sorty[miny] = tempy;
-
- sortz[j] = sortz[minz];
- sortz[minz] = tempz;
- }
- resultx = sortx[half_window];
- resulty = sorty[half_window];
- resultz = sortz[half_window];
-
- OVR_FREE(sortx);
- OVR_FREE(sorty);
- OVR_FREE(sortz);
- return Vector3f(resultx, resulty, resultz);
+ OVR_FREE(slice);
+ return result;
}
// Only the diagonal of the covariance matrix.
-Vector3f SensorFilter::Variance() const
+template <typename T>
+Vector3<T> SensorFilter<T>::Variance() const
{
- Vector3f mean = Mean();
- Vector3f total = Vector3f(0.0f, 0.0f, 0.0f);
- for (int i = 0; i < Count; i++)
+ Vector3<T> mean = this->Mean();
+ Vector3<T> total;
+ for (int i = 0; i < this->ElemCount; i++)
{
- total.x += (Elements[i].x - mean.x) * (Elements[i].x - mean.x);
- total.y += (Elements[i].y - mean.y) * (Elements[i].y - mean.y);
- total.z += (Elements[i].z - mean.z) * (Elements[i].z - mean.z);
+ total.x += (this->Data[i].x - mean.x) * (this->Data[i].x - mean.x);
+ total.y += (this->Data[i].y - mean.y) * (this->Data[i].y - mean.y);
+ total.z += (this->Data[i].z - mean.z) * (this->Data[i].z - mean.z);
}
- return total / (float) Count;
+ return total / (float) this->ElemCount;
}
-// Should be a 3x3 matrix returned, but OVR_math.h doesn't have one
-Matrix4f SensorFilter::Covariance() const
+template <typename T>
+Matrix3<T> SensorFilter<T>::Covariance() const
{
- Vector3f mean = Mean();
- Matrix4f total = Matrix4f(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
- for (int i = 0; i < Count; i++)
+ Vector3<T> mean = this->Mean();
+ Matrix3<T> total;
+ for (int i = 0; i < this->ElemCount; i++)
{
- total.M[0][0] += (Elements[i].x - mean.x) * (Elements[i].x - mean.x);
- total.M[1][0] += (Elements[i].y - mean.y) * (Elements[i].x - mean.x);
- total.M[2][0] += (Elements[i].z - mean.z) * (Elements[i].x - mean.x);
- total.M[1][1] += (Elements[i].y - mean.y) * (Elements[i].y - mean.y);
- total.M[2][1] += (Elements[i].z - mean.z) * (Elements[i].y - mean.y);
- total.M[2][2] += (Elements[i].z - mean.z) * (Elements[i].z - mean.z);
+ total.M[0][0] += (this->Data[i].x - mean.x) * (this->Data[i].x - mean.x);
+ total.M[1][0] += (this->Data[i].y - mean.y) * (this->Data[i].x - mean.x);
+ total.M[2][0] += (this->Data[i].z - mean.z) * (this->Data[i].x - mean.x);
+ total.M[1][1] += (this->Data[i].y - mean.y) * (this->Data[i].y - mean.y);
+ total.M[2][1] += (this->Data[i].z - mean.z) * (this->Data[i].y - mean.y);
+ total.M[2][2] += (this->Data[i].z - mean.z) * (this->Data[i].z - mean.z);
}
total.M[0][1] = total.M[1][0];
total.M[0][2] = total.M[2][0];
total.M[1][2] = total.M[2][1];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
- total.M[i][j] *= 1.0f / Count;
+ total.M[i][j] /= (float) this->ElemCount;
return total;
}
-Vector3f SensorFilter::PearsonCoefficient() const
+template <typename T>
+Vector3<T> SensorFilter<T>::PearsonCoefficient() const
{
- Matrix4f cov = Covariance();
- Vector3f pearson = Vector3f();
+ Matrix3<T> cov = this->Covariance();
+ Vector3<T> pearson;
pearson.x = cov.M[0][1]/(sqrt(cov.M[0][0])*sqrt(cov.M[1][1]));
pearson.y = cov.M[1][2]/(sqrt(cov.M[1][1])*sqrt(cov.M[2][2]));
pearson.z = cov.M[2][0]/(sqrt(cov.M[2][2])*sqrt(cov.M[0][0]));
diff --git a/LibOVR/Src/OVR_SensorFilter.h b/LibOVR/Src/OVR_SensorFilter.h
index 5f9481a..edd4360 100644
--- a/LibOVR/Src/OVR_SensorFilter.h
+++ b/LibOVR/Src/OVR_SensorFilter.h
@@ -6,16 +6,16 @@ Content : Basic filtering of sensor data
Created : March 7, 2013
Authors : Steve LaValle, Anna Yershova, Max Katsev
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -29,67 +29,11 @@ limitations under the License.
#define OVR_SensorFilter_h
#include "Kernel/OVR_Math.h"
-
+#include "Kernel/OVR_Deque.h"
+#include "Kernel/OVR_Alg.h"
namespace OVR {
-// A simple circular buffer data structure that stores last N elements in an array
-template <typename T>
-class CircularBuffer
-{
-protected:
- enum
- {
- DefaultFilterCapacity = 20
- };
-
- int LastIdx; // The index of the last element that was added to the buffer
- int Capacity; // The buffer size (maximum number of elements)
- int Count; // Number of elements in the filter
- T* Elements;
-
-public:
- CircularBuffer(int capacity = DefaultFilterCapacity)
- : LastIdx(-1), Capacity(capacity), Count(0)
- {
- Elements = (T*)OVR_ALLOC(capacity * sizeof(T));
- for (int i = 0; i < Capacity; i++)
- Elements[i] = T();
- }
-
- ~CircularBuffer() {
- OVR_FREE(Elements);
- }
-
-private:
- // Make the class non-copyable
- CircularBuffer(const CircularBuffer& other);
- CircularBuffer& operator=(const CircularBuffer& other);
-
-public:
- // Add a new element to the filter
- void AddElement (const T &e)
- {
- LastIdx = (LastIdx + 1) % Capacity;
- Elements[LastIdx] = e;
- if (Count < Capacity)
- Count++;
- }
-
- // Get element i. 0 is the most recent, 1 is one step ago, 2 is two steps ago, ...
- T GetPrev(int i = 0) const
- {
- OVR_ASSERT(i >= 0);
- if (i >= Count) // return 0 if the filter doesn't have enough elements
- return T();
- int idx = (LastIdx - i);
- if (idx < 0) // Fix the wraparound case
- idx += Capacity;
- OVR_ASSERT(idx >= 0); // Multiple wraparounds not allowed
- return Elements[idx];
- }
-};
-
// A base class for filters that maintains a buffer of sensor data taken over time and implements
// various simple filters, most of which are linear functions of the data history.
// Maintains the running sum of its elements for better performance on large capacity values
@@ -100,24 +44,59 @@ protected:
T RunningTotal; // Cached sum of the elements
public:
- SensorFilterBase(int capacity = CircularBuffer<T>::DefaultFilterCapacity) : CircularBuffer<T>(capacity), RunningTotal() { };
+ SensorFilterBase(int capacity = CircularBuffer<T>::DefaultCapacity)
+ : CircularBuffer<T>(capacity), RunningTotal()
+ {
+ this->Clear();
+ };
- // Add a new element to the filter
- // Updates the running sum value
- void AddElement (const T &e)
+ // The following methods are augmented to update the cached running sum value
+ void PushBack(const T &e)
{
- int NextIdx = (this->LastIdx + 1) % this->Capacity;
- RunningTotal += (e - this->Elements[NextIdx]);
- CircularBuffer<T>::AddElement(e);
- if (this->LastIdx == 0)
+ CircularBuffer<T>::PushBack(e);
+ RunningTotal += e;
+ if (this->End == 0)
{
// update the cached total to avoid error accumulation
RunningTotal = T();
- for (int i = 0; i < this->Count; i++)
- RunningTotal += this->Elements[i];
+ for (int i = 0; i < this->ElemCount; i++)
+ RunningTotal += this->Data[i];
}
}
+ void PushFront(const T &e)
+ {
+ CircularBuffer<T>::PushFront(e);
+ RunningTotal += e;
+ if (this->Beginning == 0)
+ {
+ // update the cached total to avoid error accumulation
+ RunningTotal = T();
+ for (int i = 0; i < this->ElemCount; i++)
+ RunningTotal += this->Data[i];
+ }
+ }
+
+ T PopBack()
+ {
+ T e = CircularBuffer<T>::PopBack();
+ RunningTotal -= e;
+ return e;
+ }
+
+ T PopFront()
+ {
+ T e = CircularBuffer<T>::PopFront();
+ RunningTotal -= e;
+ return e;
+ }
+
+ void Clear()
+ {
+ CircularBuffer<T>::Clear();
+ RunningTotal = T();
+ }
+
// Simple statistics
T Total() const
{
@@ -126,86 +105,201 @@ public:
T Mean() const
{
- return (this->Count == 0) ? T() : (Total() / (float) this->Count);
+ return this->IsEmpty() ? T() : (Total() / (float) this->ElemCount);
}
+ T MeanN(int n) const
+ {
+ OVR_ASSERT(n > 0);
+ OVR_ASSERT(this->Capacity >= n);
+ T total = T();
+ for (int i = 0; i < n; i++)
+ {
+ total += this->PeekBack(i);
+ }
+ return total / n;
+ }
+
// A popular family of smoothing filters and smoothed derivatives
+
+ T SavitzkyGolaySmooth4()
+ {
+ OVR_ASSERT(this->Capacity >= 4);
+ return this->PeekBack(0)*0.7f +
+ this->PeekBack(1)*0.4f +
+ this->PeekBack(2)*0.1f -
+ this->PeekBack(3)*0.2f;
+ }
+
T SavitzkyGolaySmooth8() const
{
OVR_ASSERT(this->Capacity >= 8);
- return this->GetPrev(0)*0.41667f +
- this->GetPrev(1)*0.33333f +
- this->GetPrev(2)*0.25f +
- this->GetPrev(3)*0.16667f +
- this->GetPrev(4)*0.08333f -
- this->GetPrev(6)*0.08333f -
- this->GetPrev(7)*0.16667f;
+ return this->PeekBack(0)*0.41667f +
+ this->PeekBack(1)*0.33333f +
+ this->PeekBack(2)*0.25f +
+ this->PeekBack(3)*0.16667f +
+ this->PeekBack(4)*0.08333f -
+ this->PeekBack(6)*0.08333f -
+ this->PeekBack(7)*0.16667f;
}
T SavitzkyGolayDerivative4() const
{
OVR_ASSERT(this->Capacity >= 4);
- return this->GetPrev(0)*0.3f +
- this->GetPrev(1)*0.1f -
- this->GetPrev(2)*0.1f -
- this->GetPrev(3)*0.3f;
+ return this->PeekBack(0)*0.3f +
+ this->PeekBack(1)*0.1f -
+ this->PeekBack(2)*0.1f -
+ this->PeekBack(3)*0.3f;
}
T SavitzkyGolayDerivative5() const
{
OVR_ASSERT(this->Capacity >= 5);
- return this->GetPrev(0)*0.2f +
- this->GetPrev(1)*0.1f -
- this->GetPrev(3)*0.1f -
- this->GetPrev(4)*0.2f;
- }
+ return this->PeekBack(0)*0.2f +
+ this->PeekBack(1)*0.1f -
+ this->PeekBack(3)*0.1f -
+ this->PeekBack(4)*0.2f;
+ }
T SavitzkyGolayDerivative12() const
{
OVR_ASSERT(this->Capacity >= 12);
- return this->GetPrev(0)*0.03846f +
- this->GetPrev(1)*0.03147f +
- this->GetPrev(2)*0.02448f +
- this->GetPrev(3)*0.01748f +
- this->GetPrev(4)*0.01049f +
- this->GetPrev(5)*0.0035f -
- this->GetPrev(6)*0.0035f -
- this->GetPrev(7)*0.01049f -
- this->GetPrev(8)*0.01748f -
- this->GetPrev(9)*0.02448f -
- this->GetPrev(10)*0.03147f -
- this->GetPrev(11)*0.03846f;
+ return this->PeekBack(0)*0.03846f +
+ this->PeekBack(1)*0.03147f +
+ this->PeekBack(2)*0.02448f +
+ this->PeekBack(3)*0.01748f +
+ this->PeekBack(4)*0.01049f +
+ this->PeekBack(5)*0.0035f -
+ this->PeekBack(6)*0.0035f -
+ this->PeekBack(7)*0.01049f -
+ this->PeekBack(8)*0.01748f -
+ this->PeekBack(9)*0.02448f -
+ this->PeekBack(10)*0.03147f -
+ this->PeekBack(11)*0.03846f;
}
T SavitzkyGolayDerivativeN(int n) const
{
- OVR_ASSERT(this->Capacity >= n);
+ OVR_ASSERT(this->capacity >= n);
int m = (n-1)/2;
T result = T();
for (int k = 1; k <= m; k++)
{
int ind1 = m - k;
int ind2 = n - m + k - 1;
- result += (this->GetPrev(ind1) - this->GetPrev(ind2)) * (float) k;
+ result += (this->PeekBack(ind1) - this->PeekBack(ind2)) * (float) k;
}
float coef = 3.0f/(m*(m+1.0f)*(2.0f*m+1.0f));
result = result*coef;
return result;
}
+
+ T Median() const
+ {
+ T* copy = (T*) OVR_ALLOC(this->ElemCount * sizeof(T));
+ T result = Alg::Median(ArrayAdaptor(copy));
+ OVR_FREE(copy);
+ return result;
+ }
};
// This class maintains a buffer of sensor data taken over time and implements
// various simple filters, most of which are linear functions of the data history.
-class SensorFilter : public SensorFilterBase<Vector3f>
+template <typename T>
+class SensorFilter : public SensorFilterBase<Vector3<T> >
{
public:
- SensorFilter(int capacity = DefaultFilterCapacity) : SensorFilterBase<Vector3f>(capacity) { };
+ SensorFilter(int capacity = SensorFilterBase<Vector3<T> >::DefaultCapacity) : SensorFilterBase<Vector3<T> >(capacity) { };
// Simple statistics
- Vector3f Median() const;
- Vector3f Variance() const; // The diagonal of covariance matrix
- Matrix4f Covariance() const;
- Vector3f PearsonCoefficient() const;
+ Vector3<T> Median() const;
+ Vector3<T> Variance() const; // The diagonal of covariance matrix
+ Matrix3<T> Covariance() const;
+ Vector3<T> PearsonCoefficient() const;
+};
+
+typedef SensorFilter<float> SensorFilterf;
+typedef SensorFilter<double> SensorFilterd;
+
+// This filter operates on the values that are measured in the body frame and rotate with the device
+class SensorFilterBodyFrame : public SensorFilterBase<Vector3d>
+{
+private:
+ // low pass filter gain
+ double gain;
+ // sum of squared norms of the values
+ double runningTotalLengthSq;
+ // cumulative rotation quaternion
+ Quatd Q;
+ // current low pass filter output
+ Vector3d output;
+
+ // make private so it isn't used by accident
+ // in addition to the normal SensorFilterBase::PushBack, keeps track of running sum of LengthSq
+ // for the purpose of variance computations
+ void PushBack(const Vector3d &e)
+ {
+ runningTotalLengthSq += this->IsFull() ? (e.LengthSq() - this->PeekFront().LengthSq()) : e.LengthSq();
+ SensorFilterBase<Vector3d>::PushBack(e);
+ if (this->End == 0)
+ {
+ // update the cached total to avoid error accumulation
+ runningTotalLengthSq = 0;
+ for (int i = 0; i < this->ElemCount; i++)
+ runningTotalLengthSq += this->Data[i].LengthSq();
+ }
+ }
+
+public:
+ SensorFilterBodyFrame(int capacity = SensorFilterBase<Vector3d>::DefaultCapacity)
+ : SensorFilterBase<Vector3d>(capacity), gain(2.5),
+ output(), Q(), runningTotalLengthSq(0) { };
+
+ // return the scalar variance of the filter values (rotated to be in the same frame)
+ double Variance() const
+ {
+ return this->IsEmpty() ? 0 : (runningTotalLengthSq / this->ElemCount - this->Mean().LengthSq());
+ }
+
+ // return the scalar standard deviation of the filter values (rotated to be in the same frame)
+ double StdDev() const
+ {
+ return sqrt(Variance());
+ }
+
+ // confidence value based on the stddev of the data (between 0.0 and 1.0, more is better)
+ double Confidence() const
+ {
+ return Alg::Clamp(0.48 - 0.1 * log(StdDev()), 0.0, 1.0) * this->ElemCount / this->Capacity;
+ }
+
+ // add a new element to the filter
+ // takes rotation increment since the last update
+ // in order to rotate the previous value to the current body frame
+ void Update(Vector3d value, double deltaT, Quatd deltaQ = Quatd())
+ {
+ if (this->IsEmpty())
+ {
+ output = value;
+ }
+ else
+ {
+ // rotate by deltaQ
+ output = deltaQ.Inverted().Rotate(output);
+ // apply low-pass filter
+ output += (value - output) * gain * deltaT;
+ }
+
+ // put the value into the fixed frame for the stddev computation
+ Q = Q * deltaQ;
+ PushBack(Q.Rotate(output));
+ }
+
+ // returns the filter average in the current body frame
+ Vector3d GetFilteredValue() const
+ {
+ return Q.Inverted().Rotate(this->Mean());
+ }
};
} //namespace OVR
diff --git a/LibOVR/Src/OVR_SensorFusion.cpp b/LibOVR/Src/OVR_SensorFusion.cpp
index eac0366..6cfe00c 100644
--- a/LibOVR/Src/OVR_SensorFusion.cpp
+++ b/LibOVR/Src/OVR_SensorFusion.cpp
@@ -3,18 +3,18 @@
Filename : OVR_SensorFusion.cpp
Content : Methods that determine head orientation from sensor data over time
Created : October 9, 2012
-Authors : Michael Antonov, Steve LaValle, Max Katsev
+Authors : Michael Antonov, Steve LaValle, Dov Katz, Max Katsev
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -29,8 +29,15 @@ limitations under the License.
#include "Kernel/OVR_System.h"
#include "OVR_JSON.h"
#include "OVR_Profile.h"
+#include "OVR_Stereo.h"
+#include "Recording/Recorder.h"
+
+// Temporary for debugging
+bool Global_Flag_1 = true;
+
+//Convenient global variable to temporarily extract this data.
+float TPH_CameraPoseOrientationWxyz[4];
-#define MAX_DEVICE_PROFILE_MAJOR_VERSION 1
namespace OVR {
@@ -38,579 +45,788 @@ namespace OVR {
// ***** Sensor Fusion
SensorFusion::SensorFusion(SensorDevice* sensor)
- : Stage(0), RunningTime(0), DeltaT(0.001f),
- Handler(getThis()), pDelegate(0),
- Gain(0.05f), EnableGravity(true),
- EnablePrediction(true), PredictionDT(0.03f), PredictionTimeIncrement(0.001f),
- FRawMag(10), FAngV(20),
- GyroOffset(), TiltAngleFilter(1000),
- EnableYawCorrection(false), MagCalibrated(false), MagNumReferences(0), MagRefIdx(-1), MagRefScore(0),
- MotionTrackingEnabled(true)
+ : 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)
{
+ pHandler = new BodyFrameHandler(this);
+
+ // And the clock is running...
+ LogText("*** SensorFusion Startup: TimeSeconds = %f\n", Timer::GetSeconds());
+
if (sensor)
AttachToSensor(sensor);
- MagCalibrationMatrix.SetIdentity();
+
+ // MA: 1/25/2014 for DK2
+ SetCenterPupilDepth(0.076f);
+
+ Reset();
}
SensorFusion::~SensorFusion()
-{
+{
+ delete(pHandler);
}
-
bool SensorFusion::AttachToSensor(SensorDevice* sensor)
{
- // clear the cached device information
- CachedSensorInfo.SerialNumber[0] = 0;
- CachedSensorInfo.VendorId = 0;
- CachedSensorInfo.ProductId = 0;
-
if (sensor != NULL)
{
- // Cache the sensor device so we can access this information during
- // mag saving and loading (avoid holding a reference to sensor to prevent
- // deadlock on shutdown)
- sensor->GetDeviceInfo(&CachedSensorInfo); // save the device information
- MessageHandler* pCurrentHandler = sensor->GetMessageHandler();
+ // Load IMU position
+ Array<PositionCalibrationReport> reports;
- if (pCurrentHandler == &Handler)
+ bool result = sensor->GetAllPositionCalibrationReports(&reports);
+ if(result)
{
- Reset();
- return true;
- }
+ PositionCalibrationReport const& imu = reports[reports.GetSize() - 1];
+ OVR_ASSERT(imu.PositionType == PositionCalibrationReport::PositionType_IMU);
+ IMUPosition = imu.Position;
+
+ Recorder::Buffer(imu);
+ Recorder::Buffer(reports);
- if (pCurrentHandler != NULL)
+ // convert from vision to the world frame
+ IMUPosition.x *= -1.0;
+ IMUPosition.z *= -1.0;
+ }
+ else
{
- OVR_DEBUG_LOG(
- ("SensorFusion::AttachToSensor failed - sensor %p already has handler", sensor));
- return false;
+ // TODO: set up IMUPosition for devices that don't have this report.
}
-
- // Automatically load the default mag calibration for this sensor
- LoadMagCalibration();
+ // Repopulate CPFOrigin
+ SetCenterPupilDepth(CenterPupilDepth);
}
- if (Handler.IsHandlerInstalled())
- {
- Handler.RemoveHandlerFromDevices();
- }
+ pHandler->RemoveHandlerFromDevices();
if (sensor != NULL)
{
- sensor->SetMessageHandler(&Handler);
+ 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);
+
return true;
}
-
- // Resets the current orientation
+// Resets the current orientation
void SensorFusion::Reset()
{
- Lock::Locker lockScope(Handler.GetHandlerLock());
- Q = Quatf();
- QUncorrected = Quatf();
- Stage = 0;
- RunningTime = 0;
- MagNumReferences = 0;
- MagRefIdx = -1;
- GyroOffset = Vector3f();
+ 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>();
+ VisionError = PoseState<double>();
+ CurrentExposureIMUDelta = PoseState<double>();
+ CameraPose = Pose<double>(Quatd(), DefaultCameraPosition);
+ CameraPoseConfidence = -1;
+
+ ExposureRecordHistory.Clear();
+ LastMessageExposureFrame = MessageExposureFrame(NULL);
+ LastVisionAbsoluteTime = 0;
+ FullVisionCorrectionExposureCounter = 0;
+ Stage = 0;
+
+ MagNumReferences = 0;
+ MagRefIdx = -1;
+ MagRefScore = 0;
+ MagCorrectionIntegralTerm = Quatd();
+ AccelOffset = Vector3d();
+
+ FAccelCamera.Clear();
+ FAccelHeadset.Clear();
+ FAngV.Clear();
+
+ setNeckPivotFromPose ( State.Transform );
}
-// Compute a rotation required to transform "estimated" into "measured"
-// Returns an approximation of the goal rotation in the Simultaneous Orthogonal Rotations Angle representation
-// (vector direction is the axis of rotation, norm is the angle)
-Vector3f SensorFusion_ComputeCorrection(Vector3f measured, Vector3f estimated)
+//-------------------------------------------------------------------------------------
+// Vision & message processing
+
+void SensorFusion::OnVisionFailure()
{
- measured.Normalize();
- estimated.Normalize();
- Vector3f correction = measured.Cross(estimated);
- float cosError = measured.Dot(estimated);
- // from the def. of cross product, correction.Length() = sin(error)
- // therefore sin(error) * sqrt(2 / (1 + cos(error))) = 2 * sin(error / 2) ~= error in [-pi, pi]
- // Mathf::Tolerance is used to avoid div by 0 if cos(error) = -1
- return correction * sqrt(2 / (1 + cosError + Mathf::Tolerance));
+ // do nothing
}
-void SensorFusion::handleMessage(const MessageBodyFrame& msg)
+void SensorFusion::OnVisionPreviousFrame(const Pose<double>& pose)
{
- if (msg.Type != Message_BodyFrame || !IsMotionTrackingEnabled())
- return;
+ // 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;
+}
- // Put the sensor readings into convenient local variables
- Vector3f gyro = msg.RotationRate;
- Vector3f accel = msg.Acceleration;
- Vector3f mag = msg.MagneticField;
+void SensorFusion::OnVisionSuccess(const Pose<double>& pose, UInt32 exposureCounter)
+{
+ Lock::Locker lockScope(pHandler->GetHandlerLock());
- // Insert current sensor data into filter history
- FRawMag.AddElement(mag);
- FAngV.AddElement(gyro);
+ LastVisionAbsoluteTime = GetTime();
- // Apply the calibration parameters to raw mag
- Vector3f calMag = MagCalibrated ? GetCalibratedMagValue(FRawMag.Mean()) : FRawMag.Mean();
+ // ********* LastVisionExposureRecord *********
- // Set variables accessible through the class API
- DeltaT = msg.TimeDelta;
- AngV = gyro;
- A = accel;
- RawMag = mag;
- CalMag = calMag;
+ // Skip old data and use the record that matches the exposure counter
+ while (!ExposureRecordHistory.IsEmpty() &&
+ (ExposureRecordHistory.PeekFront().ExposureCounter <= exposureCounter))
+ {
+ LastVisionExposureRecord = ExposureRecordHistory.PopFront();
+ }
- // Keep track of time
- Stage++;
- RunningTime += DeltaT;
+ // Use current values if we don't have historical data
+ // 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>());
- // Small preprocessing
- Quatf Qinv = Q.Inverted();
- Vector3f up = Qinv.Rotate(Vector3f(0, 1, 0));
+ // ********* VisionState *********
+
+ // This is stored in the camera frame, so need to be careful when combining with the IMU data,
+ // which is in the world frame
- Vector3f gyroCorrected = gyro;
+ // convert to the world frame
+ Vector3d positionChangeW = CameraPose.Orientation.Rotate(pose.Position - VisionState.Transform.Position);
- // Apply integral term
- // All the corrections are stored in the Simultaneous Orthogonal Rotations Angle representation,
- // which allows to combine and scale them by just addition and multiplication
- if (EnableGravity || EnableYawCorrection)
- gyroCorrected -= GyroOffset;
+ VisionState.TimeInSeconds = LastVisionExposureRecord.ExposureTime;
+ VisionState.Transform = pose;
- if (EnableGravity)
+ // 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)
+ {
+ // 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);
+ }
+ else
{
- const float spikeThreshold = 0.01f;
- const float gravityThreshold = 0.1f;
- float proportionalGain = 5 * Gain; // Gain parameter should be removed in a future release
- float integralGain = 0.0125f;
+ VisionState.LinearVelocity = Vector3d(0,0,0);
+ }
- Vector3f tiltCorrection = SensorFusion_ComputeCorrection(accel, up);
+ // ********* VisionError *********
- if (Stage > 5)
- {
- // Spike detection
- float tiltAngle = up.Angle(accel);
- TiltAngleFilter.AddElement(tiltAngle);
- if (tiltAngle > TiltAngleFilter.Mean() + spikeThreshold)
- proportionalGain = integralGain = 0;
- // Acceleration detection
- const float gravity = 9.8f;
- if (fabs(accel.Length() / gravity - 1) > gravityThreshold)
- integralGain = 0;
- }
- else // Apply full correction at the startup
- {
- proportionalGain = 1 / DeltaT;
- integralGain = 0;
- }
+ // This is in the world frame, so transform the vision data appropriately
- gyroCorrected += (tiltCorrection * proportionalGain);
- GyroOffset -= (tiltCorrection * integralGain * DeltaT);
- }
+ 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();
+}
- if (EnableYawCorrection && MagCalibrated && RunningTime > 2.0f)
+Pose<double> SensorFusion::GetVisionPrediction(UInt32 exposureCounter)
+{
+ Lock::Locker lockScope(pHandler->GetHandlerLock());
+
+ // Combine the small deltas together
+ // 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))
{
- const float maxMagRefDist = 0.1f;
- const float maxTiltError = 0.05f;
- float proportionalGain = 0.01f;
- float integralGain = 0.0005f;
+ record = ExposureRecordHistory.PopFront();
+ delta.AdvanceByDelta(record.Delta);
+ }
+ // Put the combine exposure record back in the history, for use in HandleVisionSuccess(...)
+ record.Delta = delta;
+ ExposureRecordHistory.PushFront(record);
- // Update the reference point if needed
- if (MagRefIdx < 0 || calMag.Distance(MagRefsInBodyFrame[MagRefIdx]) > maxMagRefDist)
- {
- // Delete a bad point
- if (MagRefIdx >= 0 && MagRefScore < 0)
- {
- MagNumReferences--;
- MagRefsInBodyFrame[MagRefIdx] = MagRefsInBodyFrame[MagNumReferences];
- MagRefsInWorldFrame[MagRefIdx] = MagRefsInWorldFrame[MagNumReferences];
- }
- // Find a new one
- MagRefIdx = -1;
- MagRefScore = 1000;
- float bestDist = maxMagRefDist;
- for (int i = 0; i < MagNumReferences; i++)
- {
- float dist = calMag.Distance(MagRefsInBodyFrame[i]);
- if (bestDist > dist)
- {
- bestDist = dist;
- MagRefIdx = i;
- }
- }
- // Create one if needed
- if (MagRefIdx < 0 && MagNumReferences < MagMaxReferences)
- {
- MagRefIdx = MagNumReferences;
- MagRefsInBodyFrame[MagRefIdx] = calMag;
- MagRefsInWorldFrame[MagRefIdx] = Q.Rotate(calMag).Normalized();
- MagNumReferences++;
- }
- }
+ // 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));
- if (MagRefIdx >= 0)
- {
- Vector3f magEstimated = Qinv.Rotate(MagRefsInWorldFrame[MagRefIdx]);
- Vector3f magMeasured = calMag.Normalized();
+ return c;
+}
- // Correction is computed in the horizontal plane (in the world frame)
- Vector3f yawCorrection = SensorFusion_ComputeCorrection(magMeasured.ProjectToPlane(up),
- magEstimated.ProjectToPlane(up));
+void SensorFusion::handleMessage(const MessageBodyFrame& msg)
+{
+ if (msg.Type != Message_BodyFrame || !IsMotionTrackingEnabled())
+ return;
- if (fabs(up.Dot(magEstimated - magMeasured)) < maxTiltError)
- {
- MagRefScore += 2;
- }
- else // If the vertical angle is wrong, decrease the score
- {
- MagRefScore -= 1;
- proportionalGain = integralGain = 0;
- }
- gyroCorrected += (yawCorrection * proportionalGain);
- GyroOffset -= (yawCorrection * integralGain * DeltaT);
- }
- }
+ // Put the sensor readings into convenient local variables
+ Vector3d gyro(msg.RotationRate);
+ Vector3d accel(msg.Acceleration);
+ Vector3d mag(msg.MagneticField);
+ double DeltaT = msg.TimeDelta;
+ MagCalibrated = msg.MagCalibrated;
+
+ // Keep track of time
+ State.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);
+ Stage++;
+
+ // Insert current sensor data into filter history
+ FAngV.PushBack(gyro);
+ FAccelHeadset.Update(accel, DeltaT, Quatd(gyro, gyro.Length() * DeltaT));
- // Update the orientation quaternion based on the corrected angular velocity vector
- float angle = gyroCorrected.Length() * DeltaT;
- if (angle > 0.0f)
- Q = Q * Quatf(gyroCorrected, angle);
+ // 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);
+
+ // Update headset orientation
+ State.StoreAndIntegrateGyro(gyro, DeltaT);
+ // Tilt correction based on accelerometer
+ if (EnableGravity)
+ applyTiltCorrection(DeltaT);
+ // Yaw correction based on camera
+ if (EnableYawCorrection && visionIsRecent)
+ applyVisionYawCorrection(DeltaT);
+ // Yaw correction based on magnetometer
+ if (EnableYawCorrection && MagCalibrated) // MagCalibrated is always false for DK2 for now
+ applyMagYawCorrection(mag, DeltaT);
+
+ // Update camera orientation
+ if (EnableCameraTiltCorrection && visionIsRecent)
+ applyCameraTiltCorrection(accel, DeltaT);
// The quaternion magnitude may slowly drift due to numerical error,
// so it is periodically normalized.
- if (Stage % 500 == 0)
- Q.Normalize();
+ if ((Stage & 0xFF) == 0)
+ {
+ State.Transform.Orientation.Normalize();
+ CameraPose.Orientation.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);
+ // Position correction based on camera
+ applyPositionCorrection(DeltaT);
+ // Compute where the neck pivot would be.
+ setNeckPivotFromPose(State.Transform);
+ }
+ 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);
+
+ // We can't trust velocity past this point.
+ State.LinearVelocity = Vector3d(0,0,0);
+ State.LinearAcceleration = accelW;
+ }
+
+ // Compute the angular acceleration
+ State.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);
+ }
+
+ // Store the lockless state.
+ LocklessState lstate;
+ lstate.StatusFlags = Status_OrientationTracked;
+ if (VisionPositionEnabled)
+ lstate.StatusFlags |= Status_PositionConnected;
+ if (VisionPositionEnabled && visionIsRecent)
+ lstate.StatusFlags |= Status_PositionTracked;
+ lstate.State = State;
+ lstate.Temperature = msg.Temperature;
+ lstate.Magnetometer = mag;
+ UpdatedState.SetState(lstate);
}
-// A predictive filter based on extrapolating the smoothed, current angular velocity
-Quatf SensorFusion::GetPredictedOrientation(float pdt)
-{
- Lock::Locker lockScope(Handler.GetHandlerLock());
- Quatf qP = Q;
-
- if (EnablePrediction)
+void SensorFusion::handleExposure(const MessageExposureFrame& msg)
+{
+ if (msg.CameraFrameCount > LastMessageExposureFrame.CameraFrameCount + 1)
{
- // This method assumes a constant angular velocity
- Vector3f angVelF = FAngV.SavitzkyGolaySmooth8();
- float angVelFL = angVelF.Length();
-
- // Force back to raw measurement
- angVelF = AngV;
- angVelFL = AngV.Length();
-
- // Dynamic prediction interval: Based on angular velocity to reduce vibration
- const float minPdt = 0.001f;
- const float slopePdt = 0.1f;
- float newpdt = pdt;
- float tpdt = minPdt + slopePdt * angVelFL;
- if (tpdt < pdt)
- newpdt = tpdt;
- //LogText("PredictonDTs: %d\n",(int)(newpdt / PredictionTimeIncrement + 0.5f));
-
- if (angVelFL > 0.001f)
+ 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)
{
- Vector3f rotAxisP = angVelF / angVelFL;
- float halfRotAngleP = angVelFL * newpdt * 0.5f;
- float sinaHRAP = sin(halfRotAngleP);
- Quatf deltaQP(rotAxisP.x*sinaHRAP, rotAxisP.y*sinaHRAP,
- rotAxisP.z*sinaHRAP, cos(halfRotAngleP));
- qP = Q * deltaQP;
+ 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++;
}
+
}
- return qP;
-}
+ CurrentExposureIMUDelta.TimeInSeconds = msg.CameraTimeSeconds - LastMessageExposureFrame.CameraTimeSeconds;
+ ExposureRecordHistory.PushBack(ExposureRecord(
+ msg.CameraFrameCount, msg.CameraTimeSeconds, State, CurrentExposureIMUDelta));
-Vector3f SensorFusion::GetCalibratedMagValue(const Vector3f& rawMag) const
+ // Every new exposure starts from zero
+ CurrentExposureIMUDelta = PoseState<double>();
+ LastMessageExposureFrame = msg;
+}
+
+// If you have a known-good pose, this sets the neck pivot position.
+void SensorFusion::setNeckPivotFromPose(Posed const &pose)
{
- OVR_ASSERT(HasMagCalibration());
- return MagCalibrationMatrix.Transform(rawMag);
- }
+ Vector3d imuInNeckPivotFrame = HeadModel - CPFPositionInIMUFrame;
+ NeckPivotPosition = pose.Position - pose.Orientation.Rotate(imuInNeckPivotFrame);
+}
-SensorFusion::BodyFrameHandler::~BodyFrameHandler()
+// These two functions need to be moved into Quat class
+// Compute a rotation required to transform "from" into "to".
+Quatd vectorAlignmentRotation(const Vector3d &from, const Vector3d &to)
{
- RemoveHandlerFromDevices();
+ Vector3d axis = from.Cross(to);
+ if (axis.LengthSq() == 0)
+ // this handles both collinear and zero-length input cases
+ return Quatd();
+ double angle = from.Angle(to);
+ return Quatd(axis, angle);
}
-void SensorFusion::BodyFrameHandler::OnMessage(const Message& msg)
+// Compute the part of the quaternion that rotates around Y axis
+Quatd extractYawRotation(const Quatd &error)
{
- if (msg.Type == Message_BodyFrame)
- pFusion->handleMessage(static_cast<const MessageBodyFrame&>(msg));
- if (pFusion->pDelegate)
- pFusion->pDelegate->OnMessage(msg);
+ if (error.y == 0)
+ return Quatd();
+ double phi = atan2(error.w, error.y);
+ double alpha = Mathd::Pi - 2 * phi;
+ return Quatd(Axis_Y, alpha);
+}
+
+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 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) ||
+ !(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;
+ }
+ 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;
+ }
}
-bool SensorFusion::BodyFrameHandler::SupportsMessageType(MessageType type) const
+void SensorFusion::applyVisionYawCorrection(double deltaT)
{
- return (type == Message_BodyFrame);
+ const double gain = 0.25;
+ const double snapThreshold = 0.1;
+
+ if (LastVisionExposureRecord.ExposureCounter <= FullVisionCorrectionExposureCounter)
+ return;
+
+ Quatd yawError = extractYawRotation(VisionError.Transform.Orientation);
+
+ 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;
}
-// Writes the current calibration for a particular device to a device profile file
-// sensor - the sensor that was calibrated
-// cal_name - an optional name for the calibration or default if cal_name == NULL
-bool SensorFusion::SaveMagCalibration(const char* calibrationName) const
+void SensorFusion::applyMagYawCorrection(Vector3d mag, double deltaT)
{
- if (CachedSensorInfo.SerialNumber[0] == 0 || !HasMagCalibration())
- return false;
-
- // A named calibration may be specified for calibration in different
- // environments, otherwise the default calibration is used
- if (calibrationName == NULL)
- calibrationName = "default";
-
- // Generate a mag calibration event
- JSON* calibration = JSON::CreateObject();
- // (hardcoded for now) the measurement and representation method
- calibration->AddStringItem("Version", "2.0");
- calibration->AddStringItem("Name", "default");
-
- // time stamp the calibration
- char time_str[64];
-
-#ifdef OVR_OS_WIN32
- struct tm caltime;
- localtime_s(&caltime, &MagCalibrationTime);
- strftime(time_str, 64, "%Y-%m-%d %H:%M:%S", &caltime);
-#else
- struct tm* caltime;
- caltime = localtime(&MagCalibrationTime);
- strftime(time_str, 64, "%Y-%m-%d %H:%M:%S", caltime);
-#endif
-
- calibration->AddStringItem("Time", time_str);
-
- // write the full calibration matrix
- char matrix[256];
- Matrix4f calmat = GetMagCalibration();
- calmat.ToString(matrix, 256);
- calibration->AddStringItem("CalibrationMatrix", matrix);
- // save just the offset, for backwards compatibility
- // this can be removed when we don't want to support 0.2.4 anymore
- Vector3f center(calmat.M[0][3], calmat.M[1][3], calmat.M[2][3]);
- Matrix4f tmp = calmat; tmp.M[0][3] = tmp.M[1][3] = tmp.M[2][3] = 0; tmp.M[3][3] = 1;
- center = tmp.Inverted().Transform(center);
- Matrix4f oldcalmat; oldcalmat.M[0][3] = center.x; oldcalmat.M[1][3] = center.y; oldcalmat.M[2][3] = center.z;
- oldcalmat.ToString(matrix, 256);
- calibration->AddStringItem("Calibration", matrix);
-
+ const double minMagLengthSq = Mathd::Tolerance; // need to use a real value to discard very weak fields
+ const double maxMagRefDist = 0.1;
+ const double maxTiltError = 0.05;
+ const double proportionalGain = 0.01;
+ const double integralGain = 0.0005;
+
+ Vector3d magW = State.Transform.Orientation.Rotate(mag);
+ // verify that the horizontal component is sufficient
+ if (magW.x * magW.x + magW.z * magW.z < minMagLengthSq)
+ return;
+ magW.Normalize();
- String path = GetBaseOVRPath(true);
- path += "/Devices.json";
-
- // Look for a prexisting device file to edit
- Ptr<JSON> root = *JSON::Load(path);
- if (root)
- { // Quick sanity check of the file type and format before we parse it
- JSON* version = root->GetFirstItem();
- if (version && version->Name == "Oculus Device Profile Version")
- {
- int major = atoi(version->Value.ToCStr());
- if (major > MAX_DEVICE_PROFILE_MAJOR_VERSION)
+ // Update the reference point if needed
+ if (MagRefScore < 0 || MagRefIdx < 0 ||
+ mag.Distance(MagRefsInBodyFrame[MagRefIdx]) > 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++)
+ {
+ double dist = mag.Distance(MagRefsInBodyFrame[i]);
+ if (bestDist > dist)
{
- // don't use the file on unsupported major version number
- root->Release();
- root = NULL;
+ bestDist = dist;
+ MagRefIdx = i;
}
}
- else
+ // Create one if needed
+ if (MagRefIdx < 0 && MagNumReferences < MagMaxReferences)
{
- root->Release();
- root = NULL;
+ MagRefIdx = MagNumReferences;
+ MagRefsInBodyFrame[MagRefIdx] = mag;
+ MagRefsInWorldFrame[MagRefIdx] = magW;
+ MagRefsPoses[MagRefIdx] = State.Transform.Orientation;
+ MagNumReferences++;
}
}
- JSON* device = NULL;
- if (root)
+ if (MagRefIdx >= 0)
{
- device = root->GetFirstItem(); // skip the header
- device = root->GetNextItem(device);
- while (device)
- { // Search for a previous calibration with the same name for this device
- // and remove it before adding the new one
- if (device->Name == "Device")
- {
- JSON* item = device->GetItemByName("Serial");
- if (item && item->Value == CachedSensorInfo.SerialNumber)
- { // found an entry for this device
- item = device->GetNextItem(item);
- while (item)
- {
- if (item->Name == "MagCalibration")
- {
- JSON* name = item->GetItemByName("Name");
- if (name && name->Value == calibrationName)
- { // found a calibration of the same name
- item->RemoveNode();
- item->Release();
- break;
- }
- }
- item = device->GetNextItem(item);
- }
-
- // update the auto-mag flag
- item = device->GetItemByName("EnableYawCorrection");
- if (item)
- item->dValue = (double)EnableYawCorrection;
- else
- device->AddBoolItem("EnableYawCorrection", EnableYawCorrection);
-
- break;
- }
- }
+ Vector3d magRefW = MagRefsInWorldFrame[MagRefIdx];
- device = root->GetNextItem(device);
+ // If the vertical angle is wrong, decrease the score and do nothing
+ if (Alg::Abs(magRefW.y - magW.y) > maxTiltError)
+ {
+ MagRefScore -= 1;
+ return;
}
+
+ MagRefScore += 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);
+#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;
}
+}
+
+void SensorFusion::applyTiltCorrection(double deltaT)
+{
+ const double gain = 0.25;
+ const double snapThreshold = 0.1;
+ const Vector3d up(0, 1, 0);
+
+ Vector3d accelW = State.Transform.Orientation.Rotate(FAccelHeadset.GetFilteredValue());
+ Quatd error = vectorAlignmentRotation(accelW, up);
+
+ Quatd correction;
+ if (FAccelHeadset.GetSize() == 1 ||
+ ((Alg::Abs(error.w) < cos(snapThreshold / 2) && FAccelHeadset.Confidence() > 0.75)))
+ // full correction for start-up
+ // or large error with high confidence
+ correction = error;
+ else if (FAccelHeadset.Confidence() > 0.5)
+ correction = error.Nlerp(Quatd(), gain * deltaT);
else
- { // Create a new device root
- root = *JSON::CreateObject();
- root->AddStringItem("Oculus Device Profile Version", "1.0");
- }
+ // accelerometer is unreliable due to movement
+ return;
- if (device == NULL)
- {
- device = JSON::CreateObject();
- device->AddStringItem("Product", CachedSensorInfo.ProductName);
- device->AddNumberItem("ProductID", CachedSensorInfo.ProductId);
- device->AddStringItem("Serial", CachedSensorInfo.SerialNumber);
- device->AddBoolItem("EnableYawCorrection", EnableYawCorrection);
+ State.Transform.Orientation = correction * State.Transform.Orientation;
+}
+
+void SensorFusion::applyCameraTiltCorrection(Vector3d accel, double deltaT)
+{
+ const double snapThreshold = 0.02; // in radians
+ 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();
- root->AddItem("Device", device);
+ Quatd headsetToCamera = CameraPose.Orientation.Inverted() * VisionError.Transform.Orientation * State.Transform.Orientation;
+ // 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());
+
+ Quatd error1 = vectorAlignmentRotation(accelCameraW, up);
+ // cancel out yaw rotation
+ Vector3d forwardCamera = (error1 * CameraPose.Orientation).Rotate(forward);
+ forwardCamera.y = 0;
+ Quatd error2 = vectorAlignmentRotation(forwardCamera, forward);
+ // combined error
+ Quatd error = error2 * error1;
+
+ double confidence = FAccelCamera.Confidence();
+ // penalize the confidence if looking away from the camera
+ // TODO: smooth fall-off
+ if (VisionState.Transform.Orientation.Rotate(forward).Angle(forward) > 1)
+ confidence *= 0.5;
+
+ Quatd correction;
+ if (FAccelCamera.GetSize() == 1 ||
+ confidence > CameraPoseConfidence + 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))
+ {
+ // 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())));
}
+ else
+ {
+ // accelerometer is unreliable due to movement
+ return;
+ }
+
+ Quatd newOrientation = correction * CameraPose.Orientation;
+ // 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);
+ // 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;
- // Create and the add the new calibration event to the device
- device->AddItem("MagCalibration", calibration);
+ CameraPose.Orientation = newOrientation;
+ CameraPose.Position = newPosition;
- return root->Save(path);
+ //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;
+
+
+ LogText("adjust camera position %f %f %f\n", newPosition.x, newPosition.y, newPosition.z);
}
-// Loads a saved calibration for the specified device from the device profile file
-// sensor - the sensor that the calibration was saved for
-// cal_name - an optional name for the calibration or the default if cal_name == NULL
-bool SensorFusion::LoadMagCalibration(const char* calibrationName)
+//-------------------------------------------------------------------------------------
+// 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)
{
- if (CachedSensorInfo.SerialNumber[0] == 0)
- return false;
-
- // A named calibration may be specified for calibration in different
- // environments, otherwise the default calibration is used
- if (calibrationName == NULL)
- calibrationName = "default";
-
- String path = GetBaseOVRPath(true);
- path += "/Devices.json";
-
- // Load the device profiles
- Ptr<JSON> root = *JSON::Load(path);
- if (root == NULL)
- return false;
-
- // Quick sanity check of the file type and format before we parse it
- JSON* version = root->GetFirstItem();
- if (version && version->Name == "Oculus Device Profile Version")
- {
- int major = atoi(version->Value.ToCStr());
- if (major > MAX_DEVICE_PROFILE_MAJOR_VERSION)
- return false; // don't parse the file on unsupported major version number
+ float neckEyeHori = OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL;
+ float neckEyeVert = OVR_DEFAULT_NECK_TO_EYE_VERTICAL;
+ if ( profile != NULL )
+ {
+ float neckeye[2];
+ if (profile->GetFloatValues(OVR_KEY_NECK_TO_EYE_DISTANCE, neckeye, 2) == 2)
+ {
+ neckEyeHori = neckeye[0];
+ neckEyeVert = neckeye[1];
+ }
}
- else
+ // 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,
+ // and they will handle the offsets needed from there to each actual eye.
+
+ // HACK HACK HACK
+ // We know for DK1 the screen->lens surface distance is roughly 0.049f, and that the faceplate->lens is 0.02357f.
+ // We're going to assume(!!!!) that all HMDs have the same screen->faceplate distance.
+ // 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 )
{
- return false;
+ // 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 );
+}
- bool autoEnableCorrection = false;
-
- JSON* device = root->GetNextItem(version);
- while (device)
- { // Search for a previous calibration with the same name for this device
- // and remove it before adding the new one
- if (device->Name == "Device")
- {
- JSON* item = device->GetItemByName("Serial");
- if (item && item->Value == CachedSensorInfo.SerialNumber)
- { // found an entry for this device
-
- JSON* autoyaw = device->GetItemByName("EnableYawCorrection");
- if (autoyaw)
- autoEnableCorrection = (autoyaw->dValue != 0);
-
- int maxCalibrationVersion = 0;
- item = device->GetNextItem(item);
- while (item)
- {
- if (item->Name == "MagCalibration")
- {
- JSON* calibration = item;
- JSON* name = calibration->GetItemByName("Name");
- if (name && name->Value == calibrationName)
- { // found a calibration with this name
-
- int major = 0;
- JSON* version = calibration->GetItemByName("Version");
- if (version)
- major = atoi(version->Value.ToCStr());
-
- if (major > maxCalibrationVersion && major <= 2)
- {
- time_t now;
- time(&now);
-
- // parse the calibration time
- time_t calibration_time = now;
- JSON* caltime = calibration->GetItemByName("Time");
- if (caltime)
- {
- const char* caltime_str = caltime->Value.ToCStr();
-
- tm ct;
- memset(&ct, 0, sizeof(tm));
-
-#ifdef OVR_OS_WIN32
- struct tm nowtime;
- localtime_s(&nowtime, &now);
- ct.tm_isdst = nowtime.tm_isdst;
- sscanf_s(caltime_str, "%d-%d-%d %d:%d:%d",
- &ct.tm_year, &ct.tm_mon, &ct.tm_mday,
- &ct.tm_hour, &ct.tm_min, &ct.tm_sec);
-#else
- struct tm* nowtime = localtime(&now);
- ct.tm_isdst = nowtime->tm_isdst;
- sscanf(caltime_str, "%d-%d-%d %d:%d:%d",
- &ct.tm_year, &ct.tm_mon, &ct.tm_mday,
- &ct.tm_hour, &ct.tm_min, &ct.tm_sec);
-#endif
- ct.tm_year -= 1900;
- ct.tm_mon--;
- calibration_time = mktime(&ct);
- }
-
- // parse the calibration matrix
- JSON* cal = calibration->GetItemByName("CalibrationMatrix");
- if (cal == NULL)
- cal = calibration->GetItemByName("Calibration");
-
- if (cal)
- {
- Matrix4f calmat = Matrix4f::FromString(cal->Value.ToCStr());
- SetMagCalibration(calmat);
- MagCalibrationTime = calibration_time;
- EnableYawCorrection = autoEnableCorrection;
-
- maxCalibrationVersion = major;
- }
- }
- }
- }
- item = device->GetNextItem(item);
- }
-
- return (maxCalibrationVersion > 0);
- }
- }
+Vector3f SensorFusion::GetHeadModel() const
+{
+ return (Vector3f)HeadModel;
+}
- device = root->GetNextItem(device);
+void SensorFusion::SetHeadModel(const Vector3f &headModel, bool resetNeckPivot /*= true*/ )
+{
+ Lock::Locker lockScope(pHandler->GetHandlerLock());
+ // The head model should look something like (0, 0.12, -0.12), so
+ // these asserts are to try to prevent sign problems, as
+ // they can be subtle but nauseating!
+ OVR_ASSERT ( headModel.y > 0.0f );
+ OVR_ASSERT ( headModel.z < 0.0f );
+ HeadModel = (Vector3d)headModel;
+ if ( resetNeckPivot )
+ {
+ setNeckPivotFromPose ( State.Transform );
}
+}
+
+float SensorFusion::GetCenterPupilDepth() const
+{
+ return CenterPupilDepth;
+}
+
+
+void SensorFusion::SetCenterPupilDepth(float centerPupilDepth)
+{
+ CenterPupilDepth = centerPupilDepth;
+
+ CPFPositionInIMUFrame = -IMUPosition;
+ CPFPositionInIMUFrame.z += CenterPupilDepth;
+
+ setNeckPivotFromPose ( State.Transform );
+}
+
+//-------------------------------------------------------------------------------------
+
+// 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
+// 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)
+{
+ Pose<double> pose = poseState.Transform;
+ const double linearCoef = 1.0;
+ Vector3d angularVelocity = poseState.AngularVelocity;
+ double angularSpeed = angularVelocity.Length();
+
+ // This could be tuned so that linear and angular are combined with different coefficients
+ double speed = angularSpeed + linearCoef * poseState.LinearVelocity.Length();
+
+ const double slope = 0.2; // The rate at which the dynamic prediction interval varies
+ double candidateDt = slope * speed; // TODO: Replace with smoothstep function
+
+ double dynamicDt = predictionDt;
+
+ // Choose the candidate if it is shorter, to improve stability
+ if (candidateDt < predictionDt)
+ dynamicDt = candidateDt;
+
+ if (angularSpeed > 0.001)
+ pose.Orientation = pose.Orientation * Quatd(angularVelocity, angularSpeed * dynamicDt);
+
+ pose.Position += poseState.LinearVelocity * dynamicDt;
+
+ return pose;
+}
+
+
+Posef SensorFusion::GetPoseAtTime(double absoluteTime) const
+{
+ SensorState ss = GetSensorStateAtTime ( absoluteTime );
+ return ss.Predicted.Transform;
+}
+
+
+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;
+
+ SensorState ss;
+ ss.Recorded = PoseStatef(lstate.State);
+ ss.Temperature = lstate.Temperature;
+ ss.Magnetometer = Vector3f(lstate.Magnetometer);
+ ss.StatusFlags = lstate.StatusFlags;
+
+ // Do prediction logic
+ ss.Predicted = ss.Recorded;
+ ss.Predicted.TimeInSeconds = absoluteTime;
+ ss.Predicted.Transform = Posef(calcPredictedPose(lstate.State, pdt));
- return false;
+ // 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);
+ return ss;
+}
+
+unsigned SensorFusion::GetStatus() const
+{
+ return UpdatedState.GetState().StatusFlags;
}
+//-------------------------------------------------------------------------------------
+void SensorFusion::OnMessage(const MessageBodyFrame& msg)
+{
+ OVR_ASSERT(!IsAttachedToSensor());
+ handleMessage(msg);
+}
-} // namespace OVR
+//-------------------------------------------------------------------------------------
+void SensorFusion::BodyFrameHandler::OnMessage(const Message& msg)
+{
+ Recorder::Buffer(msg);
+ if (msg.Type == Message_BodyFrame)
+ pFusion->handleMessage(static_cast<const MessageBodyFrame&>(msg));
+ if (msg.Type == Message_ExposureFrame)
+ pFusion->handleExposure(static_cast<const MessageExposureFrame&>(msg));
+}
+
+} // namespace OVR
diff --git a/LibOVR/Src/OVR_SensorFusion.h b/LibOVR/Src/OVR_SensorFusion.h
index 6f2ee4c..3d10c3d 100644
--- a/LibOVR/Src/OVR_SensorFusion.h
+++ b/LibOVR/Src/OVR_SensorFusion.h
@@ -4,18 +4,18 @@ 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, Max Katsev
+Authors : Michael Antonov, Steve LaValle, Dov Katz, Max Katsev
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -31,9 +31,146 @@ 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"
+
+// CAPI forward declarations.
+typedef struct ovrPoseStatef_ ovrPoseStatef;
+typedef struct ovrSensorState_ ovrSensorState;
namespace OVR {
+struct HmdRenderInfo;
+
+//-------------------------------------------------------------------------------------
+// ***** Sensor State
+
+// These values are reported as compatible with C API.
+
+
+// PoseState describes the complete pose, or a rigid body configuration, at a
+// point in time, including first and second derivatives. It is used to specify
+// instantaneous location and movement of the headset.
+// SensorState is returned as a part of the sensor state.
+
+template<class T>
+class PoseState
+{
+public:
+ typedef typename CompatibleTypes<Pose<T> >::Type CompatibleType;
+
+ PoseState() : TimeInSeconds(0.0) { }
+ // float <-> double conversion constructor.
+ explicit PoseState(const PoseState<typename Math<T>::OtherFloatType> &src)
+ : Transform(src.Transform),
+ AngularVelocity(src.AngularVelocity), LinearVelocity(src.LinearVelocity),
+ AngularAcceleration(src.AngularAcceleration), LinearAcceleration(src.LinearAcceleration),
+ TimeInSeconds(src.TimeInSeconds)
+ { }
+
+ // C-interop support: PoseStatef <-> ovrPoseStatef
+ PoseState(const typename CompatibleTypes<PoseState<T> >::Type& src)
+ : Transform(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
+ {
+ typename CompatibleTypes<PoseState<T> >::Type result;
+ result.Pose = Transform;
+ result.AngularVelocity = AngularVelocity;
+ result.LinearVelocity = LinearVelocity;
+ result.AngularAcceleration = AngularAcceleration;
+ result.LinearAcceleration = LinearAcceleration;
+ result.TimeInSeconds = TimeInSeconds;
+ return result;
+ }
+
+
+ Pose<T> Transform;
+ Vector3<T> AngularVelocity;
+ Vector3<T> LinearVelocity;
+ Vector3<T> AngularAcceleration;
+ Vector3<T> LinearAcceleration;
+ // Absolute time of this state sample; always a double measured in seconds.
+ double TimeInSeconds;
+
+
+ // ***** Helpers for Pose integration
+
+ // Stores and integrates gyro angular velocity reading for a given time step.
+ void StoreAndIntegrateGyro(Vector3d angVel, double dt);
+ // Stores and integrates position/velocity from accelerometer reading for a given time step.
+ void StoreAndIntegrateAccelerometer(Vector3d linearAccel, double dt);
+
+ // Performs integration of state by adding next state delta to it
+ // to produce a combined state change
+ void AdvanceByDelta(const PoseState<T>& delta);
+};
+
+
+
+// External API returns pose as float, but uses doubles internally for quaternion precision.
+typedef PoseState<float> PoseStatef;
+typedef PoseState<double> PoseStated;
+
+
+//-------------------------------------------------------------------------------------
+// ***** Sensor State
+
+
+// Bit flags describing the current status of sensor tracking.
+enum StatusBits
+{
+ Status_OrientationTracked = 0x0001, // Orientation is currently tracked (connected and in use).
+ Status_PositionTracked = 0x0002, // Position is currently tracked (false if out of range).
+ Status_PositionConnected = 0x0020, // Position tracking HW is conceded.
+ // Status_HMDConnected = 0x0080 // HMD Display is available & connected.
+};
+
+
+// Full state of of the sensor reported by GetSensorState() at a given absolute time.
+class SensorState
+{
+public:
+ SensorState() : Temperature(0), StatusFlags(0) { }
+
+ // C-interop support
+ SensorState(const ovrSensorState& s);
+ operator const ovrSensorState () const;
+
+ // Pose state at the time that SensorState was requested.
+ PoseStatef Predicted;
+ // Actual recorded pose configuration based on sensor sample at a
+ // moment closest to the requested time.
+ PoseStatef Recorded;
+
+ // Calibrated magnetometer reading, in Gauss, at sample time.
+ Vector3f Magnetometer;
+ // Sensor temperature reading, in degrees Celsius, at sample time.
+ float Temperature;
+ // Sensor status described by ovrStatusBits.
+ unsigned int StatusFlags;
+};
+
+
+
+//-------------------------------------------------------------------------------------
+
+class VisionHandler
+{
+public:
+ virtual void OnVisionSuccess(const Pose<double>& pose, UInt32 exposureCounter) = 0;
+ virtual void OnVisionPreviousFrame(const Pose<double>& pose) = 0;
+ virtual void OnVisionFailure() = 0;
+
+ // Get a configuration that represents the change over a short time interval
+ virtual Pose<double> GetVisionPrediction(UInt32 exposureCounter) = 0;
+};
+
//-------------------------------------------------------------------------------------
// ***** SensorFusion
@@ -50,7 +187,7 @@ namespace OVR {
// automatically handle notifications from that device.
-class SensorFusion : public NewOverrideBase
+class SensorFusion : public NewOverrideBase, public VisionHandler
{
enum
{
@@ -58,207 +195,374 @@ class SensorFusion : public NewOverrideBase
};
public:
+
+ // -------------------------------------------------------------------------------
+ // Critical components for tiny API
+
SensorFusion(SensorDevice* sensor = 0);
~SensorFusion();
-
- // *** Setup
-
- // Attaches this SensorFusion to a sensor device, from which it will receive
+ // Attaches this SensorFusion to the IMU sensor device, from which it will receive
// notification messages. If a sensor is attached, manual message notification
// is not necessary. Calling this function also resets SensorFusion state.
- bool AttachToSensor(SensorDevice* sensor);
-
- // Returns true if this Sensor fusion object is attached to a sensor.
- bool IsAttachedToSensor() const { return Handler.IsHandlerInstalled(); }
-
+ bool AttachToSensor(SensorDevice* sensor);
+ // Returns true if this Sensor fusion object is attached to the IMU.
+ bool IsAttachedToSensor() const;
- // *** State Query
+ // 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);
- // Obtain the current accumulated orientation. Many apps will want to use GetPredictedOrientation
- // instead to reduce latency.
- Quatf GetOrientation() const { return lockedGet(&Q); }
+ // Get the predicted pose (orientation, position) of the center pupil frame (CPF) at a specific point in time.
+ Posef GetPoseAtTime(double absoluteTime) const;
- // Get predicted orientaion in the near future; predictDt is lookahead amount in seconds.
- Quatf GetPredictedOrientation(float predictDt);
- Quatf GetPredictedOrientation() { return GetPredictedOrientation(PredictionDT); }
+ // Get the full dynamical system state of the CPF, which includes velocities and accelerations,
+ // predicted at a specified absolute point in time.
+ SensorState GetSensorStateAtTime(double absoluteTime) const;
- // Obtain the last absolute acceleration reading, in m/s^2.
- Vector3f GetAcceleration() const { return lockedGet(&A); }
- // Obtain the last angular velocity reading, in rad/s.
- Vector3f GetAngularVelocity() const { return lockedGet(&AngV); }
-
- // Obtain the last raw magnetometer reading, in Gauss
- Vector3f GetMagnetometer() const { return lockedGet(&RawMag); }
- // Obtain the calibrated magnetometer reading (direction and field strength)
- Vector3f GetCalibratedMagnetometer() const { OVR_ASSERT(MagCalibrated); return lockedGet(&CalMag); }
+ // Get the sensor status (same as GetSensorStateAtTime(...).Status)
+ unsigned int GetStatus() const;
+ // End tiny API components
+ // -------------------------------------------------------------------------------
// Resets the current orientation.
- void Reset();
+ void Reset ();
+ // Configuration
+ void EnableMotionTracking(bool enable = true) { MotionTrackingEnabled = enable; }
+ bool IsMotionTrackingEnabled() const { return MotionTrackingEnabled; }
+
+ // Accelerometer/Gravity Correction Control
+ // Enables/disables gravity correction (on by default).
+ void SetGravityEnabled (bool enableGravity);
+ bool IsGravityEnabled () const;
+ // Vision Position and Orientation Configuration
+ // -----------------------------------------------
+ bool IsVisionPositionEnabled () const;
+ void SetVisionPositionEnabled (bool enableVisionPosition);
+
+ // compensates for a tilted camera
+ void SetCameraTiltCorrectionEnabled(bool enable);
+ bool IsCameraTiltCorrectionEnabled () const;
+
+ // Message Handling Logic
+ // -----------------------------------------------
+ // Notifies SensorFusion object about a new BodyFrame
+ // message from a sensor.
+ // Should be called by user if not attached to sensor.
+ void OnMessage (const MessageBodyFrame& msg);
+
+
+ // 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 OnVisionFailure();
+ // Get a configuration that represents the change over a short time interval
+ virtual Pose<double> GetVisionPrediction(UInt32 exposureCounter);
+
+ double GetTime () const;
+ double GetVisionLatency () const;
+
+
+ // Detailed head dimension control
+ // -----------------------------------------------
+ // These are now deprecated in favour of SetUserHeadDimensions()
+ Vector3f GetHeadModel() const;
+ void SetHeadModel(const Vector3f &headModel, bool resetNeckPivot = true );
+ float GetCenterPupilDepth() const;
+ void SetCenterPupilDepth(float centerPupilDepth);
+
+
+ // Magnetometer and Yaw Drift Section:
+ // ---------------------------------------
+
+ // Enables/disables magnetometer based yaw drift correction.
+ // Must also have mag calibration data for this correction to work.
+ void SetYawCorrectionEnabled(bool enable);
+ // Determines if yaw correction is enabled.
+ bool IsYawCorrectionEnabled () const;
- // *** Configuration
+ // True if mag has calibration values stored
+ bool HasMagCalibration () const;
+ // Clear the reference points associating
+ // mag readings with orientations
+ void ClearMagReferences ();
- void EnableMotionTracking(bool enable = true) { MotionTrackingEnabled = enable; }
- bool IsMotionTrackingEnabled() const { return MotionTrackingEnabled; }
+private:
+
+ // -----------------------------------------------
+
+ class BodyFrameHandler : public NewOverrideBase, public MessageHandler
+ {
+ SensorFusion* pFusion;
+ public:
+ BodyFrameHandler(SensorFusion* fusion)
+ : pFusion(fusion) {}
+ ~BodyFrameHandler();
+ virtual void OnMessage(const Message& msg);
+ virtual bool SupportsMessageType(MessageType type) const;
+ };
- // *** Prediction Control
- // Prediction functions.
- // Prediction delta specifes how much prediction should be applied in seconds; it should in
- // general be under the average rendering latency. Call GetPredictedOrientation() to get
- // predicted orientation.
- float GetPredictionDelta() const { return PredictionDT; }
- void SetPrediction(float dt, bool enable = true) { PredictionDT = dt; EnablePrediction = enable; }
- void SetPredictionEnabled(bool enable = true) { EnablePrediction = enable; }
- bool IsPredictionEnabled() { return EnablePrediction; }
+ // -----------------------------------------------
+ // State version stored in lockless updater "queue" and used for
+ // prediction by GetPoseAtTime/GetSensorStateAtTime
+ struct LocklessState
+ {
+ PoseState<double> State;
+ float Temperature;
+ Vector3d Magnetometer;
+ unsigned int StatusFlags;
- // *** Accelerometer/Gravity Correction Control
+ LocklessState() : Temperature(0.0), StatusFlags(0) { };
+ };
- // Enables/disables gravity correction (on by default).
- void SetGravityEnabled(bool enableGravity) { EnableGravity = enableGravity; }
- bool IsGravityEnabled() const { return EnableGravity;}
- // Gain used to correct gyro with accel. Default value is appropriate for typical use.
- float GetAccelGain() const { return Gain; }
- void SetAccelGain(float ag) { Gain = ag; }
+ // -----------------------------------------------
+ // Entry describing the state of the headset at the time of an exposure as reported by the DK2 board.
+ // This is used in combination with the vision data for
+ // incremental tracking based on IMU change and for drift correction
+ struct ExposureRecord
+ {
+ 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)
+ : ExposureCounter(exposureCounter), ExposureTime(exposureTime),
+ State(state), Delta(stateDelta) { }
+ };
+
+ // -----------------------------------------------
+
+ // The phase of the head as estimated by sensor fusion
+ PoseState<double> State;
+
+ // 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;
+ // Past exposure records between the last update from vision and now
+ // (should only be one record unless vision latency is high)
+ CircularBuffer<ExposureRecord> ExposureRecordHistory;
+ // Timings of the previous exposure, used to populate ExposureRecordHistory
+ 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;
+
+ 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;
+
+ SensorFilterBodyFrame FAccelHeadset, FAccelCamera;
+ 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;
- // *** Magnetometer and Yaw Drift Correction Control
+ bool MotionTrackingEnabled;
+ bool VisionPositionEnabled;
- // Methods to load and save a mag calibration. Calibrations can optionally
- // be specified by name to differentiate multiple calibrations under different conditions
- // If LoadMagCalibration succeeds, it will override YawCorrectionEnabled based on
- // saved calibration setting.
- bool SaveMagCalibration(const char* calibrationName = NULL) const;
- bool LoadMagCalibration(const char* calibrationName = NULL);
+ // Built-in head model for faking
+ // position using orientation only
+ Vector3d HeadModel;
- // Enables/disables magnetometer based yaw drift correction. Must also have mag calibration
- // data for this correction to work.
- void SetYawCorrectionEnabled(bool enable) { EnableYawCorrection = enable; }
- // Determines if yaw correction is enabled.
- bool IsYawCorrectionEnabled() const { return EnableYawCorrection;}
+ //---------------------------------------------
- // Store the calibration matrix for the magnetometer
- void SetMagCalibration(const Matrix4f& m)
- {
- MagCalibrationMatrix = m;
- time(&MagCalibrationTime); // time stamp the calibration
- MagCalibrated = true;
- }
+ // Internal handler for messages
+ // bypasses error checking.
+ 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
+ // for models without camera or when camera isn't available
+ void applyMagYawCorrection(Vector3d mag, double deltaT);
+ // Apply headset tilt correction from the accelerometer
+ void applyTiltCorrection(double deltaT);
+ // Apply headset yaw correction from the camera
+ void applyVisionYawCorrection(double deltaT);
+ // Apply headset position correction from the camera
+ void applyPositionCorrection(double deltaT);
+ // Apply camera tilt correction from the accelerometer
+ void applyCameraTiltCorrection(Vector3d accel, double deltaT);
+
+ // If you have a known-good pose, this sets the neck pivot position.
+ void setNeckPivotFromPose ( Posed const &pose );
+};
- // Retrieves the magnetometer calibration matrix
- Matrix4f GetMagCalibration() const { return MagCalibrationMatrix; }
- // Retrieve the time of the calibration
- time_t GetMagCalibrationTime() const { return MagCalibrationTime; }
- // True only if the mag has calibration values stored
- bool HasMagCalibration() const { return MagCalibrated;}
- // Force the mag into the uncalibrated state
- void ClearMagCalibration() { MagCalibrated = false; }
- // These refer to reference points that associate mag readings with orientations
- void ClearMagReferences() { MagNumReferences = 0; }
+//-------------------------------------------------------------------------------------
+// ***** SensorFusion - Inlines
+inline bool SensorFusion::IsAttachedToSensor() const
+{
+ return pHandler->IsHandlerInstalled();
+}
- Vector3f GetCalibratedMagValue(const Vector3f& rawMag) const;
+inline void SensorFusion::SetGravityEnabled(bool enableGravity)
+{
+ EnableGravity = enableGravity;
+}
+inline bool SensorFusion::IsGravityEnabled() const
+{
+ return EnableGravity;
+}
+inline void SensorFusion::SetYawCorrectionEnabled(bool enable)
+{
+ EnableYawCorrection = enable;
+}
- // *** Message Handler Logic
+inline bool SensorFusion::IsYawCorrectionEnabled() const
+{
+ return EnableYawCorrection;
+}
- // Notifies SensorFusion object about a new BodyFrame message from a sensor.
- // Should be called by user if not attaching to a sensor.
- void OnMessage(const MessageBodyFrame& msg)
- {
- OVR_ASSERT(!IsAttachedToSensor());
- handleMessage(msg);
- }
+inline bool SensorFusion::HasMagCalibration() const
+{
+ return MagCalibrated;
+}
- void SetDelegateMessageHandler(MessageHandler* handler)
- { pDelegate = handler; }
+inline void SensorFusion::ClearMagReferences()
+{
+ MagNumReferences = 0;
+}
+inline bool SensorFusion::IsVisionPositionEnabled() const
+{
+ return VisionPositionEnabled;
+}
+inline void SensorFusion::SetVisionPositionEnabled(bool enableVisionPosition)
+{
+ VisionPositionEnabled = enableVisionPosition;
+}
-private:
+inline void SensorFusion::SetCameraTiltCorrectionEnabled(bool enable)
+{
+ EnableCameraTiltCorrection = enable;
+}
- SensorFusion* getThis() { return this; }
+inline bool SensorFusion::IsCameraTiltCorrectionEnabled() const
+{
+ return EnableCameraTiltCorrection;
+}
- // Helper used to read and return value within a Lock.
- template<class C>
- C lockedGet(const C* p) const
- {
- Lock::Locker lockScope(Handler.GetHandlerLock());
- return *p;
- }
+inline double SensorFusion::GetVisionLatency() const
+{
+ return LastVisionAbsoluteTime - VisionState.TimeInSeconds;
+}
- // Internal handler for messages; bypasses error checking.
- void handleMessage(const MessageBodyFrame& msg);
+inline double SensorFusion::GetTime() const
+{
+ return Timer::GetSeconds();
+}
- // Set the magnetometer's reference orientation for use in yaw correction
- // The supplied mag is an uncalibrated value
- void setMagReference(const Quatf& q, const Vector3f& rawMag);
- // Default to current HMD orientation
- void setMagReference() { setMagReference(Q, RawMag); }
+inline SensorFusion::BodyFrameHandler::~BodyFrameHandler()
+{
+ RemoveHandlerFromDevices();
+}
- class BodyFrameHandler : public MessageHandler
- {
- SensorFusion* pFusion;
- public:
- BodyFrameHandler(SensorFusion* fusion) : pFusion(fusion) { }
- ~BodyFrameHandler();
+inline bool SensorFusion::BodyFrameHandler::SupportsMessageType(MessageType type) const
+{
+ return (type == Message_BodyFrame || type == Message_ExposureFrame);
+}
- virtual void OnMessage(const Message& msg);
- virtual bool SupportsMessageType(MessageType type) const;
- };
- SensorInfo CachedSensorInfo;
-
- Quatf Q;
- Quatf QUncorrected;
- Vector3f A;
- Vector3f AngV;
- Vector3f CalMag;
- Vector3f RawMag;
- unsigned int Stage;
- float RunningTime;
- float DeltaT;
- BodyFrameHandler Handler;
- MessageHandler* pDelegate;
- float Gain;
- volatile bool EnableGravity;
-
- bool EnablePrediction;
- float PredictionDT;
- float PredictionTimeIncrement;
-
- SensorFilter FRawMag;
- SensorFilter FAngV;
-
- Vector3f GyroOffset;
- SensorFilterBase<float> TiltAngleFilter;
-
-
- bool EnableYawCorrection;
- bool MagCalibrated;
- Matrix4f MagCalibrationMatrix;
- time_t MagCalibrationTime;
- int MagNumReferences;
- Vector3f MagRefsInBodyFrame[MagMaxReferences];
- Vector3f MagRefsInWorldFrame[MagMaxReferences];
- int MagRefIdx;
- int MagRefScore;
-
- bool MotionTrackingEnabled;
-};
+//-------------------------------------------------------------------------------------
+// ***** PoseState - Inlines
+// Stores and integrates gyro angular velocity reading for a given time step.
+template<class T>
+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);
+}
+
+template<class T>
+void PoseState<T>::StoreAndIntegrateAccelerometer(Vector3d linearAccel, double dt)
+{
+ LinearAcceleration = linearAccel;
+ Transform.Position += LinearVelocity * dt + LinearAcceleration * (dt * dt * 0.5);
+ LinearVelocity += LinearAcceleration * dt;
+}
+
+// Performs integration of state by adding next state delta to it
+// to produce a combined state change
+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;
+ LinearVelocity += delta.LinearVelocity;
+ TimeInSeconds += delta.TimeInSeconds;
+}
} // namespace OVR
-
#endif
diff --git a/LibOVR/Src/OVR_SensorImpl.cpp b/LibOVR/Src/OVR_SensorImpl.cpp
index 1646ee3..43f3b67 100644
--- a/LibOVR/Src/OVR_SensorImpl.cpp
+++ b/LibOVR/Src/OVR_SensorImpl.cpp
@@ -3,18 +3,18 @@
Filename : OVR_SensorImpl.cpp
Content : Oculus Sensor device implementation.
Created : March 7, 2013
-Authors : Lee Cooper
+Authors : Lee Cooper, Dov Katz
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -25,23 +25,31 @@ limitations under the License.
*************************************************************************************/
#include "OVR_SensorImpl.h"
+#include "OVR_Sensor2Impl.h"
+#include "OVR_SensorImpl_Common.h"
+#include "OVR_JSON.h"
+#include "OVR_Profile.h"
+#include "Kernel/OVR_Alg.h"
+#include <time.h>
// HMDDeviceDesc can be created/updated through Sensor carrying DisplayInfo.
#include "Kernel/OVR_Timer.h"
+//extern FILE *SF_LOG_fp;
+
namespace OVR {
-
+
+using namespace Alg;
+
//-------------------------------------------------------------------------------------
// ***** Oculus Sensor-specific packet data structures
enum {
Sensor_VendorId = Oculus_VendorId,
- Sensor_ProductId = 0x0001,
-
- // ST's VID used originally; should be removed in the future
- Sensor_OldVendorId = 0x0483,
- Sensor_OldProductId = 0x5750,
+ Sensor_Tracker_ProductId = Device_Tracker_ProductId,
+ Sensor_Tracker2_ProductId = Device_Tracker2_ProductId,
+ Sensor_KTracker_ProductId = Device_KTracker_ProductId,
Sensor_BootLoader = 0x1001,
@@ -49,45 +57,6 @@ enum {
Sensor_MaxReportRate = 1000 // Hz
};
-// Reported data is little-endian now
-static UInt16 DecodeUInt16(const UByte* buffer)
-{
- return (UInt16(buffer[1]) << 8) | UInt16(buffer[0]);
-}
-
-static SInt16 DecodeSInt16(const UByte* buffer)
-{
- return (SInt16(buffer[1]) << 8) | SInt16(buffer[0]);
-}
-
-static UInt32 DecodeUInt32(const UByte* buffer)
-{
- return (buffer[0]) | UInt32(buffer[1] << 8) | UInt32(buffer[2] << 16) | UInt32(buffer[3] << 24);
-}
-
-static float DecodeFloat(const UByte* buffer)
-{
- union {
- UInt32 U;
- float F;
- };
-
- U = DecodeUInt32(buffer);
- return F;
-}
-
-
-static void UnpackSensor(const UByte* buffer, SInt32* x, SInt32* y, SInt32* z)
-{
- // Sign extending trick
- // from http://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend
- struct {SInt32 x:21;} s;
-
- *x = s.x = (buffer[0] << 13) | (buffer[1] << 5) | ((buffer[2] & 0xF8) >> 3);
- *y = s.x = ((buffer[2] & 0x07) << 18) | (buffer[3] << 10) | (buffer[4] << 2) |
- ((buffer[5] & 0xC0) >> 6);
- *z = s.x = ((buffer[5] & 0x3F) << 15) | (buffer[6] << 7) | (buffer[7] >> 1);
-}
// Messages we care for
enum TrackerMessageType
@@ -98,12 +67,6 @@ enum TrackerMessageType
TrackerMessage_SizeError = 0x101,
};
-struct TrackerSample
-{
- SInt32 AccelX, AccelY, AccelZ;
- SInt32 GyroX, GyroY, GyroZ;
-};
-
struct TrackerSensors
{
@@ -130,9 +93,9 @@ struct TrackerSensors
// OVR_DEBUG_LOG_TEXT(("TackerSensor::Decode SampleCount=%d\n", SampleCount));
// Only unpack as many samples as there actually are
- UByte iterationCount = (SampleCount > 2) ? 3 : SampleCount;
+ int iterationCount = (SampleCount > 2) ? 3 : SampleCount;
- for (UByte i = 0; i < iterationCount; i++)
+ for (int i = 0; i < iterationCount; i++)
{
UnpackSensor(buffer + 8 + 16 * i, &Samples[i].AccelX, &Samples[i].AccelY, &Samples[i].AccelZ);
UnpackSensor(buffer + 16 + 16 * i, &Samples[i].GyroX, &Samples[i].GyroY, &Samples[i].GyroZ);
@@ -152,210 +115,6 @@ struct TrackerMessage
TrackerSensors Sensors;
};
-bool DecodeTrackerMessage(TrackerMessage* message, UByte* buffer, int size)
-{
- memset(message, 0, sizeof(TrackerMessage));
-
- if (size < 4)
- {
- message->Type = TrackerMessage_SizeError;
- return false;
- }
-
- switch (buffer[0])
- {
- case TrackerMessage_Sensors:
- message->Type = message->Sensors.Decode(buffer, size);
- break;
-
- default:
- message->Type = TrackerMessage_Unknown;
- break;
- }
-
- return (message->Type < TrackerMessage_Unknown) && (message->Type != TrackerMessage_None);
-}
-
-
-// ***** SensorRangeImpl Implementation
-
-// Sensor HW only accepts specific maximum range values, used to maximize
-// the 16-bit sensor outputs. Use these ramps to specify and report appropriate values.
-static const UInt16 AccelRangeRamp[] = { 2, 4, 8, 16 };
-static const UInt16 GyroRangeRamp[] = { 250, 500, 1000, 2000 };
-static const UInt16 MagRangeRamp[] = { 880, 1300, 1900, 2500 };
-
-static UInt16 SelectSensorRampValue(const UInt16* ramp, unsigned count,
- float val, float factor, const char* label)
-{
- UInt16 threshold = (UInt16)(val * factor);
-
- for (unsigned i = 0; i<count; i++)
- {
- if (ramp[i] >= threshold)
- return ramp[i];
- }
- OVR_DEBUG_LOG(("SensorDevice::SetRange - %s clamped to %0.4f",
- label, float(ramp[count-1]) / factor));
- OVR_UNUSED2(factor, label);
- return ramp[count-1];
-}
-
-// SensorScaleImpl provides buffer packing logic for the Sensor Range
-// record that can be applied to DK1 sensor through Get/SetFeature. We expose this
-// through SensorRange class, which has different units.
-struct SensorRangeImpl
-{
- enum { PacketSize = 8 };
- UByte Buffer[PacketSize];
-
- UInt16 CommandId;
- UInt16 AccelScale;
- UInt16 GyroScale;
- UInt16 MagScale;
-
- SensorRangeImpl(const SensorRange& r, UInt16 commandId = 0)
- {
- SetSensorRange(r, commandId);
- }
-
- void SetSensorRange(const SensorRange& r, UInt16 commandId = 0)
- {
- CommandId = commandId;
- AccelScale = SelectSensorRampValue(AccelRangeRamp, sizeof(AccelRangeRamp)/sizeof(AccelRangeRamp[0]),
- r.MaxAcceleration, (1.0f / 9.81f), "MaxAcceleration");
- GyroScale = SelectSensorRampValue(GyroRangeRamp, sizeof(GyroRangeRamp)/sizeof(GyroRangeRamp[0]),
- r.MaxRotationRate, Math<float>::RadToDegreeFactor, "MaxRotationRate");
- MagScale = SelectSensorRampValue(MagRangeRamp, sizeof(MagRangeRamp)/sizeof(MagRangeRamp[0]),
- r.MaxMagneticField, 1000.0f, "MaxMagneticField");
- Pack();
- }
-
- void GetSensorRange(SensorRange* r)
- {
- r->MaxAcceleration = AccelScale * 9.81f;
- r->MaxRotationRate = DegreeToRad((float)GyroScale);
- r->MaxMagneticField= MagScale * 0.001f;
- }
-
- static SensorRange GetMaxSensorRange()
- {
- return SensorRange(AccelRangeRamp[sizeof(AccelRangeRamp)/sizeof(AccelRangeRamp[0]) - 1] * 9.81f,
- GyroRangeRamp[sizeof(GyroRangeRamp)/sizeof(GyroRangeRamp[0]) - 1] *
- Math<float>::DegreeToRadFactor,
- MagRangeRamp[sizeof(MagRangeRamp)/sizeof(MagRangeRamp[0]) - 1] * 0.001f);
- }
-
- void Pack()
- {
- Buffer[0] = 4;
- Buffer[1] = UByte(CommandId & 0xFF);
- Buffer[2] = UByte(CommandId >> 8);
- Buffer[3] = UByte(AccelScale);
- Buffer[4] = UByte(GyroScale & 0xFF);
- Buffer[5] = UByte(GyroScale >> 8);
- Buffer[6] = UByte(MagScale & 0xFF);
- Buffer[7] = UByte(MagScale >> 8);
- }
-
- void Unpack()
- {
- CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8);
- AccelScale= Buffer[3];
- GyroScale = Buffer[4] | (UInt16(Buffer[5]) << 8);
- MagScale = Buffer[6] | (UInt16(Buffer[7]) << 8);
- }
-};
-
-
-// Sensor configuration command, ReportId == 2.
-
-struct SensorConfigImpl
-{
- enum { PacketSize = 7 };
- UByte Buffer[PacketSize];
-
- // Flag values for Flags.
- enum {
- Flag_RawMode = 0x01,
- Flag_CallibrationTest = 0x02, // Internal test mode
- Flag_UseCallibration = 0x04,
- Flag_AutoCallibration = 0x08,
- Flag_MotionKeepAlive = 0x10,
- Flag_CommandKeepAlive = 0x20,
- Flag_SensorCoordinates = 0x40
- };
-
- UInt16 CommandId;
- UByte Flags;
- UInt16 PacketInterval;
- UInt16 KeepAliveIntervalMs;
-
- SensorConfigImpl() : CommandId(0), Flags(0), PacketInterval(0), KeepAliveIntervalMs(0)
- {
- memset(Buffer, 0, PacketSize);
- Buffer[0] = 2;
- }
-
- void SetSensorCoordinates(bool sensorCoordinates)
- { Flags = (Flags & ~Flag_SensorCoordinates) | (sensorCoordinates ? Flag_SensorCoordinates : 0); }
- bool IsUsingSensorCoordinates() const
- { return (Flags & Flag_SensorCoordinates) != 0; }
-
- void Pack()
- {
- Buffer[0] = 2;
- Buffer[1] = UByte(CommandId & 0xFF);
- Buffer[2] = UByte(CommandId >> 8);
- Buffer[3] = Flags;
- Buffer[4] = UByte(PacketInterval);
- Buffer[5] = UByte(KeepAliveIntervalMs & 0xFF);
- Buffer[6] = UByte(KeepAliveIntervalMs >> 8);
- }
-
- void Unpack()
- {
- CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8);
- Flags = Buffer[3];
- PacketInterval = Buffer[4];
- KeepAliveIntervalMs= Buffer[5] | (UInt16(Buffer[6]) << 8);
- }
-
-};
-
-
-// SensorKeepAlive - feature report that needs to be sent at regular intervals for sensor
-// to receive commands.
-struct SensorKeepAliveImpl
-{
- enum { PacketSize = 5 };
- UByte Buffer[PacketSize];
-
- UInt16 CommandId;
- UInt16 KeepAliveIntervalMs;
-
- SensorKeepAliveImpl(UInt16 interval = 0, UInt16 commandId = 0)
- : CommandId(commandId), KeepAliveIntervalMs(interval)
- {
- Pack();
- }
-
- void Pack()
- {
- Buffer[0] = 8;
- Buffer[1] = UByte(CommandId & 0xFF);
- Buffer[2] = UByte(CommandId >> 8);
- Buffer[3] = UByte(KeepAliveIntervalMs & 0xFF);
- Buffer[4] = UByte(KeepAliveIntervalMs >> 8);
- }
-
- void Unpack()
- {
- CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8);
- KeepAliveIntervalMs= Buffer[3] | (UInt16(Buffer[4]) << 8);
- }
-};
-
//-------------------------------------------------------------------------------------
// ***** SensorDisplayInfoImpl
@@ -368,22 +127,39 @@ SensorDisplayInfoImpl::SensorDisplayInfoImpl()
void SensorDisplayInfoImpl::Unpack()
{
- CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8);
- DistortionType = Buffer[3];
- HResolution = DecodeUInt16(Buffer+4);
- VResolution = DecodeUInt16(Buffer+6);
- HScreenSize = DecodeUInt32(Buffer+8) * (1/1000000.f);
- VScreenSize = DecodeUInt32(Buffer+12) * (1/1000000.f);
- VCenter = DecodeUInt32(Buffer+16) * (1/1000000.f);
- LensSeparation = DecodeUInt32(Buffer+20) * (1/1000000.f);
- EyeToScreenDistance[0] = DecodeUInt32(Buffer+24) * (1/1000000.f);
- EyeToScreenDistance[1] = DecodeUInt32(Buffer+28) * (1/1000000.f);
- DistortionK[0] = DecodeFloat(Buffer+32);
- DistortionK[1] = DecodeFloat(Buffer+36);
- DistortionK[2] = DecodeFloat(Buffer+40);
- DistortionK[3] = DecodeFloat(Buffer+44);
- DistortionK[4] = DecodeFloat(Buffer+48);
- DistortionK[5] = DecodeFloat(Buffer+52);
+ CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8);
+ DistortionType = Buffer[3];
+ HResolution = DecodeUInt16(Buffer+4);
+ VResolution = DecodeUInt16(Buffer+6);
+ HScreenSize = DecodeUInt32(Buffer+8) * (1/1000000.f);
+ VScreenSize = DecodeUInt32(Buffer+12) * (1/1000000.f);
+ VCenter = DecodeUInt32(Buffer+16) * (1/1000000.f);
+ LensSeparation = DecodeUInt32(Buffer+20) * (1/1000000.f);
+
+#if 0
+ // These are not well-measured on most devices - probably best to ignore them.
+ OutsideLensSurfaceToScreen[0] = DecodeUInt32(Buffer+24) * (1/1000000.f);
+ OutsideLensSurfaceToScreen[1] = DecodeUInt32(Buffer+28) * (1/1000000.f);
+ // TODO: add spline-based distortion.
+ // TODO: currently these values are all zeros in the HMD itself.
+ DistortionK[0] = DecodeFloat(Buffer+32);
+ DistortionK[1] = DecodeFloat(Buffer+36);
+ DistortionK[2] = DecodeFloat(Buffer+40);
+ DistortionK[3] = DecodeFloat(Buffer+44);
+ DistortionK[4] = DecodeFloat(Buffer+48);
+ DistortionK[5] = DecodeFloat(Buffer+52);
+#else
+ // The above are either measured poorly, or don't have values at all.
+ // To remove the temptation to use them, set them to junk.
+ OutsideLensSurfaceToScreen[0] = -1.0f;
+ OutsideLensSurfaceToScreen[1] = -1.0f;
+ DistortionK[0] = -1.0f;
+ DistortionK[1] = -1.0f;
+ DistortionK[2] = -1.0f;
+ DistortionK[3] = -1.0f;
+ DistortionK[4] = -1.0f;
+ DistortionK[5] = -1.0f;
+#endif
}
@@ -456,10 +232,9 @@ void SensorDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor)
bool SensorDeviceFactory::MatchVendorProduct(UInt16 vendorId, UInt16 productId) const
{
- // search for a tracker sensor or a tracker boot loader device
- return ((vendorId == Sensor_VendorId) && (productId == Sensor_ProductId)) ||
- ((vendorId == Sensor_OldVendorId) && (productId == Sensor_OldProductId)) ||
- ((vendorId == Sensor_VendorId) && (productId == Sensor_BootLoader));
+ return ((vendorId == Sensor_VendorId) && (productId == Sensor_Tracker_ProductId)) ||
+ ((vendorId == Sensor_VendorId) && (productId == Sensor_Tracker2_ProductId)) ||
+ ((vendorId == Sensor_VendorId) && (productId == Sensor_KTracker_ProductId));
}
bool SensorDeviceFactory::DetectHIDDevice(DeviceManager* pdevMgr, const HIDDeviceDesc& desc)
@@ -488,6 +263,11 @@ bool SensorDeviceFactory::DetectHIDDevice(DeviceManager* pdevMgr, const HIDDevic
DeviceBase* SensorDeviceCreateDesc::NewDeviceInstance()
{
+ if (HIDDesc.ProductId == Sensor_Tracker2_ProductId)
+ {
+ return new Sensor2DeviceImpl(this);
+ }
+
return new SensorDeviceImpl(this);
}
@@ -497,18 +277,18 @@ bool SensorDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const
(info->InfoClassType != Device_None))
return false;
- OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength, HIDDesc.Product.ToCStr());
- OVR_strcpy(info->Manufacturer, DeviceInfo::MaxNameLength, HIDDesc.Manufacturer.ToCStr());
- info->Type = Device_Sensor;
+ info->Type = Device_Sensor;
+ info->ProductName = HIDDesc.Product;
+ info->Manufacturer = HIDDesc.Manufacturer;
+ info->Version = HIDDesc.VersionNumber;
if (info->InfoClassType == Device_Sensor)
{
SensorInfo* sinfo = (SensorInfo*)info;
sinfo->VendorId = HIDDesc.VendorId;
sinfo->ProductId = HIDDesc.ProductId;
- sinfo->Version = HIDDesc.VersionNumber;
sinfo->MaxRanges = SensorRangeImpl::GetMaxSensorRange();
- OVR_strcpy(sinfo->SerialNumber, sizeof(sinfo->SerialNumber),HIDDesc.SerialNumber.ToCStr());
+ sinfo->SerialNumber = HIDDesc.SerialNumber;
}
return true;
}
@@ -520,14 +300,22 @@ SensorDeviceImpl::SensorDeviceImpl(SensorDeviceCreateDesc* createDesc)
: OVR::HIDDeviceImpl<OVR::SensorDevice>(createDesc, 0),
Coordinates(SensorDevice::Coord_Sensor),
HWCoordinates(SensorDevice::Coord_HMD), // HW reports HMD coordinates by default.
- NextKeepAliveTicks(0),
- MaxValidRange(SensorRangeImpl::GetMaxSensorRange())
+ NextKeepAliveTickSeconds(0),
+ FullTimestamp(0),
+ MaxValidRange(SensorRangeImpl::GetMaxSensorRange()),
+ magCalibrated(false)
{
- SequenceValid = false;
- LastSampleCount= 0;
+ SequenceValid = false;
+ LastSampleCount = 0;
LastTimestamp = 0;
OldCommandId = 0;
+
+ PrevAbsoluteTime = 0.0;
+
+#ifdef OVR_OS_ANDROID
+ pPhoneSensors = PhoneSensors::Create();
+#endif
}
SensorDeviceImpl::~SensorDeviceImpl()
@@ -536,15 +324,13 @@ SensorDeviceImpl::~SensorDeviceImpl()
OVR_ASSERT(!pCreateDesc->pDevice);
}
+
// Internal creation APIs.
bool SensorDeviceImpl::Initialize(DeviceBase* parent)
{
if (HIDDeviceImpl<OVR::SensorDevice>::Initialize(parent))
{
openDevice();
-
- LogText("OVR::SensorDevice initialized.\n");
-
return true;
}
@@ -566,6 +352,17 @@ void SensorDeviceImpl::openDevice()
setRange(CurrentRange);
}
+ // Read the currently configured calibration from sensor.
+ SensorFactoryCalibrationImpl sc;
+ if (GetInternalDevice()->GetFeatureReport(sc.Buffer, SensorFactoryCalibrationImpl::PacketSize))
+ {
+ sc.Unpack();
+ AccelCalibrationOffset = sc.AccelOffset;
+ GyroCalibrationOffset = sc.GyroOffset;
+ AccelCalibrationMatrix = sc.AccelMatrix;
+ GyroCalibrationMatrix = sc.GyroMatrix;
+ CalibrationTemperature = sc.Temperature;
+ }
// If the sensor has "DisplayInfo" data, use HMD coordinate frame by default.
SensorDisplayInfoImpl displayInfo;
@@ -583,12 +380,21 @@ void SensorDeviceImpl::openDevice()
// Set Keep-alive at 10 seconds.
SensorKeepAliveImpl skeepAlive(10 * 1000);
GetInternalDevice()->SetFeatureReport(skeepAlive.Buffer, SensorKeepAliveImpl::PacketSize);
+
+ // Load mag calibration
+ MagCalibrationReport report;
+ bool res = GetMagCalibrationReport(&report);
+ if (res && report.Version > 0)
+ {
+ magCalibration = report.Calibration;
+ magCalibrated = true;
+ }
}
void SensorDeviceImpl::closeDeviceOnError()
{
LogText("OVR::SensorDevice - Lost connection to '%s'\n", getHIDDesc()->Path.ToCStr());
- NextKeepAliveTicks = 0;
+ NextKeepAliveTickSeconds = 0;
}
void SensorDeviceImpl::Shutdown()
@@ -598,16 +404,14 @@ void SensorDeviceImpl::Shutdown()
LogText("OVR::SensorDevice - Closed '%s'\n", getHIDDesc()->Path.ToCStr());
}
-
void SensorDeviceImpl::OnInputReport(UByte* pData, UInt32 length)
{
- bool processed = false;
+ bool processed = false;
if (!processed)
{
-
TrackerMessage message;
- if (DecodeTrackerMessage(&message, pData, length))
+ if (decodeTrackerMessage(&message, pData, length))
{
processed = true;
onTrackerMessage(&message);
@@ -615,13 +419,12 @@ void SensorDeviceImpl::OnInputReport(UByte* pData, UInt32 length)
}
}
-UInt64 SensorDeviceImpl::OnTicks(UInt64 ticksMks)
+double SensorDeviceImpl::OnTicks(double tickSeconds)
{
-
- if (ticksMks >= NextKeepAliveTicks)
+ if (tickSeconds >= NextKeepAliveTickSeconds)
{
// Use 3-seconds keep alive by default.
- UInt64 keepAliveDelta = Timer::MksPerSecond * 3;
+ double keepAliveDelta = 3.0;
// Set Keep-alive at 10 seconds.
SensorKeepAliveImpl skeepAlive(10 * 1000);
@@ -629,9 +432,9 @@ UInt64 SensorDeviceImpl::OnTicks(UInt64 ticksMks)
GetInternalDevice()->SetFeatureReport(skeepAlive.Buffer, SensorKeepAliveImpl::PacketSize);
// Emit keep-alive every few seconds.
- NextKeepAliveTicks = ticksMks + keepAliveDelta;
+ NextKeepAliveTickSeconds = tickSeconds + keepAliveDelta;
}
- return NextKeepAliveTicks - ticksMks;
+ return NextKeepAliveTickSeconds - tickSeconds;
}
bool SensorDeviceImpl::SetRange(const SensorRange& range, bool waitFlag)
@@ -758,17 +561,49 @@ Void SensorDeviceImpl::setReportRate(unsigned rateHz)
return 0;
}
-void SensorDeviceImpl::SetMessageHandler(MessageHandler* handler)
+void SensorDeviceImpl::GetFactoryCalibration(Vector3f* AccelOffset, Vector3f* GyroOffset,
+ Matrix4f* AccelMatrix, Matrix4f* GyroMatrix,
+ float* Temperature)
{
- if (handler)
+ *AccelOffset = AccelCalibrationOffset;
+ *GyroOffset = GyroCalibrationOffset;
+ *AccelMatrix = AccelCalibrationMatrix;
+ *GyroMatrix = GyroCalibrationMatrix;
+ *Temperature = CalibrationTemperature;
+}
+
+void SensorDeviceImpl::SetOnboardCalibrationEnabled(bool enabled)
+{
+ // Push call with wait.
+ GetManagerImpl()->GetThreadQueue()->
+ PushCall(this, &SensorDeviceImpl::setOnboardCalibrationEnabled, enabled, true);
+}
+
+Void SensorDeviceImpl::setOnboardCalibrationEnabled(bool enabled)
+{
+ // Read the original configuration
+ SensorConfigImpl scfg;
+ if (GetInternalDevice()->GetFeatureReport(scfg.Buffer, SensorConfigImpl::PacketSize))
{
- SequenceValid = false;
- DeviceBase::SetMessageHandler(handler);
+ scfg.Unpack();
}
+
+ if (enabled)
+ scfg.Flags |= (SensorConfigImpl::Flag_AutoCalibration | SensorConfigImpl::Flag_UseCalibration);
else
- {
- DeviceBase::SetMessageHandler(handler);
- }
+ scfg.Flags &= ~(SensorConfigImpl::Flag_AutoCalibration | SensorConfigImpl::Flag_UseCalibration);
+
+ scfg.Pack();
+
+ GetInternalDevice()->SetFeatureReport(scfg.Buffer, SensorConfigImpl::PacketSize);
+ return 0;
+}
+
+void SensorDeviceImpl::AddMessageHandler(MessageHandler* handler)
+{
+ if (handler)
+ SequenceValid = false;
+ DeviceBase::AddMessageHandler(handler);
}
// Sensor reports data in the following coordinate system:
@@ -793,20 +628,18 @@ Vector3f AccelFromBodyFrameUpdate(const TrackerSensors& update, UByte sampleNumb
Vector3f MagFromBodyFrameUpdate(const TrackerSensors& update,
+ Matrix4f magCalibration,
bool convertHMDToSensor = false)
{
+ float mx = (float)update.MagX;
+ float my = (float)update.MagY;
+ float mz = (float)update.MagZ;
// Note: Y and Z are swapped in comparison to the Accel.
// This accounts for DK1 sensor firmware axis swap, which should be undone in future releases.
- if (!convertHMDToSensor)
- {
- return Vector3f( (float)update.MagX,
- (float)update.MagZ,
- (float)update.MagY) * 0.0001f;
- }
-
- return Vector3f( (float)update.MagX,
- (float)update.MagY,
- -(float)update.MagZ) * 0.0001f;
+ Vector3f mag = convertHMDToSensor ? Vector3f(mx, my, -mz) : Vector3f(mx, mz, my);
+ mag *= 0.0001f;
+ // Apply calibration
+ return magCalibration.Transform(mag);
}
Vector3f EulerFromBodyFrameUpdate(const TrackerSensors& update, UByte sampleNumber,
@@ -821,42 +654,86 @@ Vector3f EulerFromBodyFrameUpdate(const TrackerSensors& update, UByte sampleNumb
return val * 0.0001f;
}
+bool SensorDeviceImpl::decodeTrackerMessage(TrackerMessage* message, UByte* buffer, int size)
+{
+ memset(message, 0, sizeof(TrackerMessage));
+
+ if (size < 4)
+ {
+ message->Type = TrackerMessage_SizeError;
+ return false;
+ }
+
+ switch (buffer[0])
+ {
+ case TrackerMessage_Sensors:
+ message->Type = message->Sensors.Decode(buffer, size);
+ break;
+
+ default:
+ message->Type = TrackerMessage_Unknown;
+ break;
+ }
+
+ return (message->Type < TrackerMessage_Unknown) && (message->Type != TrackerMessage_None);
+}
void SensorDeviceImpl::onTrackerMessage(TrackerMessage* message)
{
if (message->Type != TrackerMessage_Sensors)
return;
- const float timeUnit = (1.0f / 1000.f);
- TrackerSensors& s = message->Sensors;
+ const double timeUnit = (1.0 / 1000.0);
+ double scaledTimeUnit = timeUnit;
+ TrackerSensors& s = message->Sensors;
+ // DK1 timestamps the first sample, so the actual device time will be later
+ // by the time we get the message if there are multiple samples.
+ int timestampAdjust = (s.SampleCount > 0) ? s.SampleCount-1 : 0;
+
+ const double now = Timer::GetSeconds();
+ double absoluteTimeSeconds = 0.0;
- // Call OnMessage() within a lock to avoid conflicts with handlers.
- Lock::Locker scopeLock(HandlerRef.GetLock());
-
-
if (SequenceValid)
{
unsigned timestampDelta;
if (s.Timestamp < LastTimestamp)
+ {
+ // The timestamp rolled around the 16 bit counter, so FullTimeStamp
+ // needs a high word increment.
+ FullTimestamp += 0x10000;
timestampDelta = ((((int)s.Timestamp) + 0x10000) - (int)LastTimestamp);
+ }
else
+ {
timestampDelta = (s.Timestamp - LastTimestamp);
+ }
+ // Update the low word of FullTimeStamp
+ FullTimestamp = ( FullTimestamp & ~0xffff ) | s.Timestamp;
- // If we missed a small number of samples, replicate the last sample.
+ double deviceTime = (FullTimestamp + timestampAdjust) * timeUnit;
+ absoluteTimeSeconds = TimeFilter.SampleToSystemTime(deviceTime, now, PrevAbsoluteTime);
+ scaledTimeUnit = TimeFilter.ScaleTimeUnit(timeUnit);
+ PrevAbsoluteTime = absoluteTimeSeconds;
+
+ // If we missed a small number of samples, generate the sample that would have immediately
+ // proceeded the current one. Re-use the IMU values from the last processed sample.
if ((timestampDelta > LastSampleCount) && (timestampDelta <= 254))
{
- if (HandlerRef.GetHandler())
+ if (HandlerRef.HasHandlers())
{
MessageBodyFrame sensors(this);
- sensors.TimeDelta = (timestampDelta - LastSampleCount) * timeUnit;
- sensors.Acceleration = LastAcceleration;
- sensors.RotationRate = LastRotationRate;
- sensors.MagneticField = LastMagneticField;
- sensors.Temperature = LastTemperature;
- HandlerRef.GetHandler()->OnMessage(sensors);
+ sensors.AbsoluteTimeSeconds = absoluteTimeSeconds - s.SampleCount * scaledTimeUnit;
+ sensors.TimeDelta = (float)((timestampDelta - LastSampleCount) * scaledTimeUnit);
+ sensors.Acceleration = LastAcceleration;
+ sensors.RotationRate = LastRotationRate;
+ sensors.MagneticField = LastMagneticField;
+ sensors.Temperature = LastTemperature;
+ sensors.MagCalibrated = magCalibrated;
+
+ HandlerRef.Call(sensors);
}
}
}
@@ -867,37 +744,58 @@ void SensorDeviceImpl::onTrackerMessage(TrackerMessage* message)
LastMagneticField= Vector3f(0);
LastTemperature = 0;
SequenceValid = true;
+
+ // This is our baseline sensor to host time delta,
+ // it will be adjusted with each new message.
+ FullTimestamp = s.Timestamp;
+
+ double deviceTime = (FullTimestamp + timestampAdjust) * timeUnit;
+ absoluteTimeSeconds = TimeFilter.SampleToSystemTime(deviceTime, now, PrevAbsoluteTime);
+ scaledTimeUnit = TimeFilter.ScaleTimeUnit(timeUnit);
+ PrevAbsoluteTime = absoluteTimeSeconds;
}
LastSampleCount = s.SampleCount;
LastTimestamp = s.Timestamp;
bool convertHMDToSensor = (Coordinates == Coord_Sensor) && (HWCoordinates == Coord_HMD);
-
- if (HandlerRef.GetHandler())
+
+#ifdef OVR_OS_ANDROID
+ // LDC - Normally we get the coordinate system from the tracker.
+ // Since KTracker doesn't store it we'll always assume HMD coordinate system.
+ convertHMDToSensor = false;
+#endif
+
+ if (HandlerRef.HasHandlers())
{
- MessageBodyFrame sensors(this);
+ MessageBodyFrame sensors(this);
+ sensors.MagCalibrated = magCalibrated;
UByte iterations = s.SampleCount;
if (s.SampleCount > 3)
{
iterations = 3;
- sensors.TimeDelta = (s.SampleCount - 2) * timeUnit;
+ sensors.TimeDelta = (float)((s.SampleCount - 2) * scaledTimeUnit);
}
else
{
- sensors.TimeDelta = timeUnit;
+ sensors.TimeDelta = (float)scaledTimeUnit;
}
for (UByte i = 0; i < iterations; i++)
- {
- sensors.Acceleration = AccelFromBodyFrameUpdate(s, i, convertHMDToSensor);
- sensors.RotationRate = EulerFromBodyFrameUpdate(s, i, convertHMDToSensor);
- sensors.MagneticField= MagFromBodyFrameUpdate(s, convertHMDToSensor);
- sensors.Temperature = s.Temperature * 0.01f;
- HandlerRef.GetHandler()->OnMessage(sensors);
+ {
+ sensors.AbsoluteTimeSeconds = absoluteTimeSeconds - ( iterations - 1 - i ) * scaledTimeUnit;
+ sensors.Acceleration = AccelFromBodyFrameUpdate(s, i, convertHMDToSensor);
+ sensors.RotationRate = EulerFromBodyFrameUpdate(s, i, convertHMDToSensor);
+ sensors.MagneticField = MagFromBodyFrameUpdate(s, magCalibration, convertHMDToSensor);
+
+#ifdef OVR_OS_ANDROID
+ replaceWithPhoneMag(&(sensors.MagneticField));
+#endif
+ sensors.Temperature = s.Temperature * 0.01f;
+ HandlerRef.Call(sensors);
// TimeDelta for the last two sample is always fixed.
- sensors.TimeDelta = timeUnit;
+ sensors.TimeDelta = (float)scaledTimeUnit;
}
LastAcceleration = sensors.Acceleration;
@@ -910,11 +808,309 @@ void SensorDeviceImpl::onTrackerMessage(TrackerMessage* message)
UByte i = (s.SampleCount > 3) ? 2 : (s.SampleCount - 1);
LastAcceleration = AccelFromBodyFrameUpdate(s, i, convertHMDToSensor);
LastRotationRate = EulerFromBodyFrameUpdate(s, i, convertHMDToSensor);
- LastMagneticField = MagFromBodyFrameUpdate(s, convertHMDToSensor);
+ LastMagneticField = MagFromBodyFrameUpdate(s, magCalibration, convertHMDToSensor);
+
+#ifdef OVR_OS_ANDROID
+ replaceWithPhoneMag(&LastMagneticField);
+#endif
LastTemperature = s.Temperature * 0.01f;
}
}
+
+#ifdef OVR_OS_ANDROID
+
+void SensorDeviceImpl::replaceWithPhoneMag(Vector3f* val)
+{
+
+ // Native calibrated.
+ pPhoneSensors->SetMagSource(PhoneSensors::MagnetometerSource_Native);
+
+ Vector3f magPhone;
+ pPhoneSensors->GetLatestMagValue(&magPhone);
+
+ // Phone value is in micro-Tesla. Convert it to Gauss and flip axes.
+ magPhone *= 10000.0f/1000000.0f;
+
+ Vector3f res;
+ res.x = -magPhone.y;
+ res.y = magPhone.x;
+ res.z = magPhone.z;
+
+ *val = res;
+}
+#endif
+
+const int MAX_DEVICE_PROFILE_MAJOR_VERSION = 1;
+
+// Writes the current calibration for a particular device to a device profile file
+bool SensorDeviceImpl::SetMagCalibrationReport(const MagCalibrationReport &data)
+{
+ // Get device info
+ SensorInfo sinfo;
+ GetDeviceInfo(&sinfo);
+
+ // A named calibration may be specified for calibration in different
+ // environments, otherwise the default calibration is used
+ const char* calibrationName = "default";
+
+ // Generate a mag calibration event
+ JSON* calibration = JSON::CreateObject();
+ // (hardcoded for now) the measurement and representation method
+ calibration->AddStringItem("Version", "2.0");
+ calibration->AddStringItem("Name", "default");
+
+ // time stamp the calibration
+ char time_str[64];
+
+#ifdef OVR_OS_WIN32
+ struct tm caltime;
+ time_t now = time(0);
+ localtime_s(&caltime, &now);
+ strftime(time_str, 64, "%Y-%m-%d %H:%M:%S", &caltime);
+#else
+ struct tm* caltime;
+ time_t now = time(0);
+ caltime = localtime(&now);
+ strftime(time_str, 64, "%Y-%m-%d %H:%M:%S", caltime);
+#endif
+
+ calibration->AddStringItem("Time", time_str);
+
+ // write the full calibration matrix
+ char matrix[256];
+ data.Calibration.ToString(matrix, 256);
+ calibration->AddStringItem("CalibrationMatrix", matrix);
+ // save just the offset, for backwards compatibility
+ // this can be removed when we don't want to support 0.2.4 anymore
+ Vector3f center(data.Calibration.M[0][3], data.Calibration.M[1][3], data.Calibration.M[2][3]);
+ Matrix4f tmp = data.Calibration; tmp.M[0][3] = tmp.M[1][3] = tmp.M[2][3] = 0; tmp.M[3][3] = 1;
+ center = tmp.Inverted().Transform(center);
+ Matrix4f oldcalmat; oldcalmat.M[0][3] = center.x; oldcalmat.M[1][3] = center.y; oldcalmat.M[2][3] = center.z;
+ oldcalmat.ToString(matrix, 256);
+ calibration->AddStringItem("Calibration", matrix);
+
+ String path = GetBaseOVRPath(true);
+ path += "/Devices.json";
+
+ // Look for a preexisting device file to edit
+ Ptr<JSON> root = *JSON::Load(path);
+ if (root)
+ { // Quick sanity check of the file type and format before we parse it
+ JSON* version = root->GetFirstItem();
+ if (version && version->Name == "Oculus Device Profile Version")
+ {
+ int major = atoi(version->Value.ToCStr());
+ if (major > MAX_DEVICE_PROFILE_MAJOR_VERSION)
+ {
+ // don't use the file on unsupported major version number
+ root->Release();
+ root = NULL;
+ }
+ }
+ else
+ {
+ root->Release();
+ root = NULL;
+ }
+ }
+
+ JSON* device = NULL;
+ if (root)
+ {
+ device = root->GetFirstItem(); // skip the header
+ device = root->GetNextItem(device);
+ while (device)
+ { // Search for a previous calibration with the same name for this device
+ // and remove it before adding the new one
+ if (device->Name == "Device")
+ {
+ JSON* item = device->GetItemByName("Serial");
+ if (item && item->Value == sinfo.SerialNumber)
+ { // found an entry for this device
+ item = device->GetNextItem(item);
+ while (item)
+ {
+ if (item->Name == "MagCalibration")
+ {
+ JSON* name = item->GetItemByName("Name");
+ if (name && name->Value == calibrationName)
+ { // found a calibration of the same name
+ item->RemoveNode();
+ item->Release();
+ break;
+ }
+ }
+ item = device->GetNextItem(item);
+ }
+
+
+ /*
+ this is removed temporarily, since this is a sensor fusion setting, not sensor itself
+ should be moved to the correct place when Brant has finished the user profile implementation
+ // update the auto-mag flag
+ item = device->GetItemByName("EnableYawCorrection");
+ if (item)
+ item->dValue = (double)EnableYawCorrection;
+ else
+ device->AddBoolItem("EnableYawCorrection", EnableYawCorrection);*/
+
+ break;
+ }
+ }
+
+ device = root->GetNextItem(device);
+ }
+ }
+ else
+ { // Create a new device root
+ root = *JSON::CreateObject();
+ root->AddStringItem("Oculus Device Profile Version", "1.0");
+ }
+
+ if (device == NULL)
+ {
+ device = JSON::CreateObject();
+ device->AddStringItem("Product", sinfo.ProductName);
+ device->AddNumberItem("ProductID", sinfo.ProductId);
+ device->AddStringItem("Serial", sinfo.SerialNumber);
+ // removed temporarily, see above
+ //device->AddBoolItem("EnableYawCorrection", EnableYawCorrection);
+
+ root->AddItem("Device", device);
+ }
+
+ // Create and the add the new calibration event to the device
+ device->AddItem("MagCalibration", calibration);
+ return root->Save(path);
+}
+
+// Loads a saved calibration for the specified device from the device profile file
+bool SensorDeviceImpl::GetMagCalibrationReport(MagCalibrationReport* data)
+{
+ data->Version = 0;
+ data->Calibration.SetIdentity();
+
+ // Get device info
+ SensorInfo sinfo;
+ GetDeviceInfo(&sinfo);
+
+ // A named calibration may be specified for calibration in different
+ // environments, otherwise the default calibration is used
+ const char* calibrationName = "default";
+
+ String path = GetBaseOVRPath(true);
+ path += "/Devices.json";
+
+ // Load the device profiles
+ Ptr<JSON> root = *JSON::Load(path);
+ if (root == NULL)
+ return false;
+
+ // Quick sanity check of the file type and format before we parse it
+ JSON* version = root->GetFirstItem();
+ if (version && version->Name == "Oculus Device Profile Version")
+ {
+ int major = atoi(version->Value.ToCStr());
+ if (major > MAX_DEVICE_PROFILE_MAJOR_VERSION)
+ return false; // don't parse the file on unsupported major version number
+ }
+ else
+ {
+ return false;
+ }
+
+ JSON* device = root->GetNextItem(version);
+ while (device)
+ { // Search for a previous calibration with the same name for this device
+ // and remove it before adding the new one
+ if (device->Name == "Device")
+ {
+ JSON* item = device->GetItemByName("Serial");
+ if (item && item->Value == sinfo.SerialNumber)
+ { // found an entry for this device
+
+ JSON* autoyaw = device->GetItemByName("EnableYawCorrection");
+ // as a temporary HACK, return no calibration if EnableYawCorrection is off
+ // this will force disable yaw correction in SensorFusion
+ // proper solution would load the value in the Profile, which SensorFusion can access
+ if (autoyaw && autoyaw->dValue == 0)
+ return true;
+
+ item = device->GetNextItem(item);
+ while (item)
+ {
+ if (item->Name == "MagCalibration")
+ {
+ JSON* calibration = item;
+ JSON* name = calibration->GetItemByName("Name");
+ if (name && name->Value == calibrationName)
+ { // found a calibration with this name
+
+ int major = 0;
+ JSON* version = calibration->GetItemByName("Version");
+ if (version)
+ major = atoi(version->Value.ToCStr());
+
+ if (major > data->Version && major <= 2)
+ {
+ time_t now;
+ time(&now);
+
+ // parse the calibration time
+ time_t calibration_time = now;
+ JSON* caltime = calibration->GetItemByName("Time");
+ if (caltime)
+ {
+ const char* caltime_str = caltime->Value.ToCStr();
+
+ tm ct;
+ memset(&ct, 0, sizeof(tm));
+
+#ifdef OVR_OS_WIN32
+ struct tm nowtime;
+ localtime_s(&nowtime, &now);
+ ct.tm_isdst = nowtime.tm_isdst;
+ sscanf_s(caltime_str, "%d-%d-%d %d:%d:%d",
+ &ct.tm_year, &ct.tm_mon, &ct.tm_mday,
+ &ct.tm_hour, &ct.tm_min, &ct.tm_sec);
+#else
+ struct tm* nowtime = localtime(&now);
+ ct.tm_isdst = nowtime->tm_isdst;
+ sscanf(caltime_str, "%d-%d-%d %d:%d:%d",
+ &ct.tm_year, &ct.tm_mon, &ct.tm_mday,
+ &ct.tm_hour, &ct.tm_min, &ct.tm_sec);
+#endif
+ ct.tm_year -= 1900;
+ ct.tm_mon--;
+ calibration_time = mktime(&ct);
+ }
+
+ // parse the calibration matrix
+ JSON* cal = calibration->GetItemByName("CalibrationMatrix");
+ if (!cal)
+ cal = calibration->GetItemByName("Calibration");
+ if (cal)
+ {
+ data->Calibration = Matrix4f::FromString(cal->Value.ToCStr());
+ data->Version = (UByte)major;
+ }
+ }
+ }
+ }
+ item = device->GetNextItem(item);
+ }
+
+ return true;
+ }
+ }
+
+ device = root->GetNextItem(device);
+ }
+
+ return true;
+}
+
} // namespace OVR
diff --git a/LibOVR/Src/OVR_SensorImpl.h b/LibOVR/Src/OVR_SensorImpl.h
index 8b9eefb..70e05f8 100644
--- a/LibOVR/Src/OVR_SensorImpl.h
+++ b/LibOVR/Src/OVR_SensorImpl.h
@@ -5,16 +5,16 @@ Content : Sensor device specific implementation.
Created : March 7, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -28,9 +28,14 @@ limitations under the License.
#define OVR_SensorImpl_h
#include "OVR_HIDDeviceImpl.h"
+#include "OVR_SensorTimeFilter.h"
+
+#ifdef OVR_OS_ANDROID
+#include "OVR_PhoneSensors.h"
+#endif
namespace OVR {
-
+
struct TrackerMessage;
class ExternalVisitor;
@@ -150,18 +155,23 @@ struct SensorDisplayInfoImpl
{
Mask_BaseFmt = 0x0f,
Mask_OptionFmts = 0xf0,
- Base_None = 0x00,
- Base_Screen = 0x01,
- Base_Distortion = 0x02,
+ Base_None = 0,
+ Base_ScreenOnly = 1,
+ Base_Distortion = 2,
};
UInt16 CommandId;
+
UByte DistortionType;
UInt16 HResolution, VResolution;
float HScreenSize, VScreenSize;
float VCenter;
float LensSeparation;
- float EyeToScreenDistance[2];
+ // Currently these values are not well-measured.
+ float OutsideLensSurfaceToScreen[2];
+ // TODO: add DistortionEqn
+ // TODO: currently these values are all zeros and the
+ // distortion is hard-coded in HMDDeviceCreateDesc::GetDeviceInfo()
float DistortionK[6];
SensorDisplayInfoImpl();
@@ -169,7 +179,6 @@ struct SensorDisplayInfoImpl
void Unpack();
};
-
//-------------------------------------------------------------------------------------
// ***** OVR::SensorDeviceImpl
@@ -186,11 +195,11 @@ public:
virtual bool Initialize(DeviceBase* parent);
virtual void Shutdown();
- virtual void SetMessageHandler(MessageHandler* handler);
+ virtual void AddMessageHandler(MessageHandler* handler);
// HIDDevice::Notifier interface.
virtual void OnInputReport(UByte* pData, UInt32 length);
- virtual UInt64 OnTicks(UInt64 ticksMks);
+ virtual double OnTicks(double tickSeconds);
// HMD-Mounted sensor has a different coordinate frame.
virtual void SetCoordinateFrame(CoordinateFrame coordframe);
@@ -200,6 +209,11 @@ public:
virtual bool SetRange(const SensorRange& range, bool waitFlag);
virtual void GetRange(SensorRange* range) const;
+ virtual void GetFactoryCalibration(Vector3f* AccelOffset, Vector3f* GyroOffset,
+ Matrix4f* AccelMatrix, Matrix4f* GyroMatrix,
+ float* Temperature);
+ virtual void SetOnboardCalibrationEnabled(bool enabled);
+
// 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
// called twice or thrice at the same 'tick'.
@@ -213,20 +227,28 @@ public:
virtual unsigned GetReportRate() const;
// Hack to create HMD device from sensor display info.
- static void EnumerateHMDFromSensorDisplayInfo(const SensorDisplayInfoImpl& displayInfo,
- DeviceFactory::EnumerateVisitor& visitor);
+ static void EnumerateHMDFromSensorDisplayInfo(const SensorDisplayInfoImpl& displayInfo,
+ DeviceFactory::EnumerateVisitor& visitor);
+
+ // These methods actually store data in a JSON file
+ virtual bool SetMagCalibrationReport(const MagCalibrationReport& data);
+ virtual bool GetMagCalibrationReport(MagCalibrationReport* data);
+
protected:
- void openDevice();
- void closeDeviceOnError();
+ virtual void openDevice();
+ void closeDeviceOnError();
- Void setCoordinateFrame(CoordinateFrame coordframe);
- bool setRange(const SensorRange& range);
+ Void setCoordinateFrame(CoordinateFrame coordframe);
+ bool setRange(const SensorRange& range);
- Void setReportRate(unsigned rateHz);
+ Void setReportRate(unsigned rateHz);
+
+ Void setOnboardCalibrationEnabled(bool enabled);
// Called for decoded messages
- void onTrackerMessage(TrackerMessage* message);
+ void onTrackerMessage(TrackerMessage* message);
+ bool decodeTrackerMessage(TrackerMessage* message, UByte* buffer, int size);
// Helpers to reduce casting.
/*
@@ -242,23 +264,45 @@ protected:
// so we track its state.
CoordinateFrame Coordinates;
CoordinateFrame HWCoordinates;
- UInt64 NextKeepAliveTicks;
+ double NextKeepAliveTickSeconds;
bool SequenceValid;
- SInt16 LastTimestamp;
+ UInt16 LastTimestamp;
UByte LastSampleCount;
float LastTemperature;
Vector3f LastAcceleration;
Vector3f LastRotationRate;
Vector3f LastMagneticField;
+ // This tracks wrap around, and should be monotonically increasing.
+ UInt32 FullTimestamp;
+
// Current sensor range obtained from device.
SensorRange MaxValidRange;
SensorRange CurrentRange;
+
+ // IMU calibration obtained from device.
+ Vector3f AccelCalibrationOffset;
+ Vector3f GyroCalibrationOffset;
+ Matrix4f AccelCalibrationMatrix;
+ Matrix4f GyroCalibrationMatrix;
+ float CalibrationTemperature;
UInt16 OldCommandId;
-};
+ SensorTimeFilter TimeFilter;
+ double PrevAbsoluteTime;
+
+#ifdef OVR_OS_ANDROID
+ void replaceWithPhoneMag(Vector3f* val);
+
+ PhoneSensors* pPhoneSensors;
+#endif
+
+private:
+ Matrix4f magCalibration;
+ bool magCalibrated;
+};
} // namespace OVR
diff --git a/LibOVR/Src/OVR_SensorImpl_Common.cpp b/LibOVR/Src/OVR_SensorImpl_Common.cpp
new file mode 100644
index 0000000..a84d50a
--- /dev/null
+++ b/LibOVR/Src/OVR_SensorImpl_Common.cpp
@@ -0,0 +1,245 @@
+/************************************************************************************
+
+Filename : OVR_SensorImpl_Common.cpp
+Content : Source common to SensorImpl and Sensor2Impl.
+Created : January 21, 2014
+Authors : Lee Cooper
+
+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 "OVR_SensorImpl_Common.h"
+#include "Kernel/OVR_Alg.h"
+
+namespace OVR
+{
+
+void UnpackSensor(const UByte* buffer, SInt32* x, SInt32* y, SInt32* z)
+{
+ // Sign extending trick
+ // from http://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend
+ struct {SInt32 x:21;} s;
+
+ *x = s.x = (buffer[0] << 13) | (buffer[1] << 5) | ((buffer[2] & 0xF8) >> 3);
+ *y = s.x = ((buffer[2] & 0x07) << 18) | (buffer[3] << 10) | (buffer[4] << 2) |
+ ((buffer[5] & 0xC0) >> 6);
+ *z = s.x = ((buffer[5] & 0x3F) << 15) | (buffer[6] << 7) | (buffer[7] >> 1);
+}
+
+void PackSensor(UByte* buffer, SInt32 x, SInt32 y, SInt32 z)
+{
+ // Pack 3 32 bit integers into 8 bytes
+ buffer[0] = UByte(x >> 13);
+ buffer[1] = UByte(x >> 5);
+ buffer[2] = UByte((x << 3) | ((y >> 18) & 0x07));
+ buffer[3] = UByte(y >> 10);
+ buffer[4] = UByte(y >> 2);
+ buffer[5] = UByte((y << 6) | ((z >> 15) & 0x3F));
+ buffer[6] = UByte(z >> 7);
+ buffer[7] = UByte(z << 1);
+}
+
+UInt16 SelectSensorRampValue(const UInt16* ramp, unsigned count,
+ float val, float factor, const char* label)
+{
+ UInt16 threshold = (UInt16)(val * factor);
+
+ for (unsigned i = 0; i<count; i++)
+ {
+ if (ramp[i] >= threshold)
+ return ramp[i];
+ }
+ OVR_DEBUG_LOG(("SensorDevice::SetRange - %s clamped to %0.4f",
+ label, float(ramp[count-1]) / factor));
+ OVR_UNUSED2(factor, label);
+ return ramp[count-1];
+}
+
+SensorRangeImpl::SensorRangeImpl(const SensorRange& r, UInt16 commandId)
+{
+ SetSensorRange(r, commandId);
+}
+
+void SensorRangeImpl::SetSensorRange(const SensorRange& r, UInt16 commandId)
+{
+ CommandId = commandId;
+ AccelScale = SelectSensorRampValue(AccelRangeRamp, sizeof(AccelRangeRamp)/sizeof(AccelRangeRamp[0]),
+ r.MaxAcceleration, (1.0f / 9.81f), "MaxAcceleration");
+ GyroScale = SelectSensorRampValue(GyroRangeRamp, sizeof(GyroRangeRamp)/sizeof(GyroRangeRamp[0]),
+ r.MaxRotationRate, Math<float>::RadToDegreeFactor, "MaxRotationRate");
+ MagScale = SelectSensorRampValue(MagRangeRamp, sizeof(MagRangeRamp)/sizeof(MagRangeRamp[0]),
+ r.MaxMagneticField, 1000.0f, "MaxMagneticField");
+ Pack();
+}
+
+void SensorRangeImpl::GetSensorRange(SensorRange* r)
+{
+ r->MaxAcceleration = AccelScale * 9.81f;
+ r->MaxRotationRate = DegreeToRad((float)GyroScale);
+ r->MaxMagneticField= MagScale * 0.001f;
+}
+
+SensorRange SensorRangeImpl::GetMaxSensorRange()
+{
+ return SensorRange(AccelRangeRamp[sizeof(AccelRangeRamp)/sizeof(AccelRangeRamp[0]) - 1] * 9.81f,
+ GyroRangeRamp[sizeof(GyroRangeRamp)/sizeof(GyroRangeRamp[0]) - 1] *
+ Math<float>::DegreeToRadFactor,
+ MagRangeRamp[sizeof(MagRangeRamp)/sizeof(MagRangeRamp[0]) - 1] * 0.001f);
+}
+
+void SensorRangeImpl::Pack()
+{
+ Buffer[0] = 4;
+ Buffer[1] = UByte(CommandId & 0xFF);
+ Buffer[2] = UByte(CommandId >> 8);
+ Buffer[3] = UByte(AccelScale);
+ Buffer[4] = UByte(GyroScale & 0xFF);
+ Buffer[5] = UByte(GyroScale >> 8);
+ Buffer[6] = UByte(MagScale & 0xFF);
+ Buffer[7] = UByte(MagScale >> 8);
+}
+
+void SensorRangeImpl::Unpack()
+{
+ CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8);
+ AccelScale= Buffer[3];
+ GyroScale = Buffer[4] | (UInt16(Buffer[5]) << 8);
+ MagScale = Buffer[6] | (UInt16(Buffer[7]) << 8);
+}
+
+SensorConfigImpl::SensorConfigImpl()
+ : CommandId(0), Flags(0), PacketInterval(0), KeepAliveIntervalMs(0)
+{
+ memset(Buffer, 0, PacketSize);
+ Buffer[0] = 2;
+}
+
+void SensorConfigImpl::SetSensorCoordinates(bool sensorCoordinates)
+{
+ Flags = (Flags & ~Flag_SensorCoordinates) | (sensorCoordinates ? Flag_SensorCoordinates : 0);
+}
+
+bool SensorConfigImpl::IsUsingSensorCoordinates() const
+{
+ return (Flags & Flag_SensorCoordinates) != 0;
+}
+
+void SensorConfigImpl::Pack()
+{
+ Buffer[0] = 2;
+ Buffer[1] = UByte(CommandId & 0xFF);
+ Buffer[2] = UByte(CommandId >> 8);
+ Buffer[3] = Flags;
+ Buffer[4] = UByte(PacketInterval);
+ Buffer[5] = UByte(KeepAliveIntervalMs & 0xFF);
+ Buffer[6] = UByte(KeepAliveIntervalMs >> 8);
+}
+
+void SensorConfigImpl::Unpack()
+{
+ CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8);
+ Flags = Buffer[3];
+ PacketInterval = Buffer[4];
+ KeepAliveIntervalMs= Buffer[5] | (UInt16(Buffer[6]) << 8);
+}
+
+SensorFactoryCalibrationImpl::SensorFactoryCalibrationImpl()
+ : AccelOffset(), GyroOffset(), AccelMatrix(), GyroMatrix(), Temperature(0)
+{
+ memset(Buffer, 0, PacketSize);
+ Buffer[0] = 3;
+}
+
+void SensorFactoryCalibrationImpl::Pack()
+{
+ SInt32 x, y, z;
+
+ Buffer[0] = 3;
+
+ x = SInt32(AccelOffset.x * 1e4f);
+ y = SInt32(AccelOffset.y * 1e4f);
+ z = SInt32(AccelOffset.z * 1e4f);
+ PackSensor(Buffer + 3, x, y, z);
+
+ x = SInt32(GyroOffset.x * 1e4f);
+ y = SInt32(GyroOffset.y * 1e4f);
+ z = SInt32(GyroOffset.z * 1e4f);
+ PackSensor(Buffer + 11, x, y, z);
+
+ // ignore the scale matrices for now
+}
+
+void SensorFactoryCalibrationImpl::Unpack()
+{
+ static const float sensorMax = (1 << 20) - 1;
+ SInt32 x, y, z;
+
+ UnpackSensor(Buffer + 3, &x, &y, &z);
+ AccelOffset.y = (float) y * 1e-4f;
+ AccelOffset.z = (float) z * 1e-4f;
+ AccelOffset.x = (float) x * 1e-4f;
+
+ UnpackSensor(Buffer + 11, &x, &y, &z);
+ GyroOffset.x = (float) x * 1e-4f;
+ GyroOffset.y = (float) y * 1e-4f;
+ GyroOffset.z = (float) z * 1e-4f;
+
+ for (int i = 0; i < 3; i++)
+ {
+ UnpackSensor(Buffer + 19 + 8 * i, &x, &y, &z);
+ AccelMatrix.M[i][0] = (float) x / sensorMax;
+ AccelMatrix.M[i][1] = (float) y / sensorMax;
+ AccelMatrix.M[i][2] = (float) z / sensorMax;
+ AccelMatrix.M[i][i] += 1.0f;
+ }
+
+ for (int i = 0; i < 3; i++)
+ {
+ UnpackSensor(Buffer + 43 + 8 * i, &x, &y, &z);
+ GyroMatrix.M[i][0] = (float) x / sensorMax;
+ GyroMatrix.M[i][1] = (float) y / sensorMax;
+ GyroMatrix.M[i][2] = (float) z / sensorMax;
+ GyroMatrix.M[i][i] += 1.0f;
+ }
+
+ Temperature = (float) Alg::DecodeSInt16(Buffer + 67) / 100.0f;
+}
+
+SensorKeepAliveImpl::SensorKeepAliveImpl(UInt16 interval, UInt16 commandId)
+ : CommandId(commandId), KeepAliveIntervalMs(interval)
+{
+ Pack();
+}
+
+void SensorKeepAliveImpl::Pack()
+{
+ Buffer[0] = 8;
+ Buffer[1] = UByte(CommandId & 0xFF);
+ Buffer[2] = UByte(CommandId >> 8);
+ Buffer[3] = UByte(KeepAliveIntervalMs & 0xFF);
+ Buffer[4] = UByte(KeepAliveIntervalMs >> 8);
+}
+
+void SensorKeepAliveImpl::Unpack()
+{
+ CommandId = Buffer[1] | (UInt16(Buffer[2]) << 8);
+ KeepAliveIntervalMs= Buffer[3] | (UInt16(Buffer[4]) << 8);
+}
+
+} // namespace OVR
diff --git a/LibOVR/Src/OVR_SensorImpl_Common.h b/LibOVR/Src/OVR_SensorImpl_Common.h
new file mode 100644
index 0000000..293330c
--- /dev/null
+++ b/LibOVR/Src/OVR_SensorImpl_Common.h
@@ -0,0 +1,150 @@
+/************************************************************************************
+
+Filename : OVR_SensorImpl_Common.h
+Content : Source common to SensorImpl and Sensor2Impl.
+Created : January 21, 2014
+Authors : Lee Cooper
+
+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_SensorImpl_Common_h
+#define OVR_SensorImpl_Common_h
+
+#include "Kernel/OVR_System.h"
+#include "OVR_Device.h"
+
+namespace OVR
+{
+
+void UnpackSensor(const UByte* buffer, SInt32* x, SInt32* y, SInt32* z);
+void PackSensor(UByte* buffer, SInt32 x, SInt32 y, SInt32 z);
+
+// Sensor HW only accepts specific maximum range values, used to maximize
+// the 16-bit sensor outputs. Use these ramps to specify and report appropriate values.
+const UInt16 AccelRangeRamp[] = { 2, 4, 8, 16 };
+const UInt16 GyroRangeRamp[] = { 250, 500, 1000, 2000 };
+const UInt16 MagRangeRamp[] = { 880, 1300, 1900, 2500 };
+
+UInt16 SelectSensorRampValue(const UInt16* ramp, unsigned count,
+ float val, float factor, const char* label);
+
+// SensorScaleImpl provides buffer packing logic for the Sensor Range
+// record that can be applied to DK1 sensor through Get/SetFeature. We expose this
+// through SensorRange class, which has different units.
+struct SensorRangeImpl
+{
+ enum { PacketSize = 8 };
+ UByte Buffer[PacketSize];
+
+ UInt16 CommandId;
+ UInt16 AccelScale;
+ UInt16 GyroScale;
+ UInt16 MagScale;
+
+ SensorRangeImpl(const SensorRange& r, UInt16 commandId = 0);
+
+ void SetSensorRange(const SensorRange& r, UInt16 commandId = 0);
+ void GetSensorRange(SensorRange* r);
+
+ static SensorRange GetMaxSensorRange();
+
+ void Pack();
+ void Unpack();
+};
+
+struct SensorConfigImpl
+{
+ enum { PacketSize = 7 };
+ UByte Buffer[PacketSize];
+
+ // Flag values for Flags.
+ enum {
+ Flag_RawMode = 0x01,
+ Flag_CalibrationTest = 0x02, // Internal test mode
+ Flag_UseCalibration = 0x04,
+ Flag_AutoCalibration = 0x08,
+ Flag_MotionKeepAlive = 0x10,
+ Flag_CommandKeepAlive = 0x20,
+ Flag_SensorCoordinates = 0x40
+ };
+
+ UInt16 CommandId;
+ UByte Flags;
+ UInt16 PacketInterval;
+ UInt16 KeepAliveIntervalMs;
+
+ SensorConfigImpl();
+
+ void SetSensorCoordinates(bool sensorCoordinates);
+ bool IsUsingSensorCoordinates() const;
+
+ void Pack();
+ void Unpack();
+};
+
+struct SensorFactoryCalibrationImpl
+{
+ enum { PacketSize = 69 };
+ UByte Buffer[PacketSize];
+
+ Vector3f AccelOffset;
+ Vector3f GyroOffset;
+ Matrix4f AccelMatrix;
+ Matrix4f GyroMatrix;
+ float Temperature;
+
+ SensorFactoryCalibrationImpl();
+
+ void Pack(); // Not yet implemented.
+ void Unpack();
+};
+
+
+// SensorKeepAlive - feature report that needs to be sent at regular intervals for sensor
+// to receive commands.
+struct SensorKeepAliveImpl
+{
+ enum { PacketSize = 5 };
+ UByte Buffer[PacketSize];
+
+ UInt16 CommandId;
+ UInt16 KeepAliveIntervalMs;
+
+ SensorKeepAliveImpl(UInt16 interval = 0, UInt16 commandId = 0);
+
+ void Pack();
+ void Unpack();
+};
+
+struct TrackerSample
+{
+ SInt32 AccelX, AccelY, AccelZ;
+ SInt32 GyroX, GyroY, GyroZ;
+};
+
+enum LastCommandIdFlags
+{
+ LastCommandId_Shutter = 1,
+ LastCommandId_LEDs = 2
+};
+
+} // namespace OVR
+
+#endif // OVR_SensorImpl_Common_h
diff --git a/LibOVR/Src/OVR_SensorTimeFilter.cpp b/LibOVR/Src/OVR_SensorTimeFilter.cpp
new file mode 100644
index 0000000..ee0c385
--- /dev/null
+++ b/LibOVR/Src/OVR_SensorTimeFilter.cpp
@@ -0,0 +1,385 @@
+/************************************************************************************
+
+PublicHeader: None
+Filename : OVR_SensorTimeFilter.cpp
+Content : Class to filter HMD time and convert it to system time
+Created : December 20, 2013
+Author : Michael Antonov
+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 "OVR_SensorTimeFilter.h"
+#include "Kernel/OVR_Log.h"
+
+
+#include <stdio.h>
+#include <math.h>
+
+namespace OVR {
+
+// Comment out for debug logging to file
+//#define OVR_TIMEFILTER_LOG_CODE( code ) code
+#define OVR_TIMEFILTER_LOG_CODE( code )
+
+#if defined(OVR_OS_ANDROID)
+ #define OVR_TIMEFILTER_LOG_FILENAME "/sdcard/TimeFilterLog.txt"
+#elif defined(OVR_OS_WIN32)
+ #define OVR_TIMEFILTER_LOG_FILENAME "C:\\TimeFilterLog.txt"
+#else
+ #define OVR_TIMEFILTER_LOG_FILENAME "TimeFilterLog.txt"
+#endif
+
+OVR_TIMEFILTER_LOG_CODE( FILE* pTFLogFile = 0; )
+
+
+// Ideally, the following would always be true:
+// - NewSampleTime > PrevSample
+// - NewSampleTime < now systemTime
+// - (NewSampleTime - PrevSampleTime) == integration delta, matching
+// HW sample time difference + drift
+//
+// In practice, these issues affect us:
+// - System thread can be suspended for a while
+// - System de-buffering of recorded samples cause deviceTime to advance up
+// much faster then system time for ~100+ samples
+// - Device (DK1) and system clock granularities are high; this can
+// lead to potentially having estimations in the future
+//
+
+
+// ***** TimerFilter
+
+SensorTimeFilter::SensorTimeFilter(const Settings& settings)
+{
+ FilterSettings = settings;
+
+ ClockInitialized = false;
+ ClockDelta = 0;
+ ClockDeltaDriftPerSecond = 0;
+ ClockDeltaCorrectPerSecond = 0;
+ ClockDeltaCorrectSecondsLeft = 0;
+ OldClockDeltaDriftExpire = 0;
+
+ LastLargestDeviceTime = 0;
+ PrevSystemTime = 0;
+ PastSampleResetTime = 0;
+
+ MinWindowsCollected = 0;
+ MinWindowDuration = 0; // assigned later
+ MinWindowLastTime = 0;
+ MinWindowSamples = settings.MinSamples; // Force initialization
+
+ OVR_TIMEFILTER_LOG_CODE( pTFLogFile = fopen(OVR_TIMEFILTER_LOG_FILENAME, "w+"); )
+}
+
+
+double SensorTimeFilter::SampleToSystemTime(double sampleDeviceTime, double systemTime,
+ double prevResult, const char* debugTag)
+{
+ double clockDelta = systemTime - sampleDeviceTime + FilterSettings.ClockDeltaAdjust;
+ double deviceTimeDelta = sampleDeviceTime - LastLargestDeviceTime;
+ double result;
+
+ // Collect a sample ClockDelta for a "MinimumWindow" or process
+ // the window by adjusting drift rates if it's full of samples.
+ // - (deviceTimeDelta < 1.0f) is a corner cases, as it would imply timestamp skip/wrap.
+
+ if (ClockInitialized)
+ {
+ // Samples in the past commonly occur if they come from separately incrementing
+ // data channels. Just adjust them with ClockDelta.
+
+ if (deviceTimeDelta < 0.0)
+ {
+ result = sampleDeviceTime + ClockDelta;
+
+ if (result > (prevResult - 0.00001))
+ goto clamp_and_log_result;
+
+ // Consistent samples less then prevResult for indicate a back-jump or bad input.
+ // In this case we return prevResult for a while, then reset filter if it keeps going.
+ if (PastSampleResetTime < 0.0001)
+ {
+ PastSampleResetTime = systemTime + FilterSettings.PastSampleResetSeconds;
+ goto clamp_and_log_result;
+ }
+ else if (systemTime > PastSampleResetTime)
+ {
+ OVR_DEBUG_LOG(("SensorTimeFilter - Filtering reset due to samples in the past!\n"));
+ initClockSampling(sampleDeviceTime, clockDelta);
+ // Fall through to below, to ' PastSampleResetTime = 0.0; '
+ }
+ else
+ {
+ goto clamp_and_log_result;
+ }
+ }
+
+ // Most common case: Record window sample.
+ else if ( (deviceTimeDelta < 1.0f) &&
+ ( (sampleDeviceTime < MinWindowLastTime) ||
+ (MinWindowSamples < FilterSettings.MinSamples) ) )
+ {
+ // Pick minimum ClockDelta sample.
+ if (clockDelta < MinWindowClockDelta)
+ MinWindowClockDelta = clockDelta;
+ MinWindowSamples++;
+ }
+ else
+ {
+ processFinishedMinWindow(sampleDeviceTime, clockDelta);
+ }
+
+ PastSampleResetTime = 0.0;
+ }
+ else
+ {
+ initClockSampling(sampleDeviceTime, clockDelta);
+ }
+
+
+ // Clock adjustment for drift.
+ ClockDelta += ClockDeltaDriftPerSecond * deviceTimeDelta;
+
+ // ClockDelta "nudging" towards last known MinWindowClockDelta.
+ if (ClockDeltaCorrectSecondsLeft > 0.000001)
+ {
+ double correctTimeDelta = deviceTimeDelta;
+ if (deviceTimeDelta > ClockDeltaCorrectSecondsLeft)
+ correctTimeDelta = ClockDeltaCorrectSecondsLeft;
+ ClockDeltaCorrectSecondsLeft -= correctTimeDelta;
+
+ ClockDelta += ClockDeltaCorrectPerSecond * correctTimeDelta;
+ }
+
+ // Record largest device time, so we know what samples to use in accumulation
+ // of min-window in the future.
+ LastLargestDeviceTime = sampleDeviceTime;
+
+ // Compute our resulting sample time after ClockDelta adjustment.
+ result = sampleDeviceTime + ClockDelta;
+
+
+clamp_and_log_result:
+
+ OVR_TIMEFILTER_LOG_CODE( double savedResult = result; )
+
+ // Clamp to ensure that result >= PrevResult, or not to far in the future.
+ // Future clamp primarily happens in the very beginning if we are de-queuing
+ // system buffer full of samples.
+ if (result < prevResult)
+ {
+ result = prevResult;
+ }
+ if (result > (systemTime + FilterSettings.FutureClamp))
+ {
+ result = (systemTime + FilterSettings.FutureClamp);
+ }
+
+ OVR_TIMEFILTER_LOG_CODE(
+
+ // Tag lines that were outside desired range, with '<' or '>'.
+ char rangeClamp = ' ';
+ char resultDeltaFar = ' ';
+
+ if (savedResult > (systemTime + 0.0000001))
+ rangeClamp = '>';
+ if (savedResult < prevResult)
+ rangeClamp = '<';
+
+ // Tag any result delta outside desired threshold with a '*'.
+ if (fabs(deviceTimeDelta - (result - prevResult)) >= 0.00002)
+ resultDeltaFar = '*';
+
+ fprintf(pTFLogFile, "Res%s = %13.7f, dt = % 8.7f, ClkD = %13.6f "
+ "sysT = %13.6f, sysDt = %f, "
+ "sysDiff = % f, devT = %11.6f, ddevT = %9.6f %c%c\n",
+ debugTag, result, result - prevResult, ClockDelta,
+ systemTime, systemTime - PrevSystemTime,
+ -(systemTime - result), // Negatives in the past, positive > now.
+ sampleDeviceTime, deviceTimeDelta, rangeClamp, resultDeltaFar);
+
+ ) // OVR_TIMEFILTER_LOG_CODE()
+ OVR_UNUSED(debugTag);
+
+ // Record prior values. Useful or logging and clamping.
+ PrevSystemTime = systemTime;
+
+ return result;
+}
+
+
+void SensorTimeFilter::initClockSampling(double sampleDeviceTime, double clockDelta)
+{
+ ClockInitialized = true;
+ ClockDelta = clockDelta;
+ ClockDeltaDriftPerSecond = 0;
+ OldClockDeltaDriftExpire = 0;
+ ClockDeltaCorrectSecondsLeft = 0;
+ ClockDeltaCorrectPerSecond = 0;
+
+ MinWindowsCollected = 0;
+ MinWindowDuration = 0.25;
+ MinWindowClockDelta = clockDelta;
+ MinWindowLastTime = sampleDeviceTime + MinWindowDuration;
+ MinWindowSamples = 0;
+}
+
+
+void SensorTimeFilter::processFinishedMinWindow(double sampleDeviceTime, double clockDelta)
+{
+ MinRecord newRec = { MinWindowClockDelta, sampleDeviceTime };
+
+ double clockDeltaDiff = MinWindowClockDelta - ClockDelta;
+ double absClockDeltaDiff = fabs(clockDeltaDiff);
+
+
+ // Abrupt change causes Reset of minClockDelta collection.
+ // > 8 ms would a Large jump in a minimum sample, as those are usually stable.
+ // > 1 second intantaneous jump would land us here as well, as that would imply
+ // device being suspended, clock wrap or some other unexpected issue.
+ if ((absClockDeltaDiff > 0.008) ||
+ ((sampleDeviceTime - LastLargestDeviceTime) >= 1.0))
+ {
+ OVR_TIMEFILTER_LOG_CODE(
+ fprintf(pTFLogFile,
+ "\nMinWindow Finished: %d Samples, MinWindowClockDelta=%f, MW-CD=%f,"
+ " ** ClockDelta Reset **\n\n",
+ MinWindowSamples, MinWindowClockDelta, MinWindowClockDelta-ClockDelta);
+ )
+
+ // Use old collected ClockDeltaDriftPerSecond drift value
+ // up to 1 minute until we collect better samples.
+ if (!MinRecords.IsEmpty())
+ {
+ OldClockDeltaDriftExpire = MinRecords.GetNewest().LastSampleDeviceTime -
+ MinRecords.GetOldest().LastSampleDeviceTime;
+ if (OldClockDeltaDriftExpire > 60.0)
+ OldClockDeltaDriftExpire = 60.0;
+ OldClockDeltaDriftExpire += sampleDeviceTime;
+ }
+
+ // Jump to new ClockDelta value.
+ if ((sampleDeviceTime - LastLargestDeviceTime) > 1.0)
+ ClockDelta = clockDelta;
+ else
+ ClockDelta = MinWindowClockDelta;
+
+ ClockDeltaCorrectSecondsLeft = 0;
+ ClockDeltaCorrectPerSecond = 0;
+
+ // Reset buffers, we'll be collecting a new MinWindow.
+ MinRecords.Reset();
+ MinWindowsCollected = 0;
+ MinWindowDuration = 0.25;
+ MinWindowSamples = 0;
+ }
+ else
+ {
+ OVR_ASSERT(MinWindowSamples >= FilterSettings.MinSamples);
+
+ double timeElapsed = 0;
+
+ // If we have older values, use them to update clock drift in
+ // ClockDeltaDriftPerSecond
+ if (!MinRecords.IsEmpty() && (sampleDeviceTime > OldClockDeltaDriftExpire))
+ {
+ MinRecord rec = MinRecords.GetOldest();
+
+ // Compute clock rate of drift.
+ timeElapsed = sampleDeviceTime - rec.LastSampleDeviceTime;
+
+ // Check for divide by zero shouldn't be necessary here, but just be be safe...
+ if (timeElapsed > 0.000001)
+ {
+ ClockDeltaDriftPerSecond = (MinWindowClockDelta - rec.MinClockDelta) / timeElapsed;
+ ClockDeltaDriftPerSecond = clampRate(ClockDeltaDriftPerSecond,
+ FilterSettings.MaxChangeRate);
+ }
+ else
+ {
+ ClockDeltaDriftPerSecond = 0.0;
+ }
+ }
+
+ MinRecords.AddRecord(newRec);
+
+
+ // Catchup correction nudges ClockDelta towards MinWindowClockDelta.
+ // These are needed because clock drift correction alone is not enough
+ // for past accumulated error/high-granularity clock delta changes.
+ // The further away we are, the stronger correction we apply.
+ // Correction has timeout, as we don't want it to overshoot in case
+ // of a large delay between samples.
+
+ if (absClockDeltaDiff >= 0.00125)
+ {
+ // Correct large discrepancy immediately.
+ if (absClockDeltaDiff > 0.00175)
+ {
+ if (clockDeltaDiff > 0)
+ ClockDelta += (clockDeltaDiff - 0.00175);
+ else
+ ClockDelta += (clockDeltaDiff + 0.00175);
+
+ clockDeltaDiff = MinWindowClockDelta - ClockDelta;
+ }
+
+ ClockDeltaCorrectPerSecond = clockDeltaDiff;
+ ClockDeltaCorrectSecondsLeft = 1.0;
+ }
+ else if (absClockDeltaDiff > 0.0005)
+ {
+ ClockDeltaCorrectPerSecond = clockDeltaDiff / 8.0;
+ ClockDeltaCorrectSecondsLeft = 8.0;
+ }
+ else
+ {
+ ClockDeltaCorrectPerSecond = clockDeltaDiff / 15.0;
+ ClockDeltaCorrectSecondsLeft = 15.0;
+ }
+
+ ClockDeltaCorrectPerSecond = clampRate(ClockDeltaCorrectPerSecond,
+ FilterSettings.MaxCorrectRate);
+
+ OVR_TIMEFILTER_LOG_CODE(
+ fprintf(pTFLogFile,
+ "\nMinWindow Finished: %d Samples, MinWindowClockDelta=%f, MW-CD=%f,"
+ " tileElapsed=%f, ClockChange=%f, ClockCorrect=%f\n\n",
+ MinWindowSamples, MinWindowClockDelta, MinWindowClockDelta-ClockDelta,
+ timeElapsed, ClockDeltaDriftPerSecond, ClockDeltaCorrectPerSecond);
+ )
+ }
+
+ // New MinClockDelta collection window.
+ // Switch to longer duration after first few windows.
+ MinWindowsCollected ++;
+ if (MinWindowsCollected > 5)
+ MinWindowDuration = 0.5;
+
+ MinWindowClockDelta = clockDelta;
+ MinWindowLastTime = sampleDeviceTime + MinWindowDuration;
+ MinWindowSamples = 0;
+}
+
+
+} // namespace OVR
+
diff --git a/LibOVR/Src/OVR_SensorTimeFilter.h b/LibOVR/Src/OVR_SensorTimeFilter.h
new file mode 100644
index 0000000..409fe66
--- /dev/null
+++ b/LibOVR/Src/OVR_SensorTimeFilter.h
@@ -0,0 +1,226 @@
+/************************************************************************************
+
+PublicHeader: None
+Filename : OVR_SensorTimeFilter.h
+Content : Class to filter HMD time and convert it to system time
+Created : December 20, 2013
+Author : Michael Antonov
+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_SensorTimeFilter_h
+#define OVR_SensorTimeFilter_h
+
+#include "Kernel/OVR_Types.h"
+
+namespace OVR {
+
+
+//-----------------------------------------------------------------------------------
+// ***** SensorTimeFilter
+
+// SensorTimeFilter converts sample device time, in seconds, to absolute system
+// time. It filter maintains internal state to estimate the following:
+//
+// - Difference between system and device time values (ClockDelta).
+// ~= (systemTime - deviceTime)
+// - Drift rate between system and device clocks (ClockDeltaDriftPerSecond).
+//
+// Additionally, the following criteria are enforced:
+// - Resulting samples must be increasing, compared to prevSample.
+// - Returned sample time should not exceed 'now' system time by more then a fixed
+// value.
+// * Ideally this should be 0, however, enforcing this is hard when clocks
+// have high discrete values.
+// - Returned sample AbsoluteTime values deltas are very close to HW samples,
+// adjusted by drift rate. Note that this is not always possible due to clamping,
+// in which case it is better to use ScaleTimeUnit(deviceTimeDelta)
+// for integration.
+//
+// Algorithm: We collect minimum ClockDelta on windows of
+// consecutive samples (500 ms each set). Long term difference between sample
+// set minimums is drift. ClockDelta is also continually nudged towards most recent
+// minimum.
+
+class SensorTimeFilter
+{
+public:
+
+ // It may be desirable to configure these per device/platform.
+ // For example, rates can be tighter for DK2 because of microsecond clock.
+ struct Settings
+ {
+ Settings(int minSamples = 50,
+ double clockDeltaAdjust = -0.0002, // 200 mks in the past.
+ double futureClamp = 0.0008)
+ : MinSamples(minSamples),
+ ClockDeltaAdjust(clockDeltaAdjust),
+ // PastClamp(-0.032),
+ FutureClamp(futureClamp),
+ PastSampleResetSeconds(0.2),
+ MaxChangeRate(0.004),
+ MaxCorrectRate(0.004)
+ { }
+
+ // Minimum number of samples in a window. Different number may be desirable
+ // based on how often samples come in.
+ int MinSamples;
+
+ // Factor always added to ClockDelta, used to skew all values into the past by fixed
+ // value and reduce the chances we report a sample "in the future".
+ double ClockDeltaAdjust;
+ // How much away in a past can a sample be before being shifted closer to system time.
+ //double PastClamp;
+ // How much larger then systemTime can a value be? Set to 0 to clamp to null,
+ // put small positive value is better.
+ double FutureClamp;
+
+ // How long (in system time) do we take to reset the system if a device sample.
+ // comes in the past. Generally, this should never happened, but exists as a way to
+ // address bad timing coming form firmware (temp CCove issue, presumably fixed)
+ // or buggy input.
+ double PastSampleResetSeconds;
+
+ // Maximum drift change and near-term correction rates, in seconds.
+ double MaxChangeRate;
+ double MaxCorrectRate;
+ };
+
+
+ SensorTimeFilter(const Settings& settings = Settings());
+
+
+ // Convert device sample time to system time, driving clock drift estimation.
+ // Input: SampleTime, System Time
+ // Return: Absolute system time for sample
+ double SampleToSystemTime(double sampleDeviceTime, double systemTime,
+ double prevResult, const char* debugTag = "");
+
+
+ // Scales device time to account for drift.
+ double ScaleTimeUnit(double deviceClockDelta)
+ {
+ return deviceClockDelta * (1.0 + ClockDeltaDriftPerSecond);
+ }
+
+ // Return currently estimated difference between the clocks.
+ double GetClockDelta() const { return ClockDelta; }
+
+
+private:
+
+ void initClockSampling(double sampleDeviceTime, double clockDelta);
+ void processFinishedMinWindow(double sampleDeviceTime, double systemTime);
+
+ static double clampRate(double rate, double limit)
+ {
+ if (rate > limit)
+ rate = limit;
+ else if (rate < -limit)
+ rate = -limit;
+ return rate;
+ }
+
+
+ // Describes minimum observed ClockDelta for sample set seen in the past.
+ struct MinRecord
+ {
+ double MinClockDelta;
+ double LastSampleDeviceTime;
+ };
+
+ // Circular buffer storing MinRecord(s) several minutes into the past.
+ // Oldest value here is used to help estimate drift.
+ class MinRecordBuffer
+ {
+ enum { BufferSize = 60*6 }; // 3 min
+ public:
+
+ MinRecordBuffer() : Head(0), Tail(0) { }
+
+ void Reset() { Head = Tail = 0; }
+ bool IsEmpty() const { return Head == Tail; }
+
+ const MinRecord& GetOldest() const
+ {
+ OVR_ASSERT(!IsEmpty());
+ return Records[Tail];
+ }
+ const MinRecord& GetNewest() const
+ {
+ OVR_ASSERT(!IsEmpty());
+ return Records[(BufferSize + Head - 1) % BufferSize];
+ }
+
+ void AddRecord(const MinRecord& rec)
+ {
+ Records[Head] = rec;
+ Head = advanceIndex(Head);
+ if (Head == Tail)
+ Tail = advanceIndex(Tail);
+ }
+
+ private:
+
+ static int advanceIndex(int index)
+ {
+ index++;
+ if (index >= BufferSize)
+ index = 0;
+ return index;
+ }
+
+ MinRecord Records[BufferSize];
+ int Head; // Location we will most recent entry, unused.
+ int Tail; // Oldest entry.
+ };
+
+
+ Settings FilterSettings;
+
+ // Clock correction state.
+ bool ClockInitialized;
+ double ClockDelta;
+ double ClockDeltaDriftPerSecond;
+ double ClockDeltaCorrectPerSecond;
+ double ClockDeltaCorrectSecondsLeft;
+ double OldClockDeltaDriftExpire;
+
+ double LastLargestDeviceTime;
+ double PrevSystemTime;
+ // Used to reset timing if we get multiple "samples in the past"
+ double PastSampleResetTime;
+
+ // "MinWindow" is a block of time during which minimum ClockDelta values
+ // are collected into MinWindowClockDelta.
+ int MinWindowsCollected;
+ double MinWindowDuration; // Device sample seconds
+ double MinWindowLastTime;
+ double MinWindowClockDelta;
+ int MinWindowSamples;
+
+ // Historic buffer used to determine rate of clock change over time.
+ MinRecordBuffer MinRecords;
+};
+
+} // namespace OVR
+
+#endif // OVR_SensorTimeFilter_h
diff --git a/LibOVR/Src/OVR_Stereo.cpp b/LibOVR/Src/OVR_Stereo.cpp
new file mode 100644
index 0000000..7e78b82
--- /dev/null
+++ b/LibOVR/Src/OVR_Stereo.cpp
@@ -0,0 +1,1794 @@
+/************************************************************************************
+
+Filename : OVR_Stereo.cpp
+Content : Stereo rendering functions
+Created : November 30, 2013
+Authors : Tom Fosyth
+
+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 "OVR_Stereo.h"
+#include "OVR_Profile.h"
+#include "Kernel/OVR_Log.h"
+#include "Kernel/OVR_Alg.h"
+
+//To allow custom distortion to be introduced to CatMulSpline.
+float (*CustomDistortion)(float) = NULL;
+float (*CustomDistortionInv)(float) = NULL;
+
+
+namespace OVR {
+
+
+using namespace Alg;
+
+//-----------------------------------------------------------------------------------
+
+// Inputs are 4 points (pFitX[0],pFitY[0]) through (pFitX[3],pFitY[3])
+// Result is four coefficients in pResults[0] through pResults[3] such that
+// y = pResult[0] + x * ( pResult[1] + x * ( pResult[2] + x * ( pResult[3] ) ) );
+// passes through all four input points.
+// Return is true if it succeeded, false if it failed (because two control points
+// have the same pFitX value).
+bool FitCubicPolynomial ( float *pResult, const float *pFitX, const float *pFitY )
+{
+ float d0 = ( ( pFitX[0]-pFitX[1] ) * ( pFitX[0]-pFitX[2] ) * ( pFitX[0]-pFitX[3] ) );
+ float d1 = ( ( pFitX[1]-pFitX[2] ) * ( pFitX[1]-pFitX[3] ) * ( pFitX[1]-pFitX[0] ) );
+ float d2 = ( ( pFitX[2]-pFitX[3] ) * ( pFitX[2]-pFitX[0] ) * ( pFitX[2]-pFitX[1] ) );
+ float d3 = ( ( pFitX[3]-pFitX[0] ) * ( pFitX[3]-pFitX[1] ) * ( pFitX[3]-pFitX[2] ) );
+
+ if ( ( d0 == 0.0f ) || ( d1 == 0.0f ) || ( d2 == 0.0f ) || ( d3 == 0.0f ) )
+ {
+ return false;
+ }
+
+ float f0 = pFitY[0] / d0;
+ float f1 = pFitY[1] / d1;
+ float f2 = pFitY[2] / d2;
+ float f3 = pFitY[3] / d3;
+
+ pResult[0] = -( f0*pFitX[1]*pFitX[2]*pFitX[3]
+ + f1*pFitX[0]*pFitX[2]*pFitX[3]
+ + f2*pFitX[0]*pFitX[1]*pFitX[3]
+ + f3*pFitX[0]*pFitX[1]*pFitX[2] );
+ pResult[1] = f0*(pFitX[1]*pFitX[2] + pFitX[2]*pFitX[3] + pFitX[3]*pFitX[1])
+ + f1*(pFitX[0]*pFitX[2] + pFitX[2]*pFitX[3] + pFitX[3]*pFitX[0])
+ + f2*(pFitX[0]*pFitX[1] + pFitX[1]*pFitX[3] + pFitX[3]*pFitX[0])
+ + f3*(pFitX[0]*pFitX[1] + pFitX[1]*pFitX[2] + pFitX[2]*pFitX[0]);
+ pResult[2] = -( f0*(pFitX[1]+pFitX[2]+pFitX[3])
+ + f1*(pFitX[0]+pFitX[2]+pFitX[3])
+ + f2*(pFitX[0]+pFitX[1]+pFitX[3])
+ + f3*(pFitX[0]+pFitX[1]+pFitX[2]) );
+ pResult[3] = f0 + f1 + f2 + f3;
+
+ return true;
+}
+
+
+
+float EvalCatmullRom10Spline ( float const *K, float scaledVal )
+{
+ int const NumSegments = LensConfig::NumCoefficients;
+
+ float scaledValFloor = floorf ( scaledVal );
+ scaledValFloor = Alg::Max ( 0.0f, Alg::Min ( (float)(NumSegments-1), scaledValFloor ) );
+ float t = scaledVal - scaledValFloor;
+ int k = (int)scaledValFloor;
+
+ float p0, p1;
+ float m0, m1;
+ switch ( k )
+ {
+ case 0:
+ // Curve starts at 1.0 with gradient K[1]-K[0]
+ p0 = 1.0f;
+ m0 = ( K[1] - K[0] ); // general case would have been (K[1]-K[-1])/2
+ p1 = K[1];
+ m1 = 0.5f * ( K[2] - K[0] );
+ break;
+ default:
+ // General case
+ p0 = K[k ];
+ m0 = 0.5f * ( K[k+1] - K[k-1] );
+ p1 = K[k+1];
+ m1 = 0.5f * ( K[k+2] - K[k ] );
+ break;
+ case NumSegments-2:
+ // Last tangent is just the slope of the last two points.
+ p0 = K[NumSegments-2];
+ m0 = 0.5f * ( K[NumSegments-1] - K[NumSegments-2] );
+ p1 = K[NumSegments-1];
+ m1 = K[NumSegments-1] - K[NumSegments-2];
+ break;
+ case NumSegments-1:
+ // Beyond the last segment it's just a straight line
+ p0 = K[NumSegments-1];
+ m0 = K[NumSegments-1] - K[NumSegments-2];
+ p1 = p0 + m0;
+ m1 = m0;
+ break;
+ }
+
+ float omt = 1.0f - t;
+ float res = ( p0 * ( 1.0f + 2.0f * t ) + m0 * t ) * omt * omt
+ + ( p1 * ( 1.0f + 2.0f * omt ) - m1 * omt ) * t * t;
+
+ return res;
+}
+
+
+
+
+// Converts a Profile eyecup string into an eyecup enumeration
+void SetEyeCup(HmdRenderInfo* renderInfo, const char* cup)
+{
+ if (OVR_strcmp(cup, "A") == 0)
+ renderInfo->EyeCups = EyeCup_DK1A;
+ else if (OVR_strcmp(cup, "B") == 0)
+ renderInfo->EyeCups = EyeCup_DK1B;
+ else if (OVR_strcmp(cup, "C") == 0)
+ renderInfo->EyeCups = EyeCup_DK1C;
+ else if (OVR_strcmp(cup, "Orange A") == 0)
+ renderInfo->EyeCups = EyeCup_OrangeA;
+ else if (OVR_strcmp(cup, "Red A") == 0)
+ renderInfo->EyeCups = EyeCup_RedA;
+ else if (OVR_strcmp(cup, "Pink A") == 0)
+ renderInfo->EyeCups = EyeCup_PinkA;
+ else if (OVR_strcmp(cup, "Blue A") == 0)
+ renderInfo->EyeCups = EyeCup_BlueA;
+ else
+ renderInfo->EyeCups = EyeCup_DK1A;
+}
+
+
+
+//-----------------------------------------------------------------------------------
+
+
+// The result is a scaling applied to the distance.
+float LensConfig::DistortionFnScaleRadiusSquared (float rsq) const
+{
+ float scale = 1.0f;
+ switch ( Eqn )
+ {
+ case Distortion_Poly4:
+ // This version is deprecated! Prefer one of the other two.
+ scale = ( K[0] + rsq * ( K[1] + rsq * ( K[2] + rsq * K[3] ) ) );
+ break;
+ case Distortion_RecipPoly4:
+ scale = 1.0f / ( K[0] + rsq * ( K[1] + rsq * ( K[2] + rsq * K[3] ) ) );
+ break;
+ case Distortion_CatmullRom10:{
+ // A Catmull-Rom spline through the values 1.0, K[1], K[2] ... K[10]
+ // evenly spaced in R^2 from 0.0 to MaxR^2
+ // K[0] controls the slope at radius=0.0, rather than the actual value.
+ const int NumSegments = LensConfig::NumCoefficients;
+ OVR_ASSERT ( NumSegments <= NumCoefficients );
+ float scaledRsq = (float)(NumSegments-1) * rsq / ( MaxR * MaxR );
+ scale = EvalCatmullRom10Spline ( K, scaledRsq );
+
+
+ //Intercept, and overrule if needed
+ if (CustomDistortion)
+ {
+ scale = CustomDistortion(rsq);
+ }
+
+ }break;
+ default:
+ OVR_ASSERT ( false );
+ break;
+ }
+ return scale;
+}
+
+// x,y,z components map to r,g,b
+Vector3f LensConfig::DistortionFnScaleRadiusSquaredChroma (float rsq) const
+{
+ float scale = DistortionFnScaleRadiusSquared ( rsq );
+ Vector3f scaleRGB;
+ scaleRGB.x = scale * ( 1.0f + ChromaticAberration[0] + rsq * ChromaticAberration[1] ); // Red
+ scaleRGB.y = scale; // Green
+ scaleRGB.z = scale * ( 1.0f + ChromaticAberration[2] + rsq * ChromaticAberration[3] ); // Blue
+ return scaleRGB;
+}
+
+// DistortionFnInverse computes the inverse of the distortion function on an argument.
+float LensConfig::DistortionFnInverse(float r) const
+{
+ OVR_ASSERT((r <= 20.0f));
+
+ float s, d;
+ float delta = r * 0.25f;
+
+ // Better to start guessing too low & take longer to converge than too high
+ // and hit singularities. Empirically, r * 0.5f is too high in some cases.
+ s = r * 0.25f;
+ d = fabs(r - DistortionFn(s));
+
+ for (int i = 0; i < 20; i++)
+ {
+ float sUp = s + delta;
+ float sDown = s - delta;
+ float dUp = fabs(r - DistortionFn(sUp));
+ float dDown = fabs(r - DistortionFn(sDown));
+
+ if (dUp < d)
+ {
+ s = sUp;
+ d = dUp;
+ }
+ else if (dDown < d)
+ {
+ s = sDown;
+ d = dDown;
+ }
+ else
+ {
+ delta *= 0.5f;
+ }
+ }
+
+ return s;
+}
+
+
+
+float LensConfig::DistortionFnInverseApprox(float r) const
+{
+ float rsq = r * r;
+ float scale = 1.0f;
+ switch ( Eqn )
+ {
+ case Distortion_Poly4:
+ // Deprecated
+ OVR_ASSERT ( false );
+ break;
+ case Distortion_RecipPoly4:
+ scale = 1.0f / ( InvK[0] + rsq * ( InvK[1] + rsq * ( InvK[2] + rsq * InvK[3] ) ) );
+ break;
+ case Distortion_CatmullRom10:{
+ // A Catmull-Rom spline through the values 1.0, K[1], K[2] ... K[9]
+ // evenly spaced in R^2 from 0.0 to MaxR^2
+ // K[0] controls the slope at radius=0.0, rather than the actual value.
+ const int NumSegments = LensConfig::NumCoefficients;
+ OVR_ASSERT ( NumSegments <= NumCoefficients );
+ float scaledRsq = (float)(NumSegments-1) * rsq / ( MaxInvR * MaxInvR );
+ scale = EvalCatmullRom10Spline ( InvK, scaledRsq );
+
+ //Intercept, and overrule if needed
+ if (CustomDistortionInv)
+ {
+ scale = CustomDistortionInv(rsq);
+ }
+
+ }break;
+ default:
+ OVR_ASSERT ( false );
+ break;
+ }
+ return r * scale;
+}
+
+void LensConfig::SetUpInverseApprox()
+{
+ float maxR = MaxInvR;
+
+ switch ( Eqn )
+ {
+ case Distortion_Poly4:
+ // Deprecated
+ OVR_ASSERT ( false );
+ break;
+ case Distortion_RecipPoly4:{
+
+ float sampleR[4];
+ float sampleRSq[4];
+ float sampleInv[4];
+ float sampleFit[4];
+
+ // Found heuristically...
+ sampleR[0] = 0.0f;
+ sampleR[1] = maxR * 0.4f;
+ sampleR[2] = maxR * 0.8f;
+ sampleR[3] = maxR * 1.5f;
+ for ( int i = 0; i < 4; i++ )
+ {
+ sampleRSq[i] = sampleR[i] * sampleR[i];
+ sampleInv[i] = DistortionFnInverse ( sampleR[i] );
+ sampleFit[i] = sampleR[i] / sampleInv[i];
+ }
+ sampleFit[0] = 1.0f;
+ FitCubicPolynomial ( InvK, sampleRSq, sampleFit );
+
+ #if 0
+ // Should be a nearly exact match on the chosen points.
+ OVR_ASSERT ( fabs ( DistortionFnInverse ( sampleR[0] ) - DistortionFnInverseApprox ( sampleR[0] ) ) / maxR < 0.0001f );
+ OVR_ASSERT ( fabs ( DistortionFnInverse ( sampleR[1] ) - DistortionFnInverseApprox ( sampleR[1] ) ) / maxR < 0.0001f );
+ OVR_ASSERT ( fabs ( DistortionFnInverse ( sampleR[2] ) - DistortionFnInverseApprox ( sampleR[2] ) ) / maxR < 0.0001f );
+ OVR_ASSERT ( fabs ( DistortionFnInverse ( sampleR[3] ) - DistortionFnInverseApprox ( sampleR[3] ) ) / maxR < 0.0001f );
+ // Should be a decent match on the rest of the range.
+ const int maxCheck = 20;
+ for ( int i = 0; i < maxCheck; i++ )
+ {
+ float checkR = (float)i * maxR / (float)maxCheck;
+ float realInv = DistortionFnInverse ( checkR );
+ float testInv = DistortionFnInverseApprox ( checkR );
+ float error = fabsf ( realInv - testInv ) / maxR;
+ OVR_ASSERT ( error < 0.1f );
+ }
+ #endif
+
+ }break;
+ case Distortion_CatmullRom10:{
+
+ const int NumSegments = LensConfig::NumCoefficients;
+ OVR_ASSERT ( NumSegments <= NumCoefficients );
+ for ( int i = 1; i < NumSegments; i++ )
+ {
+ float scaledRsq = (float)i;
+ float rsq = scaledRsq * MaxInvR * MaxInvR / (float)( NumSegments - 1);
+ float r = sqrtf ( rsq );
+ float inv = DistortionFnInverse ( r );
+ InvK[i] = inv / r;
+ InvK[0] = 1.0f; // TODO: fix this.
+ }
+
+#if 0
+ const int maxCheck = 20;
+ for ( int i = 0; i <= maxCheck; i++ )
+ {
+ float checkR = (float)i * MaxInvR / (float)maxCheck;
+ float realInv = DistortionFnInverse ( checkR );
+ float testInv = DistortionFnInverseApprox ( checkR );
+ float error = fabsf ( realInv - testInv ) / MaxR;
+ OVR_ASSERT ( error < 0.01f );
+ }
+#endif
+
+ }break;
+ }
+}
+
+
+void LensConfig::SetToIdentity()
+{
+ for ( int i = 0; i < NumCoefficients; i++ )
+ {
+ K[i] = 0.0f;
+ InvK[i] = 0.0f;
+ }
+ Eqn = Distortion_RecipPoly4;
+ K[0] = 1.0f;
+ InvK[0] = 1.0f;
+ MaxR = 1.0f;
+ MaxInvR = 1.0f;
+ ChromaticAberration[0] = 0.0f;
+ ChromaticAberration[1] = 0.0f;
+ ChromaticAberration[2] = 0.0f;
+ ChromaticAberration[3] = 0.0f;
+ MetersPerTanAngleAtCenter = 0.05f;
+}
+
+
+enum LensConfigStoredVersion
+{
+ LCSV_CatmullRom10Version1 = 1
+};
+
+// DO NOT CHANGE THESE ONCE THEY HAVE BEEN BAKED INTO FIRMWARE.
+// If something needs to change, add a new one!
+struct LensConfigStored_CatmullRom10Version1
+{
+ // All these items must be fixed-length integers - no "float", no "int", etc.
+ UInt16 VersionNumber; // Must be LCSV_CatmullRom10Version1
+
+ UInt16 K[11];
+ UInt16 MaxR;
+ UInt16 MetersPerTanAngleAtCenter;
+ UInt16 ChromaticAberration[4];
+ // InvK and MaxInvR are calculated on load.
+};
+
+UInt16 EncodeFixedPointUInt16 ( float val, UInt16 zeroVal, int fractionalBits )
+{
+ OVR_ASSERT ( ( fractionalBits >= 0 ) && ( fractionalBits < 31 ) );
+ float valWhole = val * (float)( 1 << fractionalBits );
+ valWhole += (float)zeroVal + 0.5f;
+ valWhole = floorf ( valWhole );
+ OVR_ASSERT ( ( valWhole >= 0.0f ) && ( valWhole < (float)( 1 << 16 ) ) );
+ return (UInt16)valWhole;
+}
+
+float DecodeFixedPointUInt16 ( UInt16 val, UInt16 zeroVal, int fractionalBits )
+{
+ OVR_ASSERT ( ( fractionalBits >= 0 ) && ( fractionalBits < 31 ) );
+ float valFloat = (float)val;
+ valFloat -= (float)zeroVal;
+ valFloat *= 1.0f / (float)( 1 << fractionalBits );
+ return valFloat;
+}
+
+
+// Returns true on success.
+bool LoadLensConfig ( LensConfig *presult, UByte const *pbuffer, int bufferSizeInBytes )
+{
+ if ( bufferSizeInBytes < 2 )
+ {
+ // Can't even tell the version number!
+ return false;
+ }
+ UInt16 version = DecodeUInt16 ( pbuffer + 0 );
+ switch ( version )
+ {
+ case LCSV_CatmullRom10Version1:
+ {
+ if ( bufferSizeInBytes < sizeof(LensConfigStored_CatmullRom10Version1) )
+ {
+ return false;
+ }
+ LensConfigStored_CatmullRom10Version1 lcs;
+ lcs.VersionNumber = DecodeUInt16 ( pbuffer + 0 );
+ for ( int i = 0; i < 11; i++ )
+ {
+ lcs.K[i] = DecodeUInt16 ( pbuffer + 2 + 2*i );
+ }
+ lcs.MaxR = DecodeUInt16 ( pbuffer + 24 );
+ lcs.MetersPerTanAngleAtCenter = DecodeUInt16 ( pbuffer + 26 );
+ for ( int i = 0; i < 4; i++ )
+ {
+ lcs.ChromaticAberration[i] = DecodeUInt16 ( pbuffer + 28 + 2*i );
+ }
+ OVR_COMPILER_ASSERT ( sizeof(lcs) == 36 );
+
+ // Convert to the real thing.
+ LensConfig result;
+ result.Eqn = Distortion_CatmullRom10;
+ for ( int i = 0; i < 11; i++ )
+ {
+ // K[] are mostly 1.something. They may get significantly bigger, but they never hit 0.0.
+ result.K[i] = DecodeFixedPointUInt16 ( lcs.K[i], 0, 14 );
+ }
+ // MaxR is tan(angle), so always >0, typically just over 1.0 (45 degrees half-fov),
+ // but may get arbitrarily high. tan(76)=4 is a very reasonable limit!
+ result.MaxR = DecodeFixedPointUInt16 ( lcs.MaxR, 0, 14 );
+ // MetersPerTanAngleAtCenter is also known as focal length!
+ // Typically around 0.04 for our current screens, minimum of 0, sensible maximum of 0.125 (i.e. 3 "extra" bits of fraction)
+ result.MetersPerTanAngleAtCenter = DecodeFixedPointUInt16 ( lcs.MetersPerTanAngleAtCenter, 0, 16+3 );
+ for ( int i = 0; i < 4; i++ )
+ {
+ // ChromaticAberration[] are mostly 0.0something, centered on 0.0. Largest seen is 0.04, so set max to 0.125 (i.e. 3 "extra" bits of fraction)
+ result.ChromaticAberration[i] = DecodeFixedPointUInt16 ( lcs.ChromaticAberration[i], 0x8000, 16+3 );
+ }
+ result.MaxInvR = result.DistortionFn ( result.MaxR );
+ result.SetUpInverseApprox();
+
+ OVR_ASSERT ( version == lcs.VersionNumber );
+
+ *presult = result;
+ }
+ break;
+ default:
+ // Unknown format.
+ return false;
+ break;
+ }
+ return true;
+}
+
+// Returns number of bytes needed.
+int SaveLensConfigSizeInBytes ( LensConfig const &config )
+{
+ OVR_UNUSED ( config );
+ return sizeof ( LensConfigStored_CatmullRom10Version1 );
+}
+
+// Returns true on success.
+bool SaveLensConfig ( UByte *pbuffer, int bufferSizeInBytes, LensConfig const &config )
+{
+ if ( bufferSizeInBytes < sizeof ( LensConfigStored_CatmullRom10Version1 ) )
+ {
+ return false;
+ }
+
+ // Construct the values.
+ LensConfigStored_CatmullRom10Version1 lcs;
+ lcs.VersionNumber = LCSV_CatmullRom10Version1;
+ for ( int i = 0; i < 11; i++ )
+ {
+ // K[] are mostly 1.something. They may get significantly bigger, but they never hit 0.0.
+ lcs.K[i] = EncodeFixedPointUInt16 ( config.K[i], 0, 14 );
+ }
+ // MaxR is tan(angle), so always >0, typically just over 1.0 (45 degrees half-fov),
+ // but may get arbitrarily high. tan(76)=4 is a very reasonable limit!
+ lcs.MaxR = EncodeFixedPointUInt16 ( config.MaxR, 0, 14 );
+ // MetersPerTanAngleAtCenter is also known as focal length!
+ // Typically around 0.04 for our current screens, minimum of 0, sensible maximum of 0.125 (i.e. 3 "extra" bits of fraction)
+ lcs.MetersPerTanAngleAtCenter = EncodeFixedPointUInt16 ( config.MetersPerTanAngleAtCenter, 0, 16+3 );
+ for ( int i = 0; i < 4; i++ )
+ {
+ // ChromaticAberration[] are mostly 0.0something, centered on 0.0. Largest seen is 0.04, so set max to 0.125 (i.e. 3 "extra" bits of fraction)
+ lcs.ChromaticAberration[i] = EncodeFixedPointUInt16 ( config.ChromaticAberration[i], 0x8000, 16+3 );
+ }
+
+
+ // Now store them out, sensitive to endinness.
+ EncodeUInt16 ( pbuffer + 0, lcs.VersionNumber );
+ for ( int i = 0; i < 11; i++ )
+ {
+ EncodeUInt16 ( pbuffer + 2 + 2*i, lcs.K[i] );
+ }
+ EncodeUInt16 ( pbuffer + 24, lcs.MaxR );
+ EncodeUInt16 ( pbuffer + 26, lcs.MetersPerTanAngleAtCenter );
+ for ( int i = 0; i < 4; i++ )
+ {
+ EncodeUInt16 ( pbuffer + 28 + 2*i, lcs.ChromaticAberration[i] );
+ }
+ OVR_COMPILER_ASSERT ( 36 == sizeof(lcs) );
+
+ return true;
+}
+
+#ifdef OVR_BUILD_DEBUG
+void TestSaveLoadLensConfig ( LensConfig const &config )
+{
+ OVR_ASSERT ( config.Eqn == Distortion_CatmullRom10 );
+ // As a test, make sure this can be encoded and decoded correctly.
+ const int bufferSize = 256;
+ UByte buffer[bufferSize];
+ OVR_ASSERT ( SaveLensConfigSizeInBytes ( config ) < bufferSize );
+ bool success;
+ success = SaveLensConfig ( buffer, bufferSize, config );
+ OVR_ASSERT ( success );
+ LensConfig testConfig;
+ success = LoadLensConfig ( &testConfig, buffer, bufferSize );
+ OVR_ASSERT ( success );
+ OVR_ASSERT ( testConfig.Eqn == config.Eqn );
+ for ( int i = 0; i < 11; i++ )
+ {
+ OVR_ASSERT ( fabs ( testConfig.K[i] - config.K[i] ) < 0.0001f );
+ }
+ OVR_ASSERT ( fabsf ( testConfig.MaxR - config.MaxR ) < 0.0001f );
+ OVR_ASSERT ( fabsf ( testConfig.MetersPerTanAngleAtCenter - config.MetersPerTanAngleAtCenter ) < 0.00001f );
+ for ( int i = 0; i < 4; i++ )
+ {
+ OVR_ASSERT ( fabsf ( testConfig.ChromaticAberration[i] - config.ChromaticAberration[i] ) < 0.00001f );
+ }
+}
+#endif
+
+
+
+//-----------------------------------------------------------------------------------
+
+// TBD: There is a question of whether this is the best file for CreateDebugHMDInfo. As long as there are many
+// constants for HmdRenderInfo here as well it is ok. The alternative would be OVR_Common_HMDDevice.cpp, but
+// that's specialized per platform... should probably move it there onces the code is in the common base class.
+
+HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType)
+{
+ HMDInfo info;
+
+ if ((hmdType != HmdType_DK1) &&
+ (hmdType != HmdType_CrystalCoveProto))
+ {
+ LogText("Debug HMDInfo - HmdType not supported. Defaulting to DK1.\n");
+ hmdType = HmdType_DK1;
+ }
+
+ // The alternative would be to initialize info.HmdType to HmdType_None instead. If we did that,
+ // code wouldn't be "maximally compatible" and devs wouldn't know what device we are
+ // simulating... so if differentiation becomes necessary we better add Debug flag in the future.
+ info.HmdType = hmdType;
+ info.Manufacturer = "Oculus VR";
+
+ switch(hmdType)
+ {
+ case HmdType_DK1:
+ info.ProductName = "Oculus Rift DK1";
+ info.ResolutionInPixels = Sizei ( 1280, 800 );
+ info.ScreenSizeInMeters = Sizef ( 0.1498f, 0.0936f );
+ info.ScreenGapSizeInMeters = 0.0f;
+ info.CenterFromTopInMeters = 0.0468f;
+ info.LensSeparationInMeters = 0.0635f;
+ info.Shutter.Type = HmdShutter_RollingTopToBottom;
+ info.Shutter.VsyncToNextVsync = ( 1.0f / 60.0f );
+ info.Shutter.VsyncToFirstScanline = 0.000052f;
+ info.Shutter.FirstScanlineToLastScanline = 0.016580f;
+ info.Shutter.PixelSettleTime = 0.015f;
+ info.Shutter.PixelPersistence = ( 1.0f / 60.0f );
+ break;
+
+ case HmdType_CrystalCoveProto:
+ info.ProductName = "Oculus Rift Crystal Cove";
+ info.ResolutionInPixels = Sizei ( 1920, 1080 );
+ info.ScreenSizeInMeters = Sizef ( 0.12576f, 0.07074f );
+ info.ScreenGapSizeInMeters = 0.0f;
+ info.CenterFromTopInMeters = info.ScreenSizeInMeters.h * 0.5f;
+ info.LensSeparationInMeters = 0.0635f;
+ info.Shutter.Type = HmdShutter_RollingRightToLeft;
+ info.Shutter.VsyncToNextVsync = ( 1.0f / 76.0f );
+ info.Shutter.VsyncToFirstScanline = 0.0000273f;
+ info.Shutter.FirstScanlineToLastScanline = 0.0131033f;
+ info.Shutter.PixelSettleTime = 0.0f;
+ info.Shutter.PixelPersistence = 0.18f * info.Shutter.VsyncToNextVsync;
+ break;
+
+ case HmdType_DK2:
+ info.ProductName = "Oculus Rift DK2";
+ info.ResolutionInPixels = Sizei ( 1920, 1080 );
+ info.ScreenSizeInMeters = Sizef ( 0.12576f, 0.07074f );
+ info.ScreenGapSizeInMeters = 0.0f;
+ info.CenterFromTopInMeters = info.ScreenSizeInMeters.h * 0.5f;
+ info.LensSeparationInMeters = 0.0635f;
+ info.Shutter.Type = HmdShutter_RollingRightToLeft;
+ info.Shutter.VsyncToNextVsync = ( 1.0f / 76.0f );
+ info.Shutter.VsyncToFirstScanline = 0.0000273f;
+ info.Shutter.FirstScanlineToLastScanline = 0.0131033f;
+ info.Shutter.PixelSettleTime = 0.0f;
+ info.Shutter.PixelPersistence = 0.18f * info.Shutter.VsyncToNextVsync;
+ break;
+ }
+
+ return info;
+}
+
+
+
+// profile may be NULL, in which case it uses the hard-coded defaults.
+HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo,
+ Profile const *profile /*=NULL*/,
+ DistortionEqnType distortionType /*= Distortion_CatmullRom10*/,
+ EyeCupType eyeCupOverride /*= EyeCup_LAST*/ )
+{
+ HmdRenderInfo renderInfo;
+
+ renderInfo.HmdType = hmdInfo.HmdType;
+ renderInfo.ResolutionInPixels = hmdInfo.ResolutionInPixels;
+ renderInfo.ScreenSizeInMeters = hmdInfo.ScreenSizeInMeters;
+ renderInfo.CenterFromTopInMeters = hmdInfo.CenterFromTopInMeters;
+ renderInfo.ScreenGapSizeInMeters = hmdInfo.ScreenGapSizeInMeters;
+ renderInfo.LensSeparationInMeters = hmdInfo.LensSeparationInMeters;
+
+ OVR_ASSERT ( sizeof(renderInfo.Shutter) == sizeof(hmdInfo.Shutter) ); // Try to keep the files in sync!
+ renderInfo.Shutter.Type = hmdInfo.Shutter.Type;
+ renderInfo.Shutter.VsyncToNextVsync = hmdInfo.Shutter.VsyncToNextVsync;
+ renderInfo.Shutter.VsyncToFirstScanline = hmdInfo.Shutter.VsyncToFirstScanline;
+ renderInfo.Shutter.FirstScanlineToLastScanline = hmdInfo.Shutter.FirstScanlineToLastScanline;
+ renderInfo.Shutter.PixelSettleTime = hmdInfo.Shutter.PixelSettleTime;
+ renderInfo.Shutter.PixelPersistence = hmdInfo.Shutter.PixelPersistence;
+
+ renderInfo.LensDiameterInMeters = 0.035f;
+ renderInfo.LensSurfaceToMidplateInMeters = 0.025f;
+ renderInfo.EyeCups = EyeCup_DK1A;
+
+#if 0 // Device settings are out of date - don't use them.
+ if (Contents & Contents_Distortion)
+ {
+ memcpy(renderInfo.DistortionK, DistortionK, sizeof(float)*4);
+ renderInfo.DistortionEqn = Distortion_RecipPoly4;
+ }
+#endif
+
+ // Defaults in case of no user profile.
+ renderInfo.EyeLeft.NoseToPupilInMeters = 0.032f;
+ renderInfo.EyeLeft.ReliefInMeters = 0.012f;
+
+ // 10mm eye-relief laser numbers for DK1 lenses.
+ // These are a decent seed for finding eye-relief and IPD.
+ // These are NOT used for rendering!
+ // Rendering distortions are now in GenerateLensConfigFromEyeRelief()
+ // So, if you're hacking in new distortions, don't do it here!
+ renderInfo.EyeLeft.Distortion.SetToIdentity();
+ renderInfo.EyeLeft.Distortion.MetersPerTanAngleAtCenter = 0.0449f;
+ renderInfo.EyeLeft.Distortion.Eqn = Distortion_RecipPoly4;
+ renderInfo.EyeLeft.Distortion.K[0] = 1.0f;
+ renderInfo.EyeLeft.Distortion.K[1] = -0.494165344f;
+ renderInfo.EyeLeft.Distortion.K[2] = 0.587046423f;
+ renderInfo.EyeLeft.Distortion.K[3] = -0.841887126f;
+ renderInfo.EyeLeft.Distortion.MaxR = 1.0f;
+
+ renderInfo.EyeLeft.Distortion.ChromaticAberration[0] = -0.006f;
+ renderInfo.EyeLeft.Distortion.ChromaticAberration[1] = 0.0f;
+ renderInfo.EyeLeft.Distortion.ChromaticAberration[2] = 0.014f;
+ renderInfo.EyeLeft.Distortion.ChromaticAberration[3] = 0.0f;
+
+ renderInfo.EyeRight = renderInfo.EyeLeft;
+
+
+ // Obtain data from profile.
+ if ( profile != NULL )
+ {
+ char eyecup[16];
+ if (profile->GetValue(OVR_KEY_EYE_CUP, eyecup, 16))
+ SetEyeCup(&renderInfo, eyecup);
+ }
+
+ switch ( hmdInfo.HmdType )
+ {
+ case HmdType_None:
+ case HmdType_DKProto:
+ case HmdType_DK1:
+ // Slight hack to improve usability.
+ // If you have a DKHD-style lens profile enabled,
+ // but you plug in DK1 and forget to change the profile,
+ // obviously you don't want those lens numbers.
+ if ( ( renderInfo.EyeCups != EyeCup_DK1A ) &&
+ ( renderInfo.EyeCups != EyeCup_DK1B ) &&
+ ( renderInfo.EyeCups != EyeCup_DK1C ) )
+ {
+ renderInfo.EyeCups = EyeCup_DK1A;
+ }
+ break;
+
+ case HmdType_DKHD2Proto:
+ renderInfo.EyeCups = EyeCup_DKHD2A;
+ break;
+ case HmdType_CrystalCoveProto:
+ renderInfo.EyeCups = EyeCup_PinkA;
+ break;
+ case HmdType_DK2:
+ renderInfo.EyeCups = EyeCup_DK2A;
+ break;
+ default:
+ break;
+ }
+
+ if ( eyeCupOverride != EyeCup_LAST )
+ {
+ renderInfo.EyeCups = eyeCupOverride;
+ }
+
+ switch ( renderInfo.EyeCups )
+ {
+ case EyeCup_DK1A:
+ case EyeCup_DK1B:
+ case EyeCup_DK1C:
+ renderInfo.LensDiameterInMeters = 0.035f;
+ renderInfo.LensSurfaceToMidplateInMeters = 0.02357f;
+ // Not strictly lens-specific, but still wise to set a reasonable default for relief.
+ renderInfo.EyeLeft.ReliefInMeters = 0.010f;
+ renderInfo.EyeRight.ReliefInMeters = 0.010f;
+ break;
+ case EyeCup_DKHD2A:
+ renderInfo.LensDiameterInMeters = 0.035f;
+ renderInfo.LensSurfaceToMidplateInMeters = 0.02357f;
+ // Not strictly lens-specific, but still wise to set a reasonable default for relief.
+ renderInfo.EyeLeft.ReliefInMeters = 0.010f;
+ renderInfo.EyeRight.ReliefInMeters = 0.010f;
+ break;
+ case EyeCup_PinkA:
+ case EyeCup_DK2A:
+ renderInfo.LensDiameterInMeters = 0.04f; // approximate
+ renderInfo.LensSurfaceToMidplateInMeters = 0.01965f;
+ // Not strictly lens-specific, but still wise to set a reasonable default for relief.
+ renderInfo.EyeLeft.ReliefInMeters = 0.012f;
+ renderInfo.EyeRight.ReliefInMeters = 0.012f;
+ break;
+ default: OVR_ASSERT ( false ); break;
+ }
+
+ if ( profile != NULL )
+ {
+ // Set the customized user eye position
+ // TBD: Maybe we should separate custom camera positioning from custom distortion rendering ??
+ if (profile->GetBoolValue(OVR_KEY_CUSTOM_EYE_RENDER, true))
+ {
+ float eye2nose[2];
+ if (profile->GetFloatValues(OVR_KEY_EYE_TO_NOSE_DISTANCE, eye2nose, 2) == 2)
+ { // Load per-eye half-IPD
+ renderInfo.EyeLeft.NoseToPupilInMeters = eye2nose[0];
+ renderInfo.EyeRight.NoseToPupilInMeters = eye2nose[1];
+ }
+ else
+ { // Use a centered IPD instead
+ float ipd = profile->GetFloatValue(OVR_KEY_IPD, OVR_DEFAULT_IPD);
+ renderInfo.EyeLeft.NoseToPupilInMeters = 0.5f * ipd;
+ renderInfo.EyeRight.NoseToPupilInMeters = 0.5f * ipd;
+ }
+
+ float eye2plate[2];
+ if (profile->GetFloatValues(OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE, eye2plate, 2) == 2)
+ { // Subtract the eye-cup height from the plate distance to get the eye-to-lens distance
+ // This measurement should be the the distance at maximum dial setting
+ // We still need to adjust with the dial offset
+ renderInfo.EyeLeft.ReliefInMeters = eye2plate[0] - renderInfo.LensSurfaceToMidplateInMeters;
+ renderInfo.EyeRight.ReliefInMeters = eye2plate[1] - renderInfo.LensSurfaceToMidplateInMeters;
+
+ // Adjust the eye relief with the dial setting (from the assumed max eye relief)
+ int dial = profile->GetIntValue(OVR_KEY_EYE_RELIEF_DIAL, -1);
+ if (dial >= 0)
+ {
+ renderInfo.EyeLeft.ReliefInMeters -= ((10 - dial) * 0.001f);
+ renderInfo.EyeRight.ReliefInMeters -= ((10 - dial) * 0.001f);
+ }
+ }
+ else
+ {
+ // Set the eye relief with the user configured dial setting
+ int dial = profile->GetIntValue(OVR_KEY_EYE_RELIEF_DIAL, -1);
+ if (dial >= 0)
+ { // Assume a default of 7 to 17 mm eye relief based on the dial. This corresponds
+ // to the sampled and tuned distortion range on the DK1.
+ renderInfo.EyeLeft.ReliefInMeters = 0.007f + (dial * 0.001f);
+ renderInfo.EyeRight.ReliefInMeters = 0.007f + (dial * 0.001f);
+ }
+ }
+ }
+ }
+
+ // Now we know where the eyes are relative to the lenses, we can compute a distortion for each.
+ // TODO: incorporate lateral offset in distortion generation.
+ // TODO: we used a distortion to calculate eye-relief, and now we're making a distortion from that eye-relief. Close the loop!
+
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ HmdRenderInfo::EyeConfig *pHmdEyeConfig = ( eyeNum == 0 ) ? &(renderInfo.EyeLeft) : &(renderInfo.EyeRight);
+
+ float eye_relief = pHmdEyeConfig->ReliefInMeters;
+ LensConfig distortionConfig = GenerateLensConfigFromEyeRelief ( eye_relief, renderInfo, distortionType );
+ pHmdEyeConfig->Distortion = distortionConfig;
+ }
+
+ return renderInfo;
+}
+
+
+LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderInfo const &hmd, DistortionEqnType distortionType /*= Distortion_CatmullRom10*/ )
+{
+ struct DistortionDescriptor
+ {
+ float EyeRelief;
+ // The three places we're going to sample & lerp the curve at.
+ // One sample is always at 0.0, and the distortion scale should be 1.0 or else!
+ // Only use for poly4 numbers - CR has an implicit scale.
+ float SampleRadius[3];
+ // Where the distortion has actually been measured/calibrated out to.
+ // Don't try to hallucinate data out beyond here.
+ float MaxRadius;
+ // The config itself.
+ LensConfig Config;
+ };
+
+ DistortionDescriptor distortions[10];
+ for ( int i = 0; i < sizeof(distortions)/sizeof(distortions[0]); i++ )
+ {
+ distortions[i].Config.SetToIdentity();
+ distortions[i].EyeRelief = 0.0f;
+ distortions[i].MaxRadius = 1.0f;
+ }
+ int numDistortions = 0;
+ int defaultDistortion = 0; // index of the default distortion curve to use if zero eye relief supplied
+
+ if ( ( hmd.EyeCups == EyeCup_DK1A ) ||
+ ( hmd.EyeCups == EyeCup_DK1B ) ||
+ ( hmd.EyeCups == EyeCup_DK1C ) )
+ {
+
+ numDistortions = 0;
+
+ // Tuned at minimum dial setting - extended to r^2 == 1.8
+ distortions[numDistortions].Config.Eqn = Distortion_CatmullRom10;
+ distortions[numDistortions].EyeRelief = 0.012760465f - 0.005f;
+ distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.0425f;
+ distortions[numDistortions].Config.K[0] = 1.0000f;
+ distortions[numDistortions].Config.K[1] = 1.06505f;
+ distortions[numDistortions].Config.K[2] = 1.14725f;
+ distortions[numDistortions].Config.K[3] = 1.2705f;
+ distortions[numDistortions].Config.K[4] = 1.48f;
+ distortions[numDistortions].Config.K[5] = 1.87f;
+ distortions[numDistortions].Config.K[6] = 2.534f;
+ distortions[numDistortions].Config.K[7] = 3.6f;
+ distortions[numDistortions].Config.K[8] = 5.1f;
+ distortions[numDistortions].Config.K[9] = 7.4f;
+ distortions[numDistortions].Config.K[10] = 11.0f;
+ distortions[numDistortions].SampleRadius[0] = 0.222717149f;
+ distortions[numDistortions].SampleRadius[1] = 0.512249443f;
+ distortions[numDistortions].SampleRadius[2] = 0.712694878f;
+ distortions[numDistortions].MaxRadius = sqrt(1.8f);
+ defaultDistortion = numDistortions; // this is the default
+ numDistortions++;
+
+ // Tuned at middle dial setting
+ distortions[numDistortions].Config.Eqn = Distortion_CatmullRom10;
+ distortions[numDistortions].EyeRelief = 0.012760465f; // my average eye-relief
+ distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.0425f;
+ distortions[numDistortions].Config.K[0] = 1.0f;
+ distortions[numDistortions].Config.K[1] = 1.032407264f;
+ distortions[numDistortions].Config.K[2] = 1.07160462f;
+ distortions[numDistortions].Config.K[3] = 1.11998388f;
+ distortions[numDistortions].Config.K[4] = 1.1808606f;
+ distortions[numDistortions].Config.K[5] = 1.2590494f;
+ distortions[numDistortions].Config.K[6] = 1.361915f;
+ distortions[numDistortions].Config.K[7] = 1.5014339f;
+ distortions[numDistortions].Config.K[8] = 1.6986004f;
+ distortions[numDistortions].Config.K[9] = 1.9940577f;
+ distortions[numDistortions].Config.K[10] = 2.4783147f;
+ distortions[numDistortions].SampleRadius[0] = 0.222717149f;
+ distortions[numDistortions].SampleRadius[1] = 0.512249443f;
+ distortions[numDistortions].SampleRadius[2] = 0.712694878f;
+ distortions[numDistortions].MaxRadius = 1.0f;
+ numDistortions++;
+
+ // Tuned at maximum dial setting
+ distortions[numDistortions].Config.Eqn = Distortion_CatmullRom10;
+ distortions[numDistortions].EyeRelief = 0.012760465f + 0.005f;
+ distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.0425f;
+ distortions[numDistortions].Config.K[0] = 1.0102f;
+ distortions[numDistortions].Config.K[1] = 1.0371f;
+ distortions[numDistortions].Config.K[2] = 1.0831f;
+ distortions[numDistortions].Config.K[3] = 1.1353f;
+ distortions[numDistortions].Config.K[4] = 1.2f;
+ distortions[numDistortions].Config.K[5] = 1.2851f;
+ distortions[numDistortions].Config.K[6] = 1.3979f;
+ distortions[numDistortions].Config.K[7] = 1.56f;
+ distortions[numDistortions].Config.K[8] = 1.8f;
+ distortions[numDistortions].Config.K[9] = 2.25f;
+ distortions[numDistortions].Config.K[10] = 3.0f;
+ distortions[numDistortions].SampleRadius[0] = 0.222717149f;
+ distortions[numDistortions].SampleRadius[1] = 0.512249443f;
+ distortions[numDistortions].SampleRadius[2] = 0.712694878f;
+ distortions[numDistortions].MaxRadius = 1.0f;
+ numDistortions++;
+
+ // Chromatic aberration doesn't seem to change with eye relief.
+ for ( int i = 0; i < numDistortions; i++ )
+ {
+ distortions[i].Config.ChromaticAberration[0] = -0.006f;
+ distortions[i].Config.ChromaticAberration[1] = 0.0f;
+ distortions[i].Config.ChromaticAberration[2] = 0.014f;
+ distortions[i].Config.ChromaticAberration[3] = 0.0f;
+ }
+ }
+ else if ( hmd.EyeCups == EyeCup_DKHD2A )
+ {
+ // Tuned DKHD2 lens
+ numDistortions = 0;
+
+ distortions[numDistortions].Config.Eqn = Distortion_CatmullRom10;
+ distortions[numDistortions].EyeRelief = 0.010f;
+ distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.0425f;
+ distortions[numDistortions].Config.K[0] = 1.0f;
+ distortions[numDistortions].Config.K[1] = 1.0425f;
+ distortions[numDistortions].Config.K[2] = 1.0826f;
+ distortions[numDistortions].Config.K[3] = 1.130f;
+ distortions[numDistortions].Config.K[4] = 1.185f;
+ distortions[numDistortions].Config.K[5] = 1.250f;
+ distortions[numDistortions].Config.K[6] = 1.338f;
+ distortions[numDistortions].Config.K[7] = 1.455f;
+ distortions[numDistortions].Config.K[8] = 1.620f;
+ distortions[numDistortions].Config.K[9] = 1.840f;
+ distortions[numDistortions].Config.K[10] = 2.200f;
+ distortions[numDistortions].SampleRadius[0] = 0.222717149f;
+ distortions[numDistortions].SampleRadius[1] = 0.512249443f;
+ distortions[numDistortions].SampleRadius[2] = 0.712694878f;
+ distortions[numDistortions].MaxRadius = 1.0f;
+
+ distortions[numDistortions].SampleRadius[0] = 0.405405405f;
+ distortions[numDistortions].SampleRadius[1] = 0.675675676f;
+ distortions[numDistortions].SampleRadius[2] = 0.945945946f;
+ defaultDistortion = numDistortions; // this is the default
+ numDistortions++;
+
+ distortions[numDistortions] = distortions[0];
+ distortions[numDistortions].EyeRelief = 0.020f;
+ numDistortions++;
+
+ // Chromatic aberration doesn't seem to change with eye relief.
+ for ( int i = 0; i < numDistortions; i++ )
+ {
+ distortions[i].Config.ChromaticAberration[0] = -0.006f;
+ distortions[i].Config.ChromaticAberration[1] = 0.0f;
+ distortions[i].Config.ChromaticAberration[2] = 0.014f;
+ distortions[i].Config.ChromaticAberration[3] = 0.0f;
+ }
+ }
+ else if ( hmd.EyeCups == EyeCup_PinkA || hmd.EyeCups == EyeCup_DK2A )
+ {
+ // Tuned Crystal Cove & DK2 Lens (CES & GDC)
+ numDistortions = 0;
+
+ distortions[numDistortions].EyeRelief = 0.010f;
+ distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.036f;
+
+ distortions[numDistortions].Config.Eqn = Distortion_CatmullRom10;
+ distortions[numDistortions].Config.K[0] = 1.003f;
+ distortions[numDistortions].Config.K[1] = 1.02f;
+ distortions[numDistortions].Config.K[2] = 1.042f;
+ distortions[numDistortions].Config.K[3] = 1.066f;
+ distortions[numDistortions].Config.K[4] = 1.094f; //1.0945f;
+ distortions[numDistortions].Config.K[5] = 1.126f; //1.127f;
+ distortions[numDistortions].Config.K[6] = 1.162f; //1.167f;
+ distortions[numDistortions].Config.K[7] = 1.203f; //1.218f;
+ distortions[numDistortions].Config.K[8] = 1.25f; //1.283f;
+ distortions[numDistortions].Config.K[9] = 1.31f; //1.37f;
+ distortions[numDistortions].Config.K[10] = 1.38f; //1.48f;
+ distortions[numDistortions].MaxRadius = 1.0f;
+
+
+ distortions[numDistortions].SampleRadius[0] = 0.405405405f;
+ distortions[numDistortions].SampleRadius[1] = 0.675675676f;
+ distortions[numDistortions].SampleRadius[2] = 0.945945946f;
+ defaultDistortion = numDistortions; // this is the default
+ numDistortions++;
+
+ distortions[numDistortions] = distortions[0];
+ distortions[numDistortions].EyeRelief = 0.020f;
+ numDistortions++;
+
+ // Chromatic aberration doesn't seem to change with eye relief.
+ for ( int i = 0; i < numDistortions; i++ )
+ {
+ distortions[i].Config.ChromaticAberration[0] = -0.015f;
+ distortions[i].Config.ChromaticAberration[1] = -0.02f;
+ distortions[i].Config.ChromaticAberration[2] = 0.025f;
+ distortions[i].Config.ChromaticAberration[3] = 0.02f;
+ }
+ }
+ else
+ {
+ // Unknown lens.
+ // Use DK1 black lens settings, just so we can continue to run with something.
+ distortions[0].EyeRelief = 0.005f;
+ distortions[0].Config.MetersPerTanAngleAtCenter = 0.043875f;
+ distortions[0].Config.Eqn = Distortion_RecipPoly4;
+ distortions[0].Config.K[0] = 1.0f;
+ distortions[0].Config.K[1] = -0.3999f;
+ distortions[0].Config.K[2] = 0.2408f;
+ distortions[0].Config.K[3] = -0.4589f;
+ distortions[0].SampleRadius[0] = 0.2f;
+ distortions[0].SampleRadius[1] = 0.4f;
+ distortions[0].SampleRadius[2] = 0.6f;
+
+ distortions[1] = distortions[0];
+ distortions[1].EyeRelief = 0.010f;
+ numDistortions = 2;
+
+ // Chromatic aberration doesn't seem to change with eye relief.
+ for ( int i = 0; i < numDistortions; i++ )
+ {
+ // These are placeholder, they have not been tuned!
+ distortions[i].Config.ChromaticAberration[0] = 0.0f;
+ distortions[i].Config.ChromaticAberration[1] = 0.0f;
+ distortions[i].Config.ChromaticAberration[2] = 0.0f;
+ distortions[i].Config.ChromaticAberration[3] = 0.0f;
+ }
+ }
+
+ OVR_ASSERT ( numDistortions < (sizeof(distortions)/sizeof(distortions[0])) );
+
+
+ DistortionDescriptor *pUpper = NULL;
+ DistortionDescriptor *pLower = NULL;
+ float lerpVal = 0.0f;
+ if (eyeReliefInMeters == 0)
+ { // Use a constant default distortion if an invalid eye-relief is supplied
+ pLower = &(distortions[defaultDistortion]);
+ pUpper = &(distortions[defaultDistortion]);
+ lerpVal = 0.0f;
+ }
+ else
+ {
+ for ( int i = 0; i < numDistortions-1; i++ )
+ {
+ OVR_ASSERT ( distortions[i].EyeRelief < distortions[i+1].EyeRelief );
+ if ( ( distortions[i].EyeRelief <= eyeReliefInMeters ) && ( distortions[i+1].EyeRelief > eyeReliefInMeters ) )
+ {
+ pLower = &(distortions[i]);
+ pUpper = &(distortions[i+1]);
+ lerpVal = ( eyeReliefInMeters - pLower->EyeRelief ) / ( pUpper->EyeRelief - pLower->EyeRelief );
+ // No break here - I want the ASSERT to check everything every time!
+ }
+ }
+ }
+
+ if ( pUpper == NULL )
+ {
+#if 0
+ // Outside the range, so extrapolate rather than interpolate.
+ if ( distortions[0].EyeRelief > eyeReliefInMeters )
+ {
+ pLower = &(distortions[0]);
+ pUpper = &(distortions[1]);
+ }
+ else
+ {
+ OVR_ASSERT ( distortions[numDistortions-1].EyeRelief <= eyeReliefInMeters );
+ pLower = &(distortions[numDistortions-2]);
+ pUpper = &(distortions[numDistortions-1]);
+ }
+ lerpVal = ( eyeReliefInMeters - pLower->EyeRelief ) / ( pUpper->EyeRelief - pLower->EyeRelief );
+#else
+ // Do not extrapolate, just clamp - slightly worried about people putting in bogus settings.
+ if ( distortions[0].EyeRelief > eyeReliefInMeters )
+ {
+ pLower = &(distortions[0]);
+ pUpper = &(distortions[0]);
+ }
+ else
+ {
+ OVR_ASSERT ( distortions[numDistortions-1].EyeRelief <= eyeReliefInMeters );
+ pLower = &(distortions[numDistortions-1]);
+ pUpper = &(distortions[numDistortions-1]);
+ }
+ lerpVal = 0.0f;
+#endif
+ }
+ float invLerpVal = 1.0f - lerpVal;
+
+ pLower->Config.MaxR = pLower->MaxRadius;
+ pUpper->Config.MaxR = pUpper->MaxRadius;
+
+ LensConfig result;
+ // Where is the edge of the lens - no point modelling further than this.
+ float maxValidRadius = invLerpVal * pLower->MaxRadius + lerpVal * pUpper->MaxRadius;
+ result.MaxR = maxValidRadius;
+
+ switch ( distortionType )
+ {
+ case Distortion_Poly4:
+ // Deprecated
+ OVR_ASSERT ( false );
+ break;
+ case Distortion_RecipPoly4:{
+ // Lerp control points and fit an equation to them.
+ float fitX[4];
+ float fitY[4];
+ fitX[0] = 0.0f;
+ fitY[0] = 1.0f;
+ for ( int ctrlPt = 1; ctrlPt < 4; ctrlPt ++ )
+ {
+ float radiusLerp = invLerpVal * pLower->SampleRadius[ctrlPt-1] + lerpVal * pUpper->SampleRadius[ctrlPt-1];
+ float radiusLerpSq = radiusLerp * radiusLerp;
+ float fitYLower = pLower->Config.DistortionFnScaleRadiusSquared ( radiusLerpSq );
+ float fitYUpper = pUpper->Config.DistortionFnScaleRadiusSquared ( radiusLerpSq );
+ fitX[ctrlPt] = radiusLerpSq;
+ fitY[ctrlPt] = 1.0f / ( invLerpVal * fitYLower + lerpVal * fitYUpper );
+ }
+
+ result.Eqn = Distortion_RecipPoly4;
+ bool bSuccess = FitCubicPolynomial ( result.K, fitX, fitY );
+ OVR_ASSERT ( bSuccess );
+ OVR_UNUSED ( bSuccess );
+
+ // Set up the fast inverse.
+ float maxRDist = result.DistortionFn ( maxValidRadius );
+ result.MaxInvR = maxRDist;
+ result.SetUpInverseApprox();
+
+ }break;
+
+ case Distortion_CatmullRom10:{
+
+ // Evenly sample & lerp points on the curve.
+ const int NumSegments = LensConfig::NumCoefficients;
+ result.MaxR = maxValidRadius;
+ // Directly interpolate the K0 values
+ result.K[0] = invLerpVal * pLower->Config.K[0] + lerpVal * pUpper->Config.K[0];
+
+ // Sample and interpolate the distortion curves to derive K[1] ... K[n]
+ for ( int ctrlPt = 1; ctrlPt < NumSegments; ctrlPt++ )
+ {
+ float radiusSq = ( (float)ctrlPt / (float)(NumSegments-1) ) * maxValidRadius * maxValidRadius;
+ float fitYLower = pLower->Config.DistortionFnScaleRadiusSquared ( radiusSq );
+ float fitYUpper = pUpper->Config.DistortionFnScaleRadiusSquared ( radiusSq );
+ float fitLerp = invLerpVal * fitYLower + lerpVal * fitYUpper;
+ result.K[ctrlPt] = fitLerp;
+ }
+
+ result.Eqn = Distortion_CatmullRom10;
+
+ for ( int ctrlPt = 1; ctrlPt < NumSegments; ctrlPt++ )
+ {
+ float radiusSq = ( (float)ctrlPt / (float)(NumSegments-1) ) * maxValidRadius * maxValidRadius;
+ float val = result.DistortionFnScaleRadiusSquared ( radiusSq );
+ OVR_ASSERT ( Alg::Abs ( val - result.K[ctrlPt] ) < 0.0001f );
+ OVR_UNUSED1(val); // For release build.
+ }
+
+ // Set up the fast inverse.
+ float maxRDist = result.DistortionFn ( maxValidRadius );
+ result.MaxInvR = maxRDist;
+ result.SetUpInverseApprox();
+
+ }break;
+
+ default: OVR_ASSERT ( false ); break;
+ }
+
+
+ // Chromatic aberration.
+ result.ChromaticAberration[0] = invLerpVal * pLower->Config.ChromaticAberration[0] + lerpVal * pUpper->Config.ChromaticAberration[0];
+ result.ChromaticAberration[1] = invLerpVal * pLower->Config.ChromaticAberration[1] + lerpVal * pUpper->Config.ChromaticAberration[1];
+ result.ChromaticAberration[2] = invLerpVal * pLower->Config.ChromaticAberration[2] + lerpVal * pUpper->Config.ChromaticAberration[2];
+ result.ChromaticAberration[3] = invLerpVal * pLower->Config.ChromaticAberration[3] + lerpVal * pUpper->Config.ChromaticAberration[3];
+
+ // Scale.
+ result.MetersPerTanAngleAtCenter = pLower->Config.MetersPerTanAngleAtCenter * invLerpVal +
+ pUpper->Config.MetersPerTanAngleAtCenter * lerpVal;
+ /*
+ // Commented out - Causes ASSERT with no HMD plugged in
+#ifdef OVR_BUILD_DEBUG
+ if ( distortionType == Distortion_CatmullRom10 )
+ {
+ TestSaveLoadLensConfig ( result );
+ }
+#endif
+ */
+ return result;
+}
+
+
+
+
+
+DistortionRenderDesc CalculateDistortionRenderDesc ( StereoEye eyeType, HmdRenderInfo const &hmd,
+ const LensConfig *pLensOverride /*= NULL */ )
+{
+ // From eye relief, IPD and device characteristics, we get the distortion mapping.
+ // This distortion does the following things:
+ // 1. It undoes the distortion that happens at the edges of the lens.
+ // 2. It maps the undistorted field into "retina" space.
+ // So the input is a pixel coordinate - the physical pixel on the display itself.
+ // The output is the real-world direction of the ray from this pixel as it comes out of the lens and hits the eye.
+ // However we typically think of rays "coming from" the eye, so the direction (TanAngleX,TanAngleY,1) is the direction
+ // that the pixel appears to be in real-world space, where AngleX and AngleY are relative to the straight-ahead vector.
+ // If your renderer is a raytracer, you can use this vector directly (normalize as appropriate).
+ // However in standard rasterisers, we have rendered a 2D image and are putting it in front of the eye,
+ // so we then need a mapping from this space to the [-1,1] UV coordinate space, which depends on exactly
+ // where "in space" the app wants to put that rendertarget.
+ // Where in space, and how large this rendertarget is, is completely up to the app and/or user,
+ // though of course we can provide some useful hints.
+
+ // TODO: Use IPD and eye relief to modify distortion (i.e. non-radial component)
+ // TODO: cope with lenses that don't produce collimated light.
+ // This means that IPD relative to the lens separation changes the light vergence,
+ // and so we actually need to change where the image is displayed.
+
+ const HmdRenderInfo::EyeConfig &hmdEyeConfig = ( eyeType == StereoEye_Left ) ? hmd.EyeLeft : hmd.EyeRight;
+
+ DistortionRenderDesc localDistortion;
+ localDistortion.Lens = hmdEyeConfig.Distortion;
+
+ if ( pLensOverride != NULL )
+ {
+ localDistortion.Lens = *pLensOverride;
+ }
+
+ Sizef pixelsPerMeter(hmd.ResolutionInPixels.w / ( hmd.ScreenSizeInMeters.w - hmd.ScreenGapSizeInMeters ),
+ hmd.ResolutionInPixels.h / hmd.ScreenSizeInMeters.h);
+
+ localDistortion.PixelsPerTanAngleAtCenter = (pixelsPerMeter * localDistortion.Lens.MetersPerTanAngleAtCenter).ToVector();
+ // Same thing, scaled to [-1,1] for each eye, rather than pixels.
+
+ localDistortion.TanEyeAngleScale = Vector2f(0.25f, 0.5f).EntrywiseMultiply(
+ (hmd.ScreenSizeInMeters / localDistortion.Lens.MetersPerTanAngleAtCenter).ToVector());
+
+ // <--------------left eye------------------><-ScreenGapSizeInMeters-><--------------right eye----------------->
+ // <------------------------------------------ScreenSizeInMeters.Width----------------------------------------->
+ // <----------------LensSeparationInMeters--------------->
+ // <--centerFromLeftInMeters->
+ // ^
+ // Center of lens
+
+ // Find the lens centers in scale of [-1,+1] (NDC) in left eye.
+ float visibleWidthOfOneEye = 0.5f * ( hmd.ScreenSizeInMeters.w - hmd.ScreenGapSizeInMeters );
+ float centerFromLeftInMeters = ( hmd.ScreenSizeInMeters.w - hmd.LensSeparationInMeters ) * 0.5f;
+ localDistortion.LensCenter.x = ( centerFromLeftInMeters / visibleWidthOfOneEye ) * 2.0f - 1.0f;
+ localDistortion.LensCenter.y = ( hmd.CenterFromTopInMeters / hmd.ScreenSizeInMeters.h ) * 2.0f - 1.0f;
+ if ( eyeType == StereoEye_Right )
+ {
+ localDistortion.LensCenter.x = -localDistortion.LensCenter.x;
+ }
+
+ return localDistortion;
+}
+
+FovPort CalculateFovFromEyePosition ( float eyeReliefInMeters,
+ float offsetToRightInMeters,
+ float offsetDownwardsInMeters,
+ float lensDiameterInMeters,
+ float extraEyeRotationInRadians /*= 0.0f*/ )
+{
+ // 2D view of things:
+ // |-| <--- offsetToRightInMeters (in this case, it is negative)
+ // |=======C=======| <--- lens surface (C=center)
+ // \ | _/
+ // \ R _/
+ // \ | _/
+ // \ | _/
+ // \|/
+ // O <--- center of pupil
+
+ // (technically the lens is round rather than square, so it's not correct to
+ // separate vertical and horizontal like this, but it's close enough)
+ float halfLensDiameter = lensDiameterInMeters * 0.5f;
+ FovPort fovPort;
+ fovPort.UpTan = ( halfLensDiameter + offsetDownwardsInMeters ) / eyeReliefInMeters;
+ fovPort.DownTan = ( halfLensDiameter - offsetDownwardsInMeters ) / eyeReliefInMeters;
+ fovPort.LeftTan = ( halfLensDiameter + offsetToRightInMeters ) / eyeReliefInMeters;
+ fovPort.RightTan = ( halfLensDiameter - offsetToRightInMeters ) / eyeReliefInMeters;
+
+ if ( extraEyeRotationInRadians > 0.0f )
+ {
+ // That's the basic looking-straight-ahead eye position relative to the lens.
+ // But if you look left, the pupil moves left as the eyeball rotates, which
+ // means you can see more to the right than this geometry suggests.
+ // So add in the bounds for the extra movement of the pupil.
+
+ // Beyond 30 degrees does not increase FOV because the pupil starts moving backwards more than sideways.
+ extraEyeRotationInRadians = Alg::Min ( DegreeToRad ( 30.0f ), Alg::Max ( 0.0f, extraEyeRotationInRadians ) );
+
+ // The rotation of the eye is a bit more complex than a simple circle. The center of rotation
+ // at 13.5mm from cornea is slightly further back than the actual center of the eye.
+ // Additionally the rotation contains a small lateral component as the muscles pull the eye
+ const float eyeballCenterToPupil = 0.0135f; // center of eye rotation
+ const float eyeballLateralPull = 0.001f * (extraEyeRotationInRadians / DegreeToRad ( 30.0f)); // lateral motion as linear function
+ float extraTranslation = eyeballCenterToPupil * sinf ( extraEyeRotationInRadians ) + eyeballLateralPull;
+ float extraRelief = eyeballCenterToPupil * ( 1.0f - cosf ( extraEyeRotationInRadians ) );
+
+ fovPort.UpTan = Alg::Max ( fovPort.UpTan , ( halfLensDiameter + offsetDownwardsInMeters + extraTranslation ) / ( eyeReliefInMeters + extraRelief ) );
+ fovPort.DownTan = Alg::Max ( fovPort.DownTan , ( halfLensDiameter - offsetDownwardsInMeters + extraTranslation ) / ( eyeReliefInMeters + extraRelief ) );
+ fovPort.LeftTan = Alg::Max ( fovPort.LeftTan , ( halfLensDiameter + offsetToRightInMeters + extraTranslation ) / ( eyeReliefInMeters + extraRelief ) );
+ fovPort.RightTan = Alg::Max ( fovPort.RightTan, ( halfLensDiameter - offsetToRightInMeters + extraTranslation ) / ( eyeReliefInMeters + extraRelief ) );
+ }
+
+ return fovPort;
+}
+
+
+
+FovPort CalculateFovFromHmdInfo ( StereoEye eyeType,
+ DistortionRenderDesc const &distortion,
+ HmdRenderInfo const &hmd,
+ float extraEyeRotationInRadians /*= 0.0f*/ )
+{
+ FovPort fovPort;
+ float eyeReliefInMeters;
+ float offsetToRightInMeters;
+ if ( eyeType == StereoEye_Right )
+ {
+ eyeReliefInMeters = hmd.EyeRight.ReliefInMeters;
+ offsetToRightInMeters = hmd.EyeRight.NoseToPupilInMeters - 0.5f * hmd.LensSeparationInMeters;
+ }
+ else
+ {
+ eyeReliefInMeters = hmd.EyeLeft.ReliefInMeters;
+ offsetToRightInMeters = -(hmd.EyeLeft.NoseToPupilInMeters - 0.5f * hmd.LensSeparationInMeters);
+ }
+
+ // Central view.
+ fovPort = CalculateFovFromEyePosition ( eyeReliefInMeters,
+ offsetToRightInMeters,
+ 0.0f,
+ hmd.LensDiameterInMeters,
+ extraEyeRotationInRadians );
+
+ // clamp to the screen
+ fovPort = ClampToPhysicalScreenFov ( eyeType, distortion, fovPort );
+
+ return fovPort;
+}
+
+
+
+FovPort GetPhysicalScreenFov ( StereoEye eyeType, DistortionRenderDesc const &distortion )
+{
+ OVR_UNUSED1 ( eyeType );
+
+ FovPort resultFovPort;
+
+ // Figure out the boundaries of the screen. We take the middle pixel of the screen,
+ // move to each of the four screen edges, and transform those back into TanAngle space.
+ Vector2f dmiddle = distortion.LensCenter;
+
+ // The gotcha is that for some distortion functions, the map will "wrap around"
+ // for screen pixels that are not actually visible to the user (especially on DK1,
+ // which has a lot of invisible pixels), and map to pixels that are close to the middle.
+ // This means the edges of the screen will actually be
+ // "closer" than the visible bounds, so we'll clip too aggressively.
+
+ // Solution - step gradually towards the boundary, noting the maximum distance.
+ struct FunctionHider
+ {
+ static FovPort FindRange ( Vector2f from, Vector2f to, int numSteps,
+ DistortionRenderDesc const &distortion )
+ {
+ FovPort result;
+ result.UpTan = 0.0f;
+ result.DownTan = 0.0f;
+ result.LeftTan = 0.0f;
+ result.RightTan = 0.0f;
+
+ float stepScale = 1.0f / ( numSteps - 1 );
+ for ( int step = 0; step < numSteps; step++ )
+ {
+ float lerpFactor = stepScale * (float)step;
+ Vector2f sample = from + (to - from) * lerpFactor;
+ Vector2f tanEyeAngle = TransformScreenNDCToTanFovSpace ( distortion, sample );
+
+ result.LeftTan = Alg::Max ( result.LeftTan, -tanEyeAngle.x );
+ result.RightTan = Alg::Max ( result.RightTan, tanEyeAngle.x );
+ result.UpTan = Alg::Max ( result.UpTan, -tanEyeAngle.y );
+ result.DownTan = Alg::Max ( result.DownTan, tanEyeAngle.y );
+ }
+ return result;
+ }
+ };
+
+ FovPort leftFovPort = FunctionHider::FindRange( dmiddle, Vector2f( -1.0f, dmiddle.y ), 10, distortion );
+ FovPort rightFovPort = FunctionHider::FindRange( dmiddle, Vector2f( 1.0f, dmiddle.y ), 10, distortion );
+ FovPort upFovPort = FunctionHider::FindRange( dmiddle, Vector2f( dmiddle.x, -1.0f ), 10, distortion );
+ FovPort downFovPort = FunctionHider::FindRange( dmiddle, Vector2f( dmiddle.x, 1.0f ), 10, distortion );
+
+ resultFovPort.LeftTan = leftFovPort.LeftTan;
+ resultFovPort.RightTan = rightFovPort.RightTan;
+ resultFovPort.UpTan = upFovPort.UpTan;
+ resultFovPort.DownTan = downFovPort.DownTan;
+
+ return resultFovPort;
+}
+
+FovPort ClampToPhysicalScreenFov( StereoEye eyeType, DistortionRenderDesc const &distortion,
+ FovPort inputFovPort )
+{
+ FovPort resultFovPort;
+ FovPort phsyicalFovPort = GetPhysicalScreenFov ( eyeType, distortion );
+ resultFovPort.LeftTan = Alg::Min ( inputFovPort.LeftTan, phsyicalFovPort.LeftTan );
+ resultFovPort.RightTan = Alg::Min ( inputFovPort.RightTan, phsyicalFovPort.RightTan );
+ resultFovPort.UpTan = Alg::Min ( inputFovPort.UpTan, phsyicalFovPort.UpTan );
+ resultFovPort.DownTan = Alg::Min ( inputFovPort.DownTan, phsyicalFovPort.DownTan );
+
+ return resultFovPort;
+}
+
+Sizei CalculateIdealPixelSize ( StereoEye eyeType, DistortionRenderDesc const &distortion,
+ FovPort tanHalfFov, float pixelsPerDisplayPixel )
+{
+ OVR_UNUSED(eyeType); // might be useful in the future if we do overlapping fovs
+
+ Sizei result;
+ // TODO: if the app passes in a FOV that doesn't cover the centre, use the distortion values for the nearest edge/corner to match pixel size.
+ result.w = (int)(0.5f + pixelsPerDisplayPixel * distortion.PixelsPerTanAngleAtCenter.x * ( tanHalfFov.LeftTan + tanHalfFov.RightTan ) );
+ result.h = (int)(0.5f + pixelsPerDisplayPixel * distortion.PixelsPerTanAngleAtCenter.y * ( tanHalfFov.UpTan + tanHalfFov.DownTan ) );
+ return result;
+}
+
+Recti GetFramebufferViewport ( StereoEye eyeType, HmdRenderInfo const &hmd )
+{
+ Recti result;
+ result.w = hmd.ResolutionInPixels.w/2;
+ result.h = hmd.ResolutionInPixels.h;
+ result.x = 0;
+ result.y = 0;
+ if ( eyeType == StereoEye_Right )
+ {
+ result.x = (hmd.ResolutionInPixels.w+1)/2; // Round up, not down.
+ }
+ return result;
+}
+
+
+ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort tanHalfFov )
+{
+ float projXScale = 2.0f / ( tanHalfFov.LeftTan + tanHalfFov.RightTan );
+ float projXOffset = ( tanHalfFov.LeftTan - tanHalfFov.RightTan ) * projXScale * 0.5f;
+ float projYScale = 2.0f / ( tanHalfFov.UpTan + tanHalfFov.DownTan );
+ float projYOffset = ( tanHalfFov.UpTan - tanHalfFov.DownTan ) * projYScale * 0.5f;
+
+ ScaleAndOffset2D result;
+ result.Scale = Vector2f(projXScale, projYScale);
+ result.Offset = Vector2f(projXOffset, projYOffset);
+ // Hey - why is that Y.Offset negated?
+ // It's because a projection matrix transforms from world coords with Y=up,
+ // whereas this is from NDC which is Y=down.
+
+ return result;
+}
+
+
+ScaleAndOffset2D CreateUVScaleAndOffsetfromNDCScaleandOffset ( ScaleAndOffset2D scaleAndOffsetNDC,
+ Recti renderedViewport,
+ Sizei renderTargetSize )
+{
+ // scaleAndOffsetNDC takes you to NDC space [-1,+1] within the given viewport on the rendertarget.
+ // We want a scale to instead go to actual UV coordinates you can sample with,
+ // which need [0,1] and ignore the viewport.
+ ScaleAndOffset2D result;
+ // Scale [-1,1] to [0,1]
+ result.Scale = scaleAndOffsetNDC.Scale * 0.5f;
+ result.Offset = scaleAndOffsetNDC.Offset * 0.5f + Vector2f(0.5f);
+
+ // ...but we will have rendered to a subsection of the RT, so scale for that.
+ Vector2f scale( (float)renderedViewport.w / (float)renderTargetSize.w,
+ (float)renderedViewport.h / (float)renderTargetSize.h );
+ Vector2f offset( (float)renderedViewport.x / (float)renderTargetSize.w,
+ (float)renderedViewport.y / (float)renderTargetSize.h );
+
+ result.Scale = result.Scale.EntrywiseMultiply(scale);
+ result.Offset = result.Offset.EntrywiseMultiply(scale) + offset;
+ return result;
+}
+
+
+
+Matrix4f CreateProjection( bool rightHanded, FovPort tanHalfFov,
+ float zNear /*= 0.01f*/, float zFar /*= 10000.0f*/ )
+{
+ // A projection matrix is very like a scaling from NDC, so we can start with that.
+ ScaleAndOffset2D scaleAndOffset = CreateNDCScaleAndOffsetFromFov ( tanHalfFov );
+
+ float handednessScale = 1.0f;
+ if ( rightHanded )
+ {
+ handednessScale = -1.0f;
+ }
+
+ Matrix4f projection;
+ // Produces X result, mapping clip edges to [-w,+w]
+ projection.M[0][0] = scaleAndOffset.Scale.x;
+ projection.M[0][1] = 0.0f;
+ projection.M[0][2] = handednessScale * scaleAndOffset.Offset.x;
+ projection.M[0][3] = 0.0f;
+
+ // Produces Y result, mapping clip edges to [-w,+w]
+ // Hey - why is that YOffset negated?
+ // It's because a projection matrix transforms from world coords with Y=up,
+ // whereas this is derived from an NDC scaling, which is Y=down.
+ projection.M[1][0] = 0.0f;
+ projection.M[1][1] = scaleAndOffset.Scale.y;
+ projection.M[1][2] = handednessScale * -scaleAndOffset.Offset.y;
+ projection.M[1][3] = 0.0f;
+
+ // Produces Z-buffer result - app needs to fill this in with whatever Z range it wants.
+ // We'll just use some defaults for now.
+ projection.M[2][0] = 0.0f;
+ projection.M[2][1] = 0.0f;
+ projection.M[2][2] = -handednessScale * zFar / (zNear - zFar);
+ projection.M[2][3] = (zFar * zNear) / (zNear - zFar);
+
+ // Produces W result (= Z in)
+ projection.M[3][0] = 0.0f;
+ projection.M[3][1] = 0.0f;
+ projection.M[3][2] = handednessScale;
+ projection.M[3][3] = 0.0f;
+
+ return projection;
+}
+
+
+Matrix4f CreateOrthoSubProjection ( bool rightHanded, StereoEye eyeType,
+ float tanHalfFovX, float tanHalfFovY,
+ float unitsX, float unitsY,
+ float distanceFromCamera, float interpupillaryDistance,
+ Matrix4f const &projection,
+ float zNear /*= 0.0f*/, float zFar /*= 0.0f*/ )
+{
+ OVR_UNUSED1 ( rightHanded );
+
+ float orthoHorizontalOffset = interpupillaryDistance * 0.5f / distanceFromCamera;
+ switch ( eyeType )
+ {
+ case StereoEye_Center:
+ orthoHorizontalOffset = 0.0f;
+ break;
+ case StereoEye_Left:
+ break;
+ case StereoEye_Right:
+ orthoHorizontalOffset = -orthoHorizontalOffset;
+ break;
+ default: OVR_ASSERT ( false ); break;
+ }
+
+ // Current projection maps real-world vector (x,y,1) to the RT.
+ // We want to find the projection that maps the range [-FovPixels/2,FovPixels/2] to
+ // the physical [-orthoHalfFov,orthoHalfFov]
+ // Note moving the offset from M[0][2]+M[1][2] to M[0][3]+M[1][3] - this means
+ // we don't have to feed in Z=1 all the time.
+ // The horizontal offset math is a little hinky because the destination is
+ // actually [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset]
+ // So we need to first map [-FovPixels/2,FovPixels/2] to
+ // [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset]:
+ // x1 = x0 * orthoHalfFov/(FovPixels/2) + orthoHorizontalOffset;
+ // = x0 * 2*orthoHalfFov/FovPixels + orthoHorizontalOffset;
+ // But then we need the sam mapping as the existing projection matrix, i.e.
+ // x2 = x1 * Projection.M[0][0] + Projection.M[0][2];
+ // = x0 * (2*orthoHalfFov/FovPixels + orthoHorizontalOffset) * Projection.M[0][0] + Projection.M[0][2];
+ // = x0 * Projection.M[0][0]*2*orthoHalfFov/FovPixels +
+ // orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2];
+ // So in the new projection matrix we need to scale by Projection.M[0][0]*2*orthoHalfFov/FovPixels and
+ // offset by orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2].
+
+ float orthoScaleX = 2.0f * tanHalfFovX / unitsX;
+ float orthoScaleY = 2.0f * tanHalfFovY / unitsY;
+ Matrix4f ortho;
+ ortho.M[0][0] = projection.M[0][0] * orthoScaleX;
+ ortho.M[0][1] = 0.0f;
+ ortho.M[0][2] = 0.0f;
+ ortho.M[0][3] = -projection.M[0][2] + ( orthoHorizontalOffset * projection.M[0][0] );
+
+ ortho.M[1][0] = 0.0f;
+ ortho.M[1][1] = -projection.M[1][1] * orthoScaleY; // Note sign flip (text rendering uses Y=down).
+ ortho.M[1][2] = 0.0f;
+ ortho.M[1][3] = -projection.M[1][2];
+
+ if ( fabsf ( zNear - zFar ) < 0.001f )
+ {
+ ortho.M[2][0] = 0.0f;
+ ortho.M[2][1] = 0.0f;
+ ortho.M[2][2] = 0.0f;
+ ortho.M[2][3] = zFar;
+ }
+ else
+ {
+ ortho.M[2][0] = 0.0f;
+ ortho.M[2][1] = 0.0f;
+ ortho.M[2][2] = zFar / (zNear - zFar);
+ ortho.M[2][3] = (zFar * zNear) / (zNear - zFar);
+ }
+
+ // No perspective correction for ortho.
+ ortho.M[3][0] = 0.0f;
+ ortho.M[3][1] = 0.0f;
+ ortho.M[3][2] = 0.0f;
+ ortho.M[3][3] = 1.0f;
+
+ return ortho;
+}
+
+
+//-----------------------------------------------------------------------------------
+// A set of "forward-mapping" functions, mapping from framebuffer space to real-world and/or texture space.
+
+// This mimics the first half of the distortion shader's function.
+Vector2f TransformScreenNDCToTanFovSpace( DistortionRenderDesc const &distortion,
+ const Vector2f &framebufferNDC )
+{
+ // Scale to TanHalfFov space, but still distorted.
+ Vector2f tanEyeAngleDistorted;
+ tanEyeAngleDistorted.x = ( framebufferNDC.x - distortion.LensCenter.x ) * distortion.TanEyeAngleScale.x;
+ tanEyeAngleDistorted.y = ( framebufferNDC.y - distortion.LensCenter.y ) * distortion.TanEyeAngleScale.y;
+ // Distort.
+ float radiusSquared = ( tanEyeAngleDistorted.x * tanEyeAngleDistorted.x )
+ + ( tanEyeAngleDistorted.y * tanEyeAngleDistorted.y );
+ float distortionScale = distortion.Lens.DistortionFnScaleRadiusSquared ( radiusSquared );
+ Vector2f tanEyeAngle;
+ tanEyeAngle.x = tanEyeAngleDistorted.x * distortionScale;
+ tanEyeAngle.y = tanEyeAngleDistorted.y * distortionScale;
+
+ return tanEyeAngle;
+}
+
+// Same, with chromatic aberration correction.
+void TransformScreenNDCToTanFovSpaceChroma ( Vector2f *resultR, Vector2f *resultG, Vector2f *resultB,
+ DistortionRenderDesc const &distortion,
+ const Vector2f &framebufferNDC )
+{
+ // Scale to TanHalfFov space, but still distorted.
+ Vector2f tanEyeAngleDistorted;
+ tanEyeAngleDistorted.x = ( framebufferNDC.x - distortion.LensCenter.x ) * distortion.TanEyeAngleScale.x;
+ tanEyeAngleDistorted.y = ( framebufferNDC.y - distortion.LensCenter.y ) * distortion.TanEyeAngleScale.y;
+ // Distort.
+ float radiusSquared = ( tanEyeAngleDistorted.x * tanEyeAngleDistorted.x )
+ + ( tanEyeAngleDistorted.y * tanEyeAngleDistorted.y );
+ Vector3f distortionScales = distortion.Lens.DistortionFnScaleRadiusSquaredChroma ( radiusSquared );
+ *resultR = tanEyeAngleDistorted * distortionScales.x;
+ *resultG = tanEyeAngleDistorted * distortionScales.y;
+ *resultB = tanEyeAngleDistorted * distortionScales.z;
+}
+
+// This mimics the second half of the distortion shader's function.
+Vector2f TransformTanFovSpaceToRendertargetTexUV( StereoEyeParams const &eyeParams,
+ Vector2f const &tanEyeAngle )
+{
+ Vector2f textureUV;
+ textureUV.x = tanEyeAngle.x * eyeParams.EyeToSourceUV.Scale.x + eyeParams.EyeToSourceUV.Offset.x;
+ textureUV.y = tanEyeAngle.y * eyeParams.EyeToSourceUV.Scale.y + eyeParams.EyeToSourceUV.Offset.y;
+ return textureUV;
+}
+
+Vector2f TransformTanFovSpaceToRendertargetNDC( StereoEyeParams const &eyeParams,
+ Vector2f const &tanEyeAngle )
+{
+ Vector2f textureNDC;
+ textureNDC.x = tanEyeAngle.x * eyeParams.EyeToSourceNDC.Scale.x + eyeParams.EyeToSourceNDC.Offset.x;
+ textureNDC.y = tanEyeAngle.y * eyeParams.EyeToSourceNDC.Scale.y + eyeParams.EyeToSourceNDC.Offset.y;
+ return textureNDC;
+}
+
+Vector2f TransformScreenPixelToScreenNDC( Recti const &distortionViewport,
+ Vector2f const &pixel )
+{
+ // Move to [-1,1] NDC coords.
+ Vector2f framebufferNDC;
+ framebufferNDC.x = -1.0f + 2.0f * ( ( pixel.x - (float)distortionViewport.x ) / (float)distortionViewport.w );
+ framebufferNDC.y = -1.0f + 2.0f * ( ( pixel.y - (float)distortionViewport.y ) / (float)distortionViewport.h );
+ return framebufferNDC;
+}
+
+Vector2f TransformScreenPixelToTanFovSpace( Recti const &distortionViewport,
+ DistortionRenderDesc const &distortion,
+ Vector2f const &pixel )
+{
+ return TransformScreenNDCToTanFovSpace( distortion,
+ TransformScreenPixelToScreenNDC( distortionViewport, pixel ) );
+}
+
+Vector2f TransformScreenNDCToRendertargetTexUV( DistortionRenderDesc const &distortion,
+ StereoEyeParams const &eyeParams,
+ Vector2f const &pixel )
+{
+ return TransformTanFovSpaceToRendertargetTexUV ( eyeParams,
+ TransformScreenNDCToTanFovSpace ( distortion, pixel ) );
+}
+
+Vector2f TransformScreenPixelToRendertargetTexUV( Recti const &distortionViewport,
+ DistortionRenderDesc const &distortion,
+ StereoEyeParams const &eyeParams,
+ Vector2f const &pixel )
+{
+ return TransformTanFovSpaceToRendertargetTexUV ( eyeParams,
+ TransformScreenPixelToTanFovSpace ( distortionViewport, distortion, pixel ) );
+}
+
+
+//-----------------------------------------------------------------------------------
+// A set of "reverse-mapping" functions, mapping from real-world and/or texture space back to the framebuffer.
+
+Vector2f TransformTanFovSpaceToScreenNDC( DistortionRenderDesc const &distortion,
+ const Vector2f &tanEyeAngle, bool usePolyApprox /*= false*/ )
+{
+ float tanEyeAngleRadius = tanEyeAngle.Length();
+ float tanEyeAngleDistortedRadius = distortion.Lens.DistortionFnInverseApprox ( tanEyeAngleRadius );
+ if ( !usePolyApprox )
+ {
+ tanEyeAngleDistortedRadius = distortion.Lens.DistortionFnInverse ( tanEyeAngleRadius );
+ }
+ Vector2f tanEyeAngleDistorted = tanEyeAngle;
+ if ( tanEyeAngleRadius > 0.0f )
+ {
+ tanEyeAngleDistorted = tanEyeAngle * ( tanEyeAngleDistortedRadius / tanEyeAngleRadius );
+ }
+
+ Vector2f framebufferNDC;
+ framebufferNDC.x = ( tanEyeAngleDistorted.x / distortion.TanEyeAngleScale.x ) + distortion.LensCenter.x;
+ framebufferNDC.y = ( tanEyeAngleDistorted.y / distortion.TanEyeAngleScale.y ) + distortion.LensCenter.y;
+
+ return framebufferNDC;
+}
+
+Vector2f TransformRendertargetNDCToTanFovSpace( const ScaleAndOffset2D &eyeToSourceNDC,
+ const Vector2f &textureNDC )
+{
+ Vector2f tanEyeAngle = (textureNDC - eyeToSourceNDC.Offset) / eyeToSourceNDC.Scale;
+ return tanEyeAngle;
+}
+
+
+
+} //namespace OVR
+
+//Just want to make a copy disentangled from all these namespaces!
+float ExtEvalCatmullRom10Spline ( float const *K, float scaledVal )
+{
+ return(OVR::EvalCatmullRom10Spline ( K, scaledVal ));
+}
+
+
diff --git a/LibOVR/Src/OVR_Stereo.h b/LibOVR/Src/OVR_Stereo.h
new file mode 100644
index 0000000..bd5438d
--- /dev/null
+++ b/LibOVR/Src/OVR_Stereo.h
@@ -0,0 +1,460 @@
+/************************************************************************************
+
+PublicHeader: OVR.h
+Filename : OVR_Stereo.h
+Content : Stereo rendering functions
+Created : November 30, 2013
+Authors : Tom Fosyth
+
+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_Stereo_h
+#define OVR_Stereo_h
+
+#include "OVR_Device.h"
+
+// CAPI Forward declaration.
+typedef struct ovrFovPort_ ovrFovPort;
+typedef struct ovrRecti_ ovrRecti;
+
+namespace OVR {
+
+//-----------------------------------------------------------------------------------
+// ***** Stereo Enumerations
+
+// StereoEye specifies which eye we are rendering for; it is used to
+// retrieve StereoEyeParams.
+enum StereoEye
+{
+ StereoEye_Center,
+ StereoEye_Left,
+ StereoEye_Right
+};
+
+
+//-----------------------------------------------------------------------------------
+// ***** FovPort
+
+// FovPort describes Field Of View (FOV) of a viewport.
+// This class has values for up, down, left and right, stored in
+// tangent of the angle units to simplify calculations.
+//
+// As an example, for a standard 90 degree vertical FOV, we would
+// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }.
+//
+// CreateFromRadians/Degrees helper functions can be used to
+// access FOV in different units.
+
+struct FovPort
+{
+ float UpTan;
+ float DownTan;
+ float LeftTan;
+ float RightTan;
+
+ FovPort ( float sideTan = 0.0f ) :
+ UpTan(sideTan), DownTan(sideTan), LeftTan(sideTan), RightTan(sideTan) { }
+ FovPort ( float u, float d, float l, float r ) :
+ 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;
+
+
+ static FovPort CreateFromRadians(float horizontalFov, float verticalFov)
+ {
+ FovPort result;
+ result.UpTan = tanf ( verticalFov * 0.5f );
+ result.DownTan = tanf ( verticalFov * 0.5f );
+ result.LeftTan = tanf ( horizontalFov * 0.5f );
+ result.RightTan = tanf ( horizontalFov * 0.5f );
+ return result;
+ }
+
+ static FovPort CreateFromDegrees(float horizontalFovDegrees,
+ float verticalFovDegrees)
+ {
+ return CreateFromRadians(DegreeToRad(horizontalFovDegrees),
+ DegreeToRad(verticalFovDegrees));
+ }
+
+ // Get Horizontal/Vertical components of Fov in radians.
+ float GetVerticalFovRadians() const { return atanf(UpTan) + atanf(DownTan); }
+ float GetHorizontalFovRadians() const { return atanf(LeftTan) + atanf(RightTan); }
+ // Get Horizontal/Vertical components of Fov in degrees.
+ float GetVerticalFovDegrees() const { return RadToDegree(GetVerticalFovRadians()); }
+ float GetHorizontalFovDegrees() const { return RadToDegree(GetHorizontalFovRadians()); }
+
+ // Compute maximum tangent value among all four sides.
+ float GetMaxSideTan() const
+ {
+ return Alg::Max(Alg::Max(UpTan, DownTan), Alg::Max(LeftTan, RightTan));
+ }
+
+ // Converts Fov Tan angle units to [-1,1] render target NDC space
+ Vector2f TanAngleToRendertargetNDC(Vector2f const &tanEyeAngle);
+
+
+ // Compute per-channel minimum and maximum of Fov.
+ static FovPort Min(const FovPort& a, const FovPort& b)
+ {
+ FovPort fov( Alg::Min( a.UpTan , b.UpTan ),
+ Alg::Min( a.DownTan , b.DownTan ),
+ Alg::Min( a.LeftTan , b.LeftTan ),
+ Alg::Min( a.RightTan, b.RightTan ) );
+ return fov;
+ }
+
+ static FovPort Max(const FovPort& a, const FovPort& b)
+ {
+ FovPort fov( Alg::Max( a.UpTan , b.UpTan ),
+ Alg::Max( a.DownTan , b.DownTan ),
+ Alg::Max( a.LeftTan , b.LeftTan ),
+ Alg::Max( a.RightTan, b.RightTan ) );
+ return fov;
+ }
+};
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** ScaleAndOffset
+
+struct ScaleAndOffset2D
+{
+ Vector2f Scale;
+ Vector2f Offset;
+
+ ScaleAndOffset2D(float sx = 0.0f, float sy = 0.0f, float ox = 0.0f, float oy = 0.0f)
+ : Scale(sx, sy), Offset(ox, oy)
+ { }
+};
+
+
+//-----------------------------------------------------------------------------------
+// ***** Misc. utility functions.
+
+// Inputs are 4 points (pFitX[0],pFitY[0]) through (pFitX[3],pFitY[3])
+// Result is four coefficients in pResults[0] through pResults[3] such that
+// y = pResult[0] + x * ( pResult[1] + x * ( pResult[2] + x * ( pResult[3] ) ) );
+// passes through all four input points.
+// Return is true if it succeeded, false if it failed (because two control points
+// have the same pFitX value).
+bool FitCubicPolynomial ( float *pResult, const float *pFitX, const float *pFitY );
+
+//-----------------------------------------------------------------------------------
+// ***** LensConfig
+
+// LensConfig describes the configuration of a single lens in an HMD.
+// - Eqn and K[] describe a distortion function.
+// - MetersPerTanAngleAtCenter is the relationship between distance on a
+// screen (at the center of the lens), and the angle variance of the light after it
+// has passed through the lens.
+// - ChromaticAberration is an array of parameters for controlling
+// additional Red and Blue scaling in order to reduce chromatic aberration
+// caused by the Rift lenses.
+struct LensConfig
+{
+ // The result is a scaling applied to the distance from the center of the lens.
+ float DistortionFnScaleRadiusSquared (float rsq) const;
+ // x,y,z components map to r,g,b scales.
+ Vector3f DistortionFnScaleRadiusSquaredChroma (float rsq) const;
+
+ // DistortionFn applies distortion to the argument.
+ // Input: the distance in TanAngle/NIC space from the optical center to the input pixel.
+ // Output: the resulting distance after distortion.
+ float DistortionFn(float r) const
+ {
+ return r * DistortionFnScaleRadiusSquared ( r * r );
+ }
+
+ // DistortionFnInverse computes the inverse of the distortion function on an argument.
+ float DistortionFnInverse(float r) const;
+
+ // Also computes the inverse, but using a polynomial approximation. Warning - it's just an approximation!
+ float DistortionFnInverseApprox(float r) const;
+ // Sets up InvK[].
+ void SetUpInverseApprox();
+
+ // Sets a bunch of sensible defaults.
+ void SetToIdentity();
+
+
+
+ enum { NumCoefficients = 11 };
+
+ DistortionEqnType Eqn;
+ float K[NumCoefficients];
+ float MaxR; // The highest R you're going to query for - the curve is unpredictable beyond it.
+
+ float MetersPerTanAngleAtCenter;
+
+ // Additional per-channel scaling is applied after distortion:
+ // Index [0] - Red channel constant coefficient.
+ // Index [1] - Red channel r^2 coefficient.
+ // Index [2] - Blue channel constant coefficient.
+ // Index [3] - Blue channel r^2 coefficient.
+ float ChromaticAberration[4];
+
+ float InvK[NumCoefficients];
+ float MaxInvR;
+};
+
+
+// For internal use - storing and loading lens config data
+
+// Returns true on success.
+bool LoadLensConfig ( LensConfig *presult, UByte const *pbuffer, int bufferSizeInBytes );
+
+// Returns number of bytes needed.
+int SaveLensConfigSizeInBytes ( LensConfig const &config );
+// Returns true on success.
+bool SaveLensConfig ( UByte *pbuffer, int bufferSizeInBytes, LensConfig const &config );
+
+
+//-----------------------------------------------------------------------------------
+// ***** DistortionRenderDesc
+
+// This describes distortion for a single eye in an HMD with a display, not just the lens by itself.
+struct DistortionRenderDesc
+{
+ // The raw lens values.
+ LensConfig Lens;
+
+ // These map from [-1,1] across the eye being rendered into TanEyeAngle space (but still distorted)
+ Vector2f LensCenter;
+ Vector2f TanEyeAngleScale;
+ // Computed from device characteristics, IPD and eye-relief.
+ // (not directly used for rendering, but very useful)
+ Vector2f PixelsPerTanAngleAtCenter;
+};
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** HmdRenderInfo
+
+// All the parts of the HMD info that are needed to set up the rendering system.
+
+struct HmdRenderInfo
+{
+ // The start of this sturucture is intentionally very similar to HMDInfo in OVER_Device.h
+ // However to reduce interdependencies, one does not simply #include the other.
+
+ HmdTypeEnum HmdType;
+
+ // Size of the entire screen
+ Size<int> ResolutionInPixels;
+ Size<float> ScreenSizeInMeters;
+ float ScreenGapSizeInMeters;
+
+ // Characteristics of the lenses.
+ float CenterFromTopInMeters;
+ float LensSeparationInMeters;
+ float LensDiameterInMeters;
+ float LensSurfaceToMidplateInMeters;
+ EyeCupType EyeCups;
+
+ // Timing & shutter data. All values in seconds.
+ struct ShutterInfo
+ {
+ HmdShutterTypeEnum Type;
+ float VsyncToNextVsync; // 1/framerate
+ float VsyncToFirstScanline; // for global shutter, vsync->shutter open.
+ float FirstScanlineToLastScanline; // for global shutter, will be zero.
+ float PixelSettleTime; // estimated.
+ float PixelPersistence; // Full persistence = 1/framerate.
+ } Shutter;
+
+
+ // These are all set from the user's profile.
+ struct EyeConfig
+ {
+ // Distance from center of eyeball to front plane of lens.
+ float ReliefInMeters;
+ // Distance from nose (technically, center of Rift) to the middle of the eye.
+ float NoseToPupilInMeters;
+
+ LensConfig Distortion;
+ } EyeLeft, EyeRight;
+
+
+ HmdRenderInfo()
+ {
+ HmdType = HmdType_None;
+ ResolutionInPixels.w = 0;
+ ResolutionInPixels.h = 0;
+ ScreenSizeInMeters.w = 0.0f;
+ ScreenSizeInMeters.h = 0.0f;
+ ScreenGapSizeInMeters = 0.0f;
+ CenterFromTopInMeters = 0.0f;
+ LensSeparationInMeters = 0.0f;
+ LensDiameterInMeters = 0.0f;
+ LensSurfaceToMidplateInMeters = 0.0f;
+ Shutter.Type = HmdShutter_LAST;
+ Shutter.VsyncToNextVsync = 0.0f;
+ Shutter.VsyncToFirstScanline = 0.0f;
+ Shutter.FirstScanlineToLastScanline = 0.0f;
+ Shutter.PixelSettleTime = 0.0f;
+ Shutter.PixelPersistence = 0.0f;
+ EyeCups = EyeCup_DK1A;
+ EyeLeft.ReliefInMeters = 0.0f;
+ EyeLeft.NoseToPupilInMeters = 0.0f;
+ EyeLeft.Distortion.SetToIdentity();
+ EyeRight = EyeLeft;
+ }
+
+ // The "center eye" is the position the HMD tracking returns,
+ // and games will also usually use it for audio, aiming reticles, some line-of-sight tests, etc.
+ EyeConfig GetEyeCenter() const
+ {
+ EyeConfig result;
+ result.ReliefInMeters = 0.5f * ( EyeLeft.ReliefInMeters + EyeRight.ReliefInMeters );
+ result.NoseToPupilInMeters = 0.0f;
+ result.Distortion.SetToIdentity();
+ return result;
+ }
+
+};
+
+
+
+
+//-----------------------------------------------------------------------------------
+
+// Stateless computation functions, in somewhat recommended execution order.
+// For examples on how to use many of them, see the StereoConfig::UpdateComputedState function.
+
+const float OVR_DEFAULT_EXTRA_EYE_ROTATION = 30.0f * Math<float>::DegreeToRadFactor;
+
+// Creates a dummy debug HMDInfo matching a particular HMD model.
+// Useful for development without an actual HMD attached.
+HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType);
+
+
+// profile may be NULL, in which case it uses the hard-coded defaults.
+// distortionType should be left at the default unless you require something specific for your distortion shaders.
+// eyeCupOverride can be EyeCup_LAST, in which case it uses the one in the profile.
+HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo,
+ Profile const *profile = NULL,
+ DistortionEqnType distortionType = Distortion_CatmullRom10,
+ EyeCupType eyeCupOverride = EyeCup_LAST );
+
+LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderInfo const &hmd,
+ DistortionEqnType distortionType = Distortion_CatmullRom10 );
+
+DistortionRenderDesc CalculateDistortionRenderDesc ( StereoEye eyeType, HmdRenderInfo const &hmd,
+ LensConfig const *pLensOverride = NULL );
+
+FovPort CalculateFovFromEyePosition ( float eyeReliefInMeters,
+ float offsetToRightInMeters,
+ float offsetDownwardsInMeters,
+ float lensDiameterInMeters,
+ float extraEyeRotationInRadians = OVR_DEFAULT_EXTRA_EYE_ROTATION);
+
+FovPort CalculateFovFromHmdInfo ( StereoEye eyeType,
+ DistortionRenderDesc const &distortion,
+ HmdRenderInfo const &hmd,
+ float extraEyeRotationInRadians = OVR_DEFAULT_EXTRA_EYE_ROTATION );
+
+FovPort GetPhysicalScreenFov ( StereoEye eyeType, DistortionRenderDesc const &distortion );
+
+FovPort ClampToPhysicalScreenFov ( StereoEye eyeType, DistortionRenderDesc const &distortion,
+ FovPort inputFovPort );
+
+Sizei CalculateIdealPixelSize ( StereoEye eyeType, DistortionRenderDesc const &distortion,
+ FovPort fov, float pixelsPerDisplayPixel );
+
+Recti GetFramebufferViewport ( StereoEye eyeType, HmdRenderInfo const &hmd );
+
+Matrix4f CreateProjection ( bool rightHanded, FovPort fov,
+ float zNear = 0.01f, float zFar = 10000.0f );
+
+Matrix4f CreateOrthoSubProjection ( bool rightHanded, StereoEye eyeType,
+ float tanHalfFovX, float tanHalfFovY,
+ float unitsX, float unitsY, float distanceFromCamera,
+ float interpupillaryDistance, Matrix4f const &projection,
+ float zNear = 0.0f, float zFar = 0.0f );
+
+ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort fov );
+
+ScaleAndOffset2D CreateUVScaleAndOffsetfromNDCScaleandOffset ( ScaleAndOffset2D scaleAndOffsetNDC,
+ Recti renderedViewport,
+ Sizei renderTargetSize );
+
+
+//-----------------------------------------------------------------------------------
+// ***** StereoEyeParams
+
+// StereoEyeParams describes RenderDevice configuration needed to render
+// the scene for one eye.
+struct StereoEyeParams
+{
+ StereoEye Eye;
+ Matrix4f ViewAdjust; // Translation to be applied to view matrix.
+
+ // Distortion and the VP on the physical display - the thing to run the distortion shader on.
+ DistortionRenderDesc Distortion;
+ Recti DistortionViewport;
+
+ // Projection and VP of a particular view (you could have multiple of these).
+ Recti RenderedViewport; // Viewport that we render the standard scene to.
+ FovPort Fov; // The FOVs of this scene.
+ Matrix4f RenderedProjection; // Projection matrix used with this eye.
+ ScaleAndOffset2D EyeToSourceNDC; // Mapping from TanEyeAngle space to [-1,+1] on the rendered image.
+ ScaleAndOffset2D EyeToSourceUV; // Mapping from TanEyeAngle space to actual texture UV coords.
+};
+
+
+//-----------------------------------------------------------------------------------
+// A set of "forward-mapping" functions, mapping from framebuffer space to real-world and/or texture space.
+Vector2f TransformScreenNDCToTanFovSpace ( DistortionRenderDesc const &distortion,
+ const Vector2f &framebufferNDC );
+void TransformScreenNDCToTanFovSpaceChroma ( Vector2f *resultR, Vector2f *resultG, Vector2f *resultB,
+ DistortionRenderDesc const &distortion,
+ const Vector2f &framebufferNDC );
+Vector2f TransformTanFovSpaceToRendertargetTexUV ( StereoEyeParams const &eyeParams,
+ Vector2f const &tanEyeAngle );
+Vector2f TransformTanFovSpaceToRendertargetNDC ( StereoEyeParams const &eyeParams,
+ Vector2f const &tanEyeAngle );
+Vector2f TransformScreenPixelToScreenNDC( Recti const &distortionViewport,
+ Vector2f const &pixel );
+Vector2f TransformScreenPixelToTanFovSpace ( Recti const &distortionViewport,
+ DistortionRenderDesc const &distortion,
+ Vector2f const &pixel );
+Vector2f TransformScreenNDCToRendertargetTexUV( DistortionRenderDesc const &distortion,
+ StereoEyeParams const &eyeParams,
+ Vector2f const &pixel );
+Vector2f TransformScreenPixelToRendertargetTexUV( Recti const &distortionViewport,
+ DistortionRenderDesc const &distortion,
+ StereoEyeParams const &eyeParams,
+ Vector2f const &pixel );
+
+// A set of "reverse-mapping" functions, mapping from real-world and/or texture space back to the framebuffer.
+// Be aware that many of these are significantly slower than their forward-mapping counterparts.
+Vector2f TransformTanFovSpaceToScreenNDC( DistortionRenderDesc const &distortion,
+ const Vector2f &tanEyeAngle, bool usePolyApprox = false );
+Vector2f TransformRendertargetNDCToTanFovSpace( const ScaleAndOffset2D &eyeToSourceNDC,
+ const Vector2f &textureNDC );
+
+} //namespace OVR
+
+#endif // OVR_Stereo_h \ No newline at end of file
diff --git a/LibOVR/Src/OVR_ThreadCommandQueue.cpp b/LibOVR/Src/OVR_ThreadCommandQueue.cpp
index abefffb..427a539 100644
--- a/LibOVR/Src/OVR_ThreadCommandQueue.cpp
+++ b/LibOVR/Src/OVR_ThreadCommandQueue.cpp
@@ -5,16 +5,16 @@ Filename : OVR_ThreadCommandQueue.cpp
Content : Command queue for operations executed on a thread
Created : October 29, 2012
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/OVR_ThreadCommandQueue.h b/LibOVR/Src/OVR_ThreadCommandQueue.h
index cd1770c..9774212 100644
--- a/LibOVR/Src/OVR_ThreadCommandQueue.h
+++ b/LibOVR/Src/OVR_ThreadCommandQueue.h
@@ -6,16 +6,16 @@ Content : Command queue for operations executed on a thread
Created : October 29, 2012
Author : Michael Antonov
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/OVR_Win32_DeviceManager.cpp b/LibOVR/Src/OVR_Win32_DeviceManager.cpp
index b9dc238..6327d58 100644
--- a/LibOVR/Src/OVR_Win32_DeviceManager.cpp
+++ b/LibOVR/Src/OVR_Win32_DeviceManager.cpp
@@ -5,16 +5,16 @@ Content : Win32 implementation of DeviceManager.
Created : September 21, 2012
Authors : Michael Antonov
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -107,8 +107,8 @@ bool DeviceManager::GetDeviceInfo(DeviceInfo* info) const
info->Type = Device_Manager;
info->Version = 0;
- OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength, "DeviceManager");
- OVR_strcpy(info->Manufacturer,DeviceInfo::MaxNameLength, "Oculus VR, Inc.");
+ info->ProductName = "DeviceManager";
+ info->Manufacturer = "Oculus VR, Inc.";
return true;
}
@@ -200,12 +200,12 @@ int DeviceManagerThread::Run()
// allowed based on current ticks.
if (!TicksNotifiers.IsEmpty())
{
- UInt64 ticksMks = Timer::GetTicks();
- DWORD waitAllowed;
-
+ double timeSeconds = Timer::GetSeconds();
+ DWORD waitAllowed;
+
for (UPInt j = 0; j < TicksNotifiers.GetSize(); j++)
{
- waitAllowed = (DWORD)(TicksNotifiers[j]->OnTicks(ticksMks) / Timer::MksPerMs);
+ waitAllowed = (DWORD)(TicksNotifiers[j]->OnTicks(timeSeconds) * Timer::MsPerSecond);
if (waitAllowed < waitMs)
waitMs = waitAllowed;
}
@@ -416,7 +416,7 @@ DeviceManager* DeviceManager::Create()
manager->AddFactory(&SensorDeviceFactory::Instance);
manager->AddFactory(&LatencyTestDeviceFactory::Instance);
manager->AddFactory(&Win32::HMDDeviceFactory::Instance);
-
+
manager->AddRef();
}
else
diff --git a/LibOVR/Src/OVR_Win32_DeviceManager.h b/LibOVR/Src/OVR_Win32_DeviceManager.h
index ecf308f..b0cf65d 100644
--- a/LibOVR/Src/OVR_Win32_DeviceManager.h
+++ b/LibOVR/Src/OVR_Win32_DeviceManager.h
@@ -5,16 +5,16 @@ Content : Win32-specific DeviceManager header.
Created : September 21, 2012
Authors : Michael Antonov
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -90,10 +90,10 @@ public:
virtual void OnOverlappedEvent(HANDLE hevent) { OVR_UNUSED1(hevent); }
// Called when timing ticks are updated.
- // Returns the largest number of microseconds this function can
+ // Returns the largest number of seconds this function can
// wait till next call.
- virtual UInt64 OnTicks(UInt64 ticksMks)
- { OVR_UNUSED1(ticksMks); return Timer::MksPerSecond * 1000; }
+ virtual double OnTicks(double tickSeconds)
+ { OVR_UNUSED1(tickSeconds); return 1000.0; }
enum DeviceMessageType
{
@@ -135,14 +135,14 @@ private:
// Event notifications for devices whose OVERLAPPED I/O we service.
// This list is modified through AddDeviceOverlappedEvent.
// WaitHandles[0] always == hCommandEvent, with null device.
- Array<HANDLE> WaitHandles;
- Array<Notifier*> WaitNotifiers;
+ ArrayPOD<HANDLE> WaitHandles;
+ ArrayPOD<Notifier*> WaitNotifiers;
// Ticks notifiers - used for time-dependent events such as keep-alive.
- Array<Notifier*> TicksNotifiers;
+ ArrayPOD<Notifier*> TicksNotifiers;
// Message notifiers.
- Array<Notifier*> MessageNotifiers;
+ ArrayPOD<Notifier*> MessageNotifiers;
// Object that manages notifications originating from Windows messages.
Ptr<DeviceStatus> pStatusObject;
diff --git a/LibOVR/Src/OVR_Win32_DeviceStatus.cpp b/LibOVR/Src/OVR_Win32_DeviceStatus.cpp
index 96655a5..22f193c 100644
--- a/LibOVR/Src/OVR_Win32_DeviceStatus.cpp
+++ b/LibOVR/Src/OVR_Win32_DeviceStatus.cpp
@@ -5,16 +5,16 @@ Content : Win32 implementation of DeviceStatus.
Created : January 24, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -36,6 +36,10 @@ namespace OVR { namespace Win32 {
static TCHAR windowClassName[] = TEXT("LibOVR_DeviceStatus_WindowClass");
+#define STATIC_KSCATEGORY_VIDEO_CAMERA \
+ 0xe5323777, 0xf976, 0x4f5b, { 0x9b, 0x55, 0xb9, 0x46, 0x99, 0xc4, 0x6e, 0x44 }
+
+
//-------------------------------------------------------------------------------------
DeviceStatus::DeviceStatus(Notifier* const pClient)
: pNotificationClient(pClient), LastTimerId(0)
@@ -259,8 +263,10 @@ LRESULT CALLBACK DeviceStatus::WindowsMessageCallback( HWND hwnd,
DeviceStatus* pDeviceStatus = (DeviceStatus*) userData;
String devicePath(hdr->dbcc_name);
+ static const GUID videoCamGuid = { STATIC_KSCATEGORY_VIDEO_CAMERA };
// check if HID device caused the event...
- if (pDeviceStatus->HidGuid == hdr->dbcc_classguid)
+ if (pDeviceStatus->HidGuid == hdr->dbcc_classguid ||
+ videoCamGuid == hdr->dbcc_classguid)
{
// check if recovery timer is already running; stop it and
// remove it, if so.
diff --git a/LibOVR/Src/OVR_Win32_DeviceStatus.h b/LibOVR/Src/OVR_Win32_DeviceStatus.h
index 31df4d5..593a450 100644
--- a/LibOVR/Src/OVR_Win32_DeviceStatus.h
+++ b/LibOVR/Src/OVR_Win32_DeviceStatus.h
@@ -5,16 +5,16 @@ Content : Win32-specific DeviceStatus header.
Created : January 24, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/OVR_Win32_HIDDevice.cpp b/LibOVR/Src/OVR_Win32_HIDDevice.cpp
index 8643041..6d33f7a 100644
--- a/LibOVR/Src/OVR_Win32_HIDDevice.cpp
+++ b/LibOVR/Src/OVR_Win32_HIDDevice.cpp
@@ -5,16 +5,16 @@ Content : Win32 HID device implementation.
Created : February 22, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -168,10 +168,10 @@ bool HIDDeviceManager::GetHIDDeviceDesc(const String& path, HIDDeviceDesc* pdevD
return false;
pdevDesc->Path = path;
- getFullDesc(hidDev, pdevDesc);
+ bool succ = getFullDesc(hidDev, pdevDesc);
::CloseHandle(hidDev);
- return true;
+ return succ;
}
OVR::HIDDevice* HIDDeviceManager::Open(const String& path)
@@ -298,10 +298,11 @@ bool HIDDevice::HIDInitialize(const String& path)
HIDManager->Manager->pThread->AddMessageNotifier(this);
LogText("OVR::Win32::HIDDevice - Opened '%s'\n"
- " Manufacturer:'%s' Product:'%s' Serial#:'%s'\n",
+ " Manufacturer:'%s' Product:'%s' Serial#:'%s' Version:'%x'\n",
DevDesc.Path.ToCStr(),
DevDesc.Manufacturer.ToCStr(), DevDesc.Product.ToCStr(),
- DevDesc.SerialNumber.ToCStr());
+ DevDesc.SerialNumber.ToCStr(),
+ DevDesc.VersionNumber);
return true;
}
@@ -500,18 +501,20 @@ void HIDDevice::closeDeviceOnIOError()
bool HIDDevice::SetFeatureReport(UByte* data, UInt32 length)
{
- if (!ReadRequested)
+ if (!ReadRequested)
return false;
- return HIDManager->HidD_SetFeature(Device, data, (ULONG) length) != FALSE;
+ BOOLEAN res = HIDManager->HidD_SetFeature(Device, data, (ULONG) length);
+ return (res == TRUE);
}
bool HIDDevice::GetFeatureReport(UByte* data, UInt32 length)
{
- if (!ReadRequested)
+ if (!ReadRequested)
return false;
- return HIDManager->HidD_GetFeature(Device, data, (ULONG) length) != FALSE;
+ BOOLEAN res = HIDManager->HidD_GetFeature(Device, data, (ULONG) length);
+ return (res == TRUE);
}
void HIDDevice::OnOverlappedEvent(HANDLE hevent)
@@ -526,14 +529,14 @@ void HIDDevice::OnOverlappedEvent(HANDLE hevent)
}
}
-UInt64 HIDDevice::OnTicks(UInt64 ticksMks)
+double HIDDevice::OnTicks(double tickSeconds)
{
if (Handler)
{
- return Handler->OnTicks(ticksMks);
+ return Handler->OnTicks(tickSeconds);
}
- return DeviceManagerThread::Notifier::OnTicks(ticksMks);
+ return DeviceManagerThread::Notifier::OnTicks(tickSeconds);
}
bool HIDDevice::OnDeviceMessage(DeviceMessageType messageType,
diff --git a/LibOVR/Src/OVR_Win32_HIDDevice.h b/LibOVR/Src/OVR_Win32_HIDDevice.h
index b8e3c9f..e43e876 100644
--- a/LibOVR/Src/OVR_Win32_HIDDevice.h
+++ b/LibOVR/Src/OVR_Win32_HIDDevice.h
@@ -5,16 +5,16 @@ Content : Win32 HID device implementation.
Created : February 22, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -107,7 +107,7 @@ public:
// DeviceManagerThread::Notifier
void OnOverlappedEvent(HANDLE hevent);
- UInt64 OnTicks(UInt64 ticksMks);
+ double OnTicks(double tickSeconds);
bool OnDeviceMessage(DeviceMessageType messageType, const String& devicePath, bool* error);
private:
diff --git a/LibOVR/Src/OVR_Win32_HMDDevice.cpp b/LibOVR/Src/OVR_Win32_HMDDevice.cpp
index e213691..08c98f2 100644
--- a/LibOVR/Src/OVR_Win32_HMDDevice.cpp
+++ b/LibOVR/Src/OVR_Win32_HMDDevice.cpp
@@ -5,16 +5,16 @@ Content : Win32 Interface to HMD - detects HMD display
Created : September 21, 2012
Authors : Michael Antonov
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -27,33 +27,40 @@ limitations under the License.
#include "OVR_Win32_HMDDevice.h"
#include "OVR_Win32_DeviceManager.h"
+#include "util/Util_Render_Stereo.h"
#include <tchar.h>
namespace OVR { namespace Win32 {
+using namespace OVR::Util::Render;
+
//-------------------------------------------------------------------------------------
HMDDeviceCreateDesc::HMDDeviceCreateDesc(DeviceFactory* factory,
const String& deviceId, const String& displayDeviceName)
: DeviceCreateDesc(factory, Device_HMD),
DeviceId(deviceId), DisplayDeviceName(displayDeviceName),
- DesktopX(0), DesktopY(0), Contents(0), EyeToScreenDistance(0),
- HResolution(0), VResolution(0), HScreenSize(0), VScreenSize(0)
+ Contents(0)
{
- for (int i=0; i<4; i++)
- DistortionK[i] = 0;
+ Desktop.X = 0;
+ Desktop.Y = 0;
+ ResolutionInPixels = Sizei(0);
+ ScreenSizeInMeters = Sizef(0.0f);
+ VCenterFromTopInMeters = 0.0f;
+ LensSeparationInMeters = 0.0f;
}
HMDDeviceCreateDesc::HMDDeviceCreateDesc(const HMDDeviceCreateDesc& other)
: DeviceCreateDesc(other.pFactory, Device_HMD),
DeviceId(other.DeviceId), DisplayDeviceName(other.DisplayDeviceName),
- DesktopX(other.DesktopX), DesktopY(other.DesktopY), Contents(other.Contents),
- HResolution(other.HResolution), VResolution(other.VResolution),
- HScreenSize(other.HScreenSize), VScreenSize(other.VScreenSize),
- EyeToScreenDistance(other.EyeToScreenDistance)
+ Contents(other.Contents)
{
- for (int i=0; i<4; i++)
- DistortionK[i] = other.DistortionK[i];
+ Desktop.X = other.Desktop.X;
+ Desktop.Y = other.Desktop.Y;
+ ResolutionInPixels = other.ResolutionInPixels;
+ ScreenSizeInMeters = other.ScreenSizeInMeters;
+ VCenterFromTopInMeters = other.VCenterFromTopInMeters;
+ LensSeparationInMeters = other.LensSeparationInMeters;
}
HMDDeviceCreateDesc::MatchResult HMDDeviceCreateDesc::MatchDevice(const DeviceCreateDesc& other,
@@ -78,8 +85,7 @@ HMDDeviceCreateDesc::MatchResult HMDDeviceCreateDesc::MatchDevice(const DeviceCr
// Non-null DeviceId may match while size is different if screen size was overwritten
// by SensorDisplayInfo in prior iteration.
if (!DeviceId.IsEmpty() ||
- ((HScreenSize == s2.HScreenSize) &&
- (VScreenSize == s2.VScreenSize)) )
+ (ScreenSizeInMeters == s2.ScreenSizeInMeters) )
{
*pcandidate = 0;
return Match_Found;
@@ -88,10 +94,8 @@ HMDDeviceCreateDesc::MatchResult HMDDeviceCreateDesc::MatchDevice(const DeviceCr
// DisplayInfo takes precedence, although we try to match it first.
- if ((HResolution == s2.HResolution) &&
- (VResolution == s2.VResolution) &&
- (HScreenSize == s2.HScreenSize) &&
- (VScreenSize == s2.VScreenSize))
+ if ((ResolutionInPixels == s2.ResolutionInPixels) &&
+ (ScreenSizeInMeters == s2.ScreenSizeInMeters))
{
if (DeviceId.IsEmpty() && !s2.DeviceId.IsEmpty())
{
@@ -133,27 +137,30 @@ bool HMDDeviceCreateDesc::UpdateMatchedCandidate(const DeviceCreateDesc& other,
// which may be corrupted by splitter reporting wrong monitor
if (s2.DeviceId.IsEmpty())
{
- HScreenSize = s2.HScreenSize;
- VScreenSize = s2.VScreenSize;
+ // disconnected HMD: replace old descriptor by the 'fake' one.
+ ScreenSizeInMeters = s2.ScreenSizeInMeters;
Contents |= Contents_Screen;
if (s2.Contents & HMDDeviceCreateDesc::Contents_Distortion)
{
memcpy(DistortionK, s2.DistortionK, sizeof(float)*4);
+ // TODO: DistortionEqn
Contents |= Contents_Distortion;
}
DeviceId = s2.DeviceId;
DisplayDeviceName = s2.DisplayDeviceName;
- DesktopX = s2.DesktopX;
- DesktopY = s2.DesktopY;
+ Desktop.X = s2.Desktop.X;
+ Desktop.Y = s2.Desktop.Y;
if (newDeviceFlag) *newDeviceFlag = true;
}
else if (DeviceId.IsEmpty())
{
+ // This branch is executed when 'fake' HMD descriptor is being replaced by
+ // the real one.
DeviceId = s2.DeviceId;
DisplayDeviceName = s2.DisplayDeviceName;
- DesktopX = s2.DesktopX;
- DesktopY = s2.DesktopY;
+ Desktop.X = s2.Desktop.X;
+ Desktop.Y = s2.Desktop.Y;
// ScreenSize and Resolution are NOT assigned here, since they may have
// come from a sensor DisplayInfo (which has precedence over HDMI).
@@ -299,24 +306,28 @@ void HMDDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor)
}
HMDDeviceCreateDesc hmdCreateDesc(this, deviceId, displayDeviceName);
-
- if (wcsstr(ddm.DeviceID, L"OVR0002"))
- {
- hmdCreateDesc.SetScreenParameters(mx, my, 1920, 1080, 0.12096f, 0.06804f);
+
+ // Hard-coded defaults in case the device doesn't have the data itself.
+ if (wcsstr(ddm.DeviceID, L"OVR0003"))
+ { // DK2 prototypes and variants (default to HmdType_DK2)
+ hmdCreateDesc.SetScreenParameters(mx, my, 1920, 1080, 0.12576f, 0.07074f, 0.12576f*0.5f, 0.0635f );
+ }
+ else if (wcsstr(ddm.DeviceID, L"OVR0002"))
+ { // HD Prototypes (default to HmdType_DKHDProto)
+ hmdCreateDesc.SetScreenParameters(mx, my, 1920, 1080, 0.12096f, 0.06804f, 0.06804f*0.5f, 0.0635f );
}
- else
- {
- if (hmdCreateDesc.Is7Inch())
- {
- // Physical dimension of SLA screen.
- hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.14976f, 0.0936f);
- }
- else
- {
- hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.12096f, 0.0756f);
- }
+ else if (wcsstr(ddm.DeviceID, L"OVR0001"))
+ { // DK1
+ hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.14976f, 0.0936f, 0.0936f*0.5f, 0.0635f);
+ }
+ else if (wcsstr(ddm.DeviceID, L"OVR00"))
+ { // Future Oculus HMD devices (default to DK1 dimensions)
+ hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.14976f, 0.0936f, 0.0936f*0.5f, 0.0635f);
}
-
+ else
+ { // Duct-tape prototype
+ hmdCreateDesc.SetScreenParameters(mx, my, mwidth, mheight, 0.12096f, 0.0756f, 0.0756f*0.5f, 0.0635f);
+ }
OVR_DEBUG_LOG_TEXT(("DeviceManager - HMD Found %s - %s\n",
deviceId.ToCStr(), displayDeviceName.ToCStr()));
@@ -341,174 +352,7 @@ void HMDDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor)
}
}
-DeviceBase* HMDDeviceCreateDesc::NewDeviceInstance()
-{
- return new HMDDevice(this);
-}
-
-bool HMDDeviceCreateDesc::Is7Inch() const
-{
- return (strstr(DeviceId.ToCStr(), "OVR0001") != 0) || (Contents & Contents_7Inch);
-}
-
-Profile* HMDDeviceCreateDesc::GetProfileAddRef() const
-{
- // Create device may override profile name, so get it from there is possible.
- ProfileManager* profileManager = GetManagerImpl()->GetProfileManager();
- ProfileType profileType = GetProfileType();
- const char * profileName = pDevice ?
- ((HMDDevice*)pDevice)->GetProfileName() :
- profileManager->GetDefaultProfileName(profileType);
-
- return profileName ?
- profileManager->LoadProfile(profileType, profileName) :
- profileManager->GetDeviceDefaultProfile(profileType);
-}
-
-
-bool HMDDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const
-{
- if ((info->InfoClassType != Device_HMD) &&
- (info->InfoClassType != Device_None))
- return false;
-
- bool is7Inch = Is7Inch();
-
- OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength,
- is7Inch ? "Oculus Rift DK1" :
- ((HResolution >= 1920) ? "Oculus Rift DK HD" : "Oculus Rift DK1-Prototype") );
- OVR_strcpy(info->Manufacturer, DeviceInfo::MaxNameLength, "Oculus VR");
- info->Type = Device_HMD;
- info->Version = 0;
-
- // Display detection.
- if (info->InfoClassType == Device_HMD)
- {
- HMDInfo* hmdInfo = static_cast<HMDInfo*>(info);
-
- hmdInfo->DesktopX = DesktopX;
- hmdInfo->DesktopY = DesktopY;
- hmdInfo->HResolution = HResolution;
- hmdInfo->VResolution = VResolution;
- hmdInfo->HScreenSize = HScreenSize;
- hmdInfo->VScreenSize = VScreenSize;
- hmdInfo->VScreenCenter = VScreenSize * 0.5f;
- hmdInfo->InterpupillaryDistance = 0.064f; // Default IPD; should be configurable.
- hmdInfo->LensSeparationDistance = 0.0635f;
-
- // Obtain IPD from profile.
- Ptr<Profile> profile = *GetProfileAddRef();
-
- if (profile)
- {
- hmdInfo->InterpupillaryDistance = profile->GetIPD();
- // TBD: Switch on EyeCup type.
- }
-
- if (Contents & Contents_Distortion)
- {
- memcpy(hmdInfo->DistortionK, DistortionK, sizeof(float)*4);
- hmdInfo->EyeToScreenDistance = EyeToScreenDistance;
- }
- else
- {
- if (is7Inch)
- {
- // 7" screen.
- hmdInfo->DistortionK[0] = 1.0f;
- hmdInfo->DistortionK[1] = 0.22f;
- hmdInfo->DistortionK[2] = 0.24f;
- hmdInfo->EyeToScreenDistance = 0.041f;
- }
- else
- {
- hmdInfo->DistortionK[0] = 1.0f;
- hmdInfo->DistortionK[1] = 0.18f;
- hmdInfo->DistortionK[2] = 0.115f;
-
- if (HResolution == 1920)
- hmdInfo->EyeToScreenDistance = 0.040f;
- else
- hmdInfo->EyeToScreenDistance = 0.0387f;
- }
- }
-
- hmdInfo->ChromaAbCorrection[0] = 0.996f;
- hmdInfo->ChromaAbCorrection[1] = -0.004f;
- hmdInfo->ChromaAbCorrection[2] = 1.014f;
- hmdInfo->ChromaAbCorrection[3] = 0.0f;
-
- OVR_strcpy(hmdInfo->DisplayDeviceName, sizeof(hmdInfo->DisplayDeviceName),
- DisplayDeviceName.ToCStr());
- }
-
- return true;
-}
-
-//-------------------------------------------------------------------------------------
-// ***** HMDDevice
-
-HMDDevice::HMDDevice(HMDDeviceCreateDesc* createDesc)
- : OVR::DeviceImpl<OVR::HMDDevice>(createDesc, 0)
-{
-}
-HMDDevice::~HMDDevice()
-{
-}
-
-bool HMDDevice::Initialize(DeviceBase* parent)
-{
- pParent = parent;
-
- // Initialize user profile to default for device.
- ProfileManager* profileManager = GetManager()->GetProfileManager();
- ProfileName = profileManager->GetDefaultProfileName(getDesc()->GetProfileType());
-
- return true;
-}
-void HMDDevice::Shutdown()
-{
- ProfileName.Clear();
- pCachedProfile.Clear();
- pParent.Clear();
-}
-
-Profile* HMDDevice::GetProfile() const
-{
- if (!pCachedProfile)
- pCachedProfile = *getDesc()->GetProfileAddRef();
- return pCachedProfile.GetPtr();
-}
-
-const char* HMDDevice::GetProfileName() const
-{
- return ProfileName.ToCStr();
-}
-
-bool HMDDevice::SetProfileName(const char* name)
-{
- pCachedProfile.Clear();
- if (!name)
- {
- ProfileName.Clear();
- return 0;
- }
- if (GetManager()->GetProfileManager()->HasProfile(getDesc()->GetProfileType(), name))
- {
- ProfileName = name;
- return true;
- }
- return false;
-}
-
-OVR::SensorDevice* HMDDevice::GetSensor()
-{
- // Just return first sensor found since we have no way to match it yet.
- OVR::SensorDevice* sensor = GetManager()->EnumerateDevices<SensorDevice>().CreateDevice();
- if (sensor)
- sensor->SetCoordinateFrame(SensorDevice::Coord_HMD);
- return sensor;
-}
+#include "OVR_Common_HMDDevice.cpp"
}} // namespace OVR::Win32
diff --git a/LibOVR/Src/OVR_Win32_HMDDevice.h b/LibOVR/Src/OVR_Win32_HMDDevice.h
index 44e5a97..d1e481c 100644
--- a/LibOVR/Src/OVR_Win32_HMDDevice.h
+++ b/LibOVR/Src/OVR_Win32_HMDDevice.h
@@ -5,16 +5,16 @@ Content : Win32 HMDDevice implementation
Created : September 21, 2012
Authors : Michael Antonov
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -63,16 +63,23 @@ protected:
{
Contents_Screen = 1,
Contents_Distortion = 2,
- Contents_7Inch = 4,
};
- String DeviceId;
- String DisplayDeviceName;
- int DesktopX, DesktopY;
- unsigned Contents;
- unsigned HResolution, VResolution;
- float HScreenSize, VScreenSize;
- float DistortionK[4];
- float EyeToScreenDistance;
+ String DeviceId;
+ String DisplayDeviceName;
+ struct
+ {
+ int X, Y;
+ } Desktop;
+ unsigned int Contents;
+
+ Sizei ResolutionInPixels;
+ Sizef ScreenSizeInMeters;
+ float VCenterFromTopInMeters;
+ float LensSeparationInMeters;
+
+ // TODO: update these to splines.
+ DistortionEqnType DistortionEqn;
+ float DistortionK[4];
public:
HMDDeviceCreateDesc(DeviceFactory* factory,
@@ -96,38 +103,13 @@ public:
virtual bool GetDeviceInfo(DeviceInfo* info) const;
- // Requests the currently used default profile. This profile affects the
- // settings reported by HMDInfo.
- Profile* GetProfileAddRef() const;
-
- ProfileType GetProfileType() const
- {
- return (HResolution >= 1920) ? Profile_RiftDKHD : Profile_RiftDK1;
- }
-
-
- void SetScreenParameters(int x, int y, unsigned hres, unsigned vres, float hsize, float vsize)
- {
- DesktopX = x;
- DesktopY = y;
- HResolution = hres;
- VResolution = vres;
- HScreenSize = hsize;
- VScreenSize = vsize;
- Contents |= Contents_Screen;
- }
- void SetDistortion(float eye2screen, const float* dks)
- {
- EyeToScreenDistance = eye2screen;
-
- for (int i = 0; i < 4; i++)
- DistortionK[i] = dks[i];
- Contents |= Contents_Distortion;
- }
-
- void Set7Inch() { Contents |= Contents_7Inch; }
-
- bool Is7Inch() const;
+ void SetScreenParameters(int x, int y,
+ int hres, int vres,
+ float hsize, float vsize,
+ float vCenterFromTopInMeters, float lensSeparationInMeters);
+ void SetDistortion(const float* dks);
+
+ HmdTypeEnum GetHmdType() const;
};
@@ -149,8 +131,8 @@ public:
// Requests the currently used default profile. This profile affects the
// settings reported by HMDInfo.
- virtual Profile* GetProfile() const;
- virtual const char* GetProfileName() const;
+ virtual Profile* GetProfile();
+ virtual const char* GetProfileName();
virtual bool SetProfileName(const char* name);
// Query associated sensor.
diff --git a/LibOVR/Src/OVR_Win32_SensorDevice.cpp b/LibOVR/Src/OVR_Win32_SensorDevice.cpp
index 88beb7a..e8beb31 100644
--- a/LibOVR/Src/OVR_Win32_SensorDevice.cpp
+++ b/LibOVR/Src/OVR_Win32_SensorDevice.cpp
@@ -5,16 +5,16 @@ Content : Win32 SensorDevice implementation
Created : March 12, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -43,13 +43,15 @@ void SensorDeviceImpl::EnumerateHMDFromSensorDisplayInfo
Win32::HMDDeviceCreateDesc hmdCreateDesc(&Win32::HMDDeviceFactory::Instance, String(), String());
hmdCreateDesc.SetScreenParameters( 0, 0,
displayInfo.HResolution, displayInfo.VResolution,
- displayInfo.HScreenSize, displayInfo.VScreenSize);
-
- if ((displayInfo.DistortionType & SensorDisplayInfoImpl::Mask_BaseFmt) & SensorDisplayInfoImpl::Base_Distortion)
- hmdCreateDesc.SetDistortion(displayInfo.EyeToScreenDistance[0], displayInfo.DistortionK);
- if (displayInfo.HScreenSize > 0.14f)
- hmdCreateDesc.Set7Inch();
-
+ displayInfo.HScreenSize, displayInfo.VScreenSize,
+ displayInfo.VCenter, displayInfo.LensSeparation);
+
+ if ((displayInfo.DistortionType & SensorDisplayInfoImpl::Mask_BaseFmt) == SensorDisplayInfoImpl::Base_Distortion)
+ {
+ // TODO: update to spline system.
+ hmdCreateDesc.SetDistortion(displayInfo.DistortionK);
+ }
+
visitor.Visit(hmdCreateDesc);
}
diff --git a/LibOVR/Src/OVR_Win32_SensorDevice.h b/LibOVR/Src/OVR_Win32_SensorDevice.h
index 85f478f..6e4e070 100644
--- a/LibOVR/Src/OVR_Win32_SensorDevice.h
+++ b/LibOVR/Src/OVR_Win32_SensorDevice.h
@@ -5,16 +5,16 @@ Content : Win32 SensorDevice implementation
Created : March 12, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
diff --git a/LibOVR/Src/Recording/Recorder.h b/LibOVR/Src/Recording/Recorder.h
new file mode 100644
index 0000000..460c3e6
--- /dev/null
+++ b/LibOVR/Src/Recording/Recorder.h
@@ -0,0 +1,273 @@
+/************************************************************************************
+
+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
new file mode 100644
index 0000000..e038d1f
--- /dev/null
+++ b/LibOVR/Src/Util/Util_ImageWindow.cpp
@@ -0,0 +1,473 @@
+/************************************************************************************
+
+Filename : Util_ImageWindow.cpp
+Content : An output object for windows that can display raw images for testing
+Created : March 13, 2014
+Authors : Dean Beeler
+
+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 "../../Include/OVR.h"
+
+#include "Util_ImageWindow.h"
+
+#include <Windows.h>
+
+typedef HRESULT (WINAPI *D2D1CreateFactoryFn)(
+ _In_ D2D1_FACTORY_TYPE,
+ _In_ REFIID,
+ _In_opt_ const D2D1_FACTORY_OPTIONS*,
+ _Out_ ID2D1Factory **
+ );
+
+
+namespace OVR { namespace Util {
+
+ID2D1Factory* ImageWindow::pD2DFactory = NULL;
+ImageWindow* ImageWindow::globalWindow = NULL;
+
+LRESULT CALLBACK MainWndProc(
+ HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_CREATE:
+ return 0;
+
+ case WM_PAINT:
+ {
+ LONG_PTR ptr = GetWindowLongPtr( hwnd, GWLP_USERDATA );
+ if( ptr )
+ {
+ ImageWindow* iw = (ImageWindow*)ptr;
+ iw->OnPaint();
+ }
+ }
+
+ return 0;
+
+ case WM_SIZE:
+ // Set the size and position of the window.
+ return 0;
+
+ case WM_DESTROY:
+ // Clean up window-specific data objects.
+ return 0;
+
+ //
+ // Process other messages.
+ //
+
+ default:
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+ }
+ //return 0;
+}
+
+ImageWindow::ImageWindow() :
+ frontBufferMutex( new Mutex() )
+{
+
+ HINSTANCE hInst = LoadLibrary( L"d2d1.dll" );
+
+ D2D1CreateFactoryFn createFactory = NULL;
+
+ if( hInst )
+ {
+ createFactory = (D2D1CreateFactoryFn)GetProcAddress( hInst, "D2D1CreateFactory" );
+ }
+
+ globalWindow = this;
+
+ int width = 752;
+ int height = 480;
+
+ if( pD2DFactory == NULL && createFactory )
+ {
+ createFactory(
+ D2D1_FACTORY_TYPE_MULTI_THREADED,
+ __uuidof(ID2D1Factory),
+ NULL,
+ &pD2DFactory
+ );
+ }
+
+ resolution = D2D1::SizeU( width, height );
+
+ SetWindowLongPtr( hWindow, GWLP_USERDATA, (LONG_PTR)this );
+
+ pRT = NULL;
+ greyBitmap = NULL;
+ colorBitmap = NULL;
+}
+
+ImageWindow::ImageWindow( UINT width, UINT height ) :
+ frontBufferMutex( new Mutex() )
+{
+
+
+ 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 );
+}
+
+ImageWindow::~ImageWindow()
+{
+ if( greyBitmap )
+ greyBitmap->Release();
+
+ if( colorBitmap )
+ colorBitmap->Release();
+
+ if( pRT )
+ pRT->Release();
+
+ delete frontBufferMutex;
+
+ ShowWindow( hWindow, SW_HIDE );
+ DestroyWindow( hWindow );
+}
+
+void ImageWindow::AssociateSurface( void* surface )
+{
+ // Assume an IUnknown
+ IUnknown* unknown = (IUnknown*)surface;
+
+ IDXGISurface *pDxgiSurface = NULL;
+ HRESULT hr = unknown->QueryInterface(&pDxgiSurface);
+ if( hr == S_OK )
+ {
+ D2D1_RENDER_TARGET_PROPERTIES props =
+ D2D1::RenderTargetProperties(
+ D2D1_RENDER_TARGET_TYPE_DEFAULT,
+ D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
+ 96,
+ 96
+ );
+
+
+ pRT = NULL;
+ ID2D1RenderTarget* tmpTarget;
+
+ hr = pD2DFactory->CreateDxgiSurfaceRenderTarget( pDxgiSurface, &props, &tmpTarget );
+
+ if( hr == S_OK )
+ {
+ DXGI_SURFACE_DESC desc = {0};
+ pDxgiSurface->GetDesc( &desc );
+ int width = desc.Width;
+ int height = desc.Height;
+
+ D2D1_SIZE_U size = D2D1::SizeU( width, height );
+
+ D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat(
+ DXGI_FORMAT_A8_UNORM,
+ D2D1_ALPHA_MODE_PREMULTIPLIED
+ );
+
+ D2D1_PIXEL_FORMAT colorPixelFormat = D2D1::PixelFormat(
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ D2D1_ALPHA_MODE_PREMULTIPLIED
+ );
+
+ D2D1_BITMAP_PROPERTIES bitmapProps;
+ bitmapProps.dpiX = 96;
+ bitmapProps.dpiY = 96;
+ bitmapProps.pixelFormat = pixelFormat;
+
+ D2D1_BITMAP_PROPERTIES colorBitmapProps;
+ colorBitmapProps.dpiX = 96;
+ colorBitmapProps.dpiY = 96;
+ colorBitmapProps.pixelFormat = colorPixelFormat;
+
+ HRESULT result = tmpTarget->CreateBitmap( size, bitmapProps, &greyBitmap );
+ if( result != S_OK )
+ {
+ tmpTarget->Release();
+ tmpTarget = NULL;
+ }
+
+ result = tmpTarget->CreateBitmap( size, colorBitmapProps, &colorBitmap );
+ if( result != S_OK )
+ {
+ greyBitmap->Release();
+ greyBitmap = NULL;
+
+ tmpTarget->Release();
+ tmpTarget = NULL;
+ }
+ pRT = tmpTarget;
+ }
+ }
+}
+
+void ImageWindow::Process()
+{
+ if( pRT && greyBitmap )
+ {
+ OnPaint();
+ }
+}
+
+void ImageWindow::Complete()
+{
+ Mutex::Locker locker( frontBufferMutex );
+
+ if( frames.IsEmpty() )
+ return;
+
+ if( frames.PeekBack(0).ready )
+ return;
+
+ Frame& frame = frames.PeekBack(0);
+
+ 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 )
+ return;
+
+ Frame currentFrame = frames.PopFront();
+ Frame dummyFrame = {0};
+
+ Frame& nextFrame = dummyFrame;
+
+ if( !frames.IsEmpty() )
+ nextFrame = frames.PeekFront(0);
+
+ while( 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;
+
+ nextFrame = frames.PeekFront(0);
+ }
+
+ if( currentFrame.imageData )
+ greyBitmap->CopyFromMemory( NULL, currentFrame.imageData, currentFrame.width );
+
+ if( currentFrame.colorImageData )
+ colorBitmap->CopyFromMemory( NULL, currentFrame.colorImageData, currentFrame.colorPitch );
+
+ pRT->BeginDraw();
+
+ pRT->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
+
+ pRT->Clear( D2D1::ColorF(D2D1::ColorF::Black) );
+
+ // This will mirror our image
+ D2D1_MATRIX_3X2_F m;
+ m._11 = -1; m._12 = 0;
+ m._21 = 0; m._22 = 1;
+ m._31 = 0; m._32 = 0;
+ pRT->SetTransform( m );
+
+ ID2D1SolidColorBrush* whiteBrush;
+
+ pRT->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::White, 1.0f), &whiteBrush );
+
+ 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)resolution.width, (FLOAT)resolution.height ) );
+ }
+ else if( currentFrame.colorImageData )
+ {
+ pRT->DrawBitmap( colorBitmap,
+ D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ) );
+
+ }
+
+ pRT->SetTransform(D2D1::Matrix3x2F::Identity());
+
+ whiteBrush->Release();
+
+ Array<CirclePlot>::Iterator it;
+
+ for( it = currentFrame.plots.Begin(); it != currentFrame.plots.End(); ++it )
+ {
+ ID2D1SolidColorBrush* aBrush;
+
+ pRT->CreateSolidColorBrush( D2D1::ColorF( it->r, it->g, it->b), &aBrush );
+
+ D2D1_ELLIPSE ellipse;
+ ellipse.point.x = it->x;
+ ellipse.point.y = it->y;
+ ellipse.radiusX = it->radius;
+ ellipse.radiusY = it->radius;
+
+ if( it->fill )
+ pRT->FillEllipse( &ellipse, aBrush );
+ else
+ pRT->DrawEllipse( &ellipse, aBrush );
+
+ aBrush->Release();
+ }
+
+ pRT->EndDraw();
+
+ if( currentFrame.imageData )
+ free( currentFrame.imageData );
+ if( currentFrame.colorImageData )
+ free( currentFrame.colorImageData );
+}
+
+void ImageWindow::UpdateImageBW( const UINT8* imageData, UINT width, UINT 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 );
+ }
+}
+
+void ImageWindow::UpdateImageRGBA( const UINT8* imageData, UINT width, UINT height, UINT 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 );
+ }
+}
+
+void ImageWindow::addCircle( float x, float y, float radius, float r, float g, float b, bool fill )
+{
+ if( pRT )
+ {
+ CirclePlot cp;
+
+ cp.x = x;
+ cp.y = y;
+ cp.radius = radius;
+ cp.r = r;
+ cp.g = g;
+ cp.b = b;
+ cp.fill = fill;
+
+ Mutex::Locker locker( frontBufferMutex );
+ Frame& frame = frames.PeekBack( 0 );
+ frame.plots.PushBack( cp );
+ }
+
+}
+
+}}
diff --git a/LibOVR/Src/Util/Util_ImageWindow.h b/LibOVR/Src/Util/Util_ImageWindow.h
new file mode 100644
index 0000000..418598c
--- /dev/null
+++ b/LibOVR/Src/Util/Util_ImageWindow.h
@@ -0,0 +1,122 @@
+/************************************************************************************
+
+Filename : Util_ImageWindow.h
+Content : An output object for windows that can display raw images for testing
+Created : March 13, 2014
+Authors : Dean Beeler
+
+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 UTIL_IMAGEWINDOW_H
+#define UTIL_IMAGEWINDOW_H
+
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#include <d2d1.h>
+
+#include "../../Include/OVR.h"
+#include "../Kernel/OVR_Hash.h"
+#include "../Kernel/OVR_Array.h"
+#include "../Kernel/OVR_Threads.h"
+#include "../Kernel/OVR_Deque.h"
+
+#include <stdint.h>
+
+namespace OVR { namespace Util {
+
+class ImageWindow
+{
+ typedef struct
+ {
+ float x;
+ float y;
+ float radius;
+ float r;
+ float g;
+ float b;
+ bool fill;
+ } CirclePlot;
+
+ typedef struct
+ {
+ float x;
+ float y;
+ float r;
+ float g;
+ float b;
+ WCHAR* text;
+ } TextPlot;
+
+ typedef struct
+ {
+ Array<CirclePlot> plots;
+ void* imageData;
+ void* colorImageData;
+ int width;
+ int height;
+ int colorPitch;
+ bool ready;
+ } Frame;
+
+ static ID2D1Factory* pD2DFactory;
+
+ HWND hWindow;
+ ID2D1RenderTarget* pRT;
+ D2D1_SIZE_U resolution;
+
+ Mutex* frontBufferMutex;
+
+ InPlaceMutableDeque<Frame> frames;
+
+ ID2D1Bitmap* greyBitmap;
+ ID2D1Bitmap* colorBitmap;
+
+public:
+ // constructors
+ ImageWindow();
+ ImageWindow( UINT width, UINT height );
+ virtual ~ImageWindow();
+
+ 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 Complete(); // Called by drawing thread to submit a frame
+
+ void Process(); // Called by rendering thread to do window processing
+
+ void AssociateSurface( void* surface );
+
+ void addCircle( float x , float y, float radius, float r, float g, float b, bool fill );
+
+ static ImageWindow* GlobalWindow() { return globalWindow; }
+
+private:
+
+
+ static ImageWindow* globalWindow;
+
+ static bool running;
+};
+
+}} // namespace OVR::Util
+
+#endif \ No newline at end of file
diff --git a/LibOVR/Src/Util/Util_Interface.cpp b/LibOVR/Src/Util/Util_Interface.cpp
new file mode 100644
index 0000000..d96423c
--- /dev/null
+++ b/LibOVR/Src/Util/Util_Interface.cpp
@@ -0,0 +1,34 @@
+/************************************************************************************
+
+Filename : Util_Interface.cpp
+Content : Simple interface, utilised by internal demos,
+ with access to wider SDK as needed.
+ Located in the body of the SDK to ensure updated
+ when new SDK features are added.
+Created : February 20, 2014
+Authors : Tom Heath
+
+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 "Util_Interface.h"
+
+
+
+//Files left in to ease its possible return...... \ No newline at end of file
diff --git a/LibOVR/Src/Util/Util_Interface.h b/LibOVR/Src/Util/Util_Interface.h
new file mode 100644
index 0000000..1bbf638
--- /dev/null
+++ b/LibOVR/Src/Util/Util_Interface.h
@@ -0,0 +1,37 @@
+/************************************************************************************
+
+PublicHeader: OVR.h
+Filename : Util_Interface.h
+Content : Simple interface, utilised by internal demos,
+ with access to wider SDK as needed.
+ Located in the body of the SDK to ensure updated
+ when new SDK features are added.
+Created : February 20, 2014
+Authors : Tom Heath
+
+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_Util_Interface_h
+#define OVR_Util_Interface_h
+#include "../../Src/OVR_CAPI.h"
+
+//Files left in to ease its possible return......
+
+#endif
diff --git a/LibOVR/Src/Util/Util_LatencyTest.cpp b/LibOVR/Src/Util/Util_LatencyTest.cpp
index b972e48..3017c72 100644
--- a/LibOVR/Src/Util/Util_LatencyTest.cpp
+++ b/LibOVR/Src/Util/Util_LatencyTest.cpp
@@ -5,16 +5,16 @@ Content : Wraps the lower level LatencyTester interface and adds functiona
Created : February 14, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -73,31 +73,19 @@ bool LatencyTest::SetDevice(LatencyTestDevice* device)
if (device != Device)
{
- if (device != NULL)
- {
- if (device->GetMessageHandler() != NULL)
- {
- OVR_DEBUG_LOG(
- ("LatencyTest::AttachToDevice failed - device %p already has handler", device));
- return false;
- }
- }
+ Handler.RemoveHandlerFromDevices();
- if (Device != NULL)
- {
- Device->SetMessageHandler(0);
- }
Device = device;
if (Device != NULL)
{
- Device->SetMessageHandler(&Handler);
+ Device->AddMessageHandler(&Handler);
// Set trigger threshold.
LatencyTestConfiguration configuration(SENSOR_DETECT_THRESHOLD, false); // No samples streaming.
Device->SetConfiguration(configuration, true);
- // Set display to intial (3 dashes).
+ // Set display to initial (3 dashes).
LatencyTestDisplay ltd(2, 0x40400040);
Device->SetDisplay(ltd);
}
@@ -251,7 +239,7 @@ void LatencyTest::handleMessage(const Message& msg, LatencyTestMessageType laten
getActiveResult()->TargetColor = RenderColor;
// Record time so we can determine usb roundtrip time.
- getActiveResult()->StartTestTicksMicroS = Timer::GetTicks();
+ getActiveResult()->StartTestSeconds = Timer::GetSeconds();
Device->SetStartTest(RenderColor);
@@ -275,7 +263,7 @@ void LatencyTest::handleMessage(const Message& msg, LatencyTestMessageType laten
clearTimer();
// Record time so we can determine usb roundtrip time.
- getActiveResult()->TestStartedTicksMicroS = Timer::GetTicks();
+ getActiveResult()->TestStartedSeconds = Timer::GetSeconds();
State = State_WaitingForColorDetected;
OVR_DEBUG_LOG(("State_WaitingForTestStarted -> State_WaitingForColorDetected."));
@@ -501,7 +489,7 @@ void LatencyTest::processResults()
}
}
- float usbRountripElapsedMilliS = 0.001f * (float) (pCurr->TestStartedTicksMicroS - pCurr->StartTestTicksMicroS);
+ float usbRountripElapsedMilliS = Timer::MsPerSecond * (float) (pCurr->TestStartedSeconds - pCurr->StartTestSeconds);
minUSBTripMilliS = Alg::Min(usbRountripElapsedMilliS, minUSBTripMilliS);
maxUSBTripMilliS = Alg::Max(usbRountripElapsedMilliS, maxUSBTripMilliS);
averageUSBTripMilliS += usbRountripElapsedMilliS;
diff --git a/LibOVR/Src/Util/Util_LatencyTest.h b/LibOVR/Src/Util/Util_LatencyTest.h
index 657a3a9..0844603 100644
--- a/LibOVR/Src/Util/Util_LatencyTest.h
+++ b/LibOVR/Src/Util/Util_LatencyTest.h
@@ -6,16 +6,16 @@ Content : Wraps the lower level LatencyTesterDevice and adds functionality
Created : February 14, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -80,6 +80,8 @@ public:
bool DisplayScreenColor(Color& colorToDisplay);
const char* GetResultsString();
+ bool IsMeasuringNow() const { return (State != State_WaitingForButton); }
+
// Begin test. Equivalent to pressing the button on the latency tester.
void BeginTest();
@@ -142,8 +144,8 @@ private:
: DeviceMeasuredElapsedMilliS(0),
TimedOutWaitingForTestStarted(false),
TimedOutWaitingForColorDetected(false),
- StartTestTicksMicroS(0),
- TestStartedTicksMicroS(0)
+ StartTestSeconds(0.0),
+ TestStartedSeconds(0.0)
{}
Color TargetColor;
@@ -153,8 +155,8 @@ private:
bool TimedOutWaitingForTestStarted;
bool TimedOutWaitingForColorDetected;
- UInt64 StartTestTicksMicroS;
- UInt64 TestStartedTicksMicroS;
+ double StartTestSeconds;
+ double TestStartedSeconds;
};
List<MeasurementResult> Results;
diff --git a/LibOVR/Src/Util/Util_LatencyTest2.cpp b/LibOVR/Src/Util/Util_LatencyTest2.cpp
new file mode 100644
index 0000000..f4baf29
--- /dev/null
+++ b/LibOVR/Src/Util/Util_LatencyTest2.cpp
@@ -0,0 +1,194 @@
+/************************************************************************************
+
+Filename : Util_LatencyTest2.cpp
+Content : Wraps the lower level LatencyTester interface for DK2 and adds functionality.
+Created : March 10, 2014
+Authors : Volga Aksoy
+
+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 "Util_LatencyTest2.h"
+
+#include "../OVR_CAPI.h"
+#include "../Kernel/OVR_Log.h"
+#include "../Kernel/OVR_Timer.h"
+
+
+namespace OVR { namespace Util {
+
+//static const float BIG_FLOAT = 1000000.0f;
+//static const float SMALL_FLOAT = -1000000.0f;
+
+//-------------------------------------------------------------------------------------
+// ***** LatencyTest2
+
+LatencyTest2::LatencyTest2(SensorDevice* device)
+ : Handler(getThis())
+ , TestActive(false)
+ , StartTiming(-1)
+ , LatencyMeasuredInSeconds(-1)
+ , LastPixelReadMsg(NULL)
+ , RenderColorValue(0)
+ , NumMsgsBeforeSettle(0)
+ , NumTestsSuccessful(0)
+{
+ if (device != NULL)
+ {
+ SetSensorDevice(device);
+ }
+}
+
+LatencyTest2::~LatencyTest2()
+{
+ HmdDevice = NULL;
+ LatencyTesterDev = NULL;
+
+ Handler.RemoveHandlerFromDevices();
+}
+
+bool LatencyTest2::SetSensorDevice(SensorDevice* device)
+{
+ Lock::Locker devLocker(&TesterLock);
+
+ // Enable/Disable pixel read from HMD
+ if (device != HmdDevice)
+ {
+ Handler.RemoveHandlerFromDevices();
+
+ HmdDevice = device;
+
+ if (HmdDevice != NULL)
+ {
+ HmdDevice->AddMessageHandler(&Handler);
+ }
+ }
+
+ return true;
+}
+
+bool LatencyTest2::SetDisplayDevice(LatencyTestDevice* device)
+{
+ Lock::Locker devLocker(&TesterLock);
+
+ if (device != LatencyTesterDev)
+ {
+ LatencyTesterDev = device;
+ if (LatencyTesterDev != NULL)
+ {
+ // Set display to initial (3 dashes).
+ LatencyTestDisplay ltd(2, 0x40400040);
+ LatencyTesterDev->SetDisplay(ltd);
+ }
+ }
+
+ return true;
+}
+
+void LatencyTest2::BeginTest(double startTime)
+{
+ Lock::Locker devLocker(&TesterLock);
+
+ if (!TestActive)
+ {
+ TestActive = true;
+ NumMsgsBeforeSettle = 0;
+
+ // Go to next pixel value
+ //RenderColorValue = (RenderColorValue == 0) ? 255 : 0;
+ RenderColorValue = (RenderColorValue + LT2_ColorIncrement) % 256;
+ RawStartTiming = LastPixelReadMsg.RawSensorTime;
+
+ if (startTime > 0.0)
+ StartTiming = startTime;
+ else
+ StartTiming = ovr_GetTimeInSeconds();
+
+ }
+}
+
+void LatencyTest2::handleMessage(const MessagePixelRead& msg)
+{
+ Lock::Locker devLocker(&TesterLock);
+
+ // Hold onto the last message as we will use this when we start a new test
+ LastPixelReadMsg = msg;
+
+ // If color readback index is valid, store it in the lock-less queue.
+ int readbackIndex = 0;
+ if (FrameTimeRecord::ColorToReadbackIndex(&readbackIndex, msg.PixelReadValue))
+ {
+ RecentFrameSet.AddValue(readbackIndex, msg.FrameTimeSeconds);
+ LockessRecords.SetState(RecentFrameSet);
+ }
+
+ NumMsgsBeforeSettle++;
+
+ if (TestActive)
+ {
+ int pixelValueDiff = RenderColorValue - LastPixelReadMsg.PixelReadValue;
+ int rawTimeDiff = LastPixelReadMsg.RawFrameTime - RawStartTiming;
+
+ if (pixelValueDiff < LT2_PixelTestThreshold && pixelValueDiff > -LT2_PixelTestThreshold)
+ {
+ TestActive = false;
+
+ LatencyMeasuredInSeconds = LastPixelReadMsg.FrameTimeSeconds - StartTiming;
+ RawLatencyMeasured = rawTimeDiff;
+ //LatencyMeasuredInSeconds = RawLatencyMeasured / 1000000.0;
+
+ if(LatencyTesterDev && (NumTestsSuccessful % 5) == 0)
+ {
+ int displayNum = (int)(RawLatencyMeasured / 100.0);
+ //int displayNum = NumMsgsBeforeSettle;
+ //int displayNum = (int)(LatencyMeasuredInSeconds * 1000.0);
+ LatencyTestDisplay ltd(1, displayNum);
+ LatencyTesterDev->SetDisplay(ltd);
+ }
+
+ NumTestsSuccessful++;
+ }
+ else if (TestActive && (rawTimeDiff / 1000) > LT2_TimeoutWaitingForColorDetected)
+ {
+ TestActive = false;
+ LatencyMeasuredInSeconds = -1;
+ }
+ }
+}
+
+LatencyTest2::PixelReadHandler::~PixelReadHandler()
+{
+ RemoveHandlerFromDevices();
+}
+
+void LatencyTest2::PixelReadHandler::OnMessage(const Message& msg)
+{
+ if(msg.Type == Message_PixelRead)
+ pLatencyTestUtil->handleMessage(static_cast<const MessagePixelRead&>(msg));
+}
+
+bool LatencyTest2::DisplayScreenColor(Color& colorToDisplay)
+{
+ Lock::Locker devLocker(&TesterLock);
+ colorToDisplay = Color(RenderColorValue, RenderColorValue, RenderColorValue, 255);
+
+ return TestActive;
+}
+
+}} // namespace OVR::Util
diff --git a/LibOVR/Src/Util/Util_LatencyTest2.h b/LibOVR/Src/Util/Util_LatencyTest2.h
new file mode 100644
index 0000000..ae11a52
--- /dev/null
+++ b/LibOVR/Src/Util/Util_LatencyTest2.h
@@ -0,0 +1,238 @@
+/************************************************************************************
+
+PublicHeader: OVR.h
+Filename : Util_LatencyTest2.h
+Content : Wraps the lower level LatencyTester interface for DK2 and adds functionality.
+Created : March 10, 2014
+Authors : Volga Aksoy
+
+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_Util_LatencyTest2_h
+#define OVR_Util_LatencyTest2_h
+
+#include "../OVR_Device.h"
+
+#include "../Kernel/OVR_String.h"
+#include "../Kernel/OVR_List.h"
+#include "../Kernel/OVR_Lockless.h"
+
+namespace OVR { namespace Util {
+
+
+enum {
+ LT2_ColorIncrement = 32,
+ LT2_PixelTestThreshold = LT2_ColorIncrement / 3,
+ LT2_IncrementCount = 256 / LT2_ColorIncrement,
+ LT2_TimeoutWaitingForColorDetected = 1000 // 1 second
+};
+
+//-------------------------------------------------------------------------------------
+
+// Describes frame scanout time used for latency testing.
+struct FrameTimeRecord
+{
+ int ReadbackIndex;
+ double TimeSeconds;
+
+ // Utility functions to convert color to readBack indices and back.
+ // The purpose of ReadbackIndex is to allow direct comparison by value.
+
+ static bool ColorToReadbackIndex(int *readbackIndex, unsigned char color)
+ {
+ int compareColor = color - LT2_ColorIncrement/2;
+ int index = color / LT2_ColorIncrement; // Use color without subtraction due to rounding.
+ int delta = compareColor - index * LT2_ColorIncrement;
+
+ if ((delta < LT2_PixelTestThreshold) && (delta > -LT2_PixelTestThreshold))
+ {
+ *readbackIndex = index;
+ return true;
+ }
+ return false;
+ }
+
+ static unsigned char ReadbackIndexToColor(int readbackIndex)
+ {
+ OVR_ASSERT(readbackIndex < LT2_IncrementCount);
+ return (unsigned char)(readbackIndex * LT2_ColorIncrement + LT2_ColorIncrement/2);
+ }
+};
+
+// FrameTimeRecordSet is a container holding multiple consecutive frame timing records
+// returned from the lock-less state. Used by FrameTimeManager.
+
+struct FrameTimeRecordSet
+{
+ enum {
+ RecordCount = 4,
+ RecordMask = RecordCount - 1
+ };
+ FrameTimeRecord Records[RecordCount];
+ int NextWriteIndex;
+
+ FrameTimeRecordSet()
+ {
+ NextWriteIndex = 0;
+ memset(this, 0, sizeof(FrameTimeRecordSet));
+ }
+
+ void AddValue(int readValue, double timeSeconds)
+ {
+ Records[NextWriteIndex].ReadbackIndex = readValue;
+ Records[NextWriteIndex].TimeSeconds = timeSeconds;
+ NextWriteIndex ++;
+ if (NextWriteIndex == RecordCount)
+ NextWriteIndex = 0;
+ }
+ // Matching should be done starting from NextWrite index
+ // until wrap-around
+
+ const FrameTimeRecord& operator [] (int i) const
+ {
+ return Records[(NextWriteIndex + i) & RecordMask];
+ }
+
+ const FrameTimeRecord& GetMostRecentFrame()
+ {
+ return Records[(NextWriteIndex - 1) & RecordMask];
+ }
+
+ // Advances I to absolute color index
+ bool FindReadbackIndex(int* i, int readbackIndex) const
+ {
+ for (; *i < RecordCount; *i++)
+ {
+ if ((*this)[*i].ReadbackIndex == readbackIndex)
+ return true;
+ }
+ return false;
+ }
+
+ bool IsAllZeroes() const
+ {
+ for (int i = 0; i < RecordCount; i++)
+ if (Records[i].ReadbackIndex != 0)
+ return false;
+ return true;
+ }
+};
+
+
+//-------------------------------------------------------------------------------------
+// ***** LatencyTest2
+//
+// LatencyTest2 utility class wraps the low level SensorDevice and manages the scheduling
+// of a latency test. A single test is composed of a series of individual latency measurements
+// which are used to derive min, max, and an average latency value.
+//
+// Developers are required to call the following methods:
+// SetDevice - Sets the SensorDevice to be used for the tests.
+// ProcessInputs - This should be called at the same place in the code where the game engine
+// reads the headset orientation from LibOVR (typically done by calling
+// 'GetOrientation' on the SensorFusion object). Calling this at the right time
+// enables us to measure the same latency that occurs for headset orientation
+// changes.
+// DisplayScreenColor - The latency tester works by sensing the color of the pixels directly
+// beneath it. The color of these pixels can be set by drawing a small
+// quad at the end of the rendering stage. The quad should be small
+// such that it doesn't significantly impact the rendering of the scene,
+// but large enough to be 'seen' by the sensor. See the SDK
+// documentation for more information.
+// GetResultsString - Call this to get a string containing the most recent results.
+// If the string has already been gotten then NULL will be returned.
+// The string pointer will remain valid until the next time this
+// method is called.
+//
+
+class LatencyTest2 : public NewOverrideBase
+{
+public:
+ LatencyTest2(SensorDevice* device = NULL);
+ ~LatencyTest2();
+
+ // Set the Latency Tester device that we'll use to send commands to and receive
+ // notification messages from.
+ bool SetSensorDevice(SensorDevice* device);
+ bool SetDisplayDevice(LatencyTestDevice* device);
+
+ // Returns true if this LatencyTestUtil has a Latency Tester device.
+ bool HasDisplayDevice() const { return LatencyTesterDev.GetPtr() != NULL; }
+ bool HasDevice() const { return Handler.IsHandlerInstalled(); }
+
+ bool DisplayScreenColor(Color& colorToDisplay);
+ //const char* GetResultsString();
+
+ // Begin test. Equivalent to pressing the button on the latency tester.
+ void BeginTest(double startTime = -1.0f);
+ bool IsMeasuringNow() const { return TestActive; }
+ double GetMeasuredLatency() const { return LatencyMeasuredInSeconds; }
+
+//
+ FrameTimeRecordSet GetLocklessState() { return LockessRecords.GetState(); }
+
+private:
+ LatencyTest2* getThis() { return this; }
+
+ enum LatencyTestMessageType
+ {
+ LatencyTest_None,
+ LatencyTest_Timer,
+ LatencyTest_ProcessInputs,
+ };
+
+ void handleMessage(const MessagePixelRead& msg);
+
+ class PixelReadHandler : public MessageHandler
+ {
+ LatencyTest2* pLatencyTestUtil;
+ public:
+ PixelReadHandler(LatencyTest2* latencyTester) : pLatencyTestUtil(latencyTester) { }
+ ~PixelReadHandler();
+
+ virtual void OnMessage(const Message& msg);
+ };
+ PixelReadHandler Handler;
+
+ Ptr<SensorDevice> HmdDevice;
+ Ptr<LatencyTestDevice> LatencyTesterDev;
+
+ Lock TesterLock;
+ bool TestActive;
+ unsigned char RenderColorValue;
+ MessagePixelRead LastPixelReadMsg;
+ double StartTiming;
+ unsigned int RawStartTiming;
+ UInt32 RawLatencyMeasured;
+ double LatencyMeasuredInSeconds;
+ int NumMsgsBeforeSettle;
+ unsigned int NumTestsSuccessful;
+
+ // MA:
+ // Frames are added here, then copied into lockess state
+ FrameTimeRecordSet RecentFrameSet;
+ LocklessUpdater<FrameTimeRecordSet> LockessRecords;
+};
+
+
+
+}} // namespace OVR::Util
+
+#endif // OVR_Util_LatencyTest2_h
diff --git a/LibOVR/Src/Util/Util_MagCalibration.cpp b/LibOVR/Src/Util/Util_MagCalibration.cpp
deleted file mode 100644
index 58b8c45..0000000
--- a/LibOVR/Src/Util/Util_MagCalibration.cpp
+++ /dev/null
@@ -1,227 +0,0 @@
-/************************************************************************************
-
-Filename : Util_MagCalibration.cpp
-Content : Procedures for calibrating the magnetometer
-Created : April 16, 2013
-Authors : Steve LaValle, Andrew Reisse
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Use of this software is subject to the terms of the Oculus license
-agreement provided at the time of installation or download, or which
-otherwise accompanies this software in either electronic or hard copy form.
-
-*************************************************************************************/
-
-#include "Util_MagCalibration.h"
-
-namespace OVR { namespace Util {
-
-void MagCalibration::BeginAutoCalibration(SensorFusion& sf)
-{
- Stat = Mag_AutoCalibrating;
- // This is a "hard" reset of the mag, so need to clear stored values
- sf.ClearMagCalibration();
- SampleCount = 0;
-
- // reset the statistics
- MinMagValues = Vector3f(10000.0f,10000.0f,10000.0f);
- MaxMagValues = Vector3f(-10000.0f,-10000.0f,-10000.0f);
- MinQuatValues = Quatf(1.0f,1.0f,1.0f,1.0f);
- MaxQuatValues = Quatf(0.0f,0.0f,0.0f,0.0f);
-}
-
-unsigned MagCalibration::UpdateAutoCalibration(SensorFusion& sf)
-{
- if (Stat != Mag_AutoCalibrating)
- return Stat;
-
- Quatf q = sf.GetOrientation();
- Vector3f m = sf.GetMagnetometer();
-
- InsertIfAcceptable(q, m);
-
- if ((SampleCount == 4) && (Stat == Mag_AutoCalibrating))
- {
- //LogText("Magnetometer Output Spread: %f %f %f\n",MagSpread.x,MagSpread.y,MagSpread.z);
- //LogText("Quaternion Spread: %f %f %f %f\n",QuatSpread.x,QuatSpread.y,QuatSpread.z,QuatSpread.w);
- SetCalibration(sf);
- }
-
- return Stat;
-
-}
-
-void MagCalibration::BeginManualCalibration(SensorFusion& sf)
-{
- Stat = Mag_ManuallyCalibrating;
- sf.ClearMagCalibration();
- SampleCount = 0;
-}
-
-bool MagCalibration::IsAcceptableSample(const Quatf& q, const Vector3f& m)
-{
- switch (SampleCount)
- {
- // Initial sample is always acceptable
- case 0:
- return true;
- break;
- case 1:
- return (q.DistanceSq(QuatSamples[0]) > MinQuatDistanceSq)&&
- ((m - MagSamples[0]).LengthSq() > MinMagDistanceSq);
- break;
- case 2:
- return (q.DistanceSq(QuatSamples[0]) > MinQuatDistanceSq)&&
- (q.DistanceSq(QuatSamples[1]) > MinQuatDistanceSq)&&
- ((m - MagSamples[0]).LengthSq() > MinMagDistanceSq)&&
- ((m - MagSamples[1]).LengthSq() > MinMagDistanceSq);
- break;
- case 3:
- return (q.DistanceSq(QuatSamples[0]) > MinQuatDistanceSq)&&
- (q.DistanceSq(QuatSamples[1]) > MinQuatDistanceSq)&&
- (q.DistanceSq(QuatSamples[2]) > MinQuatDistanceSq)&&
- ((PointToPlaneDistance(MagSamples[0],MagSamples[1],MagSamples[2],m) > MinMagDistance)||
- (PointToPlaneDistance(MagSamples[1],MagSamples[2],m,MagSamples[0]) > MinMagDistance)||
- (PointToPlaneDistance(MagSamples[2],m,MagSamples[0],MagSamples[1]) > MinMagDistance)||
- (PointToPlaneDistance(m,MagSamples[0],MagSamples[1],MagSamples[2]) > MinMagDistance));
- }
-
- return false;
-}
-
-
-bool MagCalibration::InsertIfAcceptable(const Quatf& q, const Vector3f& m)
-{
- // Update some statistics
- if (m.x < MinMagValues.x)
- MinMagValues.x = m.x;
- if (m.y < MinMagValues.y)
- MinMagValues.y = m.y;
- if (m.z < MinMagValues.z)
- MinMagValues.z = m.z;
- if (m.x > MaxMagValues.x)
- MaxMagValues.x = m.x;
- if (m.y > MaxMagValues.y)
- MaxMagValues.y = m.y;
- if (m.z > MaxMagValues.z)
- MaxMagValues.z = m.z;
- if (q.x < MinQuatValues.x)
- MinQuatValues.x = q.x;
- if (q.y < MinQuatValues.y)
- MinQuatValues.y = q.y;
- if (q.z < MinQuatValues.z)
- MinQuatValues.z = q.z;
- if (q.w < MinQuatValues.w)
- MinQuatValues.w = q.w;
- if (q.x > MaxQuatValues.x)
- MaxQuatValues.x = q.x;
- if (q.y > MaxQuatValues.y)
- MaxQuatValues.y = q.y;
- if (q.z > MaxQuatValues.z)
- MaxQuatValues.z = q.z;
- if (q.w > MaxQuatValues.w)
- MaxQuatValues.w = q.w;
- MagSpread = MaxMagValues - MinMagValues;
- QuatSpread = MaxQuatValues - MinQuatValues;
-
- if (IsAcceptableSample(q, m))
- {
- MagSamples[SampleCount] = m;
- QuatSamples[SampleCount] = q;
- SampleCount++;
- return true;
- }
-
- return false;
-}
-
-Matrix4f MagCalibration::GetMagCalibration() const
-{
- Matrix4f calMat = Matrix4f();
- calMat.M[0][3] = -MagCenter.x;
- calMat.M[1][3] = -MagCenter.y;
- calMat.M[2][3] = -MagCenter.z;
- return calMat;
-}
-
-bool MagCalibration::SetCalibration(SensorFusion& sf)
-{
- if (SampleCount < 4)
- return false;
-
- MagCenter = CalculateSphereCenter(MagSamples[0],MagSamples[1],MagSamples[2],MagSamples[3]);
- Matrix4f calMat = GetMagCalibration();
- sf.SetMagCalibration(calMat);
- Stat = Mag_Calibrated;
- //LogText("MagCenter: %f %f %f\n",MagCenter.x,MagCenter.y,MagCenter.z);
-
- return true;
-}
-
-
-// Calculate the center of a sphere that passes through p1, p2, p3, p4
-Vector3f MagCalibration::CalculateSphereCenter(const Vector3f& p1, const Vector3f& p2,
- const Vector3f& p3, const Vector3f& p4)
-{
- Matrix4f A;
- int i;
- Vector3f p[4];
- p[0] = p1;
- p[1] = p2;
- p[2] = p3;
- p[3] = p4;
-
- for (i = 0; i < 4; i++)
- {
- A.M[i][0] = p[i].x;
- A.M[i][1] = p[i].y;
- A.M[i][2] = p[i].z;
- A.M[i][3] = 1.0f;
- }
- float m11 = A.Determinant();
- OVR_ASSERT(m11 != 0.0f);
-
- for (i = 0; i < 4; i++)
- {
- A.M[i][0] = p[i].x*p[i].x + p[i].y*p[i].y + p[i].z*p[i].z;
- A.M[i][1] = p[i].y;
- A.M[i][2] = p[i].z;
- A.M[i][3] = 1.0f;
- }
- float m12 = A.Determinant();
-
- for (i = 0; i < 4; i++)
- {
- A.M[i][0] = p[i].x*p[i].x + p[i].y*p[i].y + p[i].z*p[i].z;
- A.M[i][1] = p[i].x;
- A.M[i][2] = p[i].z;
- A.M[i][3] = 1.0f;
- }
- float m13 = A.Determinant();
-
- for (i = 0; i < 4; i++)
- {
- A.M[i][0] = p[i].x*p[i].x + p[i].y*p[i].y + p[i].z*p[i].z;
- A.M[i][1] = p[i].x;
- A.M[i][2] = p[i].y;
- A.M[i][3] = 1.0f;
- }
- float m14 = A.Determinant();
-
- float c = 0.5f / m11;
- return Vector3f(c*m12, -c*m13, c*m14);
-}
-
-// Distance from p4 to the nearest point on a plane through p1, p2, p3
-float MagCalibration::PointToPlaneDistance(const Vector3f& p1, const Vector3f& p2,
- const Vector3f& p3, const Vector3f& p4)
-{
- Vector3f v1 = p1 - p2;
- Vector3f v2 = p1 - p3;
- Vector3f planeNormal = v1.Cross(v2);
- planeNormal.Normalize();
- return (fabs((planeNormal * p4) - planeNormal * p1));
-}
-
-}}
diff --git a/LibOVR/Src/Util/Util_MagCalibration.h b/LibOVR/Src/Util/Util_MagCalibration.h
deleted file mode 100644
index 1f8e8cb..0000000
--- a/LibOVR/Src/Util/Util_MagCalibration.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/************************************************************************************
-
-PublicHeader: OVR.h
-Filename : Util_MagCalibration.h
-Content : Procedures for calibrating the magnetometer
-Created : April 16, 2013
-Authors : Steve LaValle, Andrew Reisse
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Use of this software is subject to the terms of the Oculus 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_Util_MagCalibration_h
-#define OVR_Util_MagCalibration_h
-
-#include "../OVR_SensorFusion.h"
-#include "../Kernel/OVR_String.h"
-#include "../Kernel/OVR_Log.h"
-
-namespace OVR { namespace Util {
-
-class MagCalibration
-{
-public:
- enum MagStatus
- {
- Mag_Uninitialized = 0,
- Mag_AutoCalibrating = 1,
- Mag_ManuallyCalibrating = 2,
- Mag_Calibrated = 3
- };
-
- MagCalibration() :
- Stat(Mag_Uninitialized),
- MinMagDistance(0.2f), MinQuatDistance(0.5f),
- SampleCount(0)
- {
- MinMagDistanceSq = MinMagDistance * MinMagDistance;
- MinQuatDistanceSq = MinQuatDistance * MinQuatDistance;
- MinMagValues = Vector3f(10000.0f,10000.0f,10000.0f);
- MaxMagValues = Vector3f(-10000.0f,-10000.0f,-10000.0f);
- MinQuatValues = Quatf(1.0f,1.0f,1.0f,1.0f);
- MaxQuatValues = Quatf(0.0f,0.0f,0.0f,0.0f);
- }
-
- // Methods that are useful for either auto or manual calibration
- bool IsUnitialized() const { return Stat == Mag_Uninitialized; }
- bool IsCalibrated() const { return Stat == Mag_Calibrated; }
- int NumberOfSamples() const { return SampleCount; }
- int RequiredSampleCount() const { return 4; }
- void AbortCalibration()
- {
- Stat = Mag_Uninitialized;
- SampleCount = 0;
- }
-
- void ClearCalibration(SensorFusion& sf)
- {
- Stat = Mag_Uninitialized;
- SampleCount = 0;
- sf.ClearMagCalibration();
- };
-
- // Methods for automatic magnetometer calibration
- void BeginAutoCalibration(SensorFusion& sf);
- unsigned UpdateAutoCalibration(SensorFusion& sf);
- bool IsAutoCalibrating() const { return Stat == Mag_AutoCalibrating; }
-
- // Methods for building a manual (user-guided) calibraton procedure
- void BeginManualCalibration(SensorFusion& sf);
- bool IsAcceptableSample(const Quatf& q, const Vector3f& m);
- bool InsertIfAcceptable(const Quatf& q, const Vector3f& m);
- // Returns true if successful, requiring that SampleCount = 4
- bool SetCalibration(SensorFusion& sf);
- bool IsManuallyCalibrating() const { return Stat == Mag_ManuallyCalibrating; }
-
- // This is the minimum acceptable distance (Euclidean) between raw
- // magnetometer values to be acceptable for usage in calibration.
- void SetMinMagDistance(float dist)
- {
- MinMagDistance = dist;
- MinMagDistanceSq = MinMagDistance * MinMagDistance;
- }
-
- // The minimum acceptable distance (4D Euclidean) between orientations
- // to be acceptable for calibration usage.
- void SetMinQuatDistance(float dist)
- {
- MinQuatDistance = dist;
- MinQuatDistanceSq = MinQuatDistance * MinQuatDistance;
- }
-
- // A result of the calibration, which is the center of a sphere that
- // roughly approximates the magnetometer data.
- Vector3f GetMagCenter() const { return MagCenter; }
- // Retrieves the full magnetometer calibration matrix
- Matrix4f GetMagCalibration() const;
- // Retrieves the range of each quaternion term during calibration
- Quatf GetCalibrationQuatSpread() const { return QuatSpread; }
- // Retrieves the range of each magnetometer term during calibration
- Vector3f GetCalibrationMagSpread() const { return MagSpread; }
-
-private:
- // Determine the unique sphere through 4 non-coplanar points
- Vector3f CalculateSphereCenter(const Vector3f& p1, const Vector3f& p2,
- const Vector3f& p3, const Vector3f& p4);
-
- // Distance from p4 to the nearest point on a plane through p1, p2, p3
- float PointToPlaneDistance(const Vector3f& p1, const Vector3f& p2,
- const Vector3f& p3, const Vector3f& p4);
-
- Vector3f MagCenter;
- unsigned Stat;
- float MinMagDistance;
- float MinQuatDistance;
- float MinMagDistanceSq;
- float MinQuatDistanceSq;
- // For gathering statistics during calibration
- Vector3f MinMagValues;
- Vector3f MaxMagValues;
- Vector3f MagSpread;
- Quatf MinQuatValues;
- Quatf MaxQuatValues;
- Quatf QuatSpread;
-
- unsigned SampleCount;
- Vector3f MagSamples[4];
- Quatf QuatSamples[4];
-
-};
-
-}}
-
-#endif
diff --git a/LibOVR/Src/Util/Util_Render_Stereo.cpp b/LibOVR/Src/Util/Util_Render_Stereo.cpp
index 2ff3ef2..87fed3c 100644
--- a/LibOVR/Src/Util/Util_Render_Stereo.cpp
+++ b/LibOVR/Src/Util/Util_Render_Stereo.cpp
@@ -3,18 +3,18 @@
Filename : Util_Render_Stereo.cpp
Content : Stereo rendering configuration implementation
Created : October 22, 2012
-Authors : Michael Antonov, Andrew Reisse
+Authors : Michael Antonov, Andrew Reisse, Tom Forsyth
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -25,122 +25,407 @@ limitations under the License.
*************************************************************************************/
#include "Util_Render_Stereo.h"
+#include "../OVR_SensorFusion.h"
namespace OVR { namespace Util { namespace Render {
//-----------------------------------------------------------------------------------
+// **** Useful debug functions.
-// DistortionFnInverse computes the inverse of the distortion function on an argument.
-float DistortionConfig::DistortionFnInverse(float r)
-{
- OVR_ASSERT((r <= 10.0f));
+char const* GetDebugNameEyeCupType ( EyeCupType eyeCupType )
+{
+ switch ( eyeCupType )
+ {
+ case EyeCup_DK1A: return "DK1 A"; break;
+ case EyeCup_DK1B: return "DK1 B"; break;
+ case EyeCup_DK1C: return "DK1 C"; break;
+ case EyeCup_DKHD2A: return "DKHD2 A"; break;
+ case EyeCup_OrangeA: return "Orange A"; break;
+ case EyeCup_RedA: return "Red A"; break;
+ case EyeCup_PinkA: return "Pink A"; break;
+ case EyeCup_BlueA: return "Blue A"; break;
+ case EyeCup_Delilah1A: return "Delilah 1 A"; break;
+ case EyeCup_Delilah2A: return "Delilah 2 A"; break;
+ case EyeCup_JamesA: return "James A"; break;
+ case EyeCup_SunMandalaA: return "Sun Mandala A"; break;
+ case EyeCup_DK2A: return "DK2 A"; break;
+ case EyeCup_LAST: return "LAST"; break;
+ default: OVR_ASSERT ( false ); return "Error"; break;
+ }
+}
- float s, d;
- float delta = r * 0.25f;
+char const* GetDebugNameHmdType ( HmdTypeEnum hmdType )
+{
+ switch ( hmdType )
+ {
+ case HmdType_None: return "None"; break;
+ case HmdType_DK1: return "DK1"; break;
+ case HmdType_DKProto: return "DK1 prototype"; break;
+ case HmdType_DKHDProto: return "DK HD prototype 1"; break;
+ case HmdType_DKHDProto566Mi: return "DK HD prototype 566 Mi"; break;
+ case HmdType_DKHD2Proto: return "DK HD prototype 585"; break;
+ case HmdType_CrystalCoveProto: return "Crystal Cove"; break;
+ case HmdType_DK2: return "DK2"; break;
+ case HmdType_Unknown: return "Unknown"; break;
+ case HmdType_LAST: return "LAST"; break;
+ default: OVR_ASSERT ( false ); return "Error"; break;
+ }
+}
- s = r * 0.5f;
- d = fabs(r - DistortionFn(s));
- for (int i = 0; i < 20; i++)
+//-----------------------------------------------------------------------------------
+// **** Internal pipeline functions.
+
+struct DistortionAndFov
+{
+ DistortionRenderDesc Distortion;
+ FovPort Fov;
+};
+
+static DistortionAndFov CalculateDistortionAndFovInternal ( StereoEye eyeType, HmdRenderInfo const &hmd,
+ LensConfig const *pLensOverride = NULL,
+ FovPort const *pTanHalfFovOverride = NULL,
+ float extraEyeRotationInRadians = OVR_DEFAULT_EXTRA_EYE_ROTATION )
+{
+ // pLensOverride can be NULL, which means no override.
+
+ DistortionRenderDesc localDistortion = CalculateDistortionRenderDesc ( eyeType, hmd, pLensOverride );
+ FovPort fov = CalculateFovFromHmdInfo ( eyeType, localDistortion, hmd, extraEyeRotationInRadians );
+ // Here the app or the user would optionally clamp this visible fov to a smaller number if
+ // they want more perf or resolution and are willing to give up FOV.
+ // They may also choose to clamp UDLR differently e.g. to get cinemascope-style views.
+ if ( pTanHalfFovOverride != NULL )
{
- float sUp = s + delta;
- float sDown = s - delta;
- float dUp = fabs(r - DistortionFn(sUp));
- float dDown = fabs(r - DistortionFn(sDown));
+ fov = *pTanHalfFovOverride;
+ }
- if (dUp < d)
+ // Here we could call ClampToPhysicalScreenFov(), but we do want people
+ // to be able to play with larger-than-screen views.
+ // The calling app can always do the clamping itself.
+ DistortionAndFov result;
+ result.Distortion = localDistortion;
+ result.Fov = fov;
+
+ return result;
+}
+
+
+static Recti CalculateViewportInternal ( StereoEye eyeType,
+ Sizei const actualRendertargetSurfaceSize,
+ Sizei const requestedRenderedPixelSize,
+ bool bRendertargetSharedByBothEyes,
+ bool bMonoRenderingMode = false )
+{
+ Recti renderedViewport;
+ if ( bMonoRenderingMode || !bRendertargetSharedByBothEyes || (eyeType == StereoEye_Center) )
+ {
+ // One eye per RT.
+ renderedViewport.x = 0;
+ renderedViewport.y = 0;
+ renderedViewport.w = Alg::Min ( actualRendertargetSurfaceSize.w, requestedRenderedPixelSize.w );
+ renderedViewport.h = Alg::Min ( actualRendertargetSurfaceSize.h, requestedRenderedPixelSize.h );
+ }
+ else
+ {
+ // Both eyes share the RT.
+ renderedViewport.x = 0;
+ renderedViewport.y = 0;
+ renderedViewport.w = Alg::Min ( actualRendertargetSurfaceSize.w/2, requestedRenderedPixelSize.w );
+ renderedViewport.h = Alg::Min ( actualRendertargetSurfaceSize.h, requestedRenderedPixelSize.h );
+ if ( eyeType == StereoEye_Right )
{
- s = sUp;
- d = dUp;
+ renderedViewport.x = (actualRendertargetSurfaceSize.w+1)/2; // Round up, not down.
}
- else if (dDown < d)
+ }
+ return renderedViewport;
+}
+
+static Recti CalculateViewportDensityInternal ( StereoEye eyeType,
+ DistortionRenderDesc const &distortion,
+ FovPort const &fov,
+ Sizei const &actualRendertargetSurfaceSize,
+ bool bRendertargetSharedByBothEyes,
+ float desiredPixelDensity = 1.0f,
+ bool bMonoRenderingMode = false )
+{
+ OVR_ASSERT ( actualRendertargetSurfaceSize.w > 0 );
+ OVR_ASSERT ( actualRendertargetSurfaceSize.h > 0 );
+
+ // What size RT do we need to get 1:1 mapping?
+ Sizei idealPixelSize = CalculateIdealPixelSize ( eyeType, distortion, fov, desiredPixelDensity );
+ // ...but we might not actually get that size.
+ return CalculateViewportInternal ( eyeType,
+ actualRendertargetSurfaceSize,
+ idealPixelSize,
+ bRendertargetSharedByBothEyes, bMonoRenderingMode );
+}
+
+static ViewportScaleAndOffset CalculateViewportScaleAndOffsetInternal (
+ ScaleAndOffset2D const &eyeToSourceNDC,
+ Recti const &renderedViewport,
+ Sizei const &actualRendertargetSurfaceSize )
+{
+ ViewportScaleAndOffset result;
+ result.RenderedViewport = renderedViewport;
+ result.EyeToSourceUV = CreateUVScaleAndOffsetfromNDCScaleandOffset(
+ eyeToSourceNDC, renderedViewport, actualRendertargetSurfaceSize );
+ return result;
+}
+
+
+static StereoEyeParams CalculateStereoEyeParamsInternal ( StereoEye eyeType, HmdRenderInfo const &hmd,
+ DistortionRenderDesc const &distortion,
+ FovPort const &fov,
+ Sizei const &actualRendertargetSurfaceSize,
+ Recti const &renderedViewport,
+ bool bRightHanded = true, float zNear = 0.01f, float zFar = 10000.0f,
+ bool bMonoRenderingMode = false,
+ float zoomFactor = 1.0f )
+{
+ // Generate the projection matrix for intermediate rendertarget.
+ // Z range can also be inserted later by the app (though not in this particular case)
+ float fovScale = 1.0f / zoomFactor;
+ FovPort zoomedFov = fov;
+ zoomedFov.LeftTan *= fovScale;
+ zoomedFov.RightTan *= fovScale;
+ zoomedFov.UpTan *= fovScale;
+ zoomedFov.DownTan *= fovScale;
+ Matrix4f projection = CreateProjection ( bRightHanded, zoomedFov, zNear, zFar );
+
+ // Find the mapping from TanAngle space to target NDC space.
+ // Note this does NOT take the zoom factor into account because
+ // this is the mapping of actual physical eye FOV (and our eyes do not zoom!)
+ // to screen space.
+ ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov ( fov );
+
+ // The size of the final FB, which is fixed and determined by the physical size of the device display.
+ Recti distortedViewport = GetFramebufferViewport ( eyeType, hmd );
+ Vector3f virtualCameraOffset = CalculateEyeVirtualCameraOffset(hmd, eyeType, bMonoRenderingMode);
+
+ StereoEyeParams result;
+ result.Eye = eyeType;
+ result.ViewAdjust = Matrix4f::Translation(virtualCameraOffset);
+ result.Distortion = distortion;
+ result.DistortionViewport = distortedViewport;
+ result.Fov = fov;
+ result.RenderedProjection = projection;
+ result.EyeToSourceNDC = eyeToSourceNDC;
+ ViewportScaleAndOffset vsao = CalculateViewportScaleAndOffsetInternal ( eyeToSourceNDC, renderedViewport, actualRendertargetSurfaceSize );
+ result.RenderedViewport = vsao.RenderedViewport;
+ result.EyeToSourceUV = vsao.EyeToSourceUV;
+
+ return result;
+}
+
+
+Vector3f CalculateEyeVirtualCameraOffset(HmdRenderInfo const &hmd,
+ StereoEye eyeType, bool bmonoRenderingMode)
+{
+ Vector3f virtualCameraOffset(0);
+
+ if (!bmonoRenderingMode)
+ {
+ float eyeCenterRelief = hmd.GetEyeCenter().ReliefInMeters;
+
+ if (eyeType == StereoEye_Left)
{
- s = sDown;
- d = dDown;
+ virtualCameraOffset.x = hmd.EyeLeft.NoseToPupilInMeters;
+ virtualCameraOffset.z = eyeCenterRelief - hmd.EyeLeft.ReliefInMeters;
}
- else
+ else if (eyeType == StereoEye_Right)
{
- delta *= 0.5f;
+ virtualCameraOffset.x = -hmd.EyeRight.NoseToPupilInMeters;
+ virtualCameraOffset.z = eyeCenterRelief - hmd.EyeRight.ReliefInMeters;
}
}
- return s;
+ return virtualCameraOffset;
}
//-----------------------------------------------------------------------------------
-// **** StereoConfig Implementation
+// **** Higher-level utility functions.
-StereoConfig::StereoConfig(StereoMode mode, const Viewport& vp)
- : Mode(mode),
- InterpupillaryDistance(0.064f), AspectMultiplier(1.0f),
- FullView(vp), DirtyFlag(true), IPDOverride(false),
- YFov(0), Aspect(vp.w / float(vp.h)), ProjectionCenterOffset(0),
- OrthoPixelOffset(0)
+Sizei CalculateRecommendedTextureSize ( HmdRenderInfo const &hmd,
+ bool bRendertargetSharedByBothEyes,
+ float pixelDensityInCenter /*= 1.0f*/ )
{
- // And default distortion for it.
- Distortion.SetCoefficients(1.0f, 0.22f, 0.24f);
- Distortion.Scale = 1.0f; // Will be computed later.
+ Sizei idealPixelSize[2];
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ StereoEye eyeType = ( eyeNum == 0 ) ? StereoEye_Left : StereoEye_Right;
- // Fit left of the image.
- DistortionFitX = -1.0f;
- DistortionFitY = 0.0f;
+ DistortionAndFov distortionAndFov = CalculateDistortionAndFovInternal ( eyeType, hmd, NULL, NULL, OVR_DEFAULT_EXTRA_EYE_ROTATION );
- // Initialize "fake" default HMD values for testing without HMD plugged in.
- // These default values match those returned by the HMD.
- HMD.HResolution = 1280;
- HMD.VResolution = 800;
- HMD.HScreenSize = 0.14976f;
- HMD.VScreenSize = HMD.HScreenSize / (1280.0f / 800.0f);
- HMD.InterpupillaryDistance = InterpupillaryDistance;
- HMD.LensSeparationDistance = 0.0635f;
- HMD.EyeToScreenDistance = 0.041f;
- HMD.DistortionK[0] = Distortion.K[0];
- HMD.DistortionK[1] = Distortion.K[1];
- HMD.DistortionK[2] = Distortion.K[2];
- HMD.DistortionK[3] = 0;
+ idealPixelSize[eyeNum] = CalculateIdealPixelSize ( eyeType,
+ distortionAndFov.Distortion,
+ distortionAndFov.Fov,
+ pixelDensityInCenter );
+ }
- Set2DAreaFov(DegreeToRad(85.0f));
+ Sizei result;
+ result.w = Alg::Max ( idealPixelSize[0].w, idealPixelSize[1].w );
+ result.h = Alg::Max ( idealPixelSize[0].h, idealPixelSize[1].h );
+ if ( bRendertargetSharedByBothEyes )
+ {
+ result.w *= 2;
+ }
+ return result;
}
-void StereoConfig::SetFullViewport(const Viewport& vp)
+StereoEyeParams CalculateStereoEyeParams ( HmdRenderInfo const &hmd,
+ StereoEye eyeType,
+ Sizei const &actualRendertargetSurfaceSize,
+ bool bRendertargetSharedByBothEyes,
+ bool bRightHanded /*= true*/,
+ float zNear /*= 0.01f*/, float zFar /*= 10000.0f*/,
+ Sizei const *pOverrideRenderedPixelSize /* = NULL*/,
+ FovPort const *pOverrideFovport /*= NULL*/,
+ float zoomFactor /*= 1.0f*/ )
{
- if (vp != FullView)
- {
- FullView = vp;
- DirtyFlag = true;
+ DistortionAndFov distortionAndFov = CalculateDistortionAndFovInternal ( eyeType, hmd, NULL, NULL, OVR_DEFAULT_EXTRA_EYE_ROTATION );
+ if ( pOverrideFovport != NULL )
+ {
+ distortionAndFov.Fov = *pOverrideFovport;
}
+
+ Recti viewport;
+ if ( pOverrideRenderedPixelSize != NULL )
+ {
+ viewport = CalculateViewportInternal ( eyeType, actualRendertargetSurfaceSize, *pOverrideRenderedPixelSize, bRendertargetSharedByBothEyes, false );
+ }
+ else
+ {
+ viewport = CalculateViewportDensityInternal ( eyeType,
+ distortionAndFov.Distortion,
+ distortionAndFov.Fov,
+ actualRendertargetSurfaceSize, bRendertargetSharedByBothEyes, 1.0f, false );
+ }
+
+ return CalculateStereoEyeParamsInternal (
+ eyeType, hmd,
+ distortionAndFov.Distortion,
+ distortionAndFov.Fov,
+ actualRendertargetSurfaceSize, viewport,
+ bRightHanded, zNear, zFar, false, zoomFactor );
}
-void StereoConfig::SetHMDInfo(const HMDInfo& hmd)
+
+FovPort CalculateRecommendedFov ( HmdRenderInfo const &hmd,
+ StereoEye eyeType,
+ bool bMakeFovSymmetrical /* = false */ )
{
- HMD = hmd;
- Distortion.K[0] = hmd.DistortionK[0];
- Distortion.K[1] = hmd.DistortionK[1];
- Distortion.K[2] = hmd.DistortionK[2];
- Distortion.K[3] = hmd.DistortionK[3];
+ DistortionAndFov distortionAndFov = CalculateDistortionAndFovInternal ( eyeType, hmd, NULL, NULL, OVR_DEFAULT_EXTRA_EYE_ROTATION );
+ FovPort fov = distortionAndFov.Fov;
+ if ( bMakeFovSymmetrical )
+ {
+ // Deal with engines that cannot support an off-center projection.
+ // Unfortunately this means they will be rendering pixels that the user can't actually see.
+ float fovTanH = Alg::Max ( fov.LeftTan, fov.RightTan );
+ float fovTanV = Alg::Max ( fov.UpTan, fov.DownTan );
+ fov.LeftTan = fovTanH;
+ fov.RightTan = fovTanH;
+ fov.UpTan = fovTanV;
+ fov.DownTan = fovTanV;
+ }
+ return fov;
+}
- Distortion.SetChromaticAberration(hmd.ChromaAbCorrection[0], hmd.ChromaAbCorrection[1],
- hmd.ChromaAbCorrection[2], hmd.ChromaAbCorrection[3]);
+ViewportScaleAndOffset ModifyRenderViewport ( StereoEyeParams const &params,
+ Sizei const &actualRendertargetSurfaceSize,
+ Recti const &renderViewport )
+{
+ return CalculateViewportScaleAndOffsetInternal ( params.EyeToSourceNDC, renderViewport, actualRendertargetSurfaceSize );
+}
- if (!IPDOverride)
- InterpupillaryDistance = HMD.InterpupillaryDistance;
+ViewportScaleAndOffset ModifyRenderSize ( StereoEyeParams const &params,
+ Sizei const &actualRendertargetSurfaceSize,
+ Sizei const &requestedRenderSize,
+ bool bRendertargetSharedByBothEyes /*= false*/ )
+{
+ Recti renderViewport = CalculateViewportInternal ( params.Eye, actualRendertargetSurfaceSize, requestedRenderSize, bRendertargetSharedByBothEyes, false );
+ return CalculateViewportScaleAndOffsetInternal ( params.EyeToSourceNDC, renderViewport, actualRendertargetSurfaceSize );
+}
- DirtyFlag = true;
+ViewportScaleAndOffset ModifyRenderDensity ( StereoEyeParams const &params,
+ Sizei const &actualRendertargetSurfaceSize,
+ float pixelDensity /*= 1.0f*/,
+ bool bRendertargetSharedByBothEyes /*= false*/ )
+{
+ Recti renderViewport = CalculateViewportDensityInternal ( params.Eye, params.Distortion, params.Fov, actualRendertargetSurfaceSize, bRendertargetSharedByBothEyes, pixelDensity, false );
+ return CalculateViewportScaleAndOffsetInternal ( params.EyeToSourceNDC, renderViewport, actualRendertargetSurfaceSize );
}
-void StereoConfig::SetDistortionFitPointVP(float x, float y)
+
+//-----------------------------------------------------------------------------------
+// **** StereoConfig Implementation
+
+StereoConfig::StereoConfig(StereoMode mode)
+ : Mode(mode),
+ DirtyFlag(true)
{
- DistortionFitX = x;
- DistortionFitY = y;
- DirtyFlag = true;
+ // Initialize "fake" default HMD values for testing without HMD plugged in.
+ // These default values match those returned by DK1
+ // (at least they did at time of writing - certainly good enough for debugging)
+ Hmd.HmdType = HmdType_None;
+ Hmd.ResolutionInPixels = Sizei(1280, 800);
+ Hmd.ScreenSizeInMeters = Sizef(0.1498f, 0.0936f);
+ Hmd.ScreenGapSizeInMeters = 0.0f;
+ Hmd.CenterFromTopInMeters = 0.0468f;
+ Hmd.LensSeparationInMeters = 0.0635f;
+ Hmd.LensDiameterInMeters = 0.035f;
+ Hmd.LensSurfaceToMidplateInMeters = 0.025f;
+ Hmd.EyeCups = EyeCup_DK1A;
+ Hmd.Shutter.Type = HmdShutter_RollingTopToBottom;
+ Hmd.Shutter.VsyncToNextVsync = ( 1.0f / 60.0f );
+ Hmd.Shutter.VsyncToFirstScanline = 0.000052f;
+ Hmd.Shutter.FirstScanlineToLastScanline = 0.016580f;
+ Hmd.Shutter.PixelSettleTime = 0.015f;
+ Hmd.Shutter.PixelPersistence = ( 1.0f / 60.0f );
+ Hmd.EyeLeft.Distortion.SetToIdentity();
+ Hmd.EyeLeft.Distortion.MetersPerTanAngleAtCenter = 0.043875f;
+ Hmd.EyeLeft.Distortion.Eqn = Distortion_RecipPoly4;
+ Hmd.EyeLeft.Distortion.K[0] = 1.0f;
+ Hmd.EyeLeft.Distortion.K[1] = -0.3999f;
+ Hmd.EyeLeft.Distortion.K[2] = 0.2408f;
+ Hmd.EyeLeft.Distortion.K[3] = -0.4589f;
+ Hmd.EyeLeft.Distortion.MaxR = 1.0f;
+ Hmd.EyeLeft.Distortion.ChromaticAberration[0] = 0.006f;
+ Hmd.EyeLeft.Distortion.ChromaticAberration[1] = 0.0f;
+ Hmd.EyeLeft.Distortion.ChromaticAberration[2] = -0.014f;
+ Hmd.EyeLeft.Distortion.ChromaticAberration[3] = 0.0f;
+ Hmd.EyeLeft.NoseToPupilInMeters = 0.62f;
+ Hmd.EyeLeft.ReliefInMeters = 0.013f;
+ Hmd.EyeRight = Hmd.EyeLeft;
+
+ SetViewportMode = SVPM_Density;
+ SetViewportPixelsPerDisplayPixel = 1.0f;
+ // Not used in this mode, but init them anyway.
+ SetViewportSize[0] = Sizei(0,0);
+ SetViewportSize[1] = Sizei(0,0);
+ SetViewport[0] = Recti(0,0,0,0);
+ SetViewport[1] = Recti(0,0,0,0);
+
+ OverrideLens = false;
+ OverrideTanHalfFov = false;
+ OverrideZeroIpd = false;
+ ExtraEyeRotationInRadians = OVR_DEFAULT_EXTRA_EYE_ROTATION;
+ IsRendertargetSharedByBothEyes = true;
+ RightHandedProjection = true;
+
+ // This should cause an assert if the app does not call SetRendertargetSize()
+ RendertargetSize = Sizei ( 0, 0 );
+
+ ZNear = 0.01f;
+ ZFar = 10000.0f;
+
+ Set2DAreaFov(DegreeToRad(85.0f));
}
-void StereoConfig::SetDistortionFitPointPixels(float x, float y)
+void StereoConfig::SetHmdRenderInfo(const HmdRenderInfo& hmd)
{
- DistortionFitX = (4 * x / float(FullView.w)) - 1.0f;
- DistortionFitY = (2 * y / float(FullView.h)) - 1.0f;
+ Hmd = hmd;
DirtyFlag = true;
}
@@ -150,174 +435,830 @@ void StereoConfig::Set2DAreaFov(float fovRadians)
DirtyFlag = true;
}
-
-const StereoEyeParams& StereoConfig::GetEyeRenderParams(StereoEye eye)
+const StereoEyeParamsWithOrtho& StereoConfig::GetEyeRenderParams(StereoEye eye)
{
+ if ( DirtyFlag )
+ {
+ UpdateComputedState();
+ }
+
static const UByte eyeParamIndices[3] = { 0, 0, 1 };
- updateIfDirty();
OVR_ASSERT(eye < sizeof(eyeParamIndices));
return EyeRenderParams[eyeParamIndices[eye]];
}
-
-void StereoConfig::updateComputedState()
-{
- // Need to compute all of the following:
- // - Aspect Ratio
- // - FOV
- // - Projection offsets for 3D
- // - Distortion XCenterOffset
- // - Update 2D
- // - Initialize EyeRenderParams
-
- // Compute aspect ratio. Stereo mode cuts width in half.
- Aspect = float(FullView.w) / float(FullView.h);
- Aspect *= (Mode == Stereo_None) ? 1.0f : 0.5f;
- Aspect *= AspectMultiplier;
-
- updateDistortionOffsetAndScale();
-
- // Compute Vertical FOV based on distance, distortion, etc.
- // Distance from vertical center to render vertical edge perceived through the lens.
- // This will be larger then normal screen size due to magnification & distortion.
- //
- // This percievedHalfRTDistance equation should hold as long as the render target
- // and display have the same aspect ratios. What we'd like to know is where the edge
- // of the render target will on the perceived screen surface. With NO LENS,
- // the answer would be:
- //
- // halfRTDistance = (VScreenSize / 2) * aspect *
- // DistortionFn_Inverse( DistortionScale / aspect )
- //
- // To model the optical lens we eliminates DistortionFn_Inverse. Aspect ratios
- // cancel out, so we get:
- //
- // halfRTDistance = (VScreenSize / 2) * DistortionScale
- //
- if (Mode == Stereo_None)
- {
- YFov = DegreeToRad(80.0f);
+void StereoConfig::SetLensOverride ( LensConfig const *pLensOverrideLeft /*= NULL*/,
+ LensConfig const *pLensOverrideRight /*= NULL*/ )
+{
+ if ( pLensOverrideLeft == NULL )
+ {
+ OverrideLens = false;
}
else
{
- float percievedHalfRTDistance = (HMD.VScreenSize / 2) * Distortion.Scale;
- YFov = 2.0f * atan(percievedHalfRTDistance/HMD.EyeToScreenDistance);
+ OverrideLens = true;
+ LensOverrideLeft = *pLensOverrideLeft;
+ LensOverrideRight = *pLensOverrideLeft;
+ if ( pLensOverrideRight != NULL )
+ {
+ LensOverrideRight = *pLensOverrideRight;
+ }
}
-
- updateProjectionOffset();
- update2D();
- updateEyeParams();
-
- DirtyFlag = false;
+ DirtyFlag = true;
}
-void StereoConfig::updateDistortionOffsetAndScale()
+void StereoConfig::SetRendertargetSize (Size<int> const rendertargetSize,
+ bool rendertargetIsSharedByBothEyes )
{
- // Distortion center shift is stored separately, since it isn't affected
- // by the eye distance.
- float lensOffset = HMD.LensSeparationDistance * 0.5f;
- float lensShift = HMD.HScreenSize * 0.25f - lensOffset;
- float lensViewportShift = 4.0f * lensShift / HMD.HScreenSize;
- Distortion.XCenterOffset= lensViewportShift;
+ RendertargetSize = rendertargetSize;
+ IsRendertargetSharedByBothEyes = rendertargetIsSharedByBothEyes;
+ DirtyFlag = true;
+}
- // Compute distortion scale from DistortionFitX & DistortionFitY.
- // Fit value of 0.0 means "no fit".
- if ((fabs(DistortionFitX) < 0.0001f) && (fabs(DistortionFitY) < 0.0001f))
+void StereoConfig::SetFov ( FovPort const *pfovLeft /*= NULL*/,
+ FovPort const *pfovRight /*= NULL*/ )
+{
+ DirtyFlag = true;
+ if ( pfovLeft == NULL )
{
- Distortion.Scale = 1.0f;
+ OverrideTanHalfFov = false;
}
else
{
- // Convert fit value to distortion-centered coordinates before fit radius
- // calculation.
- float stereoAspect = 0.5f * float(FullView.w) / float(FullView.h);
- float dx = DistortionFitX - Distortion.XCenterOffset;
- float dy = DistortionFitY / stereoAspect;
- float fitRadius = sqrt(dx * dx + dy * dy);
- Distortion.Scale = Distortion.DistortionFn(fitRadius)/fitRadius;
- }
-}
-
-void StereoConfig::updateProjectionOffset()
-{
- // Post-projection viewport coordinates range from (-1.0, 1.0), with the
- // center of the left viewport falling at (1/4) of horizontal screen size.
- // We need to shift this projection center to match with the lens center;
- // note that we don't use the IPD here due to collimated light property of the lens.
- // We compute this shift in physical units (meters) to
- // correct for different screen sizes and then rescale to viewport coordinates.
- float viewCenter = HMD.HScreenSize * 0.25f;
- float eyeProjectionShift = viewCenter - HMD.LensSeparationDistance*0.5f;
- ProjectionCenterOffset = 4.0f * eyeProjectionShift / HMD.HScreenSize;
-}
-
-void StereoConfig::update2D()
-{
- // Orthographic projection fakes a screen at a distance of 0.8m from the
- // eye, where hmd screen projection surface is at 0.05m distance.
- // This introduces an extra off-center pixel projection shift based on eye distance.
- // This offCenterShift is the pixel offset of the other camera's center
- // in your reference camera based on surface distance.
- float metersToPixels = (HMD.HResolution / HMD.HScreenSize);
- float lensDistanceScreenPixels= metersToPixels * HMD.LensSeparationDistance;
- float eyeDistanceScreenPixels = metersToPixels * InterpupillaryDistance;
- float offCenterShiftPixels = (HMD.EyeToScreenDistance / 0.8f) * eyeDistanceScreenPixels;
- float leftPixelCenter = (HMD.HResolution / 2) - lensDistanceScreenPixels * 0.5f;
- float rightPixelCenter = lensDistanceScreenPixels * 0.5f;
- float pixelDifference = leftPixelCenter - rightPixelCenter;
-
- // This computes the number of pixels that fit within specified 2D FOV (assuming
- // distortion scaling will be done).
- float percievedHalfScreenDistance = tan(Area2DFov * 0.5f) * HMD.EyeToScreenDistance;
- float vfovSize = 2.0f * percievedHalfScreenDistance / Distortion.Scale;
- FovPixels = HMD.VResolution * vfovSize / HMD.VScreenSize;
-
- // Create orthographic matrix.
- Matrix4f& m = OrthoCenter;
- m.SetIdentity();
- m.M[0][0] = FovPixels / (FullView.w * 0.5f);
- m.M[1][1] = -FovPixels / FullView.h;
- m.M[0][3] = 0;
- m.M[1][3] = 0;
- m.M[2][2] = 0;
+ OverrideTanHalfFov = true;
+ FovOverrideLeft = *pfovLeft;
+ FovOverrideRight = *pfovLeft;
+ if ( pfovRight != NULL )
+ {
+ FovOverrideRight = *pfovRight;
+ }
+ }
+}
+
+
+void StereoConfig::SetZeroVirtualIpdOverride ( bool enableOverride )
+{
+ DirtyFlag = true;
+ OverrideZeroIpd = enableOverride;
+}
+
+
+void StereoConfig::SetZClipPlanesAndHandedness ( float zNear /*= 0.01f*/, float zFar /*= 10000.0f*/, bool rightHandedProjection /*= true*/ )
+{
+ DirtyFlag = true;
+ ZNear = zNear;
+ ZFar = zFar;
+ RightHandedProjection = rightHandedProjection;
+}
+
+void StereoConfig::SetExtraEyeRotation ( float extraEyeRotationInRadians )
+{
+ DirtyFlag = true;
+ ExtraEyeRotationInRadians = extraEyeRotationInRadians;
+}
- float orthoPixelOffset = (pixelDifference + offCenterShiftPixels/Distortion.Scale) * 0.5f;
- OrthoPixelOffset = orthoPixelOffset * 2.0f / FovPixels;
+Sizei StereoConfig::CalculateRecommendedTextureSize ( bool rendertargetSharedByBothEyes,
+ float pixelDensityInCenter /*= 1.0f*/ )
+{
+ return Render::CalculateRecommendedTextureSize ( Hmd, rendertargetSharedByBothEyes, pixelDensityInCenter );
}
-void StereoConfig::updateEyeParams()
+
+
+void StereoConfig::UpdateComputedState()
{
- // Projection matrix for the center eye, which the left/right matrices are based on.
- Matrix4f projCenter = Matrix4f::PerspectiveRH(YFov, Aspect, 0.01f, 2000.0f);
-
- switch(Mode)
+ int numEyes = 2;
+ StereoEye eyeTypes[2];
+
+ switch ( Mode )
{
case Stereo_None:
- {
- EyeRenderParams[0].Init(StereoEye_Center, FullView, 0, projCenter, OrthoCenter);
- }
+ numEyes = 1;
+ eyeTypes[0] = StereoEye_Center;
break;
case Stereo_LeftRight_Multipass:
+ numEyes = 2;
+ eyeTypes[0] = StereoEye_Left;
+ eyeTypes[1] = StereoEye_Right;
+ break;
+
+ default:
+ OVR_ASSERT( false ); break;
+ }
+
+ // If either of these fire, you've probably forgotten to call SetRendertargetSize()
+ OVR_ASSERT ( RendertargetSize.w > 0 );
+ OVR_ASSERT ( RendertargetSize.h > 0 );
+
+ for ( int eyeNum = 0; eyeNum < numEyes; eyeNum++ )
+ {
+ StereoEye eyeType = eyeTypes[eyeNum];
+ LensConfig *pLensOverride = NULL;
+ if ( OverrideLens )
{
- Matrix4f projLeft = Matrix4f::Translation(ProjectionCenterOffset, 0, 0) * projCenter,
- projRight = Matrix4f::Translation(-ProjectionCenterOffset, 0, 0) * projCenter;
-
- EyeRenderParams[0].Init(StereoEye_Left,
- Viewport(FullView.x, FullView.y, FullView.w/2, FullView.h),
- +InterpupillaryDistance * 0.5f, // World view shift.
- projLeft, OrthoCenter * Matrix4f::Translation(OrthoPixelOffset, 0, 0),
- &Distortion);
- EyeRenderParams[1].Init(StereoEye_Right,
- Viewport(FullView.x + FullView.w/2, FullView.y, FullView.w/2, FullView.h),
- -InterpupillaryDistance * 0.5f,
- projRight, OrthoCenter * Matrix4f::Translation(-OrthoPixelOffset, 0, 0),
- &Distortion);
+ if ( eyeType == StereoEye_Right )
+ {
+ pLensOverride = &LensOverrideRight;
+ }
+ else
+ {
+ pLensOverride = &LensOverrideLeft;
+ }
}
- break;
+
+ FovPort *pTanHalfFovOverride = NULL;
+ if ( OverrideTanHalfFov )
+ {
+ if ( eyeType == StereoEye_Right )
+ {
+ pTanHalfFovOverride = &FovOverrideRight;
+ }
+ else
+ {
+ pTanHalfFovOverride = &FovOverrideLeft;
+ }
+ }
+
+ DistortionAndFov distortionAndFov =
+ CalculateDistortionAndFovInternal ( eyeType, Hmd,
+ pLensOverride, pTanHalfFovOverride,
+ ExtraEyeRotationInRadians );
+
+ EyeRenderParams[eyeNum].StereoEye.Distortion = distortionAndFov.Distortion;
+ EyeRenderParams[eyeNum].StereoEye.Fov = distortionAndFov.Fov;
}
+ if ( OverrideZeroIpd )
+ {
+ // Take the union of the calculated eye FOVs.
+ FovPort fov;
+ fov.UpTan = Alg::Max ( EyeRenderParams[0].StereoEye.Fov.UpTan , EyeRenderParams[1].StereoEye.Fov.UpTan );
+ fov.DownTan = Alg::Max ( EyeRenderParams[0].StereoEye.Fov.DownTan , EyeRenderParams[1].StereoEye.Fov.DownTan );
+ fov.LeftTan = Alg::Max ( EyeRenderParams[0].StereoEye.Fov.LeftTan , EyeRenderParams[1].StereoEye.Fov.LeftTan );
+ fov.RightTan = Alg::Max ( EyeRenderParams[0].StereoEye.Fov.RightTan, EyeRenderParams[1].StereoEye.Fov.RightTan );
+ EyeRenderParams[0].StereoEye.Fov = fov;
+ EyeRenderParams[1].StereoEye.Fov = fov;
+ }
+
+ for ( int eyeNum = 0; eyeNum < numEyes; eyeNum++ )
+ {
+ StereoEye eyeType = eyeTypes[eyeNum];
+
+ DistortionRenderDesc localDistortion = EyeRenderParams[eyeNum].StereoEye.Distortion;
+ FovPort fov = EyeRenderParams[eyeNum].StereoEye.Fov;
+
+ // Use a placeholder - will be overridden later.
+ Recti tempViewport = Recti ( 0, 0, 1, 1 );
+
+ EyeRenderParams[eyeNum].StereoEye = CalculateStereoEyeParamsInternal (
+ eyeType, Hmd, localDistortion, fov,
+ RendertargetSize, tempViewport,
+ RightHandedProjection, ZNear, ZFar,
+ OverrideZeroIpd );
+
+ // We want to create a virtual 2D surface we can draw debug text messages to.
+ // We'd like it to be a fixed distance (OrthoDistance) away,
+ // and to cover a specific FOV (Area2DFov). We need to find the projection matrix for this,
+ // and also to know how large it is in pixels to achieve a 1:1 mapping at the center of the screen.
+ float orthoDistance = 0.8f;
+ float orthoHalfFov = tanf ( Area2DFov * 0.5f );
+ Vector2f unityOrthoPixelSize = localDistortion.PixelsPerTanAngleAtCenter * ( orthoHalfFov * 2.0f );
+ float localInterpupillaryDistance = Hmd.EyeLeft.NoseToPupilInMeters + Hmd.EyeRight.NoseToPupilInMeters;
+ if ( OverrideZeroIpd )
+ {
+ localInterpupillaryDistance = 0.0f;
+ }
+ Matrix4f ortho = CreateOrthoSubProjection ( true, eyeType,
+ orthoHalfFov, orthoHalfFov,
+ unityOrthoPixelSize.x, unityOrthoPixelSize.y,
+ orthoDistance, localInterpupillaryDistance,
+ EyeRenderParams[eyeNum].StereoEye.RenderedProjection );
+ EyeRenderParams[eyeNum].OrthoProjection = ortho;
+ }
+
+ // ...and now set up the viewport, scale & offset the way the app wanted.
+ setupViewportScaleAndOffsets();
+
+ if ( OverrideZeroIpd )
+ {
+ // Monocular rendering has some fragile parts... don't break any by accident.
+ OVR_ASSERT ( EyeRenderParams[0].StereoEye.Fov.UpTan == EyeRenderParams[1].StereoEye.Fov.UpTan );
+ OVR_ASSERT ( EyeRenderParams[0].StereoEye.Fov.DownTan == EyeRenderParams[1].StereoEye.Fov.DownTan );
+ OVR_ASSERT ( EyeRenderParams[0].StereoEye.Fov.LeftTan == EyeRenderParams[1].StereoEye.Fov.LeftTan );
+ OVR_ASSERT ( EyeRenderParams[0].StereoEye.Fov.RightTan == EyeRenderParams[1].StereoEye.Fov.RightTan );
+ OVR_ASSERT ( EyeRenderParams[0].StereoEye.RenderedProjection.M[0][0] == EyeRenderParams[1].StereoEye.RenderedProjection.M[0][0] );
+ OVR_ASSERT ( EyeRenderParams[0].StereoEye.RenderedProjection.M[1][1] == EyeRenderParams[1].StereoEye.RenderedProjection.M[1][1] );
+ OVR_ASSERT ( EyeRenderParams[0].StereoEye.RenderedProjection.M[0][2] == EyeRenderParams[1].StereoEye.RenderedProjection.M[0][2] );
+ OVR_ASSERT ( EyeRenderParams[0].StereoEye.RenderedProjection.M[1][2] == EyeRenderParams[1].StereoEye.RenderedProjection.M[1][2] );
+ OVR_ASSERT ( EyeRenderParams[0].StereoEye.RenderedViewport == EyeRenderParams[1].StereoEye.RenderedViewport );
+ OVR_ASSERT ( EyeRenderParams[0].StereoEye.EyeToSourceUV.Offset == EyeRenderParams[1].StereoEye.EyeToSourceUV.Offset );
+ OVR_ASSERT ( EyeRenderParams[0].StereoEye.EyeToSourceUV.Scale == EyeRenderParams[1].StereoEye.EyeToSourceUV.Scale );
+ OVR_ASSERT ( EyeRenderParams[0].StereoEye.EyeToSourceNDC.Offset == EyeRenderParams[1].StereoEye.EyeToSourceNDC.Offset );
+ OVR_ASSERT ( EyeRenderParams[0].StereoEye.EyeToSourceNDC.Scale == EyeRenderParams[1].StereoEye.EyeToSourceNDC.Scale );
+ OVR_ASSERT ( EyeRenderParams[0].OrthoProjection.M[0][0] == EyeRenderParams[1].OrthoProjection.M[0][0] );
+ OVR_ASSERT ( EyeRenderParams[0].OrthoProjection.M[1][1] == EyeRenderParams[1].OrthoProjection.M[1][1] );
+ OVR_ASSERT ( EyeRenderParams[0].OrthoProjection.M[0][2] == EyeRenderParams[1].OrthoProjection.M[0][2] );
+ OVR_ASSERT ( EyeRenderParams[0].OrthoProjection.M[1][2] == EyeRenderParams[1].OrthoProjection.M[1][2] );
+ }
+
+ DirtyFlag = false;
+}
+
+
+
+ViewportScaleAndOffsetBothEyes StereoConfig::setupViewportScaleAndOffsets()
+{
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ StereoEye eyeType = ( eyeNum == 0 ) ? StereoEye_Left : StereoEye_Right;
+
+ DistortionRenderDesc localDistortion = EyeRenderParams[eyeNum].StereoEye.Distortion;
+ FovPort fov = EyeRenderParams[eyeNum].StereoEye.Fov;
+
+ Recti renderedViewport;
+ switch ( SetViewportMode )
+ {
+ case SVPM_Density:
+ renderedViewport = CalculateViewportDensityInternal (
+ eyeType, localDistortion, fov,
+ RendertargetSize, IsRendertargetSharedByBothEyes,
+ SetViewportPixelsPerDisplayPixel, OverrideZeroIpd );
+ break;
+ case SVPM_Size:
+ if ( ( eyeType == StereoEye_Right ) && !OverrideZeroIpd )
+ {
+ renderedViewport = CalculateViewportInternal (
+ eyeType, RendertargetSize,
+ SetViewportSize[1],
+ IsRendertargetSharedByBothEyes, OverrideZeroIpd );
+ }
+ else
+ {
+ renderedViewport = CalculateViewportInternal (
+ eyeType, RendertargetSize,
+ SetViewportSize[0],
+ IsRendertargetSharedByBothEyes, OverrideZeroIpd );
+ }
+ break;
+ case SVPM_Viewport:
+ if ( ( eyeType == StereoEye_Right ) && !OverrideZeroIpd )
+ {
+ renderedViewport = SetViewport[1];
+ }
+ else
+ {
+ renderedViewport = SetViewport[0];
+ }
+ break;
+ default: OVR_ASSERT ( false ); break;
+ }
+
+ ViewportScaleAndOffset vpsao = CalculateViewportScaleAndOffsetInternal (
+ EyeRenderParams[eyeNum].StereoEye.EyeToSourceNDC,
+ renderedViewport,
+ RendertargetSize );
+ EyeRenderParams[eyeNum].StereoEye.RenderedViewport = vpsao.RenderedViewport;
+ EyeRenderParams[eyeNum].StereoEye.EyeToSourceUV = vpsao.EyeToSourceUV;
+ }
+
+ ViewportScaleAndOffsetBothEyes result;
+ result.Left.EyeToSourceUV = EyeRenderParams[0].StereoEye.EyeToSourceUV;
+ result.Left.RenderedViewport = EyeRenderParams[0].StereoEye.RenderedViewport;
+ result.Right.EyeToSourceUV = EyeRenderParams[1].StereoEye.EyeToSourceUV;
+ result.Right.RenderedViewport = EyeRenderParams[1].StereoEye.RenderedViewport;
+ return result;
+}
+
+// Specify a pixel density - how many rendered pixels per pixel in the physical display.
+ViewportScaleAndOffsetBothEyes StereoConfig::SetRenderDensity ( float pixelsPerDisplayPixel )
+{
+ SetViewportMode = SVPM_Density;
+ SetViewportPixelsPerDisplayPixel = pixelsPerDisplayPixel;
+ return setupViewportScaleAndOffsets();
+}
+
+// Supply the size directly. Will be clamped to the physical rendertarget size.
+ViewportScaleAndOffsetBothEyes StereoConfig::SetRenderSize ( Sizei const &renderSizeLeft, Sizei const &renderSizeRight )
+{
+ SetViewportMode = SVPM_Size;
+ SetViewportSize[0] = renderSizeLeft;
+ SetViewportSize[1] = renderSizeRight;
+ return setupViewportScaleAndOffsets();
+}
+
+// Supply the viewport directly. This is not clamped to the physical rendertarget - careful now!
+ViewportScaleAndOffsetBothEyes StereoConfig::SetRenderViewport ( Recti const &renderViewportLeft, Recti const &renderViewportRight )
+{
+ SetViewportMode = SVPM_Viewport;
+ SetViewport[0] = renderViewportLeft;
+ SetViewport[1] = renderViewportRight;
+ return setupViewportScaleAndOffsets();
+}
+
+Matrix4f StereoConfig::GetProjectionWithZoom ( StereoEye eye, float fovZoom ) const
+{
+ int eyeNum = ( eye == StereoEye_Right ) ? 1 : 0;
+ float fovScale = 1.0f / fovZoom;
+ FovPort fovPort = EyeRenderParams[eyeNum].StereoEye.Fov;
+ fovPort.LeftTan *= fovScale;
+ fovPort.RightTan *= fovScale;
+ fovPort.UpTan *= fovScale;
+ fovPort.DownTan *= fovScale;
+ return CreateProjection ( RightHandedProjection, fovPort, ZNear, ZFar );
+}
+
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** Distortion Mesh Rendering
+
+
+// Pow2 for the Morton order to work!
+// 4 is too low - it is easy to see the "wobbles" in the HMD.
+// 5 is realllly close but you can see pixel differences with even/odd frame checking.
+// 6 is indistinguishable on a monitor on even/odd frames.
+static const int DMA_GridSizeLog2 = 6;
+static const int DMA_GridSize = 1<<DMA_GridSizeLog2;
+static const int DMA_NumVertsPerEye = (DMA_GridSize+1)*(DMA_GridSize+1);
+static const int DMA_NumTrisPerEye = (DMA_GridSize)*(DMA_GridSize)*2;
+
+
+
+void DistortionMeshDestroy ( DistortionMeshVertexData *pVertices, UInt16 *pTriangleMeshIndices )
+{
+ OVR_FREE ( pVertices );
+ OVR_FREE ( pTriangleMeshIndices );
+}
+
+void DistortionMeshCreate ( DistortionMeshVertexData **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.
+ DistortionMeshCreate(ppVertices, ppTriangleListIndices, &vertexCount, &triangleCount,
+ rightEye, hmdRenderInfo, stereoParams.Distortion, stereoParams.EyeToSourceNDC);
+
+ *pNumVertices = vertexCount;
+ *pNumTriangles = triangleCount;
+}
+
+
+// Generate distortion mesh for a eye.
+void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices,
+ int *pNumVertices, int *pNumTriangles,
+ bool rightEye,
+ const HmdRenderInfo &hmdRenderInfo,
+ const DistortionRenderDesc &distortion, const ScaleAndOffset2D &eyeToSourceNDC )
+{
+ *pNumVertices = DMA_NumVertsPerEye;
+ *pNumTriangles = DMA_NumTrisPerEye;
+
+ *ppVertices = (DistortionMeshVertexData*)
+ OVR_ALLOC( sizeof(DistortionMeshVertexData) * (*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 = NULL;
+ *pNumVertices = NULL;
+ return;
+ }
+
+ // When does the fade-to-black edge start? Chosen heuristically.
+ const float fadeOutBorderFraction = 0.075f;
+
+
+ // 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.
+ DistortionMeshVertexData* pcurVert = *ppVertices;
+
+ for ( int y = 0; y <= DMA_GridSize; y++ )
+ {
+ for ( int x = 0; x <= DMA_GridSize; x++ )
+ {
+
+ Vector2f sourceCoordNDC;
+ // NDC texture coords [-1,+1]
+ sourceCoordNDC.x = 2.0f * ( (float)x / (float)DMA_GridSize ) - 1.0f;
+ sourceCoordNDC.y = 2.0f * ( (float)y / (float)DMA_GridSize ) - 1.0f;
+ Vector2f tanEyeAngle = TransformRendertargetNDCToTanFovSpace ( eyeToSourceNDC, sourceCoordNDC );
+
+ // This is the function that does the really heavy lifting.
+ Vector2f screenNDC = TransformTanFovSpaceToScreenNDC ( distortion, tanEyeAngle, false );
+
+ // We then need RGB UVs. Since chromatic aberration is generated from screen coords, not
+ // directly from texture NDCs, we can't just use tanEyeAngle, we need to go the long way round.
+ Vector2f tanEyeAnglesR, tanEyeAnglesG, tanEyeAnglesB;
+ TransformScreenNDCToTanFovSpaceChroma ( &tanEyeAnglesR, &tanEyeAnglesG, &tanEyeAnglesB,
+ distortion, screenNDC );
+
+ pcurVert->TanEyeAnglesR = tanEyeAnglesR;
+ pcurVert->TanEyeAnglesG = tanEyeAnglesG;
+ pcurVert->TanEyeAnglesB = tanEyeAnglesB;
+
+
+ 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 = screenNDC.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 - screenNDC.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 = screenNDC.y * 0.5f + 0.5f;
+ break;
+ default: OVR_ASSERT ( false ); break;
+ }
+
+ // Fade out at texture edges.
+ float edgeFadeIn = ( 1.0f / fadeOutBorderFraction ) *
+ ( 1.0f - Alg::Max ( Alg::Abs ( sourceCoordNDC.x ), Alg::Abs ( sourceCoordNDC.y ) ) );
+ // Also fade out at screen edges.
+ float edgeFadeInScreen = ( 2.0f / fadeOutBorderFraction ) *
+ ( 1.0f - Alg::Max ( Alg::Abs ( screenNDC.x ), Alg::Abs ( screenNDC.y ) ) );
+ edgeFadeIn = Alg::Min ( edgeFadeInScreen, edgeFadeIn );
+
+ // Don't let verts overlap to the other eye.
+ screenNDC.x = Alg::Max ( -1.0f, Alg::Min ( screenNDC.x, 1.0f ) );
+ screenNDC.y = Alg::Max ( -1.0f, Alg::Min ( screenNDC.y, 1.0f ) );
+
+ pcurVert->Shade = Alg::Max ( 0.0f, Alg::Min ( edgeFadeIn, 1.0f ) );
+ pcurVert->ScreenPosNDC.x = 0.5f * screenNDC.x - 0.5f + xOffset;
+ pcurVert->ScreenPosNDC.y = -screenNDC.y;
+
+ pcurVert++;
+ }
+ }
+
+
+ // Populate index buffer info
+ UInt16 *pcurIndex = *ppTriangleListIndices;
+
+ for ( int triNum = 0; triNum < DMA_GridSize * DMA_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 ( DMA_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 * (DMA_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 < DMA_GridSize/2 ) != ( y < DMA_GridSize/2 ) ) // != is logical XOR
+ {
+ *pcurIndex++ = (UInt16)FirstVertex;
+ *pcurIndex++ = (UInt16)FirstVertex+1;
+ *pcurIndex++ = (UInt16)FirstVertex+(DMA_GridSize+1)+1;
+
+ *pcurIndex++ = (UInt16)FirstVertex+(DMA_GridSize+1)+1;
+ *pcurIndex++ = (UInt16)FirstVertex+(DMA_GridSize+1);
+ *pcurIndex++ = (UInt16)FirstVertex;
+ }
+ else
+ {
+ *pcurIndex++ = (UInt16)FirstVertex;
+ *pcurIndex++ = (UInt16)FirstVertex+1;
+ *pcurIndex++ = (UInt16)FirstVertex+(DMA_GridSize+1);
+
+ *pcurIndex++ = (UInt16)FirstVertex+1;
+ *pcurIndex++ = (UInt16)FirstVertex+(DMA_GridSize+1)+1;
+ *pcurIndex++ = (UInt16)FirstVertex+(DMA_GridSize+1);
+ }
+ }
+}
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** Prediction and timewarp.
+//
+
+// Calculates the values from the HMD info.
+PredictionValues PredictionGetDeviceValues ( const HmdRenderInfo &hmdRenderInfo,
+ bool withTimewarp /*= true*/,
+ bool withVsync /*= true*/ )
+{
+ PredictionValues result;
+
+ result.WithTimewarp = withTimewarp;
+ result.WithVsync = withVsync;
+
+ // For unclear reasons, most graphics systems add an extra frame of latency
+ // somewhere along the way. In time we'll debug this and figure it out, but
+ // for now this gets prediction a little bit better.
+ const float extraFramesOfBufferingKludge = 1.0f;
+
+ if ( withVsync )
+ {
+ // These are the times from the Present+Flush to when the middle of the scene is "averagely visible" (without timewarp)
+ // So if you had no timewarp, this, plus the time until the next vsync, is how much to predict by.
+ result.PresentFlushToRenderedScene = extraFramesOfBufferingKludge * hmdRenderInfo.Shutter.FirstScanlineToLastScanline;
+ // Predict to the middle of the screen being scanned out.
+ result.PresentFlushToRenderedScene += hmdRenderInfo.Shutter.VsyncToFirstScanline + 0.5f * hmdRenderInfo.Shutter.FirstScanlineToLastScanline;
+ // Time for pixels to get half-way to settling.
+ result.PresentFlushToRenderedScene += hmdRenderInfo.Shutter.PixelSettleTime * 0.5f;
+ // Predict to half-way through persistence
+ result.PresentFlushToRenderedScene += hmdRenderInfo.Shutter.PixelPersistence * 0.5f;
+
+ // The time from the Present+Flush to when the first scanline is "averagely visible".
+ result.PresentFlushToTimewarpStart = extraFramesOfBufferingKludge * hmdRenderInfo.Shutter.FirstScanlineToLastScanline;
+ // Predict to the first line being scanned out.
+ result.PresentFlushToTimewarpStart += hmdRenderInfo.Shutter.VsyncToFirstScanline;
+ // Time for pixels to get half-way to settling.
+ result.PresentFlushToTimewarpStart += hmdRenderInfo.Shutter.PixelSettleTime * 0.5f;
+ // Predict to half-way through persistence
+ result.PresentFlushToTimewarpStart += hmdRenderInfo.Shutter.PixelPersistence * 0.5f;
+
+ // Time to the the last scanline.
+ result.PresentFlushToTimewarpEnd = result.PresentFlushToTimewarpStart + hmdRenderInfo.Shutter.FirstScanlineToLastScanline;
+
+ // Ideal framerate.
+ result.PresentFlushToPresentFlush = hmdRenderInfo.Shutter.VsyncToNextVsync;
+ }
+ else
+ {
+ // Timewarp without vsync is a little odd.
+ // Currently, we assume that without vsync, we have no idea which scanline
+ // is currently being sent to the display. So we can't do lerping timewarp,
+ // we can just do a full-screen late-stage fixup.
+
+ // "PresentFlushToRenderedScene" means the time from the Present+Flush to when the middle of the scene is "averagely visible" (without timewarp)
+ // So if you had no timewarp, this, plus the time until the next flush (which is usually the time to render the frame), is how much to predict by.
+ // Time for pixels to get half-way to settling.
+ result.PresentFlushToRenderedScene = hmdRenderInfo.Shutter.PixelSettleTime * 0.5f;
+ // Predict to half-way through persistence
+ result.PresentFlushToRenderedScene += hmdRenderInfo.Shutter.PixelPersistence * 0.5f;
+
+ // Without vsync, you don't know timings, and so can't do anything useful with lerped warping.
+ result.PresentFlushToTimewarpStart = result.PresentFlushToRenderedScene;
+ result.PresentFlushToTimewarpEnd = result.PresentFlushToRenderedScene;
+
+ // There's no concept of "ideal" when vsync is off.
+ result.PresentFlushToPresentFlush = 0.0f;
+ }
+
+ return result;
+}
+
+Matrix4f TimewarpComputePoseDelta ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld )
+{
+ Matrix4f worldFromPredictedView = predictedViewFromWorld.InvertedHomogeneousTransform();
+ Matrix4f matRenderFromNowStart = 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.
+ // So we need to perform a similarity transform on this delta matrix.
+ // The verbose code would look like this:
+ /*
+ Matrix4f matBasisChange;
+ matBasisChange.SetIdentity();
+ matBasisChange.M[0][0] = 1.0f;
+ matBasisChange.M[1][1] = -1.0f;
+ matBasisChange.M[2][2] = -1.0f;
+ Matrix4f matBasisChangeInv = matBasisChange.Inverted();
+ matRenderFromNow = matBasisChangeInv * matRenderFromNow * matBasisChange;
+ */
+ // ...but of course all the above is a constant transform and much more easily done.
+ // We flip the signs of the Y&Z row, then flip the signs of the Y&Z column,
+ // and of course most of the flips cancel:
+ // +++ +-- +--
+ // +++ -> flip Y&Z columns -> +-- -> flip Y&Z rows -> -++
+ // +++ +-- -++
+ matRenderFromNowStart.M[0][1] = -matRenderFromNowStart.M[0][1];
+ matRenderFromNowStart.M[0][2] = -matRenderFromNowStart.M[0][2];
+ matRenderFromNowStart.M[1][0] = -matRenderFromNowStart.M[1][0];
+ matRenderFromNowStart.M[2][0] = -matRenderFromNowStart.M[2][0];
+ matRenderFromNowStart.M[1][3] = -matRenderFromNowStart.M[1][3];
+ matRenderFromNowStart.M[2][3] = -matRenderFromNowStart.M[2][3];
+
+ return matRenderFromNowStart;
+}
+
+
+TimewarpMachine::TimewarpMachine()
+{
+ for ( int i = 0; i < 2; i++ )
+ {
+ EyeRenderPoses[i] = Posef();
+ }
+ DistortionTimeCount = 0;
+ VsyncEnabled = false;
+}
+
+void TimewarpMachine::Reset(HmdRenderInfo& renderInfo, bool vsyncEnabled, double timeNow)
+{
+ RenderInfo = renderInfo;
+ VsyncEnabled = vsyncEnabled;
+ CurrentPredictionValues = PredictionGetDeviceValues ( renderInfo, true, VsyncEnabled );
+ PresentFlushToPresentFlushSeconds = 0.0f;
+ DistortionTimeCount = 0;
+ DistortionTimeAverage = 0.0f;
+ LastFramePresentFlushTime = timeNow;
+ AfterPresentAndFlush(timeNow);
+}
+
+void TimewarpMachine::AfterPresentAndFlush(double timeNow)
+{
+ PresentFlushToPresentFlushSeconds = (float)(timeNow - LastFramePresentFlushTime);
+ LastFramePresentFlushTime = timeNow;
+ NextFramePresentFlushTime = timeNow + (double)PresentFlushToPresentFlushSeconds;
+}
+
+double TimewarpMachine::GetViewRenderPredictionTime()
+{
+ // Note that PredictionGetDeviceValues() did all the vsync-dependent thinking for us.
+ return NextFramePresentFlushTime + CurrentPredictionValues.PresentFlushToRenderedScene;
+}
+
+Posef TimewarpMachine::GetViewRenderPredictionPose(SensorFusion &sfusion)
+{
+ double predictionTime = GetViewRenderPredictionTime();
+ return sfusion.GetPoseAtTime(predictionTime);
+}
+
+double TimewarpMachine::GetVisiblePixelTimeStart()
+{
+ // Note that PredictionGetDeviceValues() did all the vsync-dependent thinking for us.
+ return NextFramePresentFlushTime + CurrentPredictionValues.PresentFlushToTimewarpStart;
+}
+double TimewarpMachine::GetVisiblePixelTimeEnd()
+{
+ // Note that PredictionGetDeviceValues() did all the vsync-dependent thinking for us.
+ return NextFramePresentFlushTime + CurrentPredictionValues.PresentFlushToTimewarpEnd;
+}
+Posef TimewarpMachine::GetPredictedVisiblePixelPoseStart(SensorFusion &sfusion)
+{
+ double predictionTime = GetVisiblePixelTimeStart();
+ return sfusion.GetPoseAtTime(predictionTime);
+}
+Posef TimewarpMachine::GetPredictedVisiblePixelPoseEnd (SensorFusion &sfusion)
+{
+ double predictionTime = GetVisiblePixelTimeEnd();
+ return sfusion.GetPoseAtTime(predictionTime);
+}
+Matrix4f TimewarpMachine::GetTimewarpDeltaStart(SensorFusion &sfusion, Posef const &renderedPose)
+{
+ Posef visiblePose = GetPredictedVisiblePixelPoseStart ( sfusion );
+ Matrix4f visibleMatrix(visiblePose);
+ Matrix4f renderedMatrix(renderedPose);
+ return TimewarpComputePoseDelta ( renderedMatrix, visibleMatrix );
+}
+Matrix4f TimewarpMachine::GetTimewarpDeltaEnd (SensorFusion &sfusion, Posef const &renderedPose)
+{
+ Posef visiblePose = GetPredictedVisiblePixelPoseEnd ( sfusion );
+ Matrix4f visibleMatrix(visiblePose);
+ Matrix4f renderedMatrix(renderedPose);
+ return TimewarpComputePoseDelta ( renderedMatrix, visibleMatrix );
+}
+
+
+// What time should the app wait until before starting distortion?
+double TimewarpMachine::JustInTime_GetDistortionWaitUntilTime()
+{
+ if ( !VsyncEnabled || ( DistortionTimeCount < NumDistortionTimes ) )
+ {
+ // Don't wait.
+ return LastFramePresentFlushTime;
+ }
+
+ const float fudgeFactor = 0.002f; // Found heuristically - 1ms is too short because of timing granularity - may need further tweaking!
+ float howLongBeforePresent = DistortionTimeAverage + fudgeFactor;
+ // Subtlety here. Technically, the correct time is NextFramePresentFlushTime - howLongBeforePresent.
+ // However, if the app drops a frame, this then perpetuates it,
+ // i.e. if the display is running at 60fps, but the last frame was slow,
+ // (e.g. because of swapping or whatever), then NextFramePresentFlushTime is
+ // 33ms in the future, not 16ms. Since this function supplies the
+ // time to wait until, the app will indeed wait until 32ms, so the framerate
+ // drops to 30fps and never comes back up!
+ // So we return the *ideal* framerate, not the *actual* framerate.
+ return LastFramePresentFlushTime + (float)( CurrentPredictionValues.PresentFlushToPresentFlush - howLongBeforePresent );
+}
+
+
+bool TimewarpMachine::JustInTime_NeedDistortionTimeMeasurement() const
+{
+ if (!VsyncEnabled)
+ {
+ return false;
+ }
+ return ( DistortionTimeCount < NumDistortionTimes );
+}
+
+void TimewarpMachine::JustInTime_BeforeDistortionTimeMeasurement(double timeNow)
+{
+ DistortionTimeCurrentStart = timeNow;
+}
+
+void TimewarpMachine::JustInTime_AfterDistortionTimeMeasurement(double timeNow)
+{
+ float timeDelta = (float)( timeNow - DistortionTimeCurrentStart );
+ if ( DistortionTimeCount < NumDistortionTimes )
+ {
+ DistortionTimes[DistortionTimeCount] = timeDelta;
+ DistortionTimeCount++;
+ if ( DistortionTimeCount == NumDistortionTimes )
+ {
+ // Median.
+ float distortionTimeMedian = 0.0f;
+ for ( int i = 0; i < NumDistortionTimes/2; i++ )
+ {
+ // Find the maximum time of those remaining.
+ float maxTime = DistortionTimes[0];
+ int maxIndex = 0;
+ for ( int j = 1; j < NumDistortionTimes; j++ )
+ {
+ if ( maxTime < DistortionTimes[j] )
+ {
+ maxTime = DistortionTimes[j];
+ maxIndex = j;
+ }
+ }
+ // Zero that max time, so we'll find the next-highest time.
+ DistortionTimes[maxIndex] = 0.0f;
+ distortionTimeMedian = maxTime;
+ }
+ DistortionTimeAverage = distortionTimeMedian;
+ }
+ }
+ else
+ {
+ OVR_ASSERT ( !"Really didn't need more measurements, thanks" );
+ }
}
diff --git a/LibOVR/Src/Util/Util_Render_Stereo.h b/LibOVR/Src/Util/Util_Render_Stereo.h
index 492080d..2ad9103 100644
--- a/LibOVR/Src/Util/Util_Render_Stereo.h
+++ b/LibOVR/Src/Util/Util_Render_Stereo.h
@@ -4,18 +4,18 @@ PublicHeader: OVR.h
Filename : Util_Render_Stereo.h
Content : Sample stereo rendering configuration classes.
Created : October 22, 2012
-Authors : Michael Antonov
+Authors : Michael Antonov, Tom Forsyth
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
-Licensed under the Oculus VR SDK License Version 2.0 (the "License");
-you may not use the Oculus VR SDK except in compliance with the License,
+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-2.0
+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,
@@ -28,135 +28,75 @@ limitations under the License.
#ifndef OVR_Util_Render_Stereo_h
#define OVR_Util_Render_Stereo_h
-#include "../OVR_Device.h"
+#include "../OVR_Stereo.h"
-namespace OVR { namespace Util { namespace Render {
+namespace OVR {
-//-----------------------------------------------------------------------------------
-// ***** Stereo Enumerations
+class SensorFusion;
-// StereoMode describes rendering modes that can be used by StereoConfig.
-// These modes control whether stereo rendering is used or not (Stereo_None),
-// and how it is implemented.
-enum StereoMode
-{
- Stereo_None = 0,
- Stereo_LeftRight_Multipass = 1
-};
+namespace Util { namespace Render {
-// StereoEye specifies which eye we are rendering for; it is used to
-// retrieve StereoEyeParams.
-enum StereoEye
-{
- StereoEye_Center,
- StereoEye_Left,
- StereoEye_Right
-};
-
//-----------------------------------------------------------------------------------
-// ***** Viewport
-
-// Viewport describes a rectangular area used for rendering, in pixels.
-struct Viewport
-{
- int x, y;
- int w, h;
-
- Viewport() {}
- Viewport(int x1, int y1, int w1, int h1) : x(x1), y(y1), w(w1), h(h1) { }
+// **** Useful debug functions.
+//
+// Purely for debugging - the results are not very end-user-friendly.
+char const* GetDebugNameEyeCupType ( EyeCupType eyeCupType );
+char const* GetDebugNameHmdType ( HmdTypeEnum hmdType );
- bool operator == (const Viewport& vp) const
- { return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); }
- bool operator != (const Viewport& vp) const
- { return !operator == (vp); }
-};
//-----------------------------------------------------------------------------------
-// ***** DistortionConfig
-
-// DistortionConfig Provides controls for the distortion shader.
-// - K[0] - K[3] are coefficients for the distortion function.
-// - XCenterOffset is the offset of lens distortion center from the
-// center of one-eye screen half. [-1, 1] Range.
-// - Scale is a factor of how much larger will the input image be,
-// with a factor of 1.0f being no scaling. An inverse of this
-// value is applied to sampled UV coordinates (1/Scale).
-// - ChromaticAberration is an array of parameters for controlling
-// additional Red and Blue scaling in order to reduce chromatic aberration
-// caused by the Rift lenses.
-class DistortionConfig
-{
-public:
- DistortionConfig(float k0 = 1.0f, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f)
- : XCenterOffset(0), YCenterOffset(0), Scale(1.0f)
- {
- SetCoefficients(k0, k1, k2, k3);
- SetChromaticAberration();
- }
+// **** Higher-level utility functions.
- void SetCoefficients(float k0, float k1 = 0.0f, float k2 = 0.0f, float k3 = 0.0f)
- { K[0] = k0; K[1] = k1; K[2] = k2; K[3] = k3; }
+Sizei CalculateRecommendedTextureSize ( HmdRenderInfo const &hmd,
+ bool bRendertargetSharedByBothEyes,
+ float pixelDensityInCenter = 1.0f );
- void SetChromaticAberration(float red1 = 1.0f, float red2 = 0.0f, float blue1 = 1.0f, float blue2 = 0.0f)
- { ChromaticAberration[0] = red1; ChromaticAberration[1] = red2; ChromaticAberration[2] = blue1; ChromaticAberration[3] = blue2; }
+FovPort CalculateRecommendedFov ( HmdRenderInfo const &hmd,
+ StereoEye eyeType,
+ bool bMakeFovSymmetrical = false);
+StereoEyeParams CalculateStereoEyeParams ( HmdRenderInfo const &hmd,
+ StereoEye eyeType,
+ Sizei const &actualRendertargetSurfaceSize,
+ bool bRendertargetSharedByBothEyes,
+ bool bRightHanded = true,
+ float zNear = 0.01f, float zFar = 10000.0f,
+ Sizei const *pOverrideRenderedPixelSize = NULL,
+ FovPort const *pOverrideFovport = NULL,
+ float zoomFactor = 1.0f );
- // DistortionFn applies distortion equation to the argument. The returned
- // value should match distortion equation used in shader.
- float DistortionFn(float r) const
- {
- float rsq = r * r;
- float scale = r * (K[0] + K[1] * rsq + K[2] * rsq * rsq + K[3] * rsq * rsq * rsq);
- return scale;
- }
-
- // DistortionFnInverse computes the inverse of the distortion function on an argument.
- float DistortionFnInverse(float r);
+Vector3f CalculateEyeVirtualCameraOffset(HmdRenderInfo const &hmd,
+ StereoEye eyeType, bool bMonoRenderingMode );
- float K[4];
- float XCenterOffset, YCenterOffset;
- float Scale;
- float ChromaticAberration[4]; // Additional per-channel scaling is applied after distortion:
- // Index [0] - Red channel constant coefficient.
- // Index [1] - Red channel r^2 coefficient.
- // Index [2] - Blue channel constant coefficient.
- // Index [3] - Blue channel r^2 coefficient.
+// These are two components from StereoEyeParams that can be changed
+// very easily without full recomputation of everything.
+struct ViewportScaleAndOffset
+{
+ Recti RenderedViewport;
+ ScaleAndOffset2D EyeToSourceUV;
};
+// Three ways to override the size of the render view dynamically.
+// None of these require changing the distortion parameters or the regenerating the distortion mesh,
+// and can be called every frame if desired.
+ViewportScaleAndOffset ModifyRenderViewport ( StereoEyeParams const &params,
+ Sizei const &actualRendertargetSurfaceSize,
+ Recti const &renderViewport );
-//-----------------------------------------------------------------------------------
-// ***** StereoEyeParams
+ViewportScaleAndOffset ModifyRenderSize ( StereoEyeParams const &params,
+ Sizei const &actualRendertargetSurfaceSize,
+ Sizei const &requestedRenderSize,
+ bool bRendertargetSharedByBothEyes = false );
-// StereoEyeParams describes RenderDevice configuration needed to render
-// the scene for one eye.
-class StereoEyeParams
-{
-public:
- StereoEye Eye;
- Viewport VP; // Viewport that we are rendering to
- const DistortionConfig* pDistortion;
-
- Matrix4f ViewAdjust; // Translation to be applied to view matrix.
- Matrix4f Projection; // Projection matrix used with this eye.
- Matrix4f OrthoProjection; // Orthographic projection used with this eye.
-
- void Init(StereoEye eye, const Viewport &vp, float vofs,
- const Matrix4f& proj, const Matrix4f& orthoProj,
- const DistortionConfig* distortion = 0)
- {
- Eye = eye;
- VP = vp;
- ViewAdjust = Matrix4f::Translation(Vector3f(vofs,0,0));
- Projection = proj;
- OrthoProjection = orthoProj;
- pDistortion = distortion;
- }
-};
+ViewportScaleAndOffset ModifyRenderDensity ( StereoEyeParams const &params,
+ Sizei const &actualRendertargetSurfaceSize,
+ float pixelDensity = 1.0f,
+ bool bRendertargetSharedByBothEyes = false );
//-----------------------------------------------------------------------------------
@@ -169,143 +109,358 @@ public:
// parameters are returned though StereoEyeParams for each eye.
//
// Beyond regular 3D projection, this class supports rendering a 2D orthographic
-// surface for UI and text. The 2D surface will be defined as fitting within a 2D
-// field of view (85 degrees by default) and used [-1,1] coordinate system with
-// square pixels. The (0,0) coordinate corresponds to eye center location
-// that is properly adjusted during rendering through SterepRenderParams::Adjust2D.
-// Genreally speaking, text outside [-1,1] coordinate range will not be readable.
+// surface for UI and text. The 2D surface will be defined by CreateOrthoSubProjection().
+// The (0,0) coordinate corresponds to eye center location.
+//
+// Applications are not required to use this class, but they should be doing very
+// similar sequences of operations, and it may be useful to start with this class
+// and modify it.
+
+struct StereoEyeParamsWithOrtho
+{
+ StereoEyeParams StereoEye;
+ Matrix4f OrthoProjection;
+};
+
+struct ViewportScaleAndOffsetBothEyes
+{
+ ViewportScaleAndOffset Left;
+ ViewportScaleAndOffset Right;
+};
class StereoConfig
{
public:
- StereoConfig(StereoMode mode = Stereo_LeftRight_Multipass,
- const Viewport& fullViewport = Viewport(0,0, 1280,800));
+ // StereoMode describes rendering modes that can be used by StereoConfig.
+ // These modes control whether stereo rendering is used or not (Stereo_None),
+ // and how it is implemented.
+ enum StereoMode
+ {
+ Stereo_None = 0, // Single eye
+ Stereo_LeftRight_Multipass = 1, // One frustum per eye
+ };
+
+
+ StereoConfig(StereoMode mode = Stereo_LeftRight_Multipass);
+ //---------------------------------------------------------------------------------------------
+ // *** Core functions - every app MUST call these functions at least once.
+
+ // Sets HMD parameters; also initializes distortion coefficients.
+ void SetHmdRenderInfo(const HmdRenderInfo& hmd);
+
+ // Set the physical size of the rendertarget surface the app created,
+ // and whether one RT is shared by both eyes, or each eye has its own RT:
+ // true: both eyes are rendered to the same RT. Left eye starts at top-left, right eye starts at top-middle.
+ // false: each eye is rendered to its own RT. Some GPU architectures prefer this arrangement.
+ // Typically, the app would call CalculateRecommendedTextureSize() to suggest the choice of RT size.
+ // This setting must be exactly the size of the actual RT created, or the UVs produced will be incorrect.
+ // If the app wants to render to a subsection of the RT, it should use SetRenderSize()
+ void SetRendertargetSize (Size<int> const rendertargetSize,
+ bool rendertargetIsSharedByBothEyes );
+
+ // Returns full set of Stereo rendering parameters for the specified eye.
+ const StereoEyeParamsWithOrtho& GetEyeRenderParams(StereoEye eye);
+
+
+
+ //---------------------------------------------------------------------------------------------
+ // *** Optional functions - an app may call these to override default behaviours.
+
+ const HmdRenderInfo& GetHmdRenderInfo() const { return Hmd; }
- // *** Modifiable State Access
+ // Returns the recommended size of rendertargets.
+ // If rendertargetIsSharedByBothEyes is true, this is the size of the combined buffer.
+ // If rendertargetIsSharedByBothEyes is false, this is the size of each individual buffer.
+ // pixelDensityInCenter may be set to any number - by default it will match the HMD resolution in the center of the image.
+ // After creating the rendertargets, the application MUST call SetRendertargetSize() with the actual size created
+ // (which can be larger or smaller as the app wishes, but StereoConfig needs to know either way)
+ Sizei CalculateRecommendedTextureSize ( bool rendertargetSharedByBothEyes,
+ float pixelDensityInCenter = 1.0f );
// Sets a stereo rendering mode and updates internal cached
// state (matrices, per-eye view) based on it.
void SetStereoMode(StereoMode mode) { Mode = mode; DirtyFlag = true; }
StereoMode GetStereoMode() const { return Mode; }
- // Sets HMD parameters; also initializes distortion coefficients.
- void SetHMDInfo(const HMDInfo& hmd);
- const HMDInfo& GetHMDInfo() const { return HMD; }
+ // Sets the fieldOfView that the 2D coordinate area stretches to.
+ void Set2DAreaFov(float fovRadians);
- // Query physical eye-to-screen distance in meters, which combines screen-to-lens and
- // and lens-to-eye pupil distances. Modifying this value adjusts FOV.
- float GetEyeToScreenDistance() const { return HMD.EyeToScreenDistance; }
- void SetEyeToScreenDistance(float esd) { HMD.EyeToScreenDistance = esd; DirtyFlag = true; }
+ // Really only for science experiments - no normal app should ever need to override
+ // the HMD's lens descriptors. Passing NULL removes the override.
+ // Supply both = set left and right.
+ // Supply just left = set both to the same.
+ // Supply neither = remove override.
+ void SetLensOverride ( LensConfig const *pLensOverrideLeft = NULL,
+ LensConfig const *pLensOverrideRight = NULL );
+
+ // Override the rendered FOV in various ways. All angles in tangent units.
+ // This is not clamped to the physical FOV of the display - you'll need to do that yourself!
+ // Supply both = set left and right.
+ // Supply just left = set both to the same.
+ // Supply neither = remove override.
+ void SetFov ( FovPort const *pfovLeft = NULL,
+ FovPort const *pfovRight = NULL );
+
+ void SetFovPortRadians ( float horizontal, float vertical )
+ {
+ FovPort fov = FovPort::CreateFromRadians(horizontal, vertical);
+ SetFov( &fov, &fov );
+ }
- // Interpupillary distance used for stereo, in meters. Default is 0.064m (64 mm).
- void SetIPD(float ipd) { InterpupillaryDistance = ipd; IPDOverride = DirtyFlag = true; }
- float GetIPD() const { return InterpupillaryDistance; }
- // Set full render target viewport; for HMD this includes both eyes.
- void SetFullViewport(const Viewport& vp);
- const Viewport& GetFullViewport() const { return FullView; }
+ // This forces a "zero IPD" mode where there is just a single render with an FOV that
+ // is the union of the two calculated FOVs.
+ // The calculated render is for the left eye. Any size & FOV overrides for the right
+ // eye will be ignored.
+ // If you query the right eye's size, you will get the same render
+ // size & position as the left eye - you should not actually do the render of course!
+ // The distortion values will be different, because it goes to a different place on the framebuffer.
+ // Note that if you do this, the rendertarget does not need to be twice the width of
+ // the render size any more.
+ void SetZeroVirtualIpdOverride ( bool enableOverride );
- // Aspect ratio defaults to ((w/h)*multiplier) computed per eye.
- // Aspect multiplier allows adjusting aspect ratio consistently for Stereo/NoStereo.
- void SetAspectMultiplier(float m) { AspectMultiplier = m; DirtyFlag = true; }
- float GetAspectMultiplier() const { return AspectMultiplier; }
+ // Allows the app to specify near and far clip planes and the right/left-handedness of the projection matrix.
+ void SetZClipPlanesAndHandedness ( float zNear = 0.01f, float zFar = 10000.0f,
+ bool rightHandedProjection = true );
-
- // For the distorted image to fill rendered viewport, input texture render target needs to be
- // scaled by DistortionScale before sampling. The scale factor is computed by fitting a point
- // on of specified radius from a distortion center, more easily specified as a coordinate.
- // SetDistortionFitPointVP sets the (x,y) coordinate of the point that scale will be "fit" to,
- // assuming [-1,1] coordinate range for full left-eye viewport. A fit point is a location
- // where source (pre-distortion) and target (post-distortion) image match each other.
- // For the right eye, the interpretation of 'u' will be inverted.
- void SetDistortionFitPointVP(float x, float y);
- // SetDistortionFitPointPixels sets the (x,y) coordinate of the point that scale will be "fit" to,
- // specified in pixeld for full left-eye texture.
- void SetDistortionFitPointPixels(float x, float y);
-
- // Changes all distortion settings.
- // Note that setting HMDInfo also changes Distortion coefficients.
- void SetDistortionConfig(const DistortionConfig& d) { Distortion = d; DirtyFlag = true; }
-
- // Modify distortion coefficients; useful for adjustment tweaking.
- void SetDistortionK(int i, float k) { Distortion.K[i] = k; DirtyFlag = true; }
- float GetDistortionK(int i) const { return Distortion.K[i]; }
+ // Allows the app to specify how much extra eye rotation to allow when determining the visible FOV.
+ void SetExtraEyeRotation ( float extraEyeRotationInRadians = 0.0f );
- // Sets the fieldOfView that the 2D coordinate area stretches to.
- void Set2DAreaFov(float fovRadians);
+ // The dirty flag is set by any of the above calls. Just handy for the app to know
+ // if e.g. the distortion mesh needs regeneration.
+ void SetDirty() { DirtyFlag = true; }
+ bool IsDirty() { return DirtyFlag; }
+
+ // An app never needs to call this - GetEyeRenderParams will call it internally if
+ // the state is dirty. However apps can call this explicitly to control when and where
+ // computation is performed (e.g. not inside critical loops)
+ void UpdateComputedState();
+
+ // This returns the projection matrix with a "zoom". Does not modify any internal state.
+ Matrix4f GetProjectionWithZoom ( StereoEye eye, float fovZoom ) const;
+ //---------------------------------------------------------------------------------------------
+ // The SetRender* functions are special.
+ //
+ // They do not require a full recalculation of state, and they do not change anything but the
+ // ViewportScaleAndOffset data for the eyes (which they return), and do not set the dirty flag!
+ // This means they can be called without regenerating the distortion mesh, and thus
+ // can happily be called every frame without causing performance problems. Dynamic rescaling
+ // of the rendertarget can help keep framerate up in demanding VR applications.
+ // See the documentation for more details on their use.
+
+ // Specify a pixel density - how many rendered pixels per pixel in the physical display.
+ ViewportScaleAndOffsetBothEyes SetRenderDensity ( float pixelsPerDisplayPixel );
+
+ // Supply the size directly. Will be clamped to the physical rendertarget size.
+ ViewportScaleAndOffsetBothEyes SetRenderSize ( Sizei const &renderSizeLeft, Sizei const &renderSizeRight );
+
+ // Supply the viewport directly. This is not clamped to the physical rendertarget - careful now!
+ ViewportScaleAndOffsetBothEyes SetRenderViewport ( Recti const &renderViewportLeft, Recti const &renderViewportRight );
+
+private:
+
+ // *** Modifiable State
+
+ StereoMode Mode;
+ HmdRenderInfo Hmd;
+
+ float Area2DFov; // FOV range mapping to the 2D area.
+
+ // Only one of these three overrides can be true!
+ enum SetViewportModeEnum
+ {
+ SVPM_Density,
+ SVPM_Size,
+ SVPM_Viewport,
+ } SetViewportMode;
+ // ...and depending which it is, one of the following are used.
+ float SetViewportPixelsPerDisplayPixel;
+ Sizei SetViewportSize[2];
+ Recti SetViewport[2];
+
+ // Other overrides.
+ bool OverrideLens;
+ LensConfig LensOverrideLeft;
+ LensConfig LensOverrideRight;
+ Sizei RendertargetSize;
+ bool OverrideTanHalfFov;
+ FovPort FovOverrideLeft;
+ FovPort FovOverrideRight;
+ bool OverrideZeroIpd;
+ float ZNear;
+ float ZFar;
+ float ExtraEyeRotationInRadians;
+ bool IsRendertargetSharedByBothEyes;
+ bool RightHandedProjection;
+
+ bool DirtyFlag; // Set when any if the modifiable state changed. Does NOT get set by SetRender*()
+
+ // Utility function.
+ ViewportScaleAndOffsetBothEyes setupViewportScaleAndOffsets();
+
// *** Computed State
- // Return current aspect ratio.
- float GetAspect() { updateIfDirty(); return Aspect; }
-
- // Return computed vertical FOV in radians/degrees.
- float GetYFOVRadians() { updateIfDirty(); return YFov; }
- float GetYFOVDegrees() { return RadToDegree(GetYFOVRadians()); }
+public: // Small hack for the config tool. Normal code should never read EyeRenderParams directly - use GetEyeRenderParams() instead.
+ // 0/1 = left/right main views.
+ StereoEyeParamsWithOrtho EyeRenderParams[2];
+};
- // Query horizontal projection center offset as a distance away from the
- // one-eye [-1,1] unit viewport.
- // Positive return value should be used for left eye, negative for right eye.
- float GetProjectionCenterOffset() { updateIfDirty(); return ProjectionCenterOffset; }
- // GetDistortionConfig isn't const because XCenterOffset bay need to be recomputed.
- const DistortionConfig& GetDistortionConfig() { updateIfDirty(); return Distortion; }
+//-----------------------------------------------------------------------------------
+// ***** Distortion Mesh Rendering
+//
- // Returns DistortionScale factor by which input texture size is increased to make
- // post-distortion result distortion fit the viewport.
- float GetDistortionScale() { updateIfDirty(); return Distortion.Scale; }
+// Stores both texture UV coords, or tan(angle) values.
+// Use whichever set of data the specific distortion algorithm requires.
+// This struct *must* be binary compatible with CAPI ovrDistortionVertex.
+struct DistortionMeshVertexData
+{
+ // [-1,+1],[-1,+1] over the entire framebuffer.
+ Vector2f ScreenPosNDC;
+ // [0.0-1.0] interpolation value for timewarping - see documentation for details.
+ float TimewarpLerp;
+ // [0.0-1.0] fade-to-black at the edges to reduce peripheral vision noise.
+ float Shade;
+ // The red, green, and blue 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 TanEyeAnglesR;
+ Vector2f TanEyeAnglesG;
+ Vector2f TanEyeAnglesB;
+};
- // Returns the size of a pixel within 2D coordinate system.
- float Get2DUnitPixel() { updateIfDirty(); return (2.0f / (FovPixels * Distortion.Scale)); }
- // Returns full set of Stereo rendering parameters for the specified eye.
- const StereoEyeParams& GetEyeRenderParams(StereoEye eye);
+void DistortionMeshCreate ( DistortionMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices,
+ int *pNumVertices, int *pNumTriangles,
+ const StereoEyeParams &stereoParams, const HmdRenderInfo &hmdRenderInfo );
+
+// Generate distortion mesh for a eye. This version requires less data then stereoParms, supporting
+// dynamic change in render target viewport.
+void DistortionMeshCreate( DistortionMeshVertexData **ppVertices, UInt16 **ppTriangleListIndices,
+ int *pNumVertices, int *pNumTriangles,
+ bool rightEye,
+ const HmdRenderInfo &hmdRenderInfo,
+ const DistortionRenderDesc &distortion, const ScaleAndOffset2D &eyeToSourceNDC );
+
+void DistortionMeshDestroy ( DistortionMeshVertexData *pVertices, UInt16 *pTriangleMeshIndices );
+
+
+
+
+//-----------------------------------------------------------------------------------
+// ***** Prediction and timewarp.
+//
+
+struct PredictionValues
+{
+ // All values in seconds.
+ // These are the times in seconds from a present+flush to the relevant display element.
+ // The time is measured to the middle of that element's visibility window,
+ // e.g. if the device is a full-persistence display, the element will be visible for
+ // an entire frame, so the time measures to the middle of that period, i.e. half the frame time.
+ float PresentFlushToRenderedScene; // To the overall rendered 3D scene being visible.
+ float PresentFlushToTimewarpStart; // To when the first timewarped scanline will be visible.
+ float PresentFlushToTimewarpEnd; // To when the last timewarped scanline will be visible.
+ float PresentFlushToPresentFlush; // To the next present+flush, i.e. the ideal framerate.
+
+ bool WithTimewarp;
+ bool WithVsync;
+};
+
+// Calculates the values from the HMD info.
+PredictionValues PredictionGetDeviceValues ( const HmdRenderInfo &hmdRenderInfo,
+ bool withTimewarp = true,
+ bool withVsync = true );
+
+// Pass in an orientation used to render the scene, and then the predicted orientation
+// (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 );
+
+
+
+// TimewarpMachine helps keep track of rendered frame timing and
+// handles predictions for time-warp rendering.
+class TimewarpMachine
+{
+public:
+ TimewarpMachine();
-private:
+ // Call this on and every time something about the setup changes.
+ void Reset ( HmdRenderInfo& renderInfo, bool vsyncEnabled, double timeNow );
- void updateIfDirty() { if (DirtyFlag) updateComputedState(); }
- void updateComputedState();
+ // The only reliable time in most engines is directly after the frame-present and GPU flush-and-wait.
+ // This call should be done right after that to give this system the timing info it needs.
+ void AfterPresentAndFlush(double timeNow);
- void updateDistortionOffsetAndScale();
- void updateProjectionOffset();
- void update2D();
- void updateEyeParams();
+ // The "average" time the rendered frame will show up,
+ // 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);
- // *** Modifiable State
+ // Timewarp prediction functions. You usually only need to call one of these three sets of functions.
+
+ // The predicted times that the first and last pixel will be visible on-screen.
+ double GetVisiblePixelTimeStart();
+ double GetVisiblePixelTimeEnd();
+ // Predicted poses of the HMD at those first and last pixels.
+ Posef GetPredictedVisiblePixelPoseStart(SensorFusion &sfusion);
+ Posef 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);
+
+
+ // Just-In-Time distortion aims to delay the second sensor reading & distortion
+ // until the very last moment to improve prediction. However, it is a little scary,
+ // since the delay might wait too long and miss the vsync completely!
+ // Use of the JustInTime_* functions is entirely optional, and we advise allowing
+ // users to turn it off in their video options to cope with odd machine configurations.
+
+ // What time should the app wait until before starting distortion?
+ double JustInTime_GetDistortionWaitUntilTime();
+
+ // Used to time the distortion rendering
+ bool JustInTime_NeedDistortionTimeMeasurement() const;
+ void JustInTime_BeforeDistortionTimeMeasurement(double timeNow);
+ void JustInTime_AfterDistortionTimeMeasurement(double timeNow);
+
+
+private:
+
+ bool VsyncEnabled;
+ HmdRenderInfo RenderInfo;
+ PredictionValues CurrentPredictionValues;
+
+ enum { NumDistortionTimes = 10 };
+ int DistortionTimeCount;
+ double DistortionTimeCurrentStart;
+ float DistortionTimes[NumDistortionTimes];
+ float DistortionTimeAverage;
+
+ // Pose at which last time the eye was rendered.
+ Posef EyeRenderPoses[2];
+
+ // Absolute time of the last present+flush
+ double LastFramePresentFlushTime;
+ // Seconds between presentflushes
+ float PresentFlushToPresentFlushSeconds;
+ // Predicted absolute time of the next present+flush
+ double NextFramePresentFlushTime;
- StereoMode Mode;
- float InterpupillaryDistance;
- float AspectMultiplier; // Multiplied into aspect ratio to change it.
- HMDInfo HMD;
- DistortionConfig Distortion;
- float DistortionFitX, DistortionFitY; // In [-1,1] half-screen viewport units.
- Viewport FullView; // Entire window viewport.
-
- float Area2DFov; // FOV range mapping to [-1, 1] 2D area.
-
- // *** Computed State
-
- bool DirtyFlag; // Set when any if the modifiable state changed.
- bool IPDOverride; // True after SetIPD was called.
- float YFov; // Vertical FOV.
- float Aspect; // Aspect ratio: (w/h)*AspectMultiplier.
- float ProjectionCenterOffset;
- StereoEyeParams EyeRenderParams[2];
-
-
- // ** 2D Rendering
-
- // Number of 2D pixels in the FOV. This defines [-1,1] coordinate range for 2D.
- float FovPixels;
- Matrix4f OrthoCenter;
- float OrthoPixelOffset;
};
+
}}} // OVR::Util::Render
#endif
diff --git a/Mac_OculusWorldDemo.app/Contents/Info.plist b/Mac_OculusWorldDemo.app/Contents/Info.plist
deleted file mode 100644
index 6a93c64..0000000
--- a/Mac_OculusWorldDemo.app/Contents/Info.plist
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>BuildMachineOSBuild</key>
- <string>12C3103</string>
- <key>CFBundleDevelopmentRegion</key>
- <string>en</string>
- <key>CFBundleExecutable</key>
- <string>OculusWorldDemo</string>
- <key>CFBundleIconFile</key>
- <string>Oculus</string>
- <key>CFBundleIdentifier</key>
- <string>com.oculusvr.OculusWorldDemo</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleName</key>
- <string>OculusWorldDemo</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleShortVersionString</key>
- <string>1.0</string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>CFBundleVersion</key>
- <string>1</string>
- <key>DTCompiler</key>
- <string></string>
- <key>DTPlatformBuild</key>
- <string>4H127</string>
- <key>DTPlatformVersion</key>
- <string>GM</string>
- <key>DTSDKBuild</key>
- <string>12C37</string>
- <key>DTSDKName</key>
- <string>macosx10.8</string>
- <key>DTXcode</key>
- <string>0460</string>
- <key>DTXcodeBuild</key>
- <string>4H127</string>
- <key>LSMinimumSystemVersion</key>
- <string>10.6</string>
- <key>NSHumanReadableCopyright</key>
- <string>Copyright © 2013 Oculus VR. All rights reserved.</string>
- <key>NSMainNibFile</key>
- <string>MainMenu</string>
- <key>NSPrincipalClass</key>
- <string>NSApplication</string>
-</dict>
-</plist>
diff --git a/Mac_OculusWorldDemo.app/Contents/MacOS/OculusWorldDemo b/Mac_OculusWorldDemo.app/Contents/MacOS/OculusWorldDemo
deleted file mode 100644
index b4c9208..0000000
--- a/Mac_OculusWorldDemo.app/Contents/MacOS/OculusWorldDemo
+++ /dev/null
Binary files differ
diff --git a/Mac_OculusWorldDemo.app/Contents/PkgInfo b/Mac_OculusWorldDemo.app/Contents/PkgInfo
deleted file mode 100644
index bd04210..0000000
--- a/Mac_OculusWorldDemo.app/Contents/PkgInfo
+++ /dev/null
@@ -1 +0,0 @@
-APPL???? \ No newline at end of file
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 62a3687..0000000
--- a/Makefile
+++ /dev/null
@@ -1,82 +0,0 @@
-#############################################################################
-#
-# Filename : Makefile
-# Content : Makefile for building linux libovr and OculusWorldDemo
-# Created : 2013
-# Authors : Simon Hallam and Peter Giokaris
-# Copyright : Copyright 2013 OculusVR, Inc. All Rights Reserved
-# Instruction : The g++ compiler and stdndard lib packages need to be
-# installed on the system. Navigate in a shell to the
-# directory where this Makefile is located and enter:
-#
-# make builds the release versions for the
-# current architechture
-# make clean delete intermediate release object files
-# and library and executable
-# make DEBUG=1 builds the debug version for the current
-# architechture
-# make clean DEBUG=1 deletes intermediate debug object files
-# and the library and executable
-#
-# Output : Relative to the directory this Makefile lives in, libraries
-# and executables are built at the following locations
-# depending upon the architechture of the system you are
-# running:
-#
-# ./LibOVR/Lib/Linux/Debug/i386/libovr.a
-# ./LibOVR/Lib/Linux/Debug/x86_64/libovr.a
-# ./LibOVR/Lib/Linux/Release/i386/libovr.a
-# ./LibOVR/Lib/Linux/Release/x86_64/libovr.a
-# ./Samples/OculusWorldDemo/Release/OculusWorldDemo_i386_Release
-# ./Samples/OculusWorldDemo/Release/OculusWorldDemo_x86_64_Release
-# ./Samples/OculusWorldDemo/Release/OculusWorldDemo_i386_Debug
-# ./Samples/OculusWorldDemo/Release/OculusWorldDemo_x86_64_Debug
-#
-#############################################################################
-
-####### Detect system architecture
-
-SYSARCH = i386
-ifeq ($(shell uname -m),x86_64)
-SYSARCH = x86_64
-endif
-
-####### Compiler, tools and options
-
-CXX = g++
-LINK = ar rvs
-DELETEFILE = rm -f
-
-####### Detect debug or release
-
-DEBUG = 0
-ifeq ($(DEBUG), 1)
- RELEASETYPE = Debug
-else
- RELEASETYPE = Release
-endif
-
-####### Paths
-
-LIBOVRPATH = ./LibOVR
-DEMOPATH = ./Samples/OculusWorldDemo
-
-####### Files
-
-LIBOVRTARGET = $(LIBOVRPATH)/Lib/Linux/$(RELEASETYPE)/$(SYSARCH)/libovr.a
-DEMOTARGET = $(DEMOPATH)/Release/OculusWorldDemo_$(RELEASETYPE)/$(SYSARCH)
-
-####### Rules
-
-all: $(LIBOVRTARGET) $(DEMOTARGET)
-
-$(DEMOTARGET): $(DEMOPATH)/Makefile
- $(MAKE) -C $(DEMOPATH) DEBUG=$(DEBUG)
-
-$(LIBOVRTARGET): $(LIBOVRPATH)/Makefile
- $(MAKE) -C $(LIBOVRPATH) DEBUG=$(DEBUG)
-
-clean:
- $(MAKE) -C $(LIBOVRPATH) clean DEBUG=$(DEBUG)
- $(MAKE) -C $(DEMOPATH) clean DEBUG=$(DEBUG)
-
diff --git a/Oculus World Demo.lnk b/Oculus World Demo.lnk
index d846ead..b320d1a 100644
--- a/Oculus World Demo.lnk
+++ b/Oculus World Demo.lnk
Binary files differ
diff --git a/OculusConfigurationUtility.sh b/OculusConfigurationUtility.sh
deleted file mode 100755
index a70d7f6..0000000
--- a/OculusConfigurationUtility.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-#############################################################################
-#
-# Filename : OculusConfigurationUtility.sh
-# Content : Linux file for starting the OculusConfigurationUtility app
-# from the SDK package root. It will determine the
-# architechture of the system it is running on, and start the
-# approprite executable
-# Created : 2013
-# Authors : Simon Hallam
-# Copyright : Copyright 2013 OculusVR, Inc. All Rights Reserved
-# Instruction : Ensure that the OculusConfigurationUtility.sh has execute
-# permissions. Navigate to a command shell, enter:
-#
-# ./OculusConfigurationUtility.sh
-#
-#############################################################################
-
-MACHINE_TYPE=`uname -m`
-if [ ${MACHINE_TYPE} == 'x86_64' ]; then
- ./Tools/OculusConfigUtil/OculusConfigUtil_x86_64
-elif [ ${MACHINE_TYPE} == 'i686' ]; then
- ./Tools/OculusConfigUtil/OculusConfigUtil_i386
-else
- echo "The Oculus Configuration Utility does not currently support this platform."
-fi
-
diff --git a/OculusWorldDemo.sh b/OculusWorldDemo.sh
deleted file mode 100755
index e668c93..0000000
--- a/OculusWorldDemo.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-#############################################################################
-#
-# Filename : OculusWorldDemo.sh
-# Content : Linux file for starting the OculusWorldDemo app from the SDK
-# package root. It will determine the architechture of the
-# system it is running on, and start the approprite executable
-# Created : 2013
-# Authors : Simon Hallam
-# Copyright : Copyright 2013 OculusVR, Inc. All Rights Reserved
-# Instruction : Ensure that the OculusWorldDemo.sh has execute permissions.
-# Navigate to a command shell, enter:
-#
-# ./OculusWorldDemo.sh
-#
-#############################################################################
-
-MACHINE_TYPE=`uname -m`
-if [ ${MACHINE_TYPE} == 'x86_64' ]; then
- ./Samples/OculusWorldDemo/Release/OculusWorldDemo_x86_64_Release
-else
- ./Samples/OculusWorldDemo/Release/OculusWorldDemo_i386_Release
-fi
-
diff --git a/README.md b/README.md
deleted file mode 100644
index e317d65..0000000
--- a/README.md
+++ /dev/null
@@ -1,49 +0,0 @@
-OculusSDK
-=========
-
-Oculus SDK with additional community supported features and bug-fixes.
-
-Goals
------
-
-* Providing new features
- * C bindings
- * Python bindings
- * Java bindings
-* Providing new tools
- * Command line diagnostics for people having trouble with Rift detection
-* Providing new sample code
- * Alternative mechanisms for rendering the Rift distortion
- * Sample code for the non-C++ language bindings
-* Helping developers write better or easier Oculus Rift compatible software
-
-Licensing
----------
-
-All code not explicitly marked with another license is made available under the
-terms of the Oculus SDK license, included in this kit as LICENSE.TXT and
-available online at https://developer.oculusvr.com/license and is Copyright 2013
-Oculus VR, Inc.
-
-Branches
---------
-
-### official
-This branch will track the SDK releases from Oculus VR. It should contain only files that are included in the official
-SDK, as well as the minimal additional files to get it to play well with GitHub. Specifically this README file for the
-uninitiated and a .gitignore file to exclude artifacts from the official SDK that we do not wish to track in GitHub.
-The latter mostly consists of the binary files distributed with the SDK and documentation or any other artifacts
-with unknown or suspect licensing that would prohibit reproduction on GitHub.
-
-### stable
-Contains features that are considered complete and safe to use.
-
-### unstable
-The tip of shared development. Contains features that may not have been merged into stable. Not guaranteed to work
-at any given time.
-
-### feature-XXX
-Feature branches for changes that will require significant time and codebase changes to function, but
-which may be being developed in a team or made available for testing to the general public.
-
-
diff --git a/Samples/CommonSrc/Makefile b/Samples/CommonSrc/Makefile
deleted file mode 100644
index 8c07a2a..0000000
--- a/Samples/CommonSrc/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-
-PLATFORM_SRCS := Samples/CommonSrc/Platform/Platform.cpp Samples/CommonSrc/Platform/X11_Platform.cpp
-
-RENDER_SRCS := Samples/CommonSrc/Render/Render_Device.cpp Samples/CommonSrc/Render/Render_Stereo.cpp \
- Samples/CommonSrc/Render/Render_GL_Device.cpp \
- Samples/CommonSrc/Render/Render_LoadTextureTGA.cpp
-
diff --git a/Samples/CommonSrc/Platform/Gamepad.h b/Samples/CommonSrc/Platform/Gamepad.h
index f32effc..95cff10 100644
--- a/Samples/CommonSrc/Platform/Gamepad.h
+++ b/Samples/CommonSrc/Platform/Gamepad.h
@@ -5,7 +5,7 @@ Content : Cross platform Gamepad interface.
Created : May 6, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -75,7 +75,7 @@ struct GamepadState
{
return !(*this == b);
}
- void Debug()
+ void Debug() const
{
OVR_DEBUG_LOG(("Buttons:0x%4x LX:%.2f LY:%.2f RX:%.2f RY:%.2f LT:%.2f RT:%.2f", Buttons, LX, LY, RX, RY, LT, RT));
}
diff --git a/Samples/CommonSrc/Platform/Linux_Gamepad.cpp b/Samples/CommonSrc/Platform/Linux_Gamepad.cpp
deleted file mode 100644
index 7bca5c5..0000000
--- a/Samples/CommonSrc/Platform/Linux_Gamepad.cpp
+++ /dev/null
@@ -1,453 +0,0 @@
-/************************************************************************************
-
-Filename : Linux_Gamepad.cpp
-Content : Linux implementation of Platform app infrastructure
-Created : May 6, 2013
-Authors : Lee Cooper, Simon Hallam
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <glob.h>
-#include <linux/joystick.h>
-#include "Linux_Gamepad.h"
-
-
-namespace OVR { namespace Platform { namespace Linux {
-
-const char* pNameXbox360Wireless = "Xbox 360";
-const char* pNameXbox360Wired = "Microsoft X-Box 360";
-
-
-GamepadManager::GamepadManager() :
- pDevice(NULL)
-{
-}
-
-GamepadManager::~GamepadManager()
-{
- // if we have an open device, close it
- if (pDevice)
- {
- pDevice->Close();
- pDevice = NULL;
- }
-}
-
-UInt32 GamepadManager::GetGamepadCount()
-{
- return 1;
-}
-
-bool GamepadManager::GetGamepadState(UInt32 index, GamepadState *pState)
-{
- if (!pDevice)
- {
- // get a list of paths to all the connected joystick devices
- glob_t joystickGlobBuffer;
- glob("/dev/input/js*", 0, NULL, &joystickGlobBuffer);
-
- // open each joystick device, until we find one that will work for our needs
- for (UInt32 i = 0; i < joystickGlobBuffer.gl_pathc; i++)
- {
- pDevice = new Gamepad();
- if (pDevice->Open(joystickGlobBuffer.gl_pathv[i]))
- {
-
- if (pDevice->IsSupportedType())
- {
- break;
- }
- }
-
- // we don't know why the device was not useable, make sure it gets closed cleanly
- pDevice->Close();
- pDevice = NULL;
- }
-
- }
-
- if (pDevice)
- {
- // we have a device, so update it
- pDevice->UpdateState();
-
- // copy the device state into the struct param
- memcpy(pState, pDevice->GetState(), sizeof(GamepadState));
-
- // TODO: is the device still active/connected? if not, we should close it
- // and clear pDevice, so that another device can take over
-
- return true;
- }
- else
- {
- return false;
- }
-}
-
-Gamepad::Gamepad() :
- IsInitialized(false),
- Name(String("Undefined")),
- Type(UNDEFINED)
-{
-}
-
-Gamepad::~Gamepad()
-{
- this->Close();
-}
-
-bool Gamepad::Open(const String& devicePathName)
-{
- Name = "Undefined";
- Type = UNDEFINED;
-
- FileDescriptor = ::open(devicePathName.ToCStr(), O_RDONLY | O_NONBLOCK);
- if (FileDescriptor == -1)
- {
- return false;
- }
-
- // get the device name
- char name[128];
- if (ioctl(FileDescriptor, JSIOCGNAME(sizeof(name)), name) < 0)
- {
- return false;
- }
-
- Name = name;
-
- // see if device name matches one of our supported devices
- static const UInt32 Wireless360Len = String(pNameXbox360Wireless).GetLength();
- static const UInt32 Wired360Len = String(pNameXbox360Wired).GetLength();
- if (Name.Substring(0, Wireless360Len) == pNameXbox360Wireless)
- {
- Type = XBOX360GAMEPADWIRELESS;
- return true;
- }
- else if(Name.Substring(0, Wired360Len) == pNameXbox360Wired)
- {
- Type = XBOX360GAMEPADWIRED;
- return true;
- }
-
- return false;
-}
-
-bool Gamepad::Close()
-{
- IsInitialized = false;
- Name = "Undefined";
- Type = UNDEFINED;
- return !::close(FileDescriptor);
-}
-
-void Gamepad::UpdateState()
-{
- GamepadState *pState = &State;
- js_event gamepadEvent;
-
- // read the latest batch of events
- while (read(FileDescriptor, &gamepadEvent, sizeof(struct js_event)) != -1)
- {
- switch (gamepadEvent.type)
- {
- case JS_EVENT_BUTTON:
- IsInitialized = true;
- SetStateButton(pState, gamepadEvent.number, gamepadEvent.value);
- break;
-
- case JS_EVENT_AXIS:
- IsInitialized = true;
- SetStateAxis(pState, gamepadEvent.number, gamepadEvent.value);
- break;
-
- case JS_EVENT_BUTTON | JS_EVENT_INIT:
- if (IsInitialized) // skip the fake values during device event initialization
- {
- SetStateButton(pState, gamepadEvent.number, gamepadEvent.value);
- }
- break;
-
- case JS_EVENT_AXIS | JS_EVENT_INIT:
- if (IsInitialized) // skip the fake values during device event initialization
- {
- SetStateAxis(pState, gamepadEvent.number, gamepadEvent.value);
- }
- break;
-
- default:
- LogText("OVR::Linux::UpdateState unknown event type\n");
- }
- }
-}
-
-const GamepadState* Gamepad::GetState()
-{
- return &State;
-}
-
-
-bool Gamepad::IsSupportedType()
-{
- return Type != UNDEFINED;
-}
-
-const String& Gamepad::GetIdentifier()
-{
- return Name;
-}
-
-static inline float NormalizeGamepadStickXbox360(SInt32 in)
-{
- float v;
- if (abs(in) < 9000) return 0;
- else if (in > 9000) v = (float)in - 9000;
- else v = (float)in + 9000;
- return v / (32767 - 9000);
-}
-
-static inline float NormalizeGamepadTriggerXbox360(SInt32 in,
- SInt32 offset,
- SInt32 deadBand,
- float divisor)
-{
- in += offset;
-
- if (in < deadBand)
- {
- return 0;
- }
- else
- {
- return float(in - deadBand) / divisor;
- }
-}
-
-static inline void UpdateButtonMaskAndBitfield(GamepadState *pState,
- SInt32 value,
- UInt32 buttonBitfield)
-{
- if (value)
- {
- pState->Buttons |= buttonBitfield;
- }
- else
- {
- pState->Buttons = pState->Buttons & (0xFFFFFFFF ^ buttonBitfield);
- }
-}
-
-void Gamepad::SetStateAxis(GamepadState *pState, UInt32 axis, SInt32 value)
-{
- // some pads/sticks have lots in common with one another,
- // handle those shared cases first
- switch (Type)
- {
- case XBOX360GAMEPADWIRELESS:
- case XBOX360GAMEPADWIRED:
- switch (axis)
- {
- case 0:
- pState->LX = NormalizeGamepadStickXbox360(value);
- break;
-
- case 1:
- pState->LY = -NormalizeGamepadStickXbox360(value);
- break;
-
- case 3:
- pState->RX = NormalizeGamepadStickXbox360(value);
- break;
-
- case 4:
- pState->RY = -NormalizeGamepadStickXbox360(value);
- break;
- }
- break;
-
- case UNDEFINED:
- default:
- break;
- }
-
- // handle the special cases, or pads/sticks which are unique
- switch (Type)
- {
- case XBOX360GAMEPADWIRELESS:
- switch (axis)
- {
- case 2:
- pState->LT = NormalizeGamepadTriggerXbox360(value, 0, 500, 32267);
- break;
-
- case 5:
- pState->RT = NormalizeGamepadTriggerXbox360(value, 0, 500, 32267);
- break;
- }
- break;
-
- case XBOX360GAMEPADWIRED:
- switch (axis)
- {
- case 2:
- pState->LT = NormalizeGamepadTriggerXbox360(value, 32767, 1000, 64535);
- break;
-
- case 5:
- pState->RT = NormalizeGamepadTriggerXbox360(value, 32767, 1000, 64535);
- break;
-
- case 6:
- if (value == 0)
- {
- UpdateButtonMaskAndBitfield(pState, 0, Gamepad_Left);
- UpdateButtonMaskAndBitfield(pState, 0, Gamepad_Right);
- }
- else if (value < 0)
- {
- UpdateButtonMaskAndBitfield(pState, 1, Gamepad_Left);
- }
- else if (value > 0)
- {
- UpdateButtonMaskAndBitfield(pState, 1, Gamepad_Right);
- }
- break;
-
- case 7:
- if (value == 0)
- {
- UpdateButtonMaskAndBitfield(pState, 0, Gamepad_Up);
- UpdateButtonMaskAndBitfield(pState, 0, Gamepad_Down);
- }
- else if (value < 0)
- {
- UpdateButtonMaskAndBitfield(pState, 1, Gamepad_Up);
- }
- else if (value > 0)
- {
- UpdateButtonMaskAndBitfield(pState, 1, Gamepad_Down);
- }
- break;
- }
- break;
-
- case UNDEFINED:
- default:
- break;
- }
-}
-
-void Gamepad::SetStateButton(GamepadState *pState, UInt32 button, SInt32 value)
-{
- // some pads/sticks have lots in common with one another,
- // handle those shared cases first
- switch (Type)
- {
- case XBOX360GAMEPADWIRELESS:
- case XBOX360GAMEPADWIRED:
- switch (button)
- {
- case 0:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_A);
- break;
-
- case 1:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_B);
- break;
-
- case 2:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_X);
- break;
-
- case 3:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_Y);
- break;
-
- case 4:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_L1);
- break;
-
- case 5:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_R1);
- break;
-
- case 6:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_Back);
- break;
-
- case 7:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_Start);
- break;
-
- case 8:
- // we have no value defined for the Xbox/power button
- break;
-
- case 9:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_LStick);
- break;
-
- case 10:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_RStick);
- break;
- }
- break;
-
- case UNDEFINED:
- default:
- break;
- }
-
- // handle the special cases, or pads/sticks which are unique
- switch (Type)
- {
- case XBOX360GAMEPADWIRELESS:
- switch (button)
- {
- case 11:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_Left);
- break;
-
- case 12:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_Right);
- break;
-
- case 13:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_Up);
- break;
-
- case 14:
- UpdateButtonMaskAndBitfield(pState, value, Gamepad_Down);
- break;
- }
-
- case XBOX360GAMEPADWIRED:
- break;
-
- case UNDEFINED:
- default:
- break;
- }
-}
-
-}}} // OVR::Platform::Linux
-
diff --git a/Samples/CommonSrc/Platform/Linux_Gamepad.h b/Samples/CommonSrc/Platform/Linux_Gamepad.h
deleted file mode 100644
index ba66e70..0000000
--- a/Samples/CommonSrc/Platform/Linux_Gamepad.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/************************************************************************************
-
-Filename : Linux_Gamepad.h
-Content : Linux implementation of Gamepad functionality.
-Created : May 6, 2013
-Authors : Lee Cooper, Simon Hallam
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#ifndef OVR_Linux_Gamepad_h
-#define OVR_Linux_Gamepad_h
-
-#include "Gamepad.h"
-
-namespace OVR { namespace Platform { namespace Linux {
-
-class Gamepad; // forward declaration for readability
-
-class GamepadManager : public Platform::GamepadManager
-{
-public:
-
- GamepadManager();
- ~GamepadManager();
-
- virtual UInt32 GetGamepadCount();
- virtual bool GetGamepadState(UInt32 index, GamepadState *pState);
-
-private:
-
- Gamepad *pDevice;
-};
-
-class Gamepad
-{
-public:
-
- Gamepad();
- virtual ~Gamepad();
-
- bool Open(const String& devicePathName);
- bool Close();
- bool IsSupportedType();
- const String& GetIdentifier();
- void UpdateState();
- const GamepadState* GetState();
-
-private:
-
- void SetStateAxis(GamepadState *pState, UInt32 axis, SInt32 value);
- void SetStateButton(GamepadState *pState, UInt32 button, SInt32 value);
-
- enum GamepadType
- {
- UNDEFINED,
- XBOX360GAMEPADWIRELESS,
- XBOX360GAMEPADWIRED
- };
-
- UInt32 FileDescriptor;
- bool IsInitialized;
- String Name;
- GamepadType Type;
- GamepadState State;
-};
-
-}}}
-
-#endif // OVR_Linux_Gamepad_h
diff --git a/Samples/CommonSrc/Platform/Linux_Platform.cpp b/Samples/CommonSrc/Platform/Linux_Platform.cpp
deleted file mode 100644
index c9d3e40..0000000
--- a/Samples/CommonSrc/Platform/Linux_Platform.cpp
+++ /dev/null
@@ -1,563 +0,0 @@
-/************************************************************************************
-
-Filename : Platform_Linux.cpp
-Content : Linux (X11) implementation of Platform app infrastructure
-Created : September 6, 2012
-Authors : Andrew Reisse
-
-Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
-
-Use of this software is subject to the terms of the Oculus LLC license
-agreement provided at the time of installation or download, or which
-otherwise accompanies this software in either electronic or hard copy form.
-
-************************************************************************************/
-
-#include "Kernel/OVR_System.h"
-#include "Kernel/OVR_Array.h"
-#include "Kernel/OVR_String.h"
-#include "Kernel/OVR_Timer.h"
-
-#include "Linux_Platform.h"
-#include "Linux_Gamepad.h"
-
-// Renderers
-#include "../Render/Render_GL_Device.h"
-
-#include <X11/extensions/Xinerama.h>
-
-
-namespace OVR { namespace Platform { namespace Linux {
-
-static const char *AtomNames[] = {"WM_PROTOCOLS", "WM_DELETE_WINDOW"};
-
-PlatformCore::PlatformCore(Application* app)
- : Platform::PlatformCore(app), Disp(NULL), Win(0), Vis(NULL), Quit(0), MMode(Mouse_Normal)
-{
- pGamepadManager = *new Linux::GamepadManager();
-}
-PlatformCore::~PlatformCore()
-{
- XFreeCursor(Disp, InvisibleCursor);
-
- if (Disp)
- XCloseDisplay(Disp);
-}
-
-// Setup an X11 window in windowed mode.
-bool PlatformCore::SetupWindow(int w, int h)
-{
-
- if (!Disp)
- {
- XInitThreads();
-
- Disp = XOpenDisplay(NULL);
- if (!Disp)
- {
- OVR_DEBUG_LOG(("XOpenDisplay failed."));
- return false;
- }
-
- XInternAtoms(Disp, const_cast<char**>(AtomNames), NumAtoms, false, Atoms);
- }
-
- XSetWindowAttributes winattr;
- unsigned attrmask = CWEventMask | CWBorderPixel;
-
- winattr.event_mask = ButtonPressMask|ButtonReleaseMask|KeyPressMask|KeyReleaseMask|ButtonMotionMask|PointerMotionMask|
- /*PointerMotionHintMask|*/StructureNotifyMask;//|ExposureMask;
- winattr.border_pixel = 0;
-
- int screenNumber = DefaultScreen(Disp);
-
- if (!Vis)
- {
- int attr[16];
- int nattr = 2;
-
- attr[0] = GLX_RGBA;
- attr[1] = GLX_DOUBLEBUFFER;
- attr[nattr++] = GLX_DEPTH_SIZE;
- attr[nattr++] = 24;
- attr[nattr] = 0;
-
- Vis = glXChooseVisual(Disp, screenNumber, attr);
-
- if (!Vis)
- {
- OVR_DEBUG_LOG(("glXChooseVisual failed."));
- return false;
- }
- }
-
- Window rootWindow = XRootWindow(Disp, Vis->screen);
-
- winattr.colormap = XCreateColormap(Disp, rootWindow, Vis->visual, AllocNone);
- attrmask |= CWColormap;
-
-
- Win = XCreateWindow(Disp, rootWindow, 0, 0, w, h, 0, Vis->depth,
- InputOutput, Vis->visual, attrmask, &winattr);
-
- if (!Win)
- {
- OVR_DEBUG_LOG(("XCreateWindow failed."));
- return false;
- }
-
-
- XStoreName(Disp, Win, "OVR App");
- XSetWMProtocols(Disp, Win, &Atoms[WM_DELETE_WINDOW], 1);
-
- // Intialize empty cursor for show/hide.
- XColor black;
- static char noData[] = { 0,0,0,0,0,0,0,0 };
- black.red = black.green = black.blue = 0;
-
- Pixmap bitmapNoData = XCreateBitmapFromData(Disp, Win, noData, 8, 8);
- InvisibleCursor = XCreatePixmapCursor(Disp, bitmapNoData, bitmapNoData,
- &black, &black, 0, 0);
- XDefineCursor(Disp, Win, InvisibleCursor);
-
- Width = w;
- Height = h;
-
- return true;
-}
-
-void PlatformCore::SetMouseMode(MouseMode mm)
-{
- if (mm == MMode)
- return;
-
- if (Win)
- {
- if (mm == Mouse_Relative)
- {
- XWarpPointer(Disp, Win, Win, 0,0,Width,Height, Width/2, Height/2);
- }
- else
- {
- //if (MMode == Mouse_Relative)
- // ShowCursor(TRUE);
- }
- }
- MMode = mm;
-}
-
-void PlatformCore::GetWindowSize(int* w, int* h) const
-{
- *w = Width;
- *h = Height;
-}
-
-void PlatformCore::SetWindowTitle(const char* title)
-{
- XStoreName(Disp, Win, title);
-}
-
-void PlatformCore::ShowWindow(bool show)
-{
- if (show)
- XRaiseWindow(Disp, Win);
- else
- XIconifyWindow(Disp, Win, 0);
-}
-
-void PlatformCore::DestroyWindow()
-{
- if (Win)
- XDestroyWindow(Disp, Win);
- Win = 0;
-}
-
-
-static int KeyMap[][2] =
-{
- { XK_BackSpace, Key_Backspace },
- { XK_Tab, Key_Tab },
- { XK_Clear, Key_Clear },
- { XK_Return, Key_Return },
- { XK_Shift_L, Key_Shift },
- { XK_Control_L, Key_Control },
- { XK_Alt_L, Key_Alt },
- { XK_Shift_R, Key_Shift },
- { XK_Control_R, Key_Control },
- { XK_Alt_R, Key_Alt },
- { XK_Pause, Key_Pause },
- { XK_Caps_Lock, Key_CapsLock },
- { XK_Escape, Key_Escape },
- { XK_space, Key_Space },
- { XK_Page_Up, Key_PageUp },
- { XK_Page_Down, Key_PageDown },
- { XK_Prior, Key_PageUp },
- { XK_Next, Key_PageDown },
- { XK_End, Key_End },
- { XK_Home, Key_Home },
- { XK_Left, Key_Left },
- { XK_Up, Key_Up },
- { XK_Right, Key_Right },
- { XK_Down, Key_Down },
- { XK_Insert, Key_Insert },
- { XK_Delete, Key_Delete },
- { XK_Help, Key_Help },
- { XK_Num_Lock, Key_NumLock },
- { XK_Scroll_Lock, Key_ScrollLock },
-};
-
-
-static KeyCode MapXKToKeyCode(unsigned vk)
-{
- unsigned key = Key_None;
-
- if ((vk >= 'a') && (vk <= 'z'))
- {
- key = vk - 'a' + Key_A;
- }
- else if ((vk >= ' ') && (vk <= '~'))
- {
- key = vk;
- }
- else if ((vk >= XK_KP_0) && (vk <= XK_KP_9))
- {
- key = vk - XK_KP_0 + Key_KP_0;
- }
- else if ((vk >= XK_F1) && (vk <= XK_F15))
- {
- key = vk - XK_F1 + Key_F1;
- }
- else
- {
- for (unsigned i = 0; i< (sizeof(KeyMap) / sizeof(KeyMap[1])); i++)
- {
- if (vk == KeyMap[i][0])
- {
- key = KeyMap[i][1];
- break;
- }
- }
- }
-
- return (KeyCode)key;
-}
-
-static int MapModifiers(int xmod)
-{
- int mod = 0;
- if (xmod & ShiftMask)
- mod |= Mod_Shift;
- if (xmod & ControlMask)
- mod |= Mod_Control;
- if (xmod & Mod1Mask)
- mod |= Mod_Alt;
- if (xmod & Mod4Mask)
- mod |= Mod_Meta;
- return mod;
-}
-
-void PlatformCore::processEvent(XEvent& event)
-{
- switch (event.xany.type)
- {
- case ConfigureNotify:
- if (event.xconfigure.width != Width || event.xconfigure.height != Height)
- {
- Width = event.xconfigure.width;
- Height = event.xconfigure.height;
- pApp->OnResize(Width, Height);
-
- if (pRender)
- pRender->SetWindowSize(Width, Height);
- }
- break;
-
- case KeyPress:
- case KeyRelease:
- {
- char chars[8] = {0};
- KeySym xk;
- XComposeStatus comp;
- XLookupString(&event.xkey, chars, sizeof(chars), &xk, &comp);
- if (xk != XK_VoidSymbol)
- pApp->OnKey(MapXKToKeyCode((unsigned)xk), chars[0], event.xany.type == KeyPress, MapModifiers(event.xkey.state));
- if (xk == XK_Escape && MMode == Mouse_Relative)
- {
- //ungrab
- MMode = Mouse_RelativeEscaped;
- showCursor(true);
- }
- }
- break;
-
- case MotionNotify:
- if (MMode == Mouse_Relative)
- {
- int dx = event.xmotion.x - Width/2;
- int dy = event.xmotion.y - Height/2;
-
- // do not remove this check, WarpPointer generates events too.
- if (dx == 0 && dy == 0)
- break;
-
- XWarpPointer(Disp, Win, Win, 0,0,Width,Height, Width/2, Height/2);
- pApp->OnMouseMove(dx, dy, Mod_MouseRelative|MapModifiers(event.xmotion.state));
- }
- else
- {
- pApp->OnMouseMove(event.xmotion.x, event.xmotion.y, MapModifiers(event.xmotion.state));
- }
- break;
-
- case MapNotify:
- if (MMode == Mouse_Relative)
- {
- XWarpPointer(Disp, Win, Win, 0,0,Width,Height, Width/2, Height/2);
- showCursor(false);
- }
- break;
-
- case ButtonPress:
- if (event.xbutton.button == 1)
- {
- //grab
-
- if (MMode == Mouse_RelativeEscaped)
- {
- XWarpPointer(Disp, Win, Win, 0,0,Width,Height, Width/2, Height/2);
- showCursor(false);
- MMode = Mouse_Relative;
- }
- }
- break;
-
- case FocusOut:
- if (MMode == Mouse_Relative)
- {
- MMode = Mouse_RelativeEscaped;
- showCursor(true);
- }
- break;
-
- case ClientMessage:
- if (event.xclient.message_type == Atoms[WM_PROTOCOLS] &&
- Atom(event.xclient.data.l[0]) == Atoms[WM_DELETE_WINDOW])
- pApp->OnQuitRequest();
- break;
- }
-}
-
-int PlatformCore::Run()
-{
- while (!Quit)
- {
- if (XPending(Disp))
- {
- XEvent event;
- XNextEvent(Disp, &event);
-
- if (pApp && event.xany.window == Win)
- processEvent(event);
- }
- else
- {
- pApp->OnIdle();
- }
- }
-
- return ExitCode;
-}
-
-bool PlatformCore::determineScreenOffset(int screenId, int* screenOffsetX, int* screenOffsetY)
-{
- Display* display = XOpenDisplay(NULL);
-
- bool foundScreen = false;
-
- if (display)
- {
- int numberOfScreens;
- XineramaScreenInfo* screens = XineramaQueryScreens(display, &numberOfScreens);
-
- if (screenId < numberOfScreens)
- {
- XineramaScreenInfo screenInfo = screens[screenId];
- *screenOffsetX = screenInfo.x_org;
- *screenOffsetY = screenInfo.y_org;
-
- foundScreen = true;
- }
-
- XFree(screens);
- }
-
- return foundScreen;
-}
-
-void PlatformCore::showWindowDecorations(bool show)
-{
- // Declaration of 'MOTIF_WM_HINTS' struct and flags can be found at:
- // https://people.gnome.org/~tthurman/docs/metacity/xprops_8h-source.html
- typedef struct WMHints
- {
- unsigned long flags;
- unsigned long functions;
- unsigned long decorations;
- long inputMode;
- unsigned long status;
- } Hints;
-
- #define MWM_DECOR_ALL (1L << 0)
- #define MWM_DECOR_BORDER (1L << 1)
- #define MWM_DECOR_RESIZEH (1L << 2)
- #define MWM_DECOR_TITLE (1L << 3)
- #define MWM_DECOR_MENU (1L << 4)
- #define MWM_DECOR_MINIMIZE (1L << 5)
- #define MWM_DECOR_MAXIMIZE (1L << 6)
-
- Atom property = XInternAtom(Disp, "_MOTIF_WM_HINTS", true);
-
- Hints hints;
- hints.flags = 2; // We only want to specify decoration.
-
- if (show)
- {
- hints.decorations = MWM_DECOR_BORDER | MWM_DECOR_TITLE | MWM_DECOR_MENU | MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE;
- }
- else
- {
- // Remove all window border items.
- hints.decorations = 0;
- }
-
- XChangeProperty(Disp,Win,property,property,32,PropModeReplace,(unsigned char *)&hints,5);
-}
-
-bool PlatformCore::SetFullscreen(const Render::RendererParams& rp, int fullscreen)
-{
- if (rp.Fullscreen == Render::Display_Window && fullscreen == Render::Display_FakeFullscreen)
- {
- // Transitioning from windowed to fake fullscreen.
- int xOffset;
- int yOffset;
-
- if (!determineScreenOffset(rp.Display.CgDisplayId, &xOffset, &yOffset))
- {
- return false;
- }
-
- showWindowDecorations(false);
-
- XMoveWindow(Disp, Win, xOffset, yOffset);
- XMapRaised(Disp, Win);
-
- Platform::PlatformCore::SetFullscreen(rp, fullscreen);
- return true;
- }
- else if (rp.Fullscreen == Render::Display_FakeFullscreen && fullscreen == Render::Display_Window)
- {
- // Transitioning from fake fullscreen to windowed.
- showWindowDecorations(true);
-
- XMoveWindow(Disp, Win, 0, 0);
- XMapRaised(Disp, Win);
-
- Platform::PlatformCore::SetFullscreen(rp, fullscreen);
- return true;
- }
- else if (fullscreen == Render::Display_Fullscreen)
- {
- return false;
- }
-}
-
-RenderDevice* PlatformCore::SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc,
- const char* type, const Render::RendererParams& rp)
-{
- const SetupGraphicsDeviceSet* setupDesc = setupGraphicsDesc.PickSetupDevice(type);
- OVR_ASSERT(setupDesc);
-
- pRender = *setupDesc->pCreateDevice(rp, this);
- if (pRender)
- pRender->SetWindowSize(Width, Height);
-
- return pRender.GetPtr();
-}
-
-void PlatformCore::showCursor(bool show)
-{
- if (show)
- {
- XUndefineCursor(Disp, Win);
- }
- else
- {
- XDefineCursor(Disp, Win, InvisibleCursor);
- }
-}
-
-}}
-
-// GL
-namespace Render { namespace GL { namespace Linux {
-
-Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* oswnd)
-{
- Platform::Linux::PlatformCore* PC = (Platform::Linux::PlatformCore*)oswnd;
-
- GLXContext context = glXCreateContext(PC->Disp, PC->Vis, 0, GL_TRUE);
-
- if (!context)
- return NULL;
-
- if (!glXMakeCurrent(PC->Disp, PC->Win, context))
- {
- glXDestroyContext(PC->Disp, context);
- return NULL;
- }
-
- XMapRaised(PC->Disp, PC->Win);
-
- return new Render::GL::Linux::RenderDevice(rp, PC->Disp, PC->Win, context);
-}
-
-void RenderDevice::Present()
-{
- glXSwapBuffers(Disp, Win);
-}
-
-void RenderDevice::Shutdown()
-{
- if (Context)
- {
- glXMakeCurrent(Disp, 0, NULL);
- glXDestroyContext(Disp, Context);
- Context = NULL;
- Win = 0;
- }
-}
-
-}}}}
-
-
-int main(int argc, const char* argv[])
-{
- using namespace OVR;
- using namespace OVR::Platform;
-
- // CreateApplication must be the first call since it does OVR::System::Initialize.
- Application* app = Application::CreateApplication();
- Linux::PlatformCore* platform = new Linux::PlatformCore(app);
- // The platform attached to an app will be deleted by DestroyApplication.
- app->SetPlatformCore(platform);
-
- int exitCode = app->OnStartup(argc, argv);
- if (!exitCode)
- exitCode = platform->Run();
-
- // No OVR functions involving memory are allowed after this.
- Application::DestroyApplication(app);
- app = 0;
-
- return exitCode;
-}
diff --git a/Samples/CommonSrc/Platform/Linux_Platform.h b/Samples/CommonSrc/Platform/Linux_Platform.h
deleted file mode 100644
index 7fbb220..0000000
--- a/Samples/CommonSrc/Platform/Linux_Platform.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/************************************************************************************
-
-Filename : Platform_Linux.h
-Content : Linux (X11) implementation of Platform app infrastructure
-Created : September 6, 2012
-Authors : Andrew Reisse
-
-Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
-
-Use of this software is subject to the terms of the Oculus LLC 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_Platform_Linux_h
-#define OVR_Platform_Linux_h
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <GL/glx.h>
-
-#include "Platform.h"
-#include "../Render/Render_GL_Device.h"
-
-namespace OVR { namespace Render {
- class RenderDevice;
-}}
-
-namespace OVR { namespace Platform { namespace Linux {
-
-class PlatformCore : public Platform::PlatformCore
-{
-public:
- Display* Disp;
- XVisualInfo* Vis;
- Window Win;
-
- bool Quit;
- int ExitCode;
- int Width, Height;
-
- MouseMode MMode;
- Cursor InvisibleCursor;
-
- enum
- {
- WM_PROTOCOLS,
- WM_DELETE_WINDOW,
- NumAtoms
- };
- Atom Atoms[NumAtoms];
-
- void processEvent(XEvent& event);
-
- Render::RenderDevice* SetupGraphics_GL(const Render::RendererParams& rp);
-
- void showCursor(bool show);
- bool determineScreenOffset(int screenId, int* screenOffsetX, int* screenOffsetY);
- void showWindowDecorations(bool show);
-
-public:
- PlatformCore(Application* app);
- ~PlatformCore();
-
- bool SetupWindow(int w, int h);
- void Exit(int exitcode) { Quit = 1; ExitCode = exitcode; }
-
- RenderDevice* SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc,
- const char* gtype, const Render::RendererParams& rp);
-
- void SetMouseMode(MouseMode mm);
- void GetWindowSize(int* w, int* h) const;
-
- void SetWindowTitle(const char*title);
-
- void ShowWindow(bool show);
- void DestroyWindow();
- bool SetFullscreen(const Render::RendererParams& rp, int fullscreen);
- int Run();
-};
-
-}}
-namespace Render { namespace GL { namespace Linux {
-
-class RenderDevice : public Render::GL::RenderDevice
-{
- Display* Disp;
- Window Win;
- GLXContext Context;
-
-public:
- RenderDevice(const Render::RendererParams& p, Display* disp, Window w, GLXContext gl)
- : GL::RenderDevice(p), Disp(disp), Win(w), Context(gl) {}
-
- virtual void Shutdown();
- virtual void Present();
-
- // oswnd = Linux::PlatformCore*
- static Render::RenderDevice* CreateDevice(const RendererParams& rp, void* oswnd);
-};
-
-}}}}
-
-
-// OVR_PLATFORM_APP_ARGS specifies the Application class to use for startup,
-// providing it with startup arguments.
-#define OVR_PLATFORM_APP_ARGS(AppClass, args) \
- OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \
- { OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); \
- return new AppClass args; } \
- void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \
- { OVR::Platform::PlatformCore* platform = app->pPlatform; \
- delete app; delete platform; OVR::System::Destroy(); };
-
-// OVR_PLATFORM_APP_ARGS specifies the Application startup class with no args.
-#define OVR_PLATFORM_APP(AppClass) OVR_PLATFORM_APP_ARGS(AppClass, ())
-
-
-#endif
diff --git a/Samples/CommonSrc/Platform/OSX_Gamepad.cpp b/Samples/CommonSrc/Platform/OSX_Gamepad.cpp
deleted file mode 100644
index 934319b..0000000
--- a/Samples/CommonSrc/Platform/OSX_Gamepad.cpp
+++ /dev/null
@@ -1,424 +0,0 @@
-/************************************************************************************
-
-Filename : OSX_Gamepad.cpp
-Content : OSX implementation of Gamepad functionality.
-Created : May 6, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#include "OSX_Gamepad.h"
-
-
-static const UInt32 Logitech_F710_VendorID = 0x046D;
-static const UInt32 Logitech_F710_ProductID = 0xC219;
-
-static const UInt32 Sony_DualShock3_VendorID = 0x054C;
-static const UInt32 Sony_DualShock3_ProductID = 0x0268;
-
-
-namespace OVR { namespace Platform { namespace OSX {
-
-
-GamepadManager::GamepadManager()
- : bStateChanged(false)
-{
-
- HidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
- IOHIDManagerOpen(HidManager, kIOHIDOptionsTypeNone);
- IOHIDManagerScheduleWithRunLoop(HidManager,
- CFRunLoopGetCurrent(),
- kCFRunLoopDefaultMode);
-
-
- // Setup device matching.
- CFStringRef keys[] = { CFSTR(kIOHIDDeviceUsagePageKey),
- CFSTR(kIOHIDDeviceUsageKey)};
-
- int value;
- CFNumberRef values[2];
- CFDictionaryRef dictionaries[2];
-
- // Match joysticks.
- value = kHIDPage_GenericDesktop;
- values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-
- value = kHIDUsage_GD_Joystick;
- values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-
- dictionaries[0] = CFDictionaryCreate(kCFAllocatorDefault,
- (const void **) keys,
- (const void **) values,
- 2,
- &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CFRelease(values[0]);
- CFRelease(values[1]);
-
- // Match gamepads.
- value = kHIDPage_GenericDesktop;
- values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-
- value = kHIDUsage_GD_GamePad;
- values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
-
- dictionaries[1] = CFDictionaryCreate(kCFAllocatorDefault,
- (const void **) keys,
- (const void **) values,
- 2,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- CFRelease(values[0]);
- CFRelease(values[1]);
-
- CFArrayRef array = CFArrayCreate( kCFAllocatorDefault,
- (const void **) dictionaries,
- 2,
- &kCFTypeArrayCallBacks);
- CFRelease(dictionaries[0]);
- CFRelease(dictionaries[1]);
-
- IOHIDManagerSetDeviceMatchingMultiple(HidManager, array);
-
- CFRelease(array);
-
-
- IOHIDManagerRegisterDeviceMatchingCallback(HidManager, staticOnDeviceMatched, this);
- IOHIDManagerRegisterDeviceRemovalCallback(HidManager, staticOnDeviceRemoved, this);
-
-}
-
-GamepadManager::~GamepadManager()
-{
- CFRelease(HidManager);
-}
-
-UInt32 GamepadManager::GetGamepadCount()
-{
- return 1;
-}
-
-bool GamepadManager::GetGamepadState(UInt32 index, GamepadState* pState)
-{
- // For now we just support one gamepad.
- OVR_UNUSED(index);
-
- if (!bStateChanged)
- {
- return false;
- }
-
- bStateChanged = false;
-// State.Debug();
-
- *pState = State;
- return true;
-}
-
-int GamepadManager::getIntDeviceProperty(IOHIDDeviceRef device, CFStringRef key)
-{
- CFTypeRef type = IOHIDDeviceGetProperty(device, key);
- OVR_ASSERT(type != NULL && CFGetTypeID(type) == CFNumberGetTypeID());
-
- int value;
- CFNumberGetValue((CFNumberRef) type, kCFNumberSInt32Type, &value);
-
- return value;
-}
-
-void GamepadManager::staticOnDeviceMatched(void* context, IOReturn result, void* sender, IOHIDDeviceRef device)
-{
- GamepadManager* pManager = (GamepadManager*) context;
- pManager->onDeviceMatched(device);
-}
-
-void GamepadManager::onDeviceMatched(IOHIDDeviceRef device)
-{
- IOHIDDeviceRegisterInputValueCallback(device, staticOnDeviceValueChanged, this);
-}
-
-void GamepadManager::staticOnDeviceRemoved(void* context, IOReturn result, void* sender, IOHIDDeviceRef device)
-{
- GamepadManager* pManager = (GamepadManager*) context;
- pManager->onDeviceRemoved(device);
-}
-
-void GamepadManager::onDeviceRemoved(IOHIDDeviceRef device)
-{
- IOHIDDeviceRegisterInputValueCallback(device, NULL, NULL);
-}
-
-void GamepadManager::staticOnDeviceValueChanged(void* context, IOReturn result, void* sender, IOHIDValueRef value)
-{
- GamepadManager* pManager = (GamepadManager*) context;
- pManager->onDeviceValueChanged(value);
-}
-
-float GamepadManager::mapAnalogAxis(IOHIDValueRef value, IOHIDElementRef element)
-{
-
- CFIndex val = IOHIDValueGetIntegerValue(value);
- CFIndex min = IOHIDElementGetLogicalMin(element);
- CFIndex max = IOHIDElementGetLogicalMax(element);
-
- float v = (float) (val - min) / (float) (max - min);
- v = v * 2.0f - 1.0f;
-
- // Dead zone.
- if (v < 0.1f && v > -0.1f)
- {
- v = 0.0f;
- }
-
- return v;
-}
-
-bool GamepadManager::setStateIfDifferent(float& state, float newState)
-{
- if (state == newState)
- return false;
-
- state = newState;
-
- return true;
-}
-
-void GamepadManager::onDeviceValueChanged(IOHIDValueRef value)
-{
-
- IOHIDElementRef element = IOHIDValueGetElement(value);
- IOHIDDeviceRef device = IOHIDElementGetDevice(element);
-
- int vendorID = getIntDeviceProperty(device, CFSTR(kIOHIDVendorIDKey));
- int productID = getIntDeviceProperty(device, CFSTR(kIOHIDProductIDKey));
- OVR_UNUSED(productID);
-
- uint32_t usagePage = IOHIDElementGetUsagePage(element);
- uint32_t usage = IOHIDElementGetUsage(element);
-
- // The following controller mapping is based on the Logitech F710, however we use it for
- // all Logitech devices on the assumption that they're likely to share the same mapping.
- if (vendorID == Logitech_F710_VendorID)
- {
- // Logitech F710 mapping.
- if (usagePage == kHIDPage_Button)
- {
- bool buttonState = IOHIDValueGetIntegerValue(value);
-
- switch(usage)
- {
- case kHIDUsage_Button_1:
- manipulateBitField(State.Buttons, Gamepad_X, buttonState);
- break;
- case kHIDUsage_Button_2:
- manipulateBitField(State.Buttons, Gamepad_A, buttonState);
- break;
- case kHIDUsage_Button_3:
- manipulateBitField(State.Buttons, Gamepad_B, buttonState);
- break;
- case kHIDUsage_Button_4:
- manipulateBitField(State.Buttons, Gamepad_Y, buttonState);
- break;
- case 0x05:
- manipulateBitField(State.Buttons, Gamepad_L1, buttonState);
- break;
- case 0x06:
- manipulateBitField(State.Buttons, Gamepad_R1, buttonState);
- break;
- case 0x07:
- State.LT = buttonState ? 1.0f:0.0f;
- break;
- case 0x08:
- State.RT = buttonState ? 1.0f:0.0f;
- break;
- case 0x09:
- manipulateBitField(State.Buttons, Gamepad_Back, buttonState);
- break;
- case 0x0A:
- manipulateBitField(State.Buttons, Gamepad_Start, buttonState);
- break;
- case 0x0B:
- manipulateBitField(State.Buttons, Gamepad_LStick, buttonState);
- break;
- case 0x0C:
- manipulateBitField(State.Buttons, Gamepad_RStick, buttonState);
- break;
- default:
- return;
- }
- }
- else if (usagePage == kHIDPage_GenericDesktop)
- {
- float v;
- switch(usage)
- {
- case kHIDUsage_GD_X:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.LX, v))
- return;
- break;
- case kHIDUsage_GD_Y:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.LY, -v))
- return;
- break;
- case kHIDUsage_GD_Z:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.RX, v))
- return;
- break;
- case kHIDUsage_GD_Rz:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.RY, -v))
- return;
- break;
- case kHIDUsage_GD_Hatswitch:
- {
- CFIndex integerValue = IOHIDValueGetIntegerValue(value);
-
- manipulateBitField(State.Buttons,
- Gamepad_Up,
- integerValue == 7 || integerValue == 0 || integerValue == 1);
- manipulateBitField(State.Buttons,
- Gamepad_Down,
- integerValue == 3 || integerValue == 4 || integerValue == 5);
- manipulateBitField(State.Buttons,
- Gamepad_Left,
- integerValue == 5 || integerValue == 6 || integerValue == 7);
- manipulateBitField(State.Buttons,
- Gamepad_Right,
- integerValue == 1 || integerValue == 2 || integerValue == 3);
- }
- break;
- default:
- return;
- }
- }
- }
- // The following controller mapping is based on the Sony DualShock3, however we use it for
- // all Sony devices on the assumption that they're likely to share the same mapping.
- else if (vendorID == Sony_DualShock3_VendorID)
- {
- // PS3 Controller.
- if (usagePage == kHIDPage_Button)
- {
- bool buttonState = IOHIDValueGetIntegerValue(value);
-
- switch(usage)
- {
- case kHIDUsage_Button_1:
- manipulateBitField(State.Buttons, Gamepad_Back, buttonState);
- break;
- case kHIDUsage_Button_2:
- manipulateBitField(State.Buttons, Gamepad_LStick, buttonState);
- break;
- case kHIDUsage_Button_3:
- manipulateBitField(State.Buttons, Gamepad_RStick, buttonState);
- break;
- case kHIDUsage_Button_4:
- manipulateBitField(State.Buttons, Gamepad_Start, buttonState);
- break;
- case 0x05:
- manipulateBitField(State.Buttons, Gamepad_Up, buttonState);
- break;
- case 0x06:
- manipulateBitField(State.Buttons, Gamepad_Right, buttonState);
- break;
- case 0x07:
- manipulateBitField(State.Buttons, Gamepad_Down, buttonState);
- break;
- case 0x08:
- manipulateBitField(State.Buttons, Gamepad_Left, buttonState);
- break;
- case 0x09:
- State.LT = buttonState ? 1.0f:0.0f;
- break;
- case 0x0A:
- State.RT = buttonState ? 1.0f:0.0f;
- break;
- case 0x0B:
- manipulateBitField(State.Buttons, Gamepad_L1, buttonState);
- break;
- case 0x0C:
- manipulateBitField(State.Buttons, Gamepad_R1, buttonState);
- break;
- case 0x0D:
- // PS3 Triangle.
- manipulateBitField(State.Buttons, Gamepad_TRIANGLE, buttonState);
- break;
- case 0x0E:
- // PS3 Circle
- manipulateBitField(State.Buttons, Gamepad_CIRCLE, buttonState);
- break;
- case 0x0F:
- // PS3 Cross
- manipulateBitField(State.Buttons, Gamepad_CROSS, buttonState);
- break;
- case 0x10:
- // PS3 Square
- manipulateBitField(State.Buttons, Gamepad_SQUARE, buttonState);
- break;
- default:
- return;
- }
- }
- else if (usagePage == kHIDPage_GenericDesktop)
- {
- float v;
- switch(usage)
- {
- case kHIDUsage_GD_X:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.LX, v))
- return;
- break;
- case kHIDUsage_GD_Y:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.LY, -v))
- return;
- break;
- case kHIDUsage_GD_Z:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.RX, v))
- return;
- break;
- case kHIDUsage_GD_Rz:
- v = mapAnalogAxis(value, element);
- if (!setStateIfDifferent(State.RY, -v))
- return;
- break;
- default:
- return;
- }
- }
- }
-
- bStateChanged = true;
-}
-
-void GamepadManager::manipulateBitField(unsigned int& bitfield, unsigned int mask, bool val)
-{
- if (val)
- {
- bitfield |= mask;
- }
- else
- {
- bitfield &= ~mask;
- }
-}
-
-}}} // OVR::Platform::OSX
diff --git a/Samples/CommonSrc/Platform/OSX_Gamepad.h b/Samples/CommonSrc/Platform/OSX_Gamepad.h
deleted file mode 100644
index 335a512..0000000
--- a/Samples/CommonSrc/Platform/OSX_Gamepad.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/************************************************************************************
-
-Filename : OSX_Gamepad.h
-Content : OSX implementation of Gamepad functionality.
-Created : May 6, 2013
-Authors : Lee Cooper
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#ifndef OVR_OSX_Gamepad_h
-#define OVR_OSX_Gamepad_h
-
-#include <IOKit/IOKitLib.h>
-#include <IOKit/hid/IOHIDManager.h>
-
-#include "Gamepad.h"
-
-namespace OVR { namespace Platform { namespace OSX {
-
-
-class GamepadManager : public Platform::GamepadManager
-{
-public:
- GamepadManager();
- ~GamepadManager();
-
- virtual UInt32 GetGamepadCount();
- virtual bool GetGamepadState(UInt32 index, GamepadState* pState);
-
-private:
- static void staticOnDeviceMatched(void* context, IOReturn result, void* sender, IOHIDDeviceRef device);
- void onDeviceMatched(IOHIDDeviceRef device);
-
- static void staticOnDeviceRemoved(void* context, IOReturn result, void* sender, IOHIDDeviceRef device);
- void onDeviceRemoved(IOHIDDeviceRef device);
-
- static void staticOnDeviceValueChanged(void* context, IOReturn result, void* sender, IOHIDValueRef value);
- void onDeviceValueChanged(IOHIDValueRef value);
-
- int getIntDeviceProperty(IOHIDDeviceRef device, CFStringRef key);
- float mapAnalogAxis(IOHIDValueRef value, IOHIDElementRef element);
- void manipulateBitField(unsigned int& bitfield, unsigned int mask, bool val);
- bool setStateIfDifferent(float& state, float newState);
-
- IOHIDManagerRef HidManager;
- GamepadState State;
- bool bStateChanged;
-};
-
-}}}
-
-#endif // OVR_OSX_Gamepad_h
diff --git a/Samples/CommonSrc/Platform/OSX_Platform.h b/Samples/CommonSrc/Platform/OSX_Platform.h
deleted file mode 100644
index 11d4279..0000000
--- a/Samples/CommonSrc/Platform/OSX_Platform.h
+++ /dev/null
@@ -1,80 +0,0 @@
-
-#include "../Platform/Platform.h"
-#include "../Render/Render_GL_Device.h"
-
-namespace OVR { namespace Platform { namespace OSX {
-
-class PlatformCore : public Platform::PlatformCore
-{
-public:
- void* Win;
- void* View;
- void* NsApp;
- bool Quit;
- int ExitCode;
- int Width, Height;
- MouseMode MMode;
-
- void RunIdle();
-
-public:
- PlatformCore(Application* app, void* nsapp);
- ~PlatformCore();
-
- bool SetupWindow(int w, int h);
- void Exit(int exitcode);
-
- RenderDevice* SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc,
- const char* gtype, const Render::RendererParams& rp);
-
- void SetMouseMode(MouseMode mm);
- void GetWindowSize(int* w, int* h) const;
-
- void SetWindowTitle(const char*title);
-
- void ShowWindow(bool show);
- void DestroyWindow();
- bool SetFullscreen(const Render::RendererParams& rp, int fullscreen);
- int GetDisplayCount();
- Render::DisplayId GetDisplay(int screen);
-
- String GetContentDirectory() const;
-};
-
-}}
-namespace Render { namespace GL { namespace OSX {
-
-class RenderDevice : public Render::GL::RenderDevice
-{
-public:
- void* Context;
-
- RenderDevice(const Render::RendererParams& p, void* context)
- : GL::RenderDevice(p), Context(context) {}
-
- virtual void Shutdown();
- virtual void Present();
-
- virtual bool SetFullscreen(DisplayMode fullscreen);
-
- // oswnd = X11::PlatformCore*
- static Render::RenderDevice* CreateDevice(const RendererParams& rp, void* oswnd);
-};
-
-}}}}
-
-
-// OVR_PLATFORM_APP_ARGS specifies the Application class to use for startup,
-// providing it with startup arguments.
-#define OVR_PLATFORM_APP_ARGS(AppClass, args) \
-OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \
-{ OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); \
-return new AppClass args; } \
-void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \
-{ OVR::Platform::PlatformCore* platform = app->pPlatform; \
-delete app; delete platform; OVR::System::Destroy(); };
-
-// OVR_PLATFORM_APP_ARGS specifies the Application startup class with no args.
-#define OVR_PLATFORM_APP(AppClass) OVR_PLATFORM_APP_ARGS(AppClass, ())
-
-
diff --git a/Samples/CommonSrc/Platform/OSX_Platform.mm b/Samples/CommonSrc/Platform/OSX_Platform.mm
deleted file mode 100644
index 491ff6c..0000000
--- a/Samples/CommonSrc/Platform/OSX_Platform.mm
+++ /dev/null
@@ -1,514 +0,0 @@
-
-#import "../Platform/OSX_PlatformObjc.h"
-
-using namespace OVR;
-using namespace OVR::Platform;
-
-@implementation OVRApp
-
-- (void)dealloc
-{
- [super dealloc];
-}
-
-- (void)run
-{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- _running = YES;
- OVR::Platform::Application* app;
- {
- using namespace OVR;
- using namespace OVR::Platform;
-
- // CreateApplication must be the first call since it does OVR::System::Initialize.
- app = Application::CreateApplication();
- OSX::PlatformCore* platform = new OSX::PlatformCore(app, self);
- // The platform attached to an app will be deleted by DestroyApplication.
- app->SetPlatformCore(platform);
-
- [self setApp:app];
- [self setPlatform:platform];
-
- const char* argv[] = {"OVRApp"};
- int exitCode = app->OnStartup(1, argv);
- if (exitCode)
- {
- Application::DestroyApplication(app);
- exit(exitCode);
- }
- }
- [self finishLaunching];
- [pool drain];
-
- while ([self isRunning])
- {
- pool = [[NSAutoreleasePool alloc] init];
- NSEvent* event = [self nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES];
- if (event)
- {
- [self sendEvent:event];
- }
- _App->OnIdle();
- [pool drain];
- }
- OVR::Platform::Application::DestroyApplication(app);
-}
-
-@end
-
-static int KeyMap[][2] =
-{
- { NSDeleteFunctionKey, OVR::Key_Delete },
- { '\t', OVR::Key_Tab },
- { '\n', OVR::Key_Return },
- { NSPauseFunctionKey, OVR::Key_Pause },
- { 27, OVR::Key_Escape },
- { 127, OVR::Key_Backspace },
- { ' ', OVR::Key_Space },
- { NSPageUpFunctionKey, OVR::Key_PageUp },
- { NSPageDownFunctionKey, OVR::Key_PageDown },
- { NSNextFunctionKey, OVR::Key_PageDown },
- { NSEndFunctionKey, OVR::Key_End },
- { NSHomeFunctionKey, OVR::Key_Home },
- { NSLeftArrowFunctionKey, OVR::Key_Left },
- { NSUpArrowFunctionKey, OVR::Key_Up },
- { NSRightArrowFunctionKey, OVR::Key_Right },
- { NSDownArrowFunctionKey, OVR::Key_Down },
- { NSInsertFunctionKey, OVR::Key_Insert },
- { NSDeleteFunctionKey, OVR::Key_Delete },
- { NSHelpFunctionKey, OVR::Key_Insert },
-};
-
-
-static KeyCode MapToKeyCode(wchar_t vk)
-{
- unsigned key = Key_None;
-
- if ((vk >= 'a') && (vk <= 'z'))
- {
- key = vk - 'a' + Key_A;
- }
- else if ((vk >= ' ') && (vk <= '~'))
- {
- key = vk;
- }
- else if ((vk >= '0') && (vk <= '9'))
- {
- key = vk - '0' + Key_Num0;
- }
- else if ((vk >= NSF1FunctionKey) && (vk <= NSF15FunctionKey))
- {
- key = vk - NSF1FunctionKey + Key_F1;
- }
- else
- {
- for (unsigned i = 0; i< (sizeof(KeyMap) / sizeof(KeyMap[1])); i++)
- {
- if (vk == KeyMap[i][0])
- {
- key = KeyMap[i][1];
- break;
- }
- }
- }
-
- return (KeyCode)key;
-}
-
-static int MapModifiers(unsigned long xmod)
-{
- int mod = 0;
- if (xmod & NSShiftKeyMask)
- mod |= OVR::Platform::Mod_Shift;
- if (xmod & NSCommandKeyMask)
- mod |= OVR::Platform::Mod_Control;
- if (xmod & NSAlternateKeyMask)
- mod |= OVR::Platform::Mod_Alt;
- if (xmod & NSControlKeyMask)
- mod |= OVR::Platform::Mod_Meta;
- return mod;
-}
-
-@implementation OVRView
-
--(BOOL) acceptsFirstResponder
-{
- return YES;
-}
--(BOOL) acceptsFirstMouse:(NSEvent *)ev
-{
- return YES;
-}
-
-+(CGDirectDisplayID) displayFromScreen:(NSScreen *)s
-{
- NSNumber* didref = (NSNumber*)[[s deviceDescription] objectForKey:@"NSScreenNumber"];
- CGDirectDisplayID disp = (CGDirectDisplayID)[didref longValue];
- return disp;
-}
-
--(void) warpMouseToCenter
-{
- NSPoint w;
- w.x = _Platform->Width/2.0f;
- w.y = _Platform->Height/2.0f;
- w = [[self window] convertBaseToScreen:w];
- CGDirectDisplayID disp = [OVRView displayFromScreen:[[self window] screen]];
- CGPoint p = {w.x, CGDisplayPixelsHigh(disp)-w.y};
- CGDisplayMoveCursorToPoint(disp, p);
-}
-
-static bool LookupKey(NSEvent* ev, wchar_t& ch, OVR::KeyCode& key, unsigned& mods)
-{
- NSString* chars = [ev charactersIgnoringModifiers];
- if ([chars length] == 0)
- return false;
- ch = [chars characterAtIndex:0];
- mods = MapModifiers([ev modifierFlags]);
-
- // check for Cmd+Latin Letter
- NSString* modchars = [ev characters];
- if ([modchars length])
- {
- wchar_t modch = [modchars characterAtIndex:0];
- if (modch >= 'a' && modch <= 'z')
- ch = modch;
- }
- key = MapToKeyCode(ch);
- return true;
-}
-
--(void) keyDown:(NSEvent*)ev
-{
- OVR::KeyCode key;
- unsigned mods;
- wchar_t ch;
- if (!LookupKey(ev, ch, key, mods))
- return;
- if (key == Key_Escape && _Platform->MMode == Mouse_Relative)
- {
- [self warpMouseToCenter];
- CGAssociateMouseAndMouseCursorPosition(true);
- [NSCursor unhide];
- _Platform->MMode = Mouse_RelativeEscaped;
- }
- _App->OnKey(key, ch, true, mods);
-}
--(void) keyUp:(NSEvent*)ev
-{
- OVR::KeyCode key;
- unsigned mods;
- wchar_t ch;
- if (LookupKey(ev, ch, key, mods))
- _App->OnKey(key, ch, false, mods);
-}
-
-static const OVR::KeyCode ModifierKeys[] = {OVR::Key_None, OVR::Key_Shift, OVR::Key_Control, OVR::Key_Alt, OVR::Key_Meta};
-
--(void)flagsChanged:(NSEvent *)ev
-{
- unsigned long cmods = [ev modifierFlags];
- if ((cmods & 0xffff0000) != _Modifiers)
- {
- uint32_t mods = MapModifiers(cmods);
- for (int i = 1; i <= 4; i++)
- {
- unsigned long m = (1 << (16+i));
- if ((cmods & m) != (_Modifiers & m))
- {
- if (cmods & m)
- _App->OnKey(ModifierKeys[i], 0, true, mods);
- else
- _App->OnKey(ModifierKeys[i], 0, false, mods);
- }
- }
- _Modifiers = cmods & 0xffff0000;
- }
-}
-
--(void)ProcessMouse:(NSEvent*)ev
-{
- switch ([ev type])
- {
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
- case NSOtherMouseDragged:
- case NSMouseMoved:
- {
- if (_Platform->MMode == OVR::Platform::Mouse_Relative)
- {
- int dx = [ev deltaX];
- int dy = [ev deltaY];
-
- if (dx != 0 || dy != 0)
- {
- _App->OnMouseMove(dx, dy, Mod_MouseRelative|MapModifiers([ev modifierFlags]));
- [self warpMouseToCenter];
- }
- }
- else
- {
- NSPoint p = [ev locationInWindow];
- _App->OnMouseMove(p.x, p.y, MapModifiers([ev modifierFlags]));
- }
- }
- break;
- case NSLeftMouseDown:
- case NSRightMouseDown:
- case NSOtherMouseDown:
- break;
- }
-}
-
--(void) mouseMoved:(NSEvent*)ev
-{
- [self ProcessMouse:ev];
-}
--(void) mouseDragged:(NSEvent*)ev
-{
- [self ProcessMouse:ev];
-}
--(void) mouseDown:(NSEvent*)ev
-{
- if (_Platform->MMode == Mouse_RelativeEscaped)
- {
- [self warpMouseToCenter];
- CGAssociateMouseAndMouseCursorPosition(false);
- [NSCursor hide];
- _Platform->MMode = Mouse_Relative;
- }
-}
-
-//-(void)
-
--(id) initWithFrame:(NSRect)frameRect
-{
- NSOpenGLPixelFormatAttribute attr[] =
- {NSOpenGLPFAWindow, NSOpenGLPFADoubleBuffer, NSOpenGLPFADepthSize, 24, nil};
-
- NSOpenGLPixelFormat *pf = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attr] autorelease];
-
- self = [super initWithFrame:frameRect pixelFormat:pf];
- GLint swap = 0;
- [[self openGLContext] setValues:&swap forParameter:NSOpenGLCPSwapInterval];
- //[self setWantsBestResolutionOpenGLSurface:YES];
- return self;
-}
-
--(void) reshape
-{
- NSRect bounds = [self bounds];
- _App->OnResize(bounds.size.width, bounds.size.height);
-
- _Platform->Width = bounds.size.width;
- _Platform->Height = bounds.size.height;
-
- if (_Platform->GetRenderer())
- _Platform->GetRenderer()->SetWindowSize(bounds.size.width, bounds.size.height);
-}
-
--(BOOL)windowShouldClose:(id)sender
-{
- if (_Platform)
- _Platform->Exit(0);
- else
- exit(0);
- return 1;
-}
-
-@end
-
-namespace OVR { namespace Platform { namespace OSX {
-
-PlatformCore::PlatformCore(Application* app, void* nsapp)
- : Platform::PlatformCore(app), NsApp(nsapp), Win(NULL), View(NULL), Quit(0), MMode(Mouse_Normal)
-{
- pGamepadManager = *new OSX::GamepadManager();
-}
-PlatformCore::~PlatformCore()
-{
-}
-
-void PlatformCore::Exit(int exitcode)
-{
- OVRApp* nsApp = (OVRApp*)NsApp;
- [nsApp stop:nil];
-}
-
-String PlatformCore::GetContentDirectory() const
-{
- NSBundle* bundle = [NSBundle mainBundle];
- if (bundle)
- return String([[bundle bundlePath] UTF8String]) + "/Contents/Resources";
- else
- return ".";
-}
-
-
-void PlatformCore::SetMouseMode(MouseMode mm)
-{
- if (mm == MMode)
- return;
-
- if (Win)
- {
- if (mm == Mouse_Relative)
- {
- [NSCursor hide];
- [(OVRView*)View warpMouseToCenter];
- CGAssociateMouseAndMouseCursorPosition(false);
- }
- else
- {
- if (MMode == Mouse_Relative)
- {
- CGAssociateMouseAndMouseCursorPosition(true);
- [NSCursor unhide];
- [(OVRView*)View warpMouseToCenter];
- }
- }
- }
- MMode = mm;
-}
-
-
-void PlatformCore::GetWindowSize(int* w, int* h) const
-{
- *w = Width;
- *h = Height;
-}
-
-bool PlatformCore::SetupWindow(int w, int h)
-{
- NSRect winrect;
- winrect.origin.x = 0;
- winrect.origin.y = 1000;
- winrect.size.width = w;
- winrect.size.height = h;
- NSWindow* win = [[NSWindow alloc] initWithContentRect:winrect styleMask:NSTitledWindowMask|NSClosableWindowMask backing:NSBackingStoreBuffered defer:NO];
-
- OVRView* view = [[OVRView alloc] initWithFrame:winrect];
- [view setPlatform:this];
- [win setContentView:view];
- [win setAcceptsMouseMovedEvents:YES];
- [win setDelegate:view];
- [view setApp:pApp];
- Win = win;
- View = view;
- return 1;
-}
-
-void PlatformCore::SetWindowTitle(const char* title)
-{
- [((NSWindow*)Win) setTitle:[[NSString alloc] initWithBytes:title length:strlen(title) encoding:NSUTF8StringEncoding]];
-}
-
-void PlatformCore::ShowWindow(bool show)
-{
- if (show)
- [((NSWindow*)Win) makeKeyAndOrderFront:nil];
- else
- [((NSWindow*)Win) orderOut:nil];
-}
-
-void PlatformCore::DestroyWindow()
-{
- [((NSWindow*)Win) close];
- Win = NULL;
-}
-
-RenderDevice* PlatformCore::SetupGraphics(const SetupGraphicsDeviceSet& setupGraphicsDesc,
- const char* type, const Render::RendererParams& rp)
-{
- const SetupGraphicsDeviceSet* setupDesc = setupGraphicsDesc.PickSetupDevice(type);
- OVR_ASSERT(setupDesc);
-
- pRender = *setupDesc->pCreateDevice(rp, this);
- if (pRender)
- pRender->SetWindowSize(Width, Height);
-
- return pRender.GetPtr();
-}
-
-int PlatformCore::GetDisplayCount()
-{
- return (int)[[NSScreen screens] count];
-}
-
-Render::DisplayId PlatformCore::GetDisplay(int i)
-{
- NSScreen* s = (NSScreen*)[[NSScreen screens] objectAtIndex:i];
- return Render::DisplayId([OVRView displayFromScreen:s]);
-}
-
-bool PlatformCore::SetFullscreen(const Render::RendererParams& rp, int fullscreen)
-{
- if (fullscreen == Render::Display_Window)
- [(OVRView*)View exitFullScreenModeWithOptions:nil];
- else
- {
- NSScreen* usescreen = [NSScreen mainScreen];
- NSArray* screens = [NSScreen screens];
- for (int i = 0; i < [screens count]; i++)
- {
- NSScreen* s = (NSScreen*)[screens objectAtIndex:i];
- CGDirectDisplayID disp = [OVRView displayFromScreen:s];
-
- if (disp == rp.Display.CgDisplayId)
- usescreen = s;
- }
-
- [(OVRView*)View enterFullScreenMode:usescreen withOptions:nil];
- }
-
- if (pRender)
- pRender->SetFullscreen((Render::DisplayMode)fullscreen);
- return 1;
-}
-
-}}
-// GL
-namespace Render { namespace GL { namespace OSX {
-
-Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* oswnd)
-{
- Platform::OSX::PlatformCore* PC = (Platform::OSX::PlatformCore*)oswnd;
-
- OVRView* view = (OVRView*)PC->View;
- NSOpenGLContext *context = [view openGLContext];
- if (!context)
- return NULL;
-
- [context makeCurrentContext];
- [((NSWindow*)PC->Win) makeKeyAndOrderFront:nil];
-
- return new Render::GL::OSX::RenderDevice(rp, context);
-}
-
-void RenderDevice::Present()
-{
- NSOpenGLContext *context = (NSOpenGLContext*)Context;
- [context flushBuffer];
-}
-
-void RenderDevice::Shutdown()
-{
- Context = NULL;
-}
-
-bool RenderDevice::SetFullscreen(DisplayMode fullscreen)
-{
- Params.Fullscreen = fullscreen;
- return 1;
-}
-
-}}}}
-
-
-int main(int argc, char *argv[])
-{
- NSApplication* nsapp = [OVRApp sharedApplication];
- [nsapp run];
- return 0;
-}
-
diff --git a/Samples/CommonSrc/Platform/OSX_PlatformObjc.h b/Samples/CommonSrc/Platform/OSX_PlatformObjc.h
deleted file mode 100644
index 7d195eb..0000000
--- a/Samples/CommonSrc/Platform/OSX_PlatformObjc.h
+++ /dev/null
@@ -1,31 +0,0 @@
-
-#import <Cocoa/Cocoa.h>
-#import "OSX_Platform.h"
-#import "OSX_Gamepad.h"
-
-#import <CoreGraphics/CoreGraphics.h>
-#import <CoreGraphics/CGDirectDisplay.h>
-
-@interface OVRApp : NSApplication
-
-@property (assign) IBOutlet NSWindow* win;
-@property (assign) OVR::Platform::OSX::PlatformCore* Platform;
-@property (assign) OVR::Platform::Application* App;
-
--(void) run;
-
-@end
-
-@interface OVRView : NSOpenGLView <NSWindowDelegate>
-
-@property (assign) OVR::Platform::OSX::PlatformCore* Platform;
-@property (assign) OVR::Platform::Application* App;
-@property unsigned long Modifiers;
-
--(void)ProcessMouse:(NSEvent*)event;
--(void)warpMouseToCenter;
-
-+(CGDirectDisplayID) displayFromScreen:(NSScreen*)s;
-
-@end
-
diff --git a/Samples/CommonSrc/Platform/OSX_WavPlayer.cpp b/Samples/CommonSrc/Platform/OSX_WavPlayer.cpp
deleted file mode 100644
index a6cb937..0000000
--- a/Samples/CommonSrc/Platform/OSX_WavPlayer.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/************************************************************************************
-
-Filename : WavPlayer_OSX.cpp
-Content : An Apple OSX audio handler.
-Created : March 5, 2013
-Authors : Robotic Arm Software - Peter Hoff, Dan Goodman, Bryan Croteau
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Use of this software is subject to the terms of the Oculus LLC license
-agreement provided at the time of installation or download, or which
-otherwise accompanies this software in either electronic or hard copy form.
-
-************************************************************************************/
-
-#include "OSX_WavPlayer.h"
-
-namespace OVR { namespace Platform { namespace OSX {
-
-WavPlayer::WavPlayer(const char* fileName)
-{
- FileName = fileName;
-}
-
-bool WavPlayer::isDataChunk(unsigned char* buffer, int index)
-{
- unsigned char a = buffer[index];
- unsigned char b = buffer[index + 1];
- unsigned char c = buffer[index + 2];
- unsigned char d = buffer[index + 3];
- return (a == 'D' || a == 'd') && (b == 'A' || b == 'a') &&
- (c == 'T' || c == 't') && (d == 'A' || d == 'a');
-}
-
-int WavPlayer::getWord(unsigned char* buffer, int index)
-{
- unsigned char a = buffer[index];
- unsigned char b = buffer[index + 1];
- unsigned char c = buffer[index + 2];
- unsigned char d = buffer[index + 3];
- int result = 0;
- result |= a;
- result |= b << 8;
- result |= c << 16;
- result |= d << 24;
- return result;
-}
-
-short WavPlayer::getHalf(unsigned char* buffer, int index)
-{
- unsigned char a = buffer[index];
- unsigned char b = buffer[index + 1];
- short result = 0;
- result |= a;
- result |= b << 8;
- return result;
-}
-
-void *WavPlayer::LoadPCM(const char *filename, unsigned long *len)
-{
- FILE *file;
- struct stat s;
- void *pcm;
-
- if(stat(filename, &s))
- {
- return NULL;
- }
- *len = s.st_size;
- pcm = (void *) malloc(s.st_size);
- if(!pcm)
- {
- return NULL;
- }
- file = fopen(filename, "rb");
- if(!file)
- {
- free(pcm);
- return NULL;
- }
- fread(pcm, s.st_size, 1, file);
- fclose(file);
- return pcm;
-}
-
-int WavPlayer::PlayBuffer(void *pcmbuffer, unsigned long len)
-{
- AQCallbackStruct aqc;
- UInt32 err, bufferSize;
- int i;
-
- aqc.DataFormat.mSampleRate = SampleRate;
- aqc.DataFormat.mFormatID = kAudioFormatLinearPCM;
- if(BitsPerSample == 16)
- {
- aqc.DataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger
- | kAudioFormatFlagIsPacked;
- }
- aqc.DataFormat.mBytesPerPacket = NumChannels * (BitsPerSample / 8);
- aqc.DataFormat.mFramesPerPacket = 1;
- aqc.DataFormat.mBytesPerFrame = NumChannels * (BitsPerSample / 8);
- aqc.DataFormat.mChannelsPerFrame = NumChannels;
- aqc.DataFormat.mBitsPerChannel = BitsPerSample;
- aqc.FrameCount = SampleRate / 60;
- aqc.SampleLen = (UInt32)(len);
- aqc.PlayPtr = 0;
- aqc.PCMBuffer = static_cast<unsigned char*>(pcmbuffer);
-
- err = AudioQueueNewOutput(&aqc.DataFormat,
- aqBufferCallback,
- &aqc,
- NULL,
- kCFRunLoopCommonModes,
- 0,
- &aqc.Queue);
- if(err)
- {
- return err;
- }
-
- aqc.FrameCount = SampleRate / 60;
- bufferSize = aqc.FrameCount * aqc.DataFormat.mBytesPerPacket;
-
- for(i = 0; i < AUDIO_BUFFERS; i++)
- {
- err = AudioQueueAllocateBuffer(aqc.Queue, bufferSize,
- &aqc.Buffers[i]);
- if(err)
- {
- return err;
- }
- aqBufferCallback(&aqc, aqc.Queue, aqc.Buffers[i]);
- }
-
- err = AudioQueueStart(aqc.Queue, NULL);
- if(err)
- {
- return err;
- }
-
- while(true)
- {
- }
- sleep(1);
- return 0;
-}
-
-void WavPlayer::aqBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB)
-{
- AQCallbackStruct *aqc;
- unsigned char *coreAudioBuffer;
-
- aqc = (AQCallbackStruct *) in;
- coreAudioBuffer = (unsigned char*) outQB->mAudioData;
-
- printf("Sync: %u / %u\n", aqc->PlayPtr, aqc->SampleLen);
-
- if(aqc->FrameCount > 0)
- {
- outQB->mAudioDataByteSize = aqc->DataFormat.mBytesPerFrame * aqc->FrameCount;
- for(int i = 0; i < aqc->FrameCount * aqc->DataFormat.mBytesPerFrame; i++)
- {
- if(aqc->PlayPtr > aqc->SampleLen)
- {
- aqc->PlayPtr = 0;
- i = 0;
- }
- coreAudioBuffer[i] = aqc->PCMBuffer[aqc->PlayPtr];
- aqc->PlayPtr++;
- }
- AudioQueueEnqueueBuffer(inQ, outQB, 0, NULL);
- }
-}
-
-int WavPlayer::PlayAudio()
-{
- unsigned long len;
- void *pcmbuffer;
- int ret;
-
- pcmbuffer = LoadPCM(FileName, &len);
- if(!pcmbuffer)
- {
- fprintf(stderr, "%s: %s\n", FileName, strerror(errno));
- exit(EXIT_FAILURE);
- }
-
- unsigned char* bytes = (unsigned char*)pcmbuffer;
- int index = 0;
-
- // 'RIFF'
- getWord(bytes, index);
- index += 4;
- // int Length
- getWord(bytes, index);
- index += 4;
- // 'WAVE'
- getWord(bytes, index);
- index += 4;
- // 'fmt '
- getWord(bytes, index);
- index += 4;
-
- // int Format Length
- int fmtLen = getWord(bytes, index);
- index += 4;
- AudioFormat = getHalf(bytes, index);
- index += 2;
- NumChannels = getHalf(bytes, index);
- index += 2;
- SampleRate = getWord(bytes, index);
- index += 4;
- ByteRate = getWord(bytes, index);
- index += 4;
- BlockAlign = getHalf(bytes, index);
- index += 2;
- BitsPerSample = getHalf(bytes, index);
- index += 2;
- index += fmtLen - 16;
- while(!isDataChunk(bytes, index))
- {
- // Any Chunk
- getWord(bytes, index);
- index += 4;
- // Any Chunk Length
- int anyChunkLen = getWord(bytes, index);
- index += 4 + anyChunkLen;
- }
- // 'data'
- getWord(bytes, index);
- index += 4;
- // int Data Length
- unsigned long dataLen = getWord(bytes, index);
- index += 4;
- unsigned char* target = &bytes[index];
-
- ret = PlayBuffer((void *)target, dataLen);
- free(pcmbuffer);
- return ret;
-}
-
-}}}
diff --git a/Samples/CommonSrc/Platform/OSX_WavPlayer.h b/Samples/CommonSrc/Platform/OSX_WavPlayer.h
deleted file mode 100644
index 4aaba10..0000000
--- a/Samples/CommonSrc/Platform/OSX_WavPlayer.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/************************************************************************************
-
-Filename : WavPlayer_OSX.h
-Content : An Apple OSX audio handler.
-Created : March 5, 2013
-Authors : Robotic Arm Software - Peter Hoff, Dan Goodman, Bryan Croteau
-
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
-Use of this software is subject to the terms of the Oculus LLC 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_WavPlayer_h
-#define OVR_WavPlayer_h
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <AudioToolbox/AudioQueue.h>
-
-#define AUDIO_BUFFERS 4
-
-namespace OVR { namespace Platform { namespace OSX {
-
-typedef struct AQCallbackStruct
-{
- AudioQueueRef Queue;
- UInt32 FrameCount;
- AudioQueueBufferRef Buffers[AUDIO_BUFFERS];
- AudioStreamBasicDescription DataFormat;
- UInt32 PlayPtr;
- UInt32 SampleLen;
- unsigned char* PCMBuffer;
-} AQCallbackStruct;
-
-class WavPlayer
-{
-public:
- WavPlayer(const char* fileName);
- int PlayAudio();
-private:
- bool isDataChunk(unsigned char* buffer, int index);
- int getWord(unsigned char* buffer, int index);
- short getHalf(unsigned char* buffer, int index);
- void *LoadPCM(const char *filename, unsigned long *len);
- int PlayBuffer(void *pcm, unsigned long len);
- static void aqBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB);
-
- short AudioFormat;
- short NumChannels;
- int SampleRate;
- int ByteRate;
- short BlockAlign;
- short BitsPerSample;
- const char* FileName;
-};
-
-}}}
-
-#endif
diff --git a/Samples/CommonSrc/Platform/Platform.cpp b/Samples/CommonSrc/Platform/Platform.cpp
index c0e4438..108c7f5 100644
--- a/Samples/CommonSrc/Platform/Platform.cpp
+++ b/Samples/CommonSrc/Platform/Platform.cpp
@@ -52,12 +52,12 @@ PlatformCore::PlatformCore(Application *app)
{
pApp = app;
pApp->SetPlatformCore(this);
- StartupTicks = OVR::Timer::GetTicks();
+ StartupSeconds = OVR::Timer::GetSeconds();
}
double PlatformCore::GetAppTime() const
{
- return (OVR::Timer::GetTicks() - StartupTicks) * (1.0 / (double)OVR::Timer::MksPerSecond);
+ return OVR::Timer::GetSeconds() - StartupSeconds;
}
bool PlatformCore::SetFullscreen(const Render::RendererParams&, int fullscreen)
diff --git a/Samples/CommonSrc/Platform/Platform.h b/Samples/CommonSrc/Platform/Platform.h
index 201aad6..47d8f67 100644
--- a/Samples/CommonSrc/Platform/Platform.h
+++ b/Samples/CommonSrc/Platform/Platform.h
@@ -111,7 +111,7 @@ protected:
Application* pApp;
Ptr<RenderDevice> pRender;
Ptr<GamepadManager> pGamepadManager;
- UInt64 StartupTicks;
+ double StartupSeconds;
public:
PlatformCore(Application *app);
diff --git a/Samples/CommonSrc/Platform/Platform_Default.h b/Samples/CommonSrc/Platform/Platform_Default.h
index e4fecf2..420b088 100644
--- a/Samples/CommonSrc/Platform/Platform_Default.h
+++ b/Samples/CommonSrc/Platform/Platform_Default.h
@@ -29,17 +29,18 @@ limitations under the License.
#if defined(OVR_OS_WIN32)
#include "Win32_Platform.h"
-
+
#include "../Render/Render_D3D11_Device.h"
#undef OVR_D3D_VERSION
#include "../Render/Render_D3D10_Device.h"
-// #include "../Render/Render_GL_Win32_Device.h"
+ #include "../Render/Render_GL_Win32_Device.h"
// Modify this list or pass a smaller set to select a specific render device,
// while avoiding linking extra classes.
- #define OVR_DEFAULT_RENDER_DEVICE_SET \
- SetupGraphicsDeviceSet("D3D11", &OVR::Render::D3D11::RenderDevice::CreateDevice, \
- SetupGraphicsDeviceSet("D3D10", &OVR::Render::D3D10::RenderDevice::CreateDevice) )
+ #define OVR_DEFAULT_RENDER_DEVICE_SET \
+ SetupGraphicsDeviceSet("D3D11", &OVR::Render::D3D11::RenderDevice::CreateDevice, \
+ SetupGraphicsDeviceSet("D3D10", &OVR::Render::D3D10::RenderDevice::CreateDevice, \
+ SetupGraphicsDeviceSet("GL", &OVR::Render::GL::Win32::RenderDevice::CreateDevice)))
#elif defined(OVR_OS_MAC) && !defined(OVR_MAC_X11)
#include "OSX_Platform.h"
diff --git a/Samples/CommonSrc/Platform/Win32_Gamepad.cpp b/Samples/CommonSrc/Platform/Win32_Gamepad.cpp
index 9b8793f..ce7af63 100644
--- a/Samples/CommonSrc/Platform/Win32_Gamepad.cpp
+++ b/Samples/CommonSrc/Platform/Win32_Gamepad.cpp
@@ -5,7 +5,7 @@ Content : Win32 implementation of Platform app infrastructure
Created : May 6, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/Samples/CommonSrc/Platform/Win32_Gamepad.h b/Samples/CommonSrc/Platform/Win32_Gamepad.h
index 09815ae..e3f81af 100644
--- a/Samples/CommonSrc/Platform/Win32_Gamepad.h
+++ b/Samples/CommonSrc/Platform/Win32_Gamepad.h
@@ -5,7 +5,7 @@ Content : Win32 implementation of Gamepad functionality.
Created : May 6, 2013
Authors : Lee Cooper
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/Samples/CommonSrc/Platform/Win32_Platform.cpp b/Samples/CommonSrc/Platform/Win32_Platform.cpp
index eeab429..0614a3f 100644
--- a/Samples/CommonSrc/Platform/Win32_Platform.cpp
+++ b/Samples/CommonSrc/Platform/Win32_Platform.cpp
@@ -21,6 +21,8 @@ limitations under the License.
************************************************************************************/
+#include <Windows.h>
+
#include "Kernel/OVR_System.h"
#include "Kernel/OVR_Array.h"
#include "Kernel/OVR_String.h"
@@ -177,7 +179,7 @@ static UByte KeyMap[][2] =
{ VK_OEM_MINUS, Key_Minus },
{ VK_OEM_PERIOD,Key_Period },
{ VK_OEM_2, Key_Slash },
- { VK_OEM_3, Key_Bar },
+ { VK_OEM_3, Key_Backtick },
{ VK_OEM_4, Key_BracketLeft },
{ VK_OEM_5, Key_Backslash },
{ VK_OEM_6, Key_BracketRight },
@@ -418,9 +420,9 @@ int PlatformCore::Run()
if (IsIconic(hWnd))
{
Sleep(10);
+ }
}
}
- }
return ExitCode;
}
@@ -545,6 +547,7 @@ Render::DisplayId PlatformCore::GetDisplay(int screen)
OVR::Platform::Application* g_app;
+
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE prevInst, LPSTR inArgs, int show)
{
using namespace OVR;
diff --git a/Samples/CommonSrc/Platform/Win32_Platform.h b/Samples/CommonSrc/Platform/Win32_Platform.h
index 6081968..23f0b70 100644
--- a/Samples/CommonSrc/Platform/Win32_Platform.h
+++ b/Samples/CommonSrc/Platform/Win32_Platform.h
@@ -98,4 +98,14 @@ KeyCode MapVKToKeyCode(unsigned vk);
// OVR_PLATFORM_APP_ARGS specifies the Application startup class with no args.
#define OVR_PLATFORM_APP(AppClass) OVR_PLATFORM_APP_ARGS(AppClass, ())
+#define OVR_PLATFORM_APP_ARGS_WITH_LOG(AppClass, LogClass, args) \
+ OVR::Platform::Application* OVR::Platform::Application::CreateApplication() \
+ { static LogClass log; OVR::System::Init(&log); \
+ return new AppClass args; } \
+ void OVR::Platform::Application::DestroyApplication(OVR::Platform::Application* app) \
+ { OVR::Platform::PlatformCore* platform = app->pPlatform; \
+ delete app; delete platform; OVR::System::Destroy(); };
+
+#define OVR_PLATFORM_APP_WITH_LOG(AppClass,LogClass) OVR_PLATFORM_APP_ARGS_WITH_LOG(AppClass,LogClass, ())
+
#endif // OVR_Win32_Platform_h
diff --git a/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp b/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp
index 6408e08..d7c606f 100644
--- a/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp
+++ b/Samples/CommonSrc/Render/Render_D3D1X_Device.cpp
@@ -21,13 +21,20 @@ limitations under the License.
************************************************************************************/
+#define GPU_PROFILING 0
+
#include "Kernel/OVR_Log.h"
#include "Kernel/OVR_Std.h"
#include "Render_D3D1X_Device.h"
+#include "Util/Util_ImageWindow.h"
+
+#include "OVR_CAPI_D3D.h"
#include <d3dcompiler.h>
+#include <d3d9.h> // for GPU markers
+
#if (OVR_D3D_VERSION == 10)
namespace OVR { namespace Render { namespace D3D10 {
#else
@@ -43,7 +50,6 @@ static D3D1x_(INPUT_ELEMENT_DESC) ModelVertexDesc[] =
{"Normal", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, Norm), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
};
-
static const char* StdVertexShaderSrc =
"float4x4 Proj;\n"
"float4x4 View;\n"
@@ -135,13 +141,18 @@ static const char* MultiTexturePixelShaderSrc =
"{\n"
"float4 color1;\n"
"float4 color2;\n"
- " color1 = Texture[0].Sample(Linear, ov.TexCoord);\n"
+ " color1 = Texture[0].Sample(Linear, ov.TexCoord);\n"
+ // go to linear space colors (assume gamma 2.0 for speed)
+ " color1.rgb *= color1.rgb;\n"
" color2 = Texture[1].Sample(Linear, ov.TexCoord1);\n"
+ // go to linear space colors (assume gamma 2.0 for speed)
+ " color2.rgb *= color2.rgb;\n"
" color2.rgb = color2.rgb * lerp(1.2, 1.9, saturate(length(color2.rgb)));\n"
" color2 = color1 * color2;\n"
" if (color2.a <= 0.4)\n"
" discard;\n"
- " return color2;\n"
+ // go to back to gamma space space colors (assume gamma 2.0 for speed)
+ " return float4(sqrt(color2.rgb), color2.a);\n"
"}\n";
#define LIGHTING_COMMON \
@@ -201,7 +212,9 @@ static const char* AlphaTexturePixelShaderSrc =
"};\n"
"float4 main(in Varyings ov) : SV_Target\n"
"{\n"
- " return ov.Color * float4(1,1,1,Texture.Sample(Linear, ov.TexCoord).r);\n"
+ " float4 finalColor = ov.Color;\n"
+ " finalColor.a *= Texture.Sample(Linear, ov.TexCoord).r;\n"
+ " return finalColor;\n"
"}\n";
@@ -211,97 +224,294 @@ static const char* PostProcessVertexShaderSrc =
"float4x4 View : register(c4);\n"
"float4x4 Texm : register(c8);\n"
"void main(in float4 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1,\n"
- " out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float2 oTexCoord : TEXCOORD0)\n"
+ " out float4 oPosition : SV_Position, out float2 oTexCoord : TEXCOORD0)\n"
"{\n"
" oPosition = mul(View, Position);\n"
" oTexCoord = mul(Texm, float4(TexCoord,0,1));\n"
- " oColor = Color;\n"
"}\n";
-// Shader with just lens distortion correction.
-static const char* PostProcessPixelShaderSrc =
+
+// Shader with lens distortion and chromatic aberration correction.
+static const char* PostProcessPixelShaderWithChromAbSrc =
"Texture2D Texture : register(t0);\n"
"SamplerState Linear : register(s0);\n"
- "float2 LensCenter;\n"
- "float2 ScreenCenter;\n"
- "float2 Scale;\n"
- "float2 ScaleIn;\n"
+ "float3 DistortionClearColor;\n"
+ "float EdgeFadeScale;\n"
+ "float2 EyeToSourceUVScale;\n"
+ "float2 EyeToSourceUVOffset;\n"
+ "float2 EyeToSourceNDCScale;\n"
+ "float2 EyeToSourceNDCOffset;\n"
+ "float2 TanEyeAngleScale;\n"
+ "float2 TanEyeAngleOffset;\n"
"float4 HmdWarpParam;\n"
+ "float4 ChromAbParam;\n"
"\n"
- // Scales input texture coordinates for distortion.
- // ScaleIn maps texture coordinates to Scales to ([-1, 1]), although top/bottom will be
- // larger due to aspect ratio.
- "float2 HmdWarp(float2 in01)\n"
+ "float4 main(in float4 oPosition : SV_Position,\n"
+ " in float2 oTexCoord : TEXCOORD0) : SV_Target\n"
"{\n"
- " float2 theta = (in01 - LensCenter) * ScaleIn;\n" // Scales to [-1, 1]
- " float rSq = theta.x * theta.x + theta.y * theta.y;\n"
- " float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
- " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
- " return LensCenter + Scale * theta1;\n"
- "}\n"
+ // Input oTexCoord is [-1,1] across the half of the screen used for a single eye.
+ " float2 TanEyeAngleDistorted = oTexCoord * TanEyeAngleScale + TanEyeAngleOffset;\n" // Scales to tan(thetaX),tan(thetaY), but still distorted (i.e. only the center is correct)
+ " float RadiusSq = TanEyeAngleDistorted.x * TanEyeAngleDistorted.x + TanEyeAngleDistorted.y * TanEyeAngleDistorted.y;\n"
+ " float Distort = rcp ( 1.0 + RadiusSq * ( HmdWarpParam.y + RadiusSq * ( HmdWarpParam.z + RadiusSq * ( HmdWarpParam.w ) ) ) );\n"
+ " float DistortR = Distort * ( ChromAbParam.x + RadiusSq * ChromAbParam.y );\n"
+ " float DistortG = Distort;\n"
+ " float DistortB = Distort * ( ChromAbParam.z + RadiusSq * ChromAbParam.w );\n"
+ " float2 TanEyeAngleR = DistortR * TanEyeAngleDistorted;\n"
+ " float2 TanEyeAngleG = DistortG * TanEyeAngleDistorted;\n"
+ " float2 TanEyeAngleB = DistortB * TanEyeAngleDistorted;\n"
+
+ // These are now in "TanEyeAngle" space.
+ // The vectors (TanEyeAngleRGB.x, TanEyeAngleRGB.y, 1.0) are real-world vectors pointing from the eye to where the components of the pixel appear to be.
+ // If you had a raytracer, you could just use them directly.
+
+ // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye)
+ " float2 SourceCoordR = TanEyeAngleR * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " float2 SourceCoordG = TanEyeAngleG * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " float2 SourceCoordB = TanEyeAngleB * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+
+ // Find the distance to the nearest edge.
+ " float2 NDCCoord = TanEyeAngleG * EyeToSourceNDCScale + EyeToSourceNDCOffset;\n"
+ " float EdgeFadeIn = EdgeFadeScale * ( 1.0 - max ( abs ( NDCCoord.x ), abs ( NDCCoord.y ) ) );\n"
+ " if ( EdgeFadeIn < 0.0 )\n"
+ " {\n"
+ " return float4(DistortionClearColor.r, DistortionClearColor.g, DistortionClearColor.b, 1.0);\n"
+ " }\n"
+ " 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"
+ "}\n";
+
+//----------------------------------------------------------------------------
+
+// A vertex format used for mesh-based distortion.
+/*
+struct DistortionVertex
+{
+ Vector2f Pos;
+ Vector2f TexR;
+ Vector2f TexG;
+ Vector2f TexB;
+ Color Col;
+};
+*/
+static D3D1x_(INPUT_ELEMENT_DESC) DistortionVertexDesc[] =
+{
+ {"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},
+ {"TexCoord", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 8+8, D3D1x_(INPUT_PER_VERTEX_DATA), 0},
+ {"TexCoord", 2, DXGI_FORMAT_R32G32_FLOAT, 0, 8+8+8, D3D1x_(INPUT_PER_VERTEX_DATA), 0},
+ {"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.
+
+static const char* PostProcessMeshVertexShaderSrc =
+ "float2 EyeToSourceUVScale;\n"
+ "float2 EyeToSourceUVOffset;\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"
+ "{\n"
+ " oPosition.x = Position.x;\n"
+ " oPosition.y = Position.y;\n"
+ " oPosition.z = 0.5;\n"
+ " oPosition.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"
+ " oTexCoord1 = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " oColor = Color;\n" // Used for vignette fade.
+ "}\n";
+
+static const char* PostProcessMeshPixelShaderSrc =
+ "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 oTexCoord : TEXCOORD0) : SV_Target\n"
+ " in float2 oTexCoord0 : TEXCOORD0, in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2) : SV_Target\n"
"{\n"
- " float2 tc = HmdWarp(oTexCoord);\n"
- " if (any(clamp(tc, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tc))\n"
- " return 0;\n"
- " return Texture.Sample(Linear, tc);\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"
"}\n";
-// Shader with lens distortion and chromatic aberration correction.
-static const char* PostProcessPixelShaderWithChromAbSrc =
+
+//----------------------------------------------------------------------------
+// Pixel shader is very simple - does three texture reads.
+// Vertex shader does all the hard work.
+// Used for mesh-based distortion with timewarp.
+
+static const char* PostProcessMeshTimewarpVertexShaderSrc =
+ "float2 EyeToSourceUVScale;\n"
+ "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"
+ "{\n"
+ " oPosition.x = Position.x;\n"
+ " oPosition.y = Position.y;\n"
+ " oPosition.z = 0.5;\n"
+ " oPosition.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.
+ " float3 TanEyeAngleR = float3 ( TexCoord0.x, TexCoord0.y, 1.0 );\n"
+ " float3 TanEyeAngleG = float3 ( TexCoord1.x, TexCoord1.y, 1.0 );\n"
+ " float3 TanEyeAngleB = float3 ( TexCoord2.x, TexCoord2.y, 1.0 );\n"
+
+ // Accurate time warp lerp vs. faster
+#if 1
+ // Apply the two 3x3 timewarp rotations to these vectors.
+ " float3 TransformedRStart = mul ( TanEyeAngleR, EyeRotationStart );\n"
+ " float3 TransformedGStart = mul ( TanEyeAngleG, EyeRotationStart );\n"
+ " float3 TransformedBStart = mul ( TanEyeAngleB, EyeRotationStart );\n"
+ " float3 TransformedREnd = mul ( TanEyeAngleR, EyeRotationEnd );\n"
+ " float3 TransformedGEnd = mul ( TanEyeAngleG, EyeRotationEnd );\n"
+ " float3 TransformedBEnd = mul ( TanEyeAngleB, EyeRotationEnd );\n"
+ // And blend between them.
+ " float3 TransformedR = lerp ( TransformedRStart, TransformedREnd, Color.a );\n"
+ " float3 TransformedG = lerp ( TransformedGStart, TransformedGEnd, Color.a );\n"
+ " float3 TransformedB = lerp ( TransformedBStart, TransformedBEnd, Color.a );\n"
+#else
+ " float3x3 EyeRotation = lerp ( EyeRotationStart, EyeRotationEnd, Color.a );\n"
+ " float3 TransformedR = mul ( TanEyeAngleR, EyeRotation );\n"
+ " float3 TransformedG = mul ( TanEyeAngleG, EyeRotation );\n"
+ " float3 TransformedB = mul ( TanEyeAngleB, EyeRotation );\n"
+#endif
+
+ // Project them back onto the Z=1 plane of the rendered images.
+ " float RecipZR = rcp ( TransformedR.z );\n"
+ " float RecipZG = rcp ( TransformedG.z );\n"
+ " float RecipZB = rcp ( TransformedB.z );\n"
+ " float2 FlattenedR = float2 ( TransformedR.x * RecipZR, TransformedR.y * RecipZR );\n"
+ " float2 FlattenedG = float2 ( TransformedG.x * RecipZG, TransformedG.y * RecipZG );\n"
+ " float2 FlattenedB = float2 ( 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)
+ " 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"
+ " oColor = Color.r;\n" // Used for vignette fade.
+ "}\n";
+
+static const char* PostProcessMeshTimewarpPixelShaderSrc =
"Texture2D Texture : register(t0);\n"
"SamplerState Linear : register(s0);\n"
- "float2 LensCenter;\n"
- "float2 ScreenCenter;\n"
- "float2 Scale;\n"
- "float2 ScaleIn;\n"
- "float4 HmdWarpParam;\n"
- "float4 ChromAbParam;\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"
+ "}\n";
- // Scales input texture coordinates for distortion.
- // ScaleIn maps texture coordinates to Scales to ([-1, 1]), although top/bottom will be
- // larger due to aspect ratio.
+//----------------------------------------------------------------------------
+// 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"
+ // 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"
+ "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"
+ " retVal.xyz *= linearDepth;\n"
+ " return retVal;\n"
+ "}\n"
+
+ "float2 TimewarpTexCoordToWarpedPos(float2 inTexCoord, float4x4 rotMat)\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.
+ " float4 inputPos = PositionFromDepth(inTexCoord);\n"
+ " float3 transformed = float3( mul ( rotMat, inputPos ).xyz);\n"
+ // Project them back onto the Z=1 plane of the rendered images.
+ " float2 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)
+ " float2 noDepthUV = flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ //" float depth = DepthTexture.SampleLevel(Linear, noDepthUV, 0).r;\n"
+ " 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"
+ "{\n"
+ " oPosition.x = Position.x;\n"
+ " oPosition.y = Position.y;\n"
+ " oPosition.z = 0.5;\n"
+ " oPosition.w = 1.0;\n"
+
+ " float timewarpLerpFactor = Color.a;\n"
+ " float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, timewarpLerpFactor);\n"
+ //" 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"
+
+ " oColor = Color.r; // Used for vignette fade.\n"
+ "}\n";
+
+static const char* PostProcessMeshPositionalTimewarpPixelShaderSrc =
+ "Texture2D Texture : register(t0);\n"
+ "SamplerState Linear : register(s0);\n"
+ "float2 DepthDimSize;\n"
+ "\n"
"float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n"
- " in float2 oTexCoord : TEXCOORD0) : SV_Target\n"
+ " in float2 oTexCoord0 : TEXCOORD0, in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2) : SV_Target\n"
"{\n"
- " float2 theta = (oTexCoord - LensCenter) * ScaleIn;\n" // Scales to [-1, 1]
- " float rSq = theta.x * theta.x + theta.y * theta.y;\n"
- " float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
- " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
- " \n"
- " // Detect whether blue texture coordinates are out of range since these will scaled out the furthest.\n"
- " float2 thetaBlue = theta1 * (ChromAbParam.z + ChromAbParam.w * rSq);\n"
- " float2 tcBlue = LensCenter + Scale * thetaBlue;\n"
- " if (any(clamp(tcBlue, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tcBlue))\n"
- " return 0;\n"
- " \n"
- " // Now do blue texture lookup.\n"
- " float blue = Texture.Sample(Linear, tcBlue).b;\n"
- " \n"
- " // Do green lookup (no scaling).\n"
- " float2 tcGreen = LensCenter + Scale * theta1;\n"
- " float4 greenColor = Texture.Sample(Linear, tcGreen);\n"
- " float green = greenColor.g;\n"
- " float alpha = greenColor.a;\n"
- " \n"
- " // Do red scale and lookup.\n"
- " float2 thetaRed = theta1 * (ChromAbParam.x + ChromAbParam.y * rSq);\n"
- " float2 tcRed = LensCenter + Scale * thetaRed;\n"
- " float red = Texture.Sample(Linear, tcRed).r;\n"
- " \n"
- " return float4(red, green, blue, alpha);\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"
"}\n";
+//----------------------------------------------------------------------------
static const char* VShaderSrcs[VShader_Count] =
{
DirectVertexShaderSrc,
StdVertexShaderSrc,
- PostProcessVertexShaderSrc
+ PostProcessVertexShaderSrc,
+ PostProcessMeshVertexShaderSrc,
+ PostProcessMeshTimewarpVertexShaderSrc,
+ PostProcessMeshPositionalTimewarpVertexShaderSrc
};
static const char* FShaderSrcs[FShader_Count] =
{
@@ -309,11 +519,13 @@ static const char* FShaderSrcs[FShader_Count] =
GouraudPixelShaderSrc,
TexturePixelShaderSrc,
AlphaTexturePixelShaderSrc,
- PostProcessPixelShaderSrc,
PostProcessPixelShaderWithChromAbSrc,
LitSolidPixelShaderSrc,
LitTexturePixelShaderSrc,
- MultiTexturePixelShaderSrc
+ MultiTexturePixelShaderSrc,
+ PostProcessMeshPixelShaderSrc,
+ PostProcessMeshTimewarpPixelShaderSrc,
+ PostProcessMeshPositionalTimewarpPixelShaderSrc
};
RenderDevice::RenderDevice(const RendererParams& p, HWND window)
@@ -322,8 +534,8 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window)
GetClientRect(window, &rc);
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;
- WindowWidth = width;
- WindowHeight = height;
+ ::OVR::Render::RenderDevice::SetWindowSize(width, height);
+
Window = window;
Params = p;
@@ -359,17 +571,18 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window)
UpdateMonitorOutputs();
}
- int flags = 0;
+ int flags = D3D10_CREATE_DEVICE_BGRA_SUPPORT; //0;
#if (OVR_D3D_VERSION == 10)
- hr = D3D10CreateDevice(Adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D1x_(SDK_VERSION),
+ hr = D3D10CreateDevice1(Adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D10_FEATURE_LEVEL_10_1, D3D10_1_SDK_VERSION,
&Device.GetRawRef());
Context = Device;
Context->AddRef();
#else //11
+ D3D_FEATURE_LEVEL featureLevel; // TODO: Limit certain features based on D3D feature level
hr = D3D11CreateDevice(Adapter, Adapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE,
NULL, flags, NULL, 0, D3D1x_(SDK_VERSION),
- &Device.GetRawRef(), NULL, &Context.GetRawRef());
+ &Device.GetRawRef(), &featureLevel, &Context.GetRawRef());
#endif
if (FAILED(hr))
return;
@@ -387,25 +600,43 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window)
MaxTextureSet[i] = 0;
}
- ID3D10Blob* vsData = CompileShader("vs_4_0", DirectVertexShaderSrc);
+ ID3D10Blob* vsData = CompileShader("vs_4_1", DirectVertexShaderSrc);
VertexShaders[VShader_MV] = *new VertexShader(this, vsData);
for(int i = 1; i < VShader_Count; i++)
{
- VertexShaders[i] = *new VertexShader(this, CompileShader("vs_4_0", VShaderSrcs[i]));
+ OVR_ASSERT ( VShaderSrcs[i] != NULL ); // You forgot a shader!
+ ID3D10Blob *pShader = CompileShader("vs_4_1", VShaderSrcs[i]);
+ VertexShaders[i] = NULL;
+ if ( pShader != NULL )
+ {
+ VertexShaders[i] = *new VertexShader(this, pShader);
+ }
}
for(int i = 0; i < FShader_Count; i++)
{
- PixelShaders[i] = *new PixelShader(this, CompileShader("ps_4_0", FShaderSrcs[i]));
+ OVR_ASSERT ( FShaderSrcs[i] != NULL ); // You forgot a shader!
+ ID3D10Blob *pShader = CompileShader("ps_4_1", FShaderSrcs[i]);
+ PixelShaders[i] = NULL;
+ if ( pShader != NULL )
+ {
+ PixelShaders[i] = *new PixelShader(this, pShader);
+ }
}
SPInt bufferSize = vsData->GetBufferSize();
const void* buffer = vsData->GetBufferPointer();
ID3D1xInputLayout** objRef = &ModelVertexIL.GetRawRef();
-
- HRESULT validate = Device->CreateInputLayout(ModelVertexDesc, 5, buffer, bufferSize, objRef);
+ 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);
+
Ptr<ShaderSet> gouraudShaders = *new ShaderSet();
gouraudShaders->SetShader(VertexShaders[VShader_MVP]);
gouraudShaders->SetShader(PixelShaders[FShader_Gouraud]);
@@ -433,7 +664,7 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window)
D3D1x_(RASTERIZER_DESC) rs;
memset(&rs, 0, sizeof(rs));
- rs.AntialiasedLineEnable = true;
+ rs.AntialiasedLineEnable = false; // You can't just turn this on - it needs alpha modes etc setting up and doesn't work with Z buffers.
rs.CullMode = D3D1x_(CULL_BACK);
// rs.CullMode = D3D1x_(CULL_NONE);
rs.DepthClipEnable = true;
@@ -568,10 +799,11 @@ bool RenderDevice::RecreateSwapChain()
DXGI_SWAP_CHAIN_DESC scDesc;
memset(&scDesc, 0, sizeof(scDesc));
scDesc.BufferCount = 1;
- scDesc.BufferDesc.Width = WindowWidth;
+ scDesc.BufferDesc.Width = WindowWidth;
scDesc.BufferDesc.Height = WindowHeight;
scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- scDesc.BufferDesc.RefreshRate.Numerator = 60;
+ // Use default refresh rate; switching rate on CC prototype can cause screen lockup.
+ scDesc.BufferDesc.RefreshRate.Numerator = 0;
scDesc.BufferDesc.RefreshRate.Denominator = 1;
scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scDesc.OutputWindow = Window;
@@ -621,18 +853,60 @@ bool RenderDevice::SetParams(const RendererParams& newParams)
UpdateMonitorOutputs(true);
}
- // Cause this to be recreated with the new multisample mode.
- pSceneColorTex = NULL;
return RecreateSwapChain();
}
+
+ovrRenderAPIConfig RenderDevice::Get_ovrRenderAPIConfig() const
+{
+#if (OVR_D3D_VERSION == 10)
+ static ovrD3D10Config cfg;
+ cfg.D3D10.Header.API = ovrRenderAPI_D3D10;
+ cfg.D3D10.Header.RTSize = Sizei(WindowWidth, WindowHeight);
+ cfg.D3D10.Header.Multisample = Params.Multisample;
+ cfg.D3D10.pDevice = Device;
+ cfg.D3D10.pBackBufferRT = BackBufferRT;
+ cfg.D3D10.pSwapChain = SwapChain;
+#else
+ static ovrD3D11Config cfg;
+ cfg.D3D11.Header.API = ovrRenderAPI_D3D11;
+ cfg.D3D11.Header.RTSize = Sizei(WindowWidth, WindowHeight);
+ cfg.D3D11.Header.Multisample = Params.Multisample;
+ cfg.D3D11.pDevice = Device;
+ cfg.D3D11.pDeviceContext = Context;
+ cfg.D3D11.pBackBufferRT = BackBufferRT;
+ cfg.D3D11.pSwapChain = SwapChain;
+#endif
+ return cfg.Config;
+}
+
+ovrTexture Texture::Get_ovrTexture()
+{
+ ovrTexture tex;
+
+ OVR::Sizei newRTSize(Width, Height);
+
+#if (OVR_D3D_VERSION == 10)
+ ovrD3D10TextureData* texData = (ovrD3D10TextureData*)&tex;
+ texData->Header.API = ovrRenderAPI_D3D10;
+#else
+ ovrD3D11TextureData* texData = (ovrD3D11TextureData*)&tex;
+ texData->Header.API = ovrRenderAPI_D3D11;
+#endif
+ texData->Header.TextureSize = newRTSize;
+ texData->Header.RenderViewport = Recti(newRTSize);
+ texData->pTexture = Tex;
+ texData->pSRView = TexSv;
+
+ return tex;
+}
void RenderDevice::SetWindowSize(int w, int h)
{
if (w == WindowWidth && h == WindowHeight)
return;
- WindowWidth = w;
- WindowHeight = h;
+ ::OVR::Render::RenderDevice::SetWindowSize(w, h);
+
Context->OMSetRenderTargets(0, NULL, NULL);
BackBuffer = NULL;
BackBufferRT = NULL;
@@ -698,32 +972,24 @@ bool RenderDevice::SetFullscreen(DisplayMode fullscreen)
return true;
}
-void RenderDevice::SetMultipleViewports(int n, const Viewport* vps)
+void RenderDevice::SetViewport(const Recti& vp)
{
- if (n > 2)
- {
- n = 2;
- }
- for(int i = 0; i < n; i++)
- {
#if (OVR_D3D_VERSION == 10)
- Viewports[i].Width = vps[i].w;
- Viewports[i].Height = vps[i].h;
- Viewports[i].MinDepth = 0;
- Viewports[i].MaxDepth = 1;
- Viewports[i].TopLeftX = vps[i].x;
- Viewports[i].TopLeftY = vps[i].y;
+ D3DViewport.Width = vp.w;
+ D3DViewport.Height = vp.h;
+ D3DViewport.MinDepth = 0;
+ D3DViewport.MaxDepth = 1;
+ D3DViewport.TopLeftX = vp.x;
+ D3DViewport.TopLeftY = vp.y;
#else
- Viewports[i].Width = (float)vps[i].w;
- Viewports[i].Height = (float)vps[i].h;
- Viewports[i].MinDepth = 0;
- Viewports[i].MaxDepth = 1;
- Viewports[i].TopLeftX = (float)vps[i].x;
- Viewports[i].TopLeftY = (float)vps[i].y;
+ D3DViewport.Width = (float)vp.w;
+ D3DViewport.Height = (float)vp.h;
+ D3DViewport.MinDepth = 0;
+ D3DViewport.MaxDepth = 1;
+ D3DViewport.TopLeftX = (float)vp.x;
+ D3DViewport.TopLeftY = (float)vp.y;
#endif
- }
- NumViewports = n;
- Context->RSSetViewports(n, Viewports);
+ Context->RSSetViewports(1,&D3DViewport);
}
static int GetDepthStateIndex(bool enable, bool write, RenderDevice::CompareFunc func)
@@ -754,7 +1020,7 @@ void RenderDevice::SetDepthMode(bool enable, bool write, CompareFunc func)
case Compare_Less: dss.DepthFunc = D3D1x_(COMPARISON_LESS); break;
case Compare_Greater: dss.DepthFunc = D3D1x_(COMPARISON_GREATER); break;
default:
- assert(0);
+ OVR_ASSERT(0);
}
dss.DepthWriteMask = write ? D3D1x_(DEPTH_WRITE_MASK_ALL) : D3D1x_(DEPTH_WRITE_MASK_ZERO);
Device->CreateDepthStencilState(&dss, &DepthStates[index].GetRawRef());
@@ -782,70 +1048,27 @@ Texture* RenderDevice::GetDepthBuffer(int w, int h, int ms)
return newDepth.GetPtr();
}
-void RenderDevice::Clear(float r, float g, float b, float a, float depth)
+void RenderDevice::Clear(float r /*= 0*/, float g /*= 0*/, float b /*= 0*/, float a /*= 1*/,
+ float depth /*= 1*/,
+ bool clearColor /*= true*/, bool clearDepth /*= true*/)
{
- const float color[] = {r, g, b, a};
-
- // save state that is affected by clearing this way
- ID3D1xDepthStencilState* oldDepthState = CurDepthState;
- StandardUniformData clearUniforms;
-
- SetDepthMode(true, true, Compare_Always);
-
- Context->IASetInputLayout(ModelVertexIL);
-#if (OVR_D3D_VERSION == 10)
- Context->GSSetShader(NULL);
-#else
- Context->GSSetShader(NULL, NULL, 0);
-#endif
- //Shader<Shader_Geometry,ID3D1xGeometryShader> NullGS(this,(ID3D1xGeometryShader*)NULL);
- //NullGS.Set(Prim_TriangleStrip);
-
- ID3D1xShaderResourceView* sv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
- if (MaxTextureSet[Shader_Fragment])
- {
- Context->PSSetShaderResources(0, MaxTextureSet[Shader_Fragment], sv);
- }
-
- ID3D1xBuffer* vertexBuffer = QuadVertexBuffer->GetBuffer();
- UINT vertexStride = sizeof(Vertex);
- UINT vertexOffset = 0;
- Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
-
- clearUniforms.View = Matrix4f(2, 0, 0, 0,
- 0, 2, 0, 0,
- 0, 0, 0, 0,
- -1, -1, depth, 1);
- UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, &clearUniforms, sizeof(clearUniforms));
-
- ID3D1xBuffer* vertexConstants = UniformBuffers[Shader_Vertex]->GetBuffer();
- Context->VSSetConstantBuffers(0, 1, &vertexConstants);
- Context->IASetPrimitiveTopology(D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP));
- VertexShaders[VShader_MV]->Set(Prim_TriangleStrip);
- PixelShaders[FShader_Solid]->Set(Prim_TriangleStrip);
-
- UniformBuffers[Shader_Pixel]->Data(Buffer_Uniform, color, sizeof(color));
- PixelShaders[FShader_Solid]->SetUniformBuffer(UniformBuffers[Shader_Pixel]);
-
- if (NumViewports > 1)
+ if ( clearColor )
{
- for(int i = 0; i < NumViewports; i++)
+ const float color[] = {r, g, b, a};
+ if ( CurRenderTarget == NULL )
+ {
+ Context->ClearRenderTargetView ( BackBufferRT.GetRawRef(), color );
+ }
+ else
{
- Context->RSSetViewports(1, &Viewports[i]);
- Context->OMSetBlendState(NULL, NULL, 0xffffffff);
- Context->Draw(4, 0);
+ Context->ClearRenderTargetView ( CurRenderTarget->TexRtv, color );
}
- Context->RSSetViewports(NumViewports, Viewports);
}
- else
+
+ if ( clearDepth )
{
- Context->OMSetBlendState(NULL, NULL, 0xffffffff);
- Context->Draw(4, 0);
+ Context->ClearDepthStencilView ( CurDepthBuffer->TexDsv, D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL, depth, 0 );
}
-
- // reset
- CurDepthState = oldDepthState;
- Context->OMSetDepthStencilState(CurDepthState, 0);
}
// Buffers
@@ -1280,6 +1503,11 @@ Texture::Texture(RenderDevice* ren, int fmt, int w, int h) : Ren(ren), Tex(NULL)
Sampler = Ren->GetSamplerState(0);
}
+void* Texture::GetInternalImplementation()
+{
+ return Tex;
+}
+
Texture::~Texture()
{
}
@@ -1312,6 +1540,10 @@ void RenderDevice::SetTexture(Render::ShaderStage stage, int slot, const Texture
case Shader_Vertex:
Context->VSSetShaderResources(slot, 1, &sv);
+ if (t)
+ {
+ Context->VSSetSamplers(slot, 1, &t->Sampler.GetRawRef());
+ }
break;
}
}
@@ -1501,10 +1733,22 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
}
else
{
+ int samples = (format & Texture_SamplesMask);
+ if (samples < 1)
+ {
+ samples = 1;
+ }
+
+ bool createDepthSrv = (format & Texture_SampleDepth) > 0;
+
DXGI_FORMAT d3dformat;
int bpp;
switch(format & Texture_TypeMask)
{
+ case Texture_BGRA:
+ bpp = 4;
+ d3dformat = DXGI_FORMAT_B8G8R8A8_UNORM;
+ break;
case Texture_RGBA:
bpp = 4;
d3dformat = DXGI_FORMAT_R8G8B8A8_UNORM;
@@ -1513,30 +1757,28 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
bpp = 1;
d3dformat = DXGI_FORMAT_R8_UNORM;
break;
+ case Texture_A:
+ bpp = 1;
+ d3dformat = DXGI_FORMAT_A8_UNORM;
+ break;
case Texture_Depth:
bpp = 0;
- d3dformat = DXGI_FORMAT_D32_FLOAT;
+ d3dformat = createDepthSrv ? DXGI_FORMAT_R32_TYPELESS : DXGI_FORMAT_D32_FLOAT;
break;
default:
return NULL;
}
- int samples = (format & Texture_SamplesMask);
- if (samples < 1)
- {
- samples = 1;
- }
-
Texture* NewTex = new Texture(this, format, width, height);
NewTex->Samples = samples;
D3D1x_(TEXTURE2D_DESC) dsDesc;
- dsDesc.Width = width;
- dsDesc.Height = height;
+ dsDesc.Width = width;
+ dsDesc.Height = height;
dsDesc.MipLevels = (format == (Texture_RGBA | Texture_GenMipmaps) && data) ? GetNumMipLevels(width, height) : 1;
dsDesc.ArraySize = 1;
dsDesc.Format = d3dformat;
- dsDesc.SampleDesc.Count = samples;
+ dsDesc.SampleDesc.Count = samples;
dsDesc.SampleDesc.Quality = 0;
dsDesc.Usage = D3D1x_(USAGE_DEFAULT);
dsDesc.BindFlags = D3D1x_(BIND_SHADER_RESOURCE);
@@ -1546,9 +1788,8 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
if (format & Texture_RenderTarget)
{
if ((format & Texture_TypeMask) == Texture_Depth)
- // We don't use depth textures, and creating them in d3d10 requires different options.
{
- dsDesc.BindFlags = D3D1x_(BIND_DEPTH_STENCIL);
+ dsDesc.BindFlags = createDepthSrv ? (dsDesc.BindFlags | D3D1x_(BIND_DEPTH_STENCIL)) : D3D1x_(BIND_DEPTH_STENCIL);
}
else
{
@@ -1565,7 +1806,19 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
}
if (dsDesc.BindFlags & D3D1x_(BIND_SHADER_RESOURCE))
{
- Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef());
+ if((dsDesc.BindFlags & D3D1x_(BIND_DEPTH_STENCIL)) > 0 && createDepthSrv)
+ {
+ D3D1x_(SHADER_RESOURCE_VIEW_DESC) depthSrv;
+ depthSrv.Format = DXGI_FORMAT_R32_FLOAT;
+ depthSrv.ViewDimension = samples > 1 ? D3D1x_(SRV_DIMENSION_TEXTURE2DMS) : D3D1x_(SRV_DIMENSION_TEXTURE2D);
+ depthSrv.Texture2D.MostDetailedMip = 0;
+ depthSrv.Texture2D.MipLevels = dsDesc.MipLevels;
+ Device->CreateShaderResourceView(NewTex->Tex, &depthSrv, &NewTex->TexSv.GetRawRef());
+ }
+ else
+ {
+ Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef());
+ }
}
if (data)
@@ -1611,7 +1864,12 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
{
if ((format & Texture_TypeMask) == Texture_Depth)
{
- Device->CreateDepthStencilView(NewTex->Tex, NULL, &NewTex->TexDsv.GetRawRef());
+ D3D1x_(DEPTH_STENCIL_VIEW_DESC) depthDsv;
+ ZeroMemory(&depthDsv, sizeof(depthDsv));
+ depthDsv.Format = DXGI_FORMAT_D32_FLOAT;
+ depthDsv.ViewDimension = samples > 1 ? D3D1x_(DSV_DIMENSION_TEXTURE2DMS) : D3D1x_(DSV_DIMENSION_TEXTURE2D);
+ depthDsv.Texture2D.MipSlice = 0;
+ Device->CreateDepthStencilView(NewTex->Tex, createDepthSrv ? &depthDsv : NULL, &NewTex->TexDsv.GetRawRef());
}
else
{
@@ -1703,38 +1961,54 @@ 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)
+ const Matrix4f& matrix, int offset, int count, PrimitiveType rprim, bool useDistortionVertex/* = false*/)
{
- Context->IASetInputLayout(ModelVertexIL);
+ ID3D1xBuffer* vertexBuffer = ((Buffer*)vertices)->GetBuffer();
+ UINT vertexOffset = offset;
+ UINT vertexStride = sizeof(Vertex);
+ if ( useDistortionVertex )
+ {
+ Context->IASetInputLayout(DistortionVertexIL);
+ vertexStride = sizeof(DistortionVertex);
+ }
+ else
+ {
+ Context->IASetInputLayout(ModelVertexIL);
+ vertexStride = sizeof(Vertex);
+ }
+ Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
+
if (indices)
{
Context->IASetIndexBuffer(((Buffer*)indices)->GetBuffer(), DXGI_FORMAT_R16_UINT, 0);
}
- ID3D1xBuffer* vertexBuffer = ((Buffer*)vertices)->GetBuffer();
- UINT vertexStride = sizeof(Vertex);
- UINT vertexOffset = offset;
- Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
-
ShaderSet* shaders = ((ShaderFill*)fill)->GetShaders();
ShaderBase* vshader = ((ShaderBase*)shaders->GetShader(Shader_Vertex));
unsigned char* vertexData = vshader->UniformData;
- if (vertexData)
+ if ( vertexData != NULL )
{
- StandardUniformData* stdUniforms = (StandardUniformData*) vertexData;
- stdUniforms->View = matrix.Transposed();
- stdUniforms->Proj = StdUniforms.Proj;
+ // TODO: some VSes don't start with StandardUniformData!
+ if ( vshader->UniformsSize >= sizeof(StandardUniformData) )
+ {
+ StandardUniformData* stdUniforms = (StandardUniformData*) vertexData;
+ stdUniforms->View = matrix.Transposed();
+ stdUniforms->Proj = StdUniforms.Proj;
+ }
+
UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, vertexData, vshader->UniformsSize);
vshader->SetUniformBuffer(UniformBuffers[Shader_Vertex]);
}
for(int i = Shader_Vertex + 1; i < Shader_Count; i++)
+ {
if (shaders->GetShader(i))
{
((ShaderBase*)shaders->GetShader(i))->UpdateBuffer(UniformBuffers[i]);
((ShaderBase*)shaders->GetShader(i))->SetUniformBuffer(UniformBuffers[i]);
}
+ }
D3D1x_(PRIMITIVE_TOPOLOGY) prim;
switch(rprim)
@@ -1749,7 +2023,7 @@ void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Bu
prim = D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
break;
default:
- assert(0);
+ OVR_ASSERT(0);
return;
}
Context->IASetPrimitiveTopology(prim);
@@ -1782,20 +2056,40 @@ UPInt RenderDevice::QueryGPUMemorySize()
}
-void RenderDevice::Present()
+void RenderDevice::Present ( bool withVsync )
{
- SwapChain->Present(0, 0);
+ if( OVR::Util::ImageWindow::GlobalWindow() )
+ {
+ OVR::Util::ImageWindow::GlobalWindow()->Process();
+ }
+
+ if ( withVsync )
+ {
+ SwapChain->Present(1, 0);
+ }
+ else
+ {
+ // Immediate present
+ SwapChain->Present(0, 0);
+ }
}
-void RenderDevice::ForceFlushGPU()
+void RenderDevice::WaitUntilGpuIdle()
{
+#if 0
+ // If enabling this option and using an NVIDIA GPU,
+ // then make sure your "max pre-rendered frames" is set to 1 under the NVIDIA GPU settings.
+
+ // Flush GPU data and don't stall CPU waiting for GPU to complete
+ Context->Flush();
+#else
+ // 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 (Device->CreateQuery(&queryDesc, &query.GetRawRef()) == S_OK)
{
-
#if (OVR_D3D_VERSION == 10)
// Begin() not used for EVENT query.
query->End();
@@ -1808,10 +2102,10 @@ void RenderDevice::ForceFlushGPU()
do { }
while(!done && !FAILED(Context->GetData(query, &done, sizeof(BOOL), 0)));
#endif
-
}
-}
+#endif
+}
void RenderDevice::FillRect(float left, float top, float right, float bottom, Color c)
{
@@ -1841,5 +2135,27 @@ void RenderDevice::RenderImage(float left, float top, float right, float bottom,
Context->OMSetBlendState(NULL, NULL, 0xffffffff);
}
+void RenderDevice::BeginGpuEvent(const char* markerText, UInt32 markerColor)
+{
+#if GPU_PROFILING
+ WCHAR wStr[255];
+ size_t newStrLen = 0;
+ mbstowcs_s(&newStrLen, wStr, markerText, 255);
+ LPCWSTR pwStr = wStr;
+
+ D3DPERF_BeginEvent(markerColor, pwStr);
+#else
+ OVR_UNUSED(markerText);
+ OVR_UNUSED(markerColor);
+#endif
+}
+
+void RenderDevice::EndGpuEvent()
+{
+#if GPU_PROFILING
+ D3DPERF_EndEvent();
+#endif
+}
+
}}}
diff --git a/Samples/CommonSrc/Render/Render_D3D1X_Device.h b/Samples/CommonSrc/Render/Render_D3D1X_Device.h
index b615e2b..e06bcda 100644
--- a/Samples/CommonSrc/Render/Render_D3D1X_Device.h
+++ b/Samples/CommonSrc/Render/Render_D3D1X_Device.h
@@ -42,7 +42,7 @@ limitations under the License.
#if (OVR_D3D_VERSION == 10)
#define _OVR_RENDERER_D3D10
-#include <d3d10.h>
+#include <d3d10_1.h>
namespace OVR { namespace Render { namespace D3D10 {
@@ -64,8 +64,8 @@ class RenderDevice;
#endif
#if (OVR_D3D_VERSION == 10)
-typedef ID3D10Device ID3D1xDevice;
-typedef ID3D10Device ID3D1xDeviceContext;
+typedef ID3D10Device1 ID3D1xDevice;
+typedef ID3D10Device1 ID3D1xDeviceContext;
typedef ID3D10RenderTargetView ID3D1xRenderTargetView;
typedef ID3D10Texture2D ID3D1xTexture2D;
typedef ID3D10ShaderResourceView ID3D1xShaderResourceView;
@@ -73,6 +73,7 @@ typedef ID3D10DepthStencilView ID3D1xDepthStencilView;
typedef ID3D10DepthStencilState ID3D1xDepthStencilState;
typedef ID3D10InputLayout ID3D1xInputLayout;
typedef ID3D10Buffer ID3D1xBuffer;
+typedef ID3D10Resource ID3D1xResource;
typedef ID3D10VertexShader ID3D1xVertexShader;
typedef ID3D10PixelShader ID3D1xPixelShader;
typedef ID3D10GeometryShader ID3D1xGeometryShader;
@@ -96,6 +97,7 @@ typedef ID3D11DepthStencilView ID3D1xDepthStencilView;
typedef ID3D11DepthStencilState ID3D1xDepthStencilState;
typedef ID3D11InputLayout ID3D1xInputLayout;
typedef ID3D11Buffer ID3D1xBuffer;
+typedef ID3D11Resource ID3D1xResource;
typedef ID3D10Blob ID3D1xBlob;
typedef ID3D11VertexShader ID3D1xVertexShader;
typedef ID3D11PixelShader ID3D1xPixelShader;
@@ -201,11 +203,12 @@ public:
class Texture : public Render::Texture
{
public:
- RenderDevice* Ren;
+ RenderDevice* Ren;
Ptr<ID3D1xTexture2D> Tex;
Ptr<ID3D1xShaderResourceView> TexSv;
Ptr<ID3D1xRenderTargetView> TexRtv;
Ptr<ID3D1xDepthStencilView> TexDsv;
+ Ptr<ID3D1xTexture2D> TexStaging;
mutable Ptr<ID3D1xSamplerState> Sampler;
int Width, Height;
int Samples;
@@ -229,6 +232,11 @@ public:
virtual void SetSampleMode(int sm);
virtual void Set(int slot, Render::ShaderStage stage = Render::Shader_Fragment) const;
+
+ virtual ovrTexture Get_ovrTexture();
+
+ virtual void* GetInternalImplementation();
+
};
class RenderDevice : public Render::RenderDevice
@@ -251,12 +259,12 @@ public:
Ptr<Texture> CurDepthBuffer;
Ptr<ID3D1xRasterizerState> Rasterizer;
Ptr<ID3D1xBlendState> BlendState;
- int NumViewports;
- D3D1x_VIEWPORT Viewports[2];
+ D3D1x_VIEWPORT D3DViewport;
Ptr<ID3D1xDepthStencilState> DepthStates[1 + 2 * Compare_Count];
Ptr<ID3D1xDepthStencilState> CurDepthState;
Ptr<ID3D1xInputLayout> ModelVertexIL;
+ Ptr<ID3D1xInputLayout> DistortionVertexIL;
Ptr<ID3D1xSamplerState> SamplerStates[Sample_Count];
@@ -292,18 +300,22 @@ public:
// and it should be recreated.
void UpdateMonitorOutputs(bool needRecreate = false);
- virtual void SetMultipleViewports(int n, const Viewport* vps);
+ virtual void SetViewport(const Recti& vp);
virtual void SetWindowSize(int w, int h);
virtual bool SetParams(const RendererParams& newParams);
- //virtual void SetScissor(int x, int y, int w, int h);
- virtual void Present();
- virtual void ForceFlushGPU();
+ // Returns details needed by CAPI distortion rendering.
+ virtual ovrRenderAPIConfig Get_ovrRenderAPIConfig() const;
+
+ virtual void Present ( bool withVsync );
+ virtual void WaitUntilGpuIdle();
virtual bool SetFullscreen(DisplayMode fullscreen);
virtual UPInt QueryGPUMemorySize();
- virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1, float depth = 1);
+ virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1,
+ float depth = 1,
+ bool clearColor = true, bool clearDepth = true);
virtual void Rect(float left, float top, float right, float bottom)
{
OVR_UNUSED4(left, top, right, bottom);
@@ -331,7 +343,6 @@ public:
ExtraShaders = s;
}
-
// Overrident to apply proper blend state.
virtual void FillRect(float left, float top, float right, float bottom, Color c);
virtual void FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm);
@@ -340,7 +351,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);
+ const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles, bool useDistortionVertex = false);
virtual void RenderWithAlpha( const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices,
const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles);
@@ -355,6 +366,10 @@ public:
ID3D1xSamplerState* GetSamplerState(int sm);
void SetTexture(Render::ShaderStage stage, int slot, const Texture* t);
+
+ // GPU Profiling
+ virtual void BeginGpuEvent(const char* markerText, UInt32 markerColor);
+ virtual void EndGpuEvent();
};
}}}
diff --git a/Samples/CommonSrc/Render/Render_Device.cpp b/Samples/CommonSrc/Render/Render_Device.cpp
index d0f3228..e917fb0 100644
--- a/Samples/CommonSrc/Render/Render_Device.cpp
+++ b/Samples/CommonSrc/Render/Render_Device.cpp
@@ -25,107 +25,112 @@ limitations under the License.
#include "../Render/Render_Font.h"
#include "Kernel/OVR_Log.h"
+#include "Util/Util_Render_Stereo.h"
+using namespace OVR::Util::Render;
namespace OVR { namespace Render {
-void Model::Render(const Matrix4f& ltw, RenderDevice* ren)
-{
- if(Visible)
- {
- Matrix4f m = ltw * GetMatrix();
- ren->Render(m, this);
- }
-}
-
-void Container::Render(const Matrix4f& ltw, RenderDevice* ren)
-{
- Matrix4f m = ltw * GetMatrix();
- for(unsigned i = 0; i < Nodes.GetSize(); i++)
- {
- Nodes[i]->Render(m, ren);
- }
-}
-
-Matrix4f SceneView::GetViewMatrix() const
-{
- Matrix4f view = Matrix4f(GetOrientation().Conj()) * Matrix4f::Translation(GetPosition());
- return view;
-}
-
-void LightingParams::Update(const Matrix4f& view, const Vector4f* SceneLightPos)
-{
- Version++;
- for (int i = 0; i < LightCount; i++)
- {
- LightPos[i] = view.Transform(SceneLightPos[i]);
- }
-}
-
-void Scene::Render(RenderDevice* ren, const Matrix4f& view)
-{
- Lighting.Update(view, LightPos);
-
- ren->SetLighting(&Lighting);
-
- World.Render(view, ren);
-}
-
-
-
-UInt16 CubeIndices[] =
-{
- 0, 1, 3,
- 3, 1, 2,
-
- 5, 4, 6,
- 6, 4, 7,
-
- 8, 9, 11,
- 11, 9, 10,
-
- 13, 12, 14,
- 14, 12, 15,
-
- 16, 17, 19,
- 19, 17, 18,
-
- 21, 20, 22,
- 22, 20, 23
-};
-
-// Colors are specified for planes perpendicular to the axis
-// For example, "xColor" is the color of the y-z plane
-Model* Model::CreateAxisFaceColorBox(float x1, float x2, Color xcolor,
- float y1, float y2, Color ycolor,
- float z1, float z2, Color zcolor)
-{
- float t;
-
- if(x1 > x2)
- {
- t = x1;
- x1 = x2;
- x2 = t;
- }
- if(y1 > y2)
- {
- t = y1;
- y1 = y2;
- y2 = t;
- }
- if(z1 > z2)
- {
- t = z1;
- z1 = z2;
- z2 = t;
- }
-
- Model* box = new Model();
-
- UInt16 startIndex = 0;
- // Cube
- startIndex =
- box->AddVertex(Vector3f(x1, y2, z1), ycolor);
+ void Model::Render(const Matrix4f& ltw, RenderDevice* ren)
+ {
+ if(Visible)
+ {
+ AutoGpuProf prof(ren, "Model_Render");
+ Matrix4f m = ltw * GetMatrix();
+ ren->Render(m, this);
+ }
+ }
+
+ void Container::Render(const Matrix4f& ltw, RenderDevice* ren)
+ {
+ Matrix4f m = ltw * GetMatrix();
+ for(unsigned i = 0; i < Nodes.GetSize(); i++)
+ {
+ Nodes[i]->Render(m, ren);
+ }
+ }
+
+ Matrix4f SceneView::GetViewMatrix() const
+ {
+ Matrix4f view = Matrix4f(GetOrientation().Conj()) * Matrix4f::Translation(GetPosition());
+ return view;
+ }
+
+ void LightingParams::Update(const Matrix4f& view, const Vector3f* SceneLightPos)
+ {
+ Version++;
+ for (int i = 0; i < LightCount; i++)
+ {
+ LightPos[i] = view.Transform(SceneLightPos[i]);
+ }
+ }
+
+ void Scene::Render(RenderDevice* ren, const Matrix4f& view)
+ {
+ AutoGpuProf prof(ren, "Scene_Render");
+
+ Lighting.Update(view, LightPos);
+
+ ren->SetLighting(&Lighting);
+
+ World.Render(view, ren);
+ }
+
+
+
+ UInt16 CubeIndices[] =
+ {
+ 0, 1, 3,
+ 3, 1, 2,
+
+ 5, 4, 6,
+ 6, 4, 7,
+
+ 8, 9, 11,
+ 11, 9, 10,
+
+ 13, 12, 14,
+ 14, 12, 15,
+
+ 16, 17, 19,
+ 19, 17, 18,
+
+ 21, 20, 22,
+ 22, 20, 23
+ };
+
+ // Colors are specified for planes perpendicular to the axis
+ // For example, "xColor" is the color of the y-z plane
+ Model* Model::CreateAxisFaceColorBox(float x1, float x2, Color xcolor,
+ float y1, float y2, Color ycolor,
+ float z1, float z2, Color zcolor)
+ {
+ float t;
+
+ if(x1 > x2)
+ {
+ t = x1;
+ x1 = x2;
+ x2 = t;
+ }
+ if(y1 > y2)
+ {
+ t = y1;
+ y1 = y2;
+ y2 = t;
+ }
+ if(z1 > z2)
+ {
+ t = z1;
+ z1 = z2;
+ z2 = t;
+ }
+
+ Model* box = new Model();
+
+ UInt16 startIndex = 0;
+ // Cube
+ startIndex =
+ box->AddVertex(Vector3f(x1, y2, z1), ycolor);
box->AddVertex(Vector3f(x2, y2, z1), ycolor);
box->AddVertex(Vector3f(x2, y2, z2), ycolor);
box->AddVertex(Vector3f(x1, y2, z2), ycolor);
@@ -156,960 +161,1233 @@ Model* Model::CreateAxisFaceColorBox(float x1, float x2, Color xcolor,
box->AddVertex(Vector3f(x1, y2, z2), zcolor);
- enum
- {
- // CubeVertexCount = sizeof(CubeVertices)/sizeof(CubeVertices[0]),
- CubeIndexCount = sizeof(CubeIndices) / sizeof(CubeIndices[0])
- };
-
- // Renumber indices
- for(int i = 0; i < CubeIndexCount / 3; i++)
- {
- box->AddTriangle(CubeIndices[i * 3] + startIndex,
- CubeIndices[i * 3 + 1] + startIndex,
- CubeIndices[i * 3 + 2] + startIndex);
- }
-
- return box;
-}
-
-void Model::AddSolidColorBox(float x1, float y1, float z1,
- float x2, float y2, float z2,
- Color c)
-{
- float t;
-
- if(x1 > x2)
- {
- t = x1;
- x1 = x2;
- x2 = t;
- }
- if(y1 > y2)
- {
- t = y1;
- y1 = y2;
- y2 = t;
- }
- if(z1 > z2)
- {
- t = z1;
- z1 = z2;
- z2 = t;
- }
-
- // 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)
- };
-
-
- UInt16 startIndex = GetNextVertexIndex();
-
- enum
- {
- CubeVertexCount = sizeof(CubeVertices) / sizeof(CubeVertices[0]),
- CubeIndexCount = sizeof(CubeIndices) / sizeof(CubeIndices[0])
- };
-
- for(int v = 0; v < CubeVertexCount; v++)
- {
- AddVertex(Vertex(CubeVertices[v][0], c, CubeVertices[v][1].x, CubeVertices[v][1].y, CubeVertices[v][2]));
- }
-
- // Renumber indices
- for(int i = 0; i < CubeIndexCount / 3; i++)
- {
- AddTriangle(CubeIndices[i * 3] + startIndex,
- CubeIndices[i * 3 + 1] + startIndex,
- CubeIndices[i * 3 + 2] + startIndex);
- }
-}
-
-
-
-Model* Model::CreateBox(Color c, Vector3f origin, Vector3f size)
-{
- Model *box = new Model();
- Vector3f s = size * 0.5f;
-
- box->AddVertex(-s.x, s.y, -s.z, c, 0, 1, 0, 0, -1);
- box->AddVertex(s.x, s.y, -s.z, c, 1, 1, 0, 0, -1);
- box->AddVertex(s.x, -s.y, -s.z, c, 1, 0, 0, 0, -1);
- box->AddVertex(-s.x, -s.y, -s.z, c, 0, 0, 0, 0, -1);
- box->AddTriangle(2, 1, 0);
- box->AddTriangle(0, 3, 2);
-
- box->AddVertex(s.x, s.y, s.z, c, 1, 1, 0, 0, 1);
- box->AddVertex(-s.x, s.y, s.z, c, 0, 1, 0, 0, 1);
- box->AddVertex(-s.x, -s.y, s.z, c, 0, 0, 0, 0, 1);
- box->AddVertex(s.x, -s.y, s.z, c, 1, 0, 0, 0, 1);
- box->AddTriangle(6, 5, 4);
- box->AddTriangle(4, 7, 6);
-
- box->AddVertex(-s.x, s.y, -s.z, c, 1, 0, -1, 0, 0);
- box->AddVertex(-s.x, s.y, s.z, c, 1, 1, -1, 0, 0);
- box->AddVertex(-s.x, -s.y, s.z, c, 0, 1, -1, 0, 0);
- box->AddVertex(-s.x, -s.y, -s.z, c, 0, 0, -1, 0, 0);
- box->AddTriangle(10, 11, 8);
- box->AddTriangle(8, 9, 10);
-
- box->AddVertex(s.x, s.y, -s.z, c, 1, 0, 1, 0, 0);
- box->AddVertex(s.x, -s.y, -s.z, c, 0, 0, 1, 0, 0);
- box->AddVertex(s.x, -s.y, s.z, c, 0, 1, 1, 0, 0);
- box->AddVertex(s.x, s.y, s.z, c, 1, 1, 1, 0, 0);
- box->AddTriangle(14, 15, 12);
- box->AddTriangle(12, 13, 14);
-
- box->AddVertex(-s.x, -s.y, s.z, c, 0, 1, 0, -1, 0);
- box->AddVertex(s.x, -s.y, s.z, c, 1, 1, 0, -1, 0);
- box->AddVertex(s.x, -s.y, -s.z, c, 1, 0, 0, -1, 0);
- box->AddVertex(-s.x, -s.y, -s.z, c, 0, 0, 0, -1, 0);
- box->AddTriangle(18, 19, 16);
- box->AddTriangle(16, 17, 18);
-
- box->AddVertex(-s.x, s.y, -s.z, c, 0, 0, 0, 1, 0);
- box->AddVertex(s.x, s.y, -s.z, c, 1, 0, 0, 1, 0);
- box->AddVertex(s.x, s.y, s.z, c, 1, 1, 0, 1, 0);
- box->AddVertex(-s.x, s.y, s.z, c, 0, 1, 0, 1, 0);
- box->AddTriangle(20, 21, 22);
- box->AddTriangle(22, 23, 20);
-
- box->SetPosition(origin);
- return box;
-}
-
-// Triangulation of a cylinder centered at the origin
-Model* Model::CreateCylinder(Color color, Vector3f origin, float height, float radius, int sides)
-{
- Model *cyl = new Model();
- float halfht = height * 0.5f;
- for(UInt16 i = 0; i < sides; i++)
- {
- float x = cosf(Math<float>::TwoPi * i / float(sides));
- float y = sinf(Math<float>::TwoPi * i / float(sides));
-
- cyl->AddVertex(radius * x, radius * y, halfht, color, x + 1, y, 0, 0, 1);
- cyl->AddVertex(radius * x, radius * y, -1.0f*halfht, color, x, y, 0, 0, -1);
-
- UInt16 j = 0;
- if(i < sides - 1)
- {
- j = i + 1;
- cyl->AddTriangle(0, i * 4 + 4, i * 4);
- cyl->AddTriangle(1, i * 4 + 1, i * 4 + 5);
- }
-
- float nx = cosf(Math<float>::Pi * (0.5f + 2.0f * i / float(sides)));
- float ny = sinf(Math<float>::Pi * (0.5f + 2.0f * i / float(sides)));
- cyl->AddVertex(radius * x, radius * y, halfht, color, x + 1, y, nx, ny, 0);
- cyl->AddVertex(radius * x, radius * y, -1.0f*halfht, color, x, y, nx, ny, 0);
-
- cyl->AddTriangle(i * 4 + 2, j * 4 + 2, i * 4 + 3);
- cyl->AddTriangle(i * 4 + 3, j * 4 + 2, j * 4 + 3);
- }
- cyl->SetPosition(origin);
- return cyl;
-};
-
-//Triangulation of a cone centered at the origin
-Model* Model::CreateCone(Color color, Vector3f origin, float height, float radius, int sides)
-{
- Model *cone = new Model();
- float halfht = height * 0.5f;
- cone->AddVertex(0.0f, 0.0f, -1.0f*halfht, color, 0, 0, 0, 0, -1);
-
- for(UInt16 i = 0; i < sides; i++)
- {
- float x = cosf(Math<float>::TwoPi * i / float(sides));
- float y = sinf(Math<float>::TwoPi * i / float(sides));
-
- cone->AddVertex(radius * x, radius * y, -1.0f*halfht, color, 0, 0, 0, 0, -1);
-
- UInt16 j = 1;
- if(i < sides - 1)
- {
- j = i + 1;
- }
-
- float next_x = cosf(Math<float>::TwoPi * j / float(sides));
- float next_y = sinf(Math<float>::TwoPi * j / float(sides));
-
- Vector3f normal = Vector3f(x, y, -halfht).Cross(Vector3f(next_x, next_y, -halfht));
-
- cone->AddVertex(0.0f, 0.0f, halfht, color, 1, 0, normal.x, normal.y, normal.z);
- cone->AddVertex(radius * x, radius * y, -1.0f*halfht, color, 0, 0, normal.x, normal.y, normal.z);
-
- cone->AddTriangle(0, 3*i + 1, 3*j + 1);
- cone->AddTriangle(3*i + 2, 3*j + 3, 3*i + 3);
- }
- cone->SetPosition(origin);
- return cone;
-};
-
-//Triangulation of a sphere centered at the origin
-Model* Model::CreateSphere(Color color, Vector3f origin, float radius, int sides)
-{
- Model *sphere = new Model();
- UInt16 usides = (UInt16) sides;
- UInt16 halfsides = usides/2;
-
- for(UInt16 k = 0; k < halfsides; k++) {
-
- float z = cosf(Math<float>::Pi * k / float(halfsides));
- float z_r = sinf(Math<float>::Pi * k / float(halfsides)); // the radius of the cross circle with coordinate z
-
- if (k == 0)
- { // add north and south poles
- sphere->AddVertex(0.0f, 0.0f, radius, color, 0, 0, 0, 0, 1);
- sphere->AddVertex(0.0f, 0.0f, -radius, color, 1, 1, 0, 0, -1);
- }
- else
- {
- for(UInt16 i = 0; i < sides; i++)
- {
- float x = cosf(Math<float>::TwoPi * i / float(sides)) * z_r;
- float y = sinf(Math<float>::TwoPi * i / float(sides)) * z_r;
-
- UInt16 j = 0;
- if(i < sides - 1)
- {
- j = i + 1;
- }
-
- sphere->AddVertex(radius * x, radius * y, radius * z, color, 0, 1, x, y, z);
-
- UInt16 indi = 2 + (k -1)*usides + i;
- UInt16 indj = 2 + (k -1)*usides + j;
- if (k == 1) // NorthPole
- sphere->AddTriangle(0, j + 2, i + 2);
- else if (k == halfsides - 1) //SouthPole
- {
- sphere->AddTriangle(1, indi, indj);
- sphere->AddTriangle(indi, indi - usides, indj);
- sphere->AddTriangle(indi - usides, indj - usides, indj);
- }
- else
- {
- sphere->AddTriangle(indi, indi - usides, indj);
- sphere->AddTriangle(indi - usides, indj - usides, indj);
- }
- }
- } // end else
- }
- sphere->SetPosition(origin);
- return sphere;
-};
-
-Model* Model::CreateGrid(Vector3f origin, Vector3f stepx, Vector3f stepy,
- int halfx, int halfy, int nmajor, Color minor, Color major)
-{
- Model* grid = new Model(Prim_Lines);
- float halfxf = (float)halfx;
- float halfyf = (float)halfy;
-
- for(int jn = 0; jn <= halfy; jn++)
- {
- float j = (float)jn;
-
- grid->AddLine(grid->AddVertex((stepx * -halfxf) + (stepy * j), (jn % nmajor) ? minor : major, 0, 0.5f),
- grid->AddVertex((stepx * halfxf) + (stepy * j), (jn % nmajor) ? minor : major, 1, 0.5f));
-
- if(j)
- grid->AddLine(grid->AddVertex((stepx * -halfxf) + (stepy * -j), (jn % nmajor) ? minor : major, 0, 0.5f),
- grid->AddVertex((stepx * halfxf) + (stepy * -j), (jn % nmajor) ? minor : major, 1, 0.5f));
- }
-
- for(int in = 0; in <= halfx; in++)
- {
- float i = (float)in;
-
- grid->AddLine(grid->AddVertex((stepx * i) + (stepy * -halfyf), (in % nmajor) ? minor : major, 0, 0.5f),
- grid->AddVertex((stepx * i) + (stepy * halfyf), (in % nmajor) ? minor : major, 1, 0.5f));
-
- if(i)
- grid->AddLine(grid->AddVertex((stepx * -i) + (stepy * -halfyf), (in % nmajor) ? minor : major, 0, 0.5f),
- grid->AddVertex((stepx * -i) + (stepy * halfyf), (in % nmajor) ? minor : major, 1, 0.5f));
- }
-
- grid->SetPosition(origin);
- return grid;
-}
-
-
-//-------------------------------------------------------------------------------------
-
-
-void ShaderFill::Set(PrimitiveType prim) const
-{
- Shaders->Set(prim);
- for(int i = 0; i < 8; i++)
- if(Textures[i])
- {
- Textures[i]->Set(i);
- }
-}
-
-
-
-//-------------------------------------------------------------------------------------
-// ***** Rendering
-
-
-RenderDevice::RenderDevice()
- : CurPostProcess(PostProcess_None),
- SceneColorTexW(0), SceneColorTexH(0),
- SceneRenderScale(1),
-
- Distortion(1.0f, 0.18f, 0.115f),
- DistortionClearColor(0, 0, 0),
- PostProcessShaderActive(PostProcessShader_DistortionAndChromAb),
- TotalTextureMemoryUsage(0)
-{
- PostProcessShaderRequested = PostProcessShaderActive;
-}
-
-Fill* RenderDevice::CreateTextureFill(Render::Texture* t, bool useAlpha)
-{
- ShaderSet* shaders = CreateShaderSet();
- shaders->SetShader(LoadBuiltinShader(Shader_Vertex, VShader_MVP));
- shaders->SetShader(LoadBuiltinShader(Shader_Fragment, useAlpha ? FShader_AlphaTexture : FShader_Texture));
- Fill* f = new ShaderFill(*shaders);
- f->SetTexture(0, t);
- return f;
-}
-
-void LightingParams::Set(ShaderSet* s) const
-{
- s->SetUniform4fv("Ambient", 1, &Ambient);
- s->SetUniform1f("LightCount", LightCount);
- s->SetUniform4fv("LightPos", (int)LightCount, LightPos);
- s->SetUniform4fv("LightColor", (int)LightCount, LightColor);
-}
-
-void RenderDevice::SetLighting(const LightingParams* lt)
-{
- if (!LightingBuffer)
- LightingBuffer = *CreateBuffer();
-
- LightingBuffer->Data(Buffer_Uniform, lt, sizeof(LightingParams));
- SetCommonUniformBuffer(1, LightingBuffer);
-}
-
-float RenderDevice::MeasureText(const Font* font, const char* str, float size, float* strsize)
-{
- UPInt length = strlen(str);
- float w = 0;
- float xp = 0;
- float yp = 0;
-
- for (UPInt i = 0; i < length; i++)
- {
- if(str[i] == '\n')
- {
- yp += font->lineheight;
- if(xp > w)
- {
- w = xp;
- }
- xp = 0;
- continue;
- }
-
- // Tab followed by a numbers sets position to specified offset.
- if(str[i] == '\t')
- {
- char *p = 0;
- float tabPixels = (float)OVR_strtoq(str + i + 1, &p, 10);
- i += p - (str + i + 1);
- xp = tabPixels;
- }
- else
- {
- const Font::Char* ch = &font->chars[str[i]];
- xp += ch->advance;
- }
- }
-
- if(xp > w)
- {
- w = xp;
- }
-
- if(strsize)
- {
- strsize[0] = (size / font->lineheight) * w;
- strsize[1] = (size / font->lineheight) * (yp + font->lineheight);
- }
- return (size / font->lineheight) * w;
-}
-
-void RenderDevice::RenderText(const Font* font, const char* str,
- float x, float y, float size, Color c)
-{
- if(!pTextVertexBuffer)
- {
- pTextVertexBuffer = *CreateBuffer();
- if(!pTextVertexBuffer)
- {
- return;
- }
- }
-
- if(!font->fill)
- {
- font->fill = CreateTextureFill(Ptr<Texture>(
- *CreateTexture(Texture_R, font->twidth, font->theight, font->tex)), true);
- }
-
- UPInt length = strlen(str);
-
- pTextVertexBuffer->Data(Buffer_Vertex, NULL, length * 6 * sizeof(Vertex));
- Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, length * 6 * sizeof(Vertex), Map_Discard);
- if(!vertices)
- {
- return;
- }
+ enum
+ {
+ // CubeVertexCount = sizeof(CubeVertices)/sizeof(CubeVertices[0]),
+ CubeIndexCount = sizeof(CubeIndices) / sizeof(CubeIndices[0])
+ };
+
+ // Renumber indices
+ for(int i = 0; i < CubeIndexCount / 3; i++)
+ {
+ box->AddTriangle(CubeIndices[i * 3] + startIndex,
+ CubeIndices[i * 3 + 1] + startIndex,
+ CubeIndices[i * 3 + 2] + startIndex);
+ }
+
+ return box;
+ }
+
+ void Model::AddSolidColorBox(float x1, float y1, float z1,
+ float x2, float y2, float z2,
+ Color c)
+ {
+ float t;
+
+ if(x1 > x2)
+ {
+ t = x1;
+ x1 = x2;
+ x2 = t;
+ }
+ if(y1 > y2)
+ {
+ t = y1;
+ y1 = y2;
+ y2 = t;
+ }
+ if(z1 > z2)
+ {
+ t = z1;
+ z1 = z2;
+ z2 = t;
+ }
+
+ // 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)
+ };
+
+
+ UInt16 startIndex = GetNextVertexIndex();
+
+ enum
+ {
+ CubeVertexCount = sizeof(CubeVertices) / sizeof(CubeVertices[0]),
+ CubeIndexCount = sizeof(CubeIndices) / sizeof(CubeIndices[0])
+ };
+
+ for(int v = 0; v < CubeVertexCount; v++)
+ {
+ AddVertex(Vertex(CubeVertices[v][0], c, CubeVertices[v][1].x, CubeVertices[v][1].y, CubeVertices[v][2]));
+ }
+
+ // Renumber indices
+ for(int i = 0; i < CubeIndexCount / 3; i++)
+ {
+ AddTriangle(CubeIndices[i * 3] + startIndex,
+ CubeIndices[i * 3 + 1] + startIndex,
+ CubeIndices[i * 3 + 2] + startIndex);
+ }
+ }
+
+ // Adds box at specified location to current vertices.
+ void Model::AddBox(Color c, Vector3f origin, Vector3f size)
+ {
+ Vector3f s = size * 0.5f;
+ Vector3f o = origin;
+ UInt16 i = GetNextVertexIndex();
+
+ AddVertex(-s.x + o.x, s.y + o.y, -s.z + o.z, c, 0, 1, 0, 0, -1);
+ AddVertex(s.x + o.x, s.y + o.y, -s.z + o.z, c, 1, 1, 0, 0, -1);
+ AddVertex(s.x + o.x, -s.y + o.y, -s.z + o.z, c, 1, 0, 0, 0, -1);
+ AddVertex(-s.x + o.x, -s.y + o.y, -s.z + o.z, c, 0, 0, 0, 0, -1);
+ AddTriangle(2 + i, 1 + i, 0 + i);
+ AddTriangle(0 + i, 3 + i, 2 + i);
+
+ AddVertex(s.x + o.x, s.y + o.y, s.z + o.z, c, 1, 1, 0, 0, 1);
+ AddVertex(-s.x+ o.x, s.y + o.y, s.z + o.z, c, 0, 1, 0, 0, 1);
+ AddVertex(-s.x+ o.x, -s.y + o.y, s.z + o.z, c, 0, 0, 0, 0, 1);
+ AddVertex(s.x + o.x, -s.y + o.y, s.z + o.z, c, 1, 0, 0, 0, 1);
+ AddTriangle(6 + i, 5 + i, 4 + i);
+ AddTriangle(4 + i, 7 + i, 6 + i);
+
+ AddVertex(-s.x + o.x, s.y + o.y, -s.z + o.z, c, 1, 0, -1, 0, 0);
+ AddVertex(-s.x + o.x, s.y + o.y, s.z + o.z, c, 1, 1, -1, 0, 0);
+ AddVertex(-s.x + o.x, -s.y + o.y, s.z + o.z, c, 0, 1, -1, 0, 0);
+ AddVertex(-s.x + o.x, -s.y + o.y, -s.z + o.z, c, 0, 0, -1, 0, 0);
+ AddTriangle(10 + i, 11 + i, 8 + i);
+ AddTriangle(8 + i, 9 + i, 10 + i);
+
+ AddVertex(s.x + o.x, s.y + o.y, -s.z + o.z, c, 1, 0, 1, 0, 0);
+ AddVertex(s.x + o.x, -s.y + o.y, -s.z + o.z, c, 0, 0, 1, 0, 0);
+ AddVertex(s.x + o.x, -s.y + o.y, s.z + o.z, c, 0, 1, 1, 0, 0);
+ AddVertex(s.x + o.x, s.y + o.y, s.z + o.z, c, 1, 1, 1, 0, 0);
+ AddTriangle(14 + i, 15 + i, 12 + i);
+ AddTriangle(12 + i, 13 + i, 14 + i);
+
+ AddVertex(-s.x+ o.x, -s.y + o.y, s.z + o.z, c, 0, 1, 0, -1, 0);
+ AddVertex(s.x + o.x, -s.y + o.y, s.z + o.z, c, 1, 1, 0, -1, 0);
+ AddVertex(s.x + o.x, -s.y + o.y, -s.z + o.z, c, 1, 0, 0, -1, 0);
+ AddVertex(-s.x+ o.x, -s.y + o.y, -s.z + o.z, c, 0, 0, 0, -1, 0);
+ AddTriangle(18 + i, 19 + i, 16 + i);
+ AddTriangle(16 + i, 17 + i, 18 + i);
+
+ AddVertex(-s.x + o.x, s.y + o.y, -s.z + o.z, c, 0, 0, 0, 1, 0);
+ AddVertex(s.x + o.x, s.y + o.y, -s.z + o.z, c, 1, 0, 0, 1, 0);
+ AddVertex(s.x + o.x, s.y + o.y, s.z + o.z, c, 1, 1, 0, 1, 0);
+ AddVertex(-s.x + o.x, s.y + o.y, s.z + o.z, c, 0, 1, 0, 1, 0);
+ AddTriangle(20 + i, 21 + i, 22 + i);
+ AddTriangle(22 + i, 23 + i, 20 + i);
+ }
+
+
+ Model* Model::CreateBox(Color c, Vector3f origin, Vector3f size)
+ {
+ Model *box = new Model();
+ box->AddBox(c, Vector3f(0), size);
+ box->SetPosition(origin);
+ return box;
+ }
+
+ // Triangulation of a cylinder centered at the origin
+ Model* Model::CreateCylinder(Color color, Vector3f origin, float height, float radius, int sides)
+ {
+ Model *cyl = new Model();
+ float halfht = height * 0.5f;
+ for(UInt16 i = 0; i < sides; i++)
+ {
+ float x = cosf(Math<float>::TwoPi * i / float(sides));
+ float y = sinf(Math<float>::TwoPi * i / float(sides));
+
+ cyl->AddVertex(radius * x, radius * y, halfht, color, x + 1, y, 0, 0, 1);
+ cyl->AddVertex(radius * x, radius * y, -1.0f*halfht, color, x, y, 0, 0, -1);
+
+ UInt16 j = 0;
+ if(i < sides - 1)
+ {
+ j = i + 1;
+ cyl->AddTriangle(0, i * 4 + 4, i * 4);
+ cyl->AddTriangle(1, i * 4 + 1, i * 4 + 5);
+ }
+
+ float nx = cosf(Math<float>::Pi * (0.5f + 2.0f * i / float(sides)));
+ float ny = sinf(Math<float>::Pi * (0.5f + 2.0f * i / float(sides)));
+ cyl->AddVertex(radius * x, radius * y, halfht, color, x + 1, y, nx, ny, 0);
+ cyl->AddVertex(radius * x, radius * y, -1.0f*halfht, color, x, y, nx, ny, 0);
+
+ cyl->AddTriangle(i * 4 + 2, j * 4 + 2, i * 4 + 3);
+ cyl->AddTriangle(i * 4 + 3, j * 4 + 2, j * 4 + 3);
+ }
+ cyl->SetPosition(origin);
+ return cyl;
+ };
+
+ //Triangulation of a cone centered at the origin
+ Model* Model::CreateCone(Color color, Vector3f origin, float height, float radius, int sides)
+ {
+ Model *cone = new Model();
+ float halfht = height * 0.5f;
+ cone->AddVertex(0.0f, 0.0f, -1.0f*halfht, color, 0, 0, 0, 0, -1);
+
+ for(UInt16 i = 0; i < sides; i++)
+ {
+ float x = cosf(Math<float>::TwoPi * i / float(sides));
+ float y = sinf(Math<float>::TwoPi * i / float(sides));
+
+ cone->AddVertex(radius * x, radius * y, -1.0f*halfht, color, 0, 0, 0, 0, -1);
+
+ UInt16 j = 1;
+ if(i < sides - 1)
+ {
+ j = i + 1;
+ }
+
+ float next_x = cosf(Math<float>::TwoPi * j / float(sides));
+ float next_y = sinf(Math<float>::TwoPi * j / float(sides));
+
+ Vector3f normal = Vector3f(x, y, -halfht).Cross(Vector3f(next_x, next_y, -halfht));
+
+ cone->AddVertex(0.0f, 0.0f, halfht, color, 1, 0, normal.x, normal.y, normal.z);
+ cone->AddVertex(radius * x, radius * y, -1.0f*halfht, color, 0, 0, normal.x, normal.y, normal.z);
+
+ cone->AddTriangle(0, 3*i + 1, 3*j + 1);
+ cone->AddTriangle(3*i + 2, 3*j + 3, 3*i + 3);
+ }
+ cone->SetPosition(origin);
+ return cone;
+ };
+
+ //Triangulation of a sphere centered at the origin
+ Model* Model::CreateSphere(Color color, Vector3f origin, float radius, int sides)
+ {
+ Model *sphere = new Model();
+ UInt16 usides = (UInt16) sides;
+ UInt16 halfsides = usides/2;
+
+ for(UInt16 k = 0; k < halfsides; k++) {
+
+ float z = cosf(Math<float>::Pi * k / float(halfsides));
+ float z_r = sinf(Math<float>::Pi * k / float(halfsides)); // the radius of the cross circle with coordinate z
+
+ if (k == 0)
+ { // add north and south poles
+ sphere->AddVertex(0.0f, 0.0f, radius, color, 0, 0, 0, 0, 1);
+ sphere->AddVertex(0.0f, 0.0f, -radius, color, 1, 1, 0, 0, -1);
+ }
+ else
+ {
+ for(UInt16 i = 0; i < sides; i++)
+ {
+ float x = cosf(Math<float>::TwoPi * i / float(sides)) * z_r;
+ float y = sinf(Math<float>::TwoPi * i / float(sides)) * z_r;
- Matrix4f m = Matrix4f(size / font->lineheight, 0, 0, 0,
- 0, size / font->lineheight, 0, 0,
- 0, 0, 0, 0,
- x, y, 0, 1).Transposed();
+ UInt16 j = 0;
+ if(i < sides - 1)
+ {
+ j = i + 1;
+ }
- float xp = 0, yp = (float)font->ascent;
- int ivertex = 0;
+ sphere->AddVertex(radius * x, radius * y, radius * z, color, 0, 1, x, y, z);
- for (UPInt i = 0; i < length; i++)
- {
- if(str[i] == '\n')
- {
- yp += font->lineheight;
- xp = 0;
- continue;
- }
- // Tab followed by a numbers sets position to specified offset.
- if(str[i] == '\t')
- {
- char *p = 0;
- float tabPixels = (float)OVR_strtoq(str + i + 1, &p, 10);
- i += p - (str + i + 1);
- xp = tabPixels;
- continue;
- }
-
- const Font::Char* ch = &font->chars[str[i]];
- Vertex* chv = &vertices[ivertex];
- for(int j = 0; j < 6; j++)
- {
- chv[j].C = c;
- }
- float x = xp + ch->x;
- float y = yp - ch->y;
- float cx = font->twidth * (ch->u2 - ch->u1);
- float cy = font->theight * (ch->v2 - ch->v1);
- chv[0] = Vertex(Vector3f(x, y, 0), c, ch->u1, ch->v1);
- chv[1] = Vertex(Vector3f(x + cx, y, 0), c, ch->u2, ch->v1);
- chv[2] = Vertex(Vector3f(x + cx, cy + y, 0), c, ch->u2, ch->v2);
- chv[3] = Vertex(Vector3f(x, y, 0), c, ch->u1, ch->v1);
- chv[4] = Vertex(Vector3f(x + cx, cy + y, 0), c, ch->u2, ch->v2);
- chv[5] = Vertex(Vector3f(x, y + cy, 0), c, ch->u1, ch->v2);
- ivertex += 6;
-
- xp += ch->advance;
- }
-
- pTextVertexBuffer->Unmap(vertices);
+ UInt16 indi = 2 + (k -1)*usides + i;
+ UInt16 indj = 2 + (k -1)*usides + j;
+ if (k == 1) // NorthPole
+ sphere->AddTriangle(0, j + 2, i + 2);
+ else if (k == halfsides - 1) //SouthPole
+ {
+ sphere->AddTriangle(1, indi, indj);
+ sphere->AddTriangle(indi, indi - usides, indj);
+ sphere->AddTriangle(indi - usides, indj - usides, indj);
+ }
+ else
+ {
+ sphere->AddTriangle(indi, indi - usides, indj);
+ sphere->AddTriangle(indi - usides, indj - usides, indj);
+ }
+ }
+ } // end else
+ }
+ sphere->SetPosition(origin);
+ return sphere;
+ };
- Render(font->fill, pTextVertexBuffer, NULL, m, 0, ivertex, Prim_Triangles);
-}
+ Model* Model::CreateGrid(Vector3f origin, Vector3f stepx, Vector3f stepy,
+ int halfx, int halfy, int nmajor, Color minor, Color major)
+ {
+ Model* grid = new Model(Prim_Lines);
+ float halfxf = (float)halfx;
+ float halfyf = (float)halfy;
-void RenderDevice::FillRect(float left, float top, float right, float bottom, Color c)
-{
- if(!pTextVertexBuffer)
- {
- pTextVertexBuffer = *CreateBuffer();
- if(!pTextVertexBuffer)
- {
- return;
- }
- }
+ for(int jn = 0; jn <= halfy; jn++)
+ {
+ float j = (float)jn;
- // Get!!
- Fill* fill = CreateSimpleFill();
+ grid->AddLine(grid->AddVertex((stepx * -halfxf) + (stepy * j), (jn % nmajor) ? minor : major, 0, 0.5f),
+ grid->AddVertex((stepx * halfxf) + (stepy * j), (jn % nmajor) ? minor : major, 1, 0.5f));
- pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
- Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
- if(!vertices)
- {
- return;
- }
+ if(j)
+ grid->AddLine(grid->AddVertex((stepx * -halfxf) + (stepy * -j), (jn % nmajor) ? minor : major, 0, 0.5f),
+ grid->AddVertex((stepx * halfxf) + (stepy * -j), (jn % nmajor) ? minor : major, 1, 0.5f));
+ }
- vertices[0] = Vertex(Vector3f(left, top, 0.0f), c);
- vertices[1] = Vertex(Vector3f(right, top, 0), c);
- vertices[2] = Vertex(Vector3f(left, bottom, 0), c);
- vertices[3] = Vertex(Vector3f(left, bottom, 0), c);
- vertices[4] = Vertex(Vector3f(right, top, 0), c);
- vertices[5] = Vertex(Vector3f(right, bottom, 0), c);
+ for(int in = 0; in <= halfx; in++)
+ {
+ float i = (float)in;
- pTextVertexBuffer->Unmap(vertices);
+ grid->AddLine(grid->AddVertex((stepx * i) + (stepy * -halfyf), (in % nmajor) ? minor : major, 0, 0.5f),
+ grid->AddVertex((stepx * i) + (stepy * halfyf), (in % nmajor) ? minor : major, 1, 0.5f));
- Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
-}
+ if(i)
+ grid->AddLine(grid->AddVertex((stepx * -i) + (stepy * -halfyf), (in % nmajor) ? minor : major, 0, 0.5f),
+ grid->AddVertex((stepx * -i) + (stepy * halfyf), (in % nmajor) ? minor : major, 1, 0.5f));
+ }
-void RenderDevice::FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm)
-{
- if(!pTextVertexBuffer)
- {
- pTextVertexBuffer = *CreateBuffer();
- if(!pTextVertexBuffer)
- {
- return;
- }
- }
+ grid->SetPosition(origin);
+ return grid;
+ }
- // Get!!
- Fill* fill = CreateSimpleFill();
- pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
- Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
- if(!vertices)
- {
- return;
- }
+ //-------------------------------------------------------------------------------------
- vertices[0] = Vertex(Vector3f(left, top, 0.0f), col_top);
- vertices[1] = Vertex(Vector3f(right, top, 0), col_top);
- vertices[2] = Vertex(Vector3f(left, bottom, 0), col_btm);
- vertices[3] = Vertex(Vector3f(left, bottom, 0), col_btm);
- vertices[4] = Vertex(Vector3f(right, top, 0), col_top);
- vertices[5] = Vertex(Vector3f(right, bottom, 0), col_btm);
-
- pTextVertexBuffer->Unmap(vertices);
-
- Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
-}
-
-void RenderDevice::RenderImage(float left,
- float top,
- float right,
- float bottom,
- ShaderFill* image,
- unsigned char alpha)
-{
- /*
- if(!pTextVertexBuffer)
- {
- pTextVertexBuffer = *CreateBuffer();
- if(!pTextVertexBuffer)
- {
- return;
- }
- }
- pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
- Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
- if(!vertices)
- {
- return;
- }
+ void ShaderFill::Set(PrimitiveType prim) const
+ {
+ Shaders->Set(prim);
- vertices[0] = Vertex(Vector3f(left, top, 0.0f), Color(255, 255, 255, 255));
- vertices[1] = Vertex(Vector3f(right, top, 0), Color(255, 255, 255, 255));
- vertices[2] = Vertex(Vector3f(left, bottom, 0), Color(255, 255, 255, 255));
- vertices[3] = Vertex(Vector3f(left, bottom, 0), Color(255, 255, 255, 255));
- vertices[4] = Vertex(Vector3f(right, top, 0), Color(255, 255, 255, 255));
- vertices[5] = Vertex(Vector3f(right, bottom, 0), Color(255, 255, 255, 255));
-
- pTextVertexBuffer->Unmap(vertices);
-
- Render(image, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
- */
-
- Color c = Color(255, 255, 255, alpha);
- Ptr<Model> m = *new Model(Prim_Triangles);
- m->AddVertex(left, bottom, 0.0f, c, 0.0f, 0.0f);
- m->AddVertex(right, bottom, 0.0f, c, 1.0f, 0.0f);
- m->AddVertex(right, top, 0.0f, c, 1.0f, 1.0f);
- m->AddVertex(left, top, 0.0f, c, 0.0f, 1.0f);
- m->AddTriangle(2,1,0);
- m->AddTriangle(0,3,2);
- m->Fill = image;
-
- Render(Matrix4f(), m);
-}
-
-/*
-void RenderDevice::GetStereoViewports(const Viewport& in, Viewport* out) const
-{
- out[0] = out[1] = in;
- if (StereoBufferMode == Stereo_SplitH)
- {
- out[0].w = out[1].w = in.w / 2;
- out[1].x += WindowWidth / 2;
- }
-}
-*/
+ for(int i = 0; i < 8 && VtxTextures[i] != NULL; ++i)
+ VtxTextures[i]->Set(i, Shader_Vertex);
-void RenderDevice::SetSceneRenderScale(float ss)
-{
- SceneRenderScale = ss;
- pSceneColorTex = NULL;
-}
+ for (int i = 0; i < 8 && Textures[i] != NULL; ++i)
+ Textures[i]->Set(i);
+ }
-void RenderDevice::SetViewport(const Viewport& vp)
-{
- VP = vp;
- if(CurPostProcess == PostProcess_Distortion)
- {
- Viewport svp = vp;
- svp.w = (int)ceil(SceneRenderScale * vp.w);
- svp.h = (int)ceil(SceneRenderScale * vp.h);
- svp.x = (int)ceil(SceneRenderScale * vp.x);
- svp.y = (int)ceil(SceneRenderScale * vp.y);
- SetRealViewport(svp);
- }
- else
- {
- SetRealViewport(vp);
- }
-}
+ //-------------------------------------------------------------------------------------
+ // ***** Rendering
-bool RenderDevice::initPostProcessSupport(PostProcessType pptype)
-{
- if(pptype != PostProcess_Distortion)
- {
- return true;
- }
+ RenderDevice::RenderDevice()
+ : DistortionClearColor(0, 0, 0),
+ TotalTextureMemoryUsage(0),
+ FadeOutBorderFraction(0)
+ {
+ // Ensure these are different, so that the first time it's run, things actually get initialized.
+ PostProcessShaderActive = PostProcessShader_Count;
+ PostProcessShaderRequested = PostProcessShader_DistortionAndChromAb;
+ }
- if (PostProcessShaderRequested != PostProcessShaderActive)
+ void RenderDevice::Shutdown()
{
+ // This runs before the subclass's Shutdown(), where the context, etc, may be deleted.
+ pTextVertexBuffer.Clear();
pPostProcessShader.Clear();
- PostProcessShaderActive = PostProcessShaderRequested;
- }
-
- if (!pPostProcessShader)
- {
- Shader *vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcess);
-
- Shader *ppfs = NULL;
-
- if (PostProcessShaderActive == PostProcessShader_Distortion)
- {
- ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcess);
- }
- else if (PostProcessShaderActive == PostProcessShader_DistortionAndChromAb)
- {
- ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessWithChromAb);
- }
- else
- OVR_ASSERT(false);
-
- pPostProcessShader = *CreateShaderSet();
- pPostProcessShader->SetShader(vs);
- pPostProcessShader->SetShader(ppfs);
- }
-
-
- int texw = (int)ceil(SceneRenderScale * WindowWidth),
- texh = (int)ceil(SceneRenderScale * WindowHeight);
-
- // If pSceneColorTex is already created and is of correct size, we are done.
- // It's important to check width/height in case window size changed.
- if (pSceneColorTex && (texw == SceneColorTexW) && (texh == SceneColorTexH))
- {
- return true;
- }
-
- pSceneColorTex = *CreateTexture(Texture_RGBA | Texture_RenderTarget | Params.Multisample,
- texw, texh, NULL);
- if(!pSceneColorTex)
- {
- return false;
- }
- SceneColorTexW = texw;
- SceneColorTexH = texh;
- pSceneColorTex->SetSampleMode(Sample_ClampBorder | Sample_Linear);
-
-
- if(!pFullScreenVertexBuffer)
- {
- pFullScreenVertexBuffer = *CreateBuffer();
- const Render::Vertex QuadVertices[] =
- {
- Vertex(Vector3f(0, 1, 0), Color(1, 1, 1, 1), 0, 0),
- Vertex(Vector3f(1, 1, 0), Color(1, 1, 1, 1), 1, 0),
- 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.Clear();
+ pDistortionMeshVertexBuffer[0].Clear();
+ pDistortionMeshVertexBuffer[1].Clear();
+ pDistortionMeshIndexBuffer[0].Clear();
+ pDistortionMeshIndexBuffer[1].Clear();
+ LightingBuffer.Clear();
}
- return true;
-}
-
-void RenderDevice::SetProjection(const Matrix4f& proj)
-{
- Proj = proj;
- SetWorldUniforms(proj);
-}
-
-void RenderDevice::BeginScene(PostProcessType pptype)
-{
- BeginRendering();
-
- if((pptype != PostProcess_None) && initPostProcessSupport(pptype))
- {
- CurPostProcess = pptype;
- }
- else
- {
- CurPostProcess = PostProcess_None;
- }
-
- if(CurPostProcess == PostProcess_Distortion)
- {
- SetRenderTarget(pSceneColorTex);
- SetViewport(VP);
- }
- else
- {
- SetRenderTarget(0);
- }
-
- SetWorldUniforms(Proj);
- SetExtraShaders(NULL);
-}
-
-void RenderDevice::FinishScene()
-{
- SetExtraShaders(0);
- if(CurPostProcess == PostProcess_None)
- {
- return;
- }
-
- SetRenderTarget(0);
- SetRealViewport(VP);
- FinishScene1();
-
- CurPostProcess = PostProcess_None;
-}
-
+ Fill* RenderDevice::CreateTextureFill(Render::Texture* t, bool useAlpha)
+ {
+ ShaderSet* shaders = CreateShaderSet();
+ shaders->SetShader(LoadBuiltinShader(Shader_Vertex, VShader_MVP));
+ shaders->SetShader(LoadBuiltinShader(Shader_Fragment, useAlpha ? FShader_AlphaTexture : FShader_Texture));
+ Fill* f = new ShaderFill(*shaders);
+ f->SetTexture(0, t);
+ return f;
+ }
+
+ void LightingParams::Set(ShaderSet* s) const
+ {
+ s->SetUniform4fvArray("Ambient", 1, &Ambient);
+ s->SetUniform1f("LightCount", LightCount);
+ s->SetUniform4fvArray("LightPos", (int)LightCount, LightPos);
+ s->SetUniform4fvArray("LightColor", (int)LightCount, LightColor);
+ }
+
+ void RenderDevice::SetLighting(const LightingParams* lt)
+ {
+ if (!LightingBuffer)
+ LightingBuffer = *CreateBuffer();
+
+ LightingBuffer->Data(Buffer_Uniform, lt, sizeof(LightingParams));
+ SetCommonUniformBuffer(1, LightingBuffer);
+ }
+
+ float RenderDevice::MeasureText(const Font* font, const char* str, float size, float strsize[2],
+ const UPInt charRange[2], Vector2f charRangeRect[2])
+ {
+ UPInt length = strlen(str);
+ float w = 0;
+ float xp = 0;
+ float yp = 0;
+
+ for (UPInt i = 0; i < length; i++)
+ {
+ if (str[i] == '\n')
+ {
+ yp += font->lineheight;
+ if(xp > w)
+ {
+ w = xp;
+ }
+ xp = 0;
+ continue;
+ }
+
+ // Record top-left charRange rectangle coordinate.
+ if (charRange && charRangeRect && (i == charRange[0]))
+ charRangeRect[0] = Vector2f(xp, yp);
+
+ // Tab followed by a numbers sets position to specified offset.
+ if (str[i] == '\t')
+ {
+ char *p = 0;
+ float tabPixels = (float)OVR_strtoq(str + i + 1, &p, 10);
+ i += p - (str + i + 1);
+ xp = tabPixels;
+ }
+ else
+ {
+ const Font::Char* ch = &font->chars[str[i]];
+ xp += ch->advance;
+ }
+
+ // End of character range.
+ // Store 'xp' after advance, yp will advance later.
+ if (charRange && charRangeRect && (i == charRange[1]))
+ charRangeRect[1] = Vector2f(xp, yp);
+ }
+
+ if (xp > w)
+ {
+ w = xp;
+ }
+
+ float scale = (size / font->lineheight);
+
+ if (strsize)
+ {
+ strsize[0] = scale * w;
+ strsize[1] = scale * (yp + font->lineheight);
+ }
+
+ if (charRange && charRangeRect)
+ {
+ // Selection rectangle ends in teh bottom.
+ charRangeRect[1].y += font->lineheight;
+ charRangeRect[0] *= scale;
+ charRangeRect[1] *= scale;
+ }
+
+ return (size / font->lineheight) * w;
+ }
+
+
+
+
+
+ void RenderDevice::RenderText(const Font* font, const char* str,
+ float x, float y, float size, Color c)
+ {
+ if(!pTextVertexBuffer)
+ {
+ pTextVertexBuffer = *CreateBuffer();
+ if(!pTextVertexBuffer)
+ {
+ return;
+ }
+ }
+
+ if(!font->fill)
+ {
+ font->fill = CreateTextureFill(Ptr<Texture>(
+ *CreateTexture(Texture_R, font->twidth, font->theight, font->tex)), true);
+ }
+
+ UPInt length = strlen(str);
+
+ pTextVertexBuffer->Data(Buffer_Vertex, NULL, length * 6 * sizeof(Vertex));
+ Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, length * 6 * sizeof(Vertex), Map_Discard);
+ if(!vertices)
+ {
+ return;
+ }
+
+ Matrix4f m = Matrix4f(size / font->lineheight, 0, 0, 0,
+ 0, size / font->lineheight, 0, 0,
+ 0, 0, 0, 0,
+ x, y, 0, 1).Transposed();
+
+ float xp = 0, yp = (float)font->ascent;
+ int ivertex = 0;
+
+ for (UPInt i = 0; i < length; i++)
+ {
+ if(str[i] == '\n')
+ {
+ yp += font->lineheight;
+ xp = 0;
+ continue;
+ }
+ // Tab followed by a numbers sets position to specified offset.
+ if(str[i] == '\t')
+ {
+ char *p = 0;
+ float tabPixels = (float)OVR_strtoq(str + i + 1, &p, 10);
+ i += p - (str + i + 1);
+ xp = tabPixels;
+ continue;
+ }
+
+ const Font::Char* ch = &font->chars[str[i]];
+ Vertex* chv = &vertices[ivertex];
+ for(int j = 0; j < 6; j++)
+ {
+ chv[j].C = c;
+ }
+ float x = xp + ch->x;
+ float y = yp - ch->y;
+ float cx = font->twidth * (ch->u2 - ch->u1);
+ float cy = font->theight * (ch->v2 - ch->v1);
+ chv[0] = Vertex(Vector3f(x, y, 0), c, ch->u1, ch->v1);
+ chv[1] = Vertex(Vector3f(x + cx, y, 0), c, ch->u2, ch->v1);
+ chv[2] = Vertex(Vector3f(x + cx, cy + y, 0), c, ch->u2, ch->v2);
+ chv[3] = Vertex(Vector3f(x, y, 0), c, ch->u1, ch->v1);
+ chv[4] = Vertex(Vector3f(x + cx, cy + y, 0), c, ch->u2, ch->v2);
+ chv[5] = Vertex(Vector3f(x, y + cy, 0), c, ch->u1, ch->v2);
+ ivertex += 6;
+
+ xp += ch->advance;
+ }
+
+ pTextVertexBuffer->Unmap(vertices);
+
+ Render(font->fill, pTextVertexBuffer, NULL, m, 0, ivertex, Prim_Triangles);
+ }
+
+ void RenderDevice::FillRect(float left, float top, float right, float bottom, Color c)
+ {
+ if(!pTextVertexBuffer)
+ {
+ pTextVertexBuffer = *CreateBuffer();
+ if(!pTextVertexBuffer)
+ {
+ return;
+ }
+ }
+
+ // Get!!
+ Fill* fill = CreateSimpleFill();
+
+ pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
+ Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
+ if(!vertices)
+ {
+ return;
+ }
+
+ vertices[0] = Vertex(Vector3f(left, top, 0.0f), c);
+ vertices[1] = Vertex(Vector3f(right, top, 0.0f), c);
+ vertices[2] = Vertex(Vector3f(left, bottom, 0.0f), c);
+ vertices[3] = Vertex(Vector3f(left, bottom, 0.0f), c);
+ vertices[4] = Vertex(Vector3f(right, top, 0.0f), c);
+ vertices[5] = Vertex(Vector3f(right, bottom, 0.0f), c);
+
+ pTextVertexBuffer->Unmap(vertices);
+
+ Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
+ }
+
+
+
+ void RenderDevice::FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm)
+ {
+ if(!pTextVertexBuffer)
+ {
+ pTextVertexBuffer = *CreateBuffer();
+ if(!pTextVertexBuffer)
+ {
+ return;
+ }
+ }
+
+ // Get!!
+ Fill* fill = CreateSimpleFill();
+
+ pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
+ Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
+ if(!vertices)
+ {
+ return;
+ }
+
+ vertices[0] = Vertex(Vector3f(left, top, 0.0f), col_top);
+ vertices[1] = Vertex(Vector3f(right, top, 0.0f), col_top);
+ vertices[2] = Vertex(Vector3f(left, bottom, 0.0f), col_btm);
+ vertices[3] = Vertex(Vector3f(left, bottom, 0.0f), col_btm);
+ vertices[4] = Vertex(Vector3f(right, top, 0.0f), col_top);
+ vertices[5] = Vertex(Vector3f(right, bottom, 0.0f), col_btm);
+
+ pTextVertexBuffer->Unmap(vertices);
+
+ Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
+ }
+
+
+ void RenderDevice::FillTexturedRect(float left, float top, float right, float bottom, float ul, float vt, float ur, float vb, Color c, Ptr<Texture> tex)
+ {
+ if(!pTextVertexBuffer)
+ {
+ pTextVertexBuffer = *CreateBuffer();
+ if(!pTextVertexBuffer)
+ {
+ return;
+ }
+ }
+
+ static Fill *fill = NULL;
+ if ( fill == NULL )
+ {
+ fill = CreateTextureFill(tex, false);
+ }
+ fill->SetTexture ( 0, tex );
+
+ pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
+ Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
+ if(!vertices)
+ {
+ return;
+ }
+
+ vertices[0] = Vertex(Vector3f(left, top, 0.0f), c, ul, vt);
+ vertices[1] = Vertex(Vector3f(right, top, 0.0f), c, ur, vt);
+ vertices[2] = Vertex(Vector3f(left, bottom, 0.0f), c, ul, vb);
+ vertices[3] = Vertex(Vector3f(left, bottom, 0.0f), c, ul, vb);
+ vertices[4] = Vertex(Vector3f(right, top, 0.0f), c, ur, vt);
+ vertices[5] = Vertex(Vector3f(right, bottom, 0.0f), c, ur, vb);
+
+ pTextVertexBuffer->Unmap(vertices);
+
+ Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
+ }
+
+
+ void RenderDevice::RenderLines ( int NumLines, Color c, float *x, float *y, float *z /*= NULL*/ )
+ {
+ OVR_ASSERT ( x != NULL );
+ OVR_ASSERT ( y != NULL );
+ // z can be NULL for 2D stuff.
+
+ if(!pTextVertexBuffer)
+ {
+ pTextVertexBuffer = *CreateBuffer();
+ if(!pTextVertexBuffer)
+ {
+ return;
+ }
+ }
+
+ // Get!!
+ Fill* fill = CreateSimpleFill();
+
+ int NumVerts = NumLines * 2;
+
+ pTextVertexBuffer->Data(Buffer_Vertex, NULL, NumVerts * sizeof(Vertex));
+ Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, NumVerts * sizeof(Vertex), Map_Discard);
+ if(!vertices)
+ {
+ return;
+ }
+
+ if ( z != NULL )
+ {
+ for ( int VertNum = 0; VertNum < NumVerts; VertNum++ )
+ {
+ vertices[VertNum] = Vertex(Vector3f(x[VertNum], y[VertNum], z[VertNum]), c);
+ }
+ }
+ else
+ {
+ for ( int VertNum = 0; VertNum < NumVerts; VertNum++ )
+ {
+ vertices[VertNum] = Vertex(Vector3f(x[VertNum], y[VertNum], 1.0f), c);
+ }
+ }
+
+ pTextVertexBuffer->Unmap(vertices);
+
+ Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, NumVerts, Prim_Lines);
+ }
+
+
+
+ void RenderDevice::RenderImage(float left,
+ float top,
+ float right,
+ float bottom,
+ ShaderFill* image,
+ unsigned char alpha)
+ {
+ Color c = Color(255, 255, 255, alpha);
+ Ptr<Model> m = *new Model(Prim_Triangles);
+ m->AddVertex(left, bottom, 0.0f, c, 0.0f, 0.0f);
+ m->AddVertex(right, bottom, 0.0f, c, 1.0f, 0.0f);
+ m->AddVertex(right, top, 0.0f, c, 1.0f, 1.0f);
+ m->AddVertex(left, top, 0.0f, c, 0.0f, 1.0f);
+ m->AddTriangle(2,1,0);
+ m->AddTriangle(0,3,2);
+ m->Fill = image;
+
+ Render(Matrix4f(), m);
+ }
+
+ bool RenderDevice::initPostProcessSupport(PostProcessType pptype)
+ {
+ if(pptype == PostProcess_None)
+ {
+ return true;
+ }
+
+
+ if (PostProcessShaderRequested != PostProcessShaderActive)
+ {
+ pPostProcessShader.Clear();
+ PostProcessShaderActive = PostProcessShaderRequested;
+ }
+
+ if (!pPostProcessShader)
+ {
+ Shader *vs = NULL;
+ Shader *ppfs = NULL;
+
+ if (PostProcessShaderActive == PostProcessShader_DistortionAndChromAb)
+ {
+ ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessWithChromAb);
+ vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcess);
+ }
+ else if (PostProcessShaderActive == PostProcessShader_MeshDistortionAndChromAb)
+ {
+ ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessMeshWithChromAb);
+ vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcessMesh);
+ }
+ else if (PostProcessShaderActive == PostProcessShader_MeshDistortionAndChromAbTimewarp)
+ {
+ 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
+ {
+ OVR_ASSERT(false);
+ }
+ OVR_ASSERT(ppfs); // Means the shader failed to compile - look in the debug spew.
+ OVR_ASSERT(vs);
+
+ pPostProcessShader = *CreateShaderSet();
+ pPostProcessShader->SetShader(vs);
+ pPostProcessShader->SetShader(ppfs);
+ }
+
+
+ if(!pFullScreenVertexBuffer)
+ {
+ pFullScreenVertexBuffer = *CreateBuffer();
+ const Render::Vertex QuadVertices[] =
+ {
+ Vertex(Vector3f(0, 1, 0), Color(1, 1, 1, 1), 0, 0),
+ Vertex(Vector3f(1, 1, 0), Color(1, 1, 1, 1), 1, 0),
+ 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));
+ }
+ return true;
+ }
+
+ void RenderDevice::SetProjection(const Matrix4f& proj)
+ {
+ Proj = proj;
+ SetWorldUniforms(proj);
+ }
+
+ void RenderDevice::BeginScene(PostProcessType pptype)
+ {
+ BeginRendering();
+ initPostProcessSupport(pptype);
+ SetViewport(VP);
+ SetWorldUniforms(Proj);
+ SetExtraShaders(NULL);
+ }
+
+ void RenderDevice::FinishScene()
+ {
+ SetExtraShaders(0);
+ SetRenderTarget(0);
+ }
+
+
+
+ void RenderDevice::PrecalculatePostProcess(PostProcessType pptype,
+ const StereoEyeParams &stereoParamsLeft, const StereoEyeParams &stereoParamsRight,
+ const HmdRenderInfo &hmdRenderInfo )
+ {
+ PostProcessingType = pptype;
+
+ if ( ( pptype == PostProcess_MeshDistortion ) ||
+ ( pptype == PostProcess_MeshDistortionTimewarp ) ||
+ ( pptype == PostProcess_MeshDistortionPositionalTimewarp ) )
+ {
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight;
+
+ // Get the mesh data.
+ int numVerts = 0;
+ int numTris = 0;
+ DistortionMeshVertexData *pRawVerts = NULL;
+ UInt16 *pIndices = NULL;
+ DistortionMeshCreate ( &pRawVerts, &pIndices, &numVerts, &numTris, stereoParams, hmdRenderInfo );
+ int numIndices = numTris * 3;
+
+ // Convert to final vertex data.
+ DistortionVertex *pVerts = (DistortionVertex*)OVR_ALLOC ( sizeof(DistortionVertex) * numVerts );
+ DistortionVertex *pCurVert = pVerts;
+ DistortionMeshVertexData *pCurRawVert = pRawVerts;
+ for ( int vertNum = 0; vertNum < numVerts; vertNum++ )
+ {
+ pCurVert->Pos.x = pCurRawVert->ScreenPosNDC.x;
+ pCurVert->Pos.y = pCurRawVert->ScreenPosNDC.y;
+ pCurVert->TexR = pCurRawVert->TanEyeAnglesR;
+ pCurVert->TexG = pCurRawVert->TanEyeAnglesG;
+ pCurVert->TexB = pCurRawVert->TanEyeAnglesB;
+ // Convert [0.0f,1.0f] to [0,255]
+ pCurVert->Col.R = (OVR::UByte)( floorf ( pCurRawVert->Shade * 255.999f ) );
+ pCurVert->Col.G = pCurVert->Col.R;
+ pCurVert->Col.B = pCurVert->Col.R;
+ pCurVert->Col.A = (OVR::UByte)( floorf ( pCurRawVert->TimewarpLerp * 255.999f ) );
+ pCurRawVert++;
+ pCurVert++;
+ }
-void RenderDevice::FinishScene1()
-{
- float r, g, b, a;
- DistortionClearColor.GetRGBA(&r, &g, &b, &a);
- Clear(r, g, b, a);
-
- float w = float(VP.w) / float(WindowWidth),
- h = float(VP.h) / float(WindowHeight),
- x = float(VP.x) / float(WindowWidth),
- y = float(VP.y) / float(WindowHeight);
-
- float as = float(VP.w) / float(VP.h);
-
- // We are using 1/4 of DistortionCenter offset value here, since it is
- // relative to [-1,1] range that gets mapped to [0, 0.5].
- pPostProcessShader->SetUniform2f("LensCenter",
- x + (w + Distortion.XCenterOffset * 0.5f)*0.5f, y + h*0.5f);
- pPostProcessShader->SetUniform2f("ScreenCenter", x + w*0.5f, y + h*0.5f);
-
- // MA: This is more correct but we would need higher-res texture vertically; we should adopt this
- // once we have asymmetric input texture scale.
- float scaleFactor = 1.0f / Distortion.Scale;
-
- pPostProcessShader->SetUniform2f("Scale", (w/2) * scaleFactor, (h/2) * scaleFactor * as);
- pPostProcessShader->SetUniform2f("ScaleIn", (2/w), (2/h) / as);
-
- pPostProcessShader->SetUniform4f("HmdWarpParam",
- Distortion.K[0], Distortion.K[1], Distortion.K[2], Distortion.K[3]);
-
- if (PostProcessShaderRequested == PostProcessShader_DistortionAndChromAb)
- {
- pPostProcessShader->SetUniform4f("ChromAbParam",
- Distortion.ChromaticAberration[0],
- Distortion.ChromaticAberration[1],
- Distortion.ChromaticAberration[2],
- Distortion.ChromaticAberration[3]);
- }
+ DistortionMeshNumTris[eyeNum] = numTris;
+ pDistortionMeshVertexBuffer[eyeNum] = *CreateBuffer();
+ pDistortionMeshVertexBuffer[eyeNum]->Data ( Buffer_Vertex, pVerts, sizeof(DistortionVertex) * numVerts );
+ pDistortionMeshIndexBuffer[eyeNum] = *CreateBuffer();
+ pDistortionMeshIndexBuffer[eyeNum]->Data ( Buffer_Index, pIndices, ( sizeof(UInt16) * numIndices ) );
+
+ DistortionMeshDestroy ( pRawVerts, pIndices );
+ OVR_FREE ( pVerts );
+ }
+ }
+ else
+ {
+ // ...no setup needed for other distortion types.
+ }
+ }
+
+
+ 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)
+ {
+ 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 );
+ }
- Matrix4f texm(w, 0, 0, x,
- 0, h, 0, y,
- 0, 0, 0, 0,
- 0, 0, 0, 1);
- pPostProcessShader->SetUniform4x4f("Texm", texm);
-
- Matrix4f view(2, 0, 0, -1,
- 0, 2, 0, -1,
- 0, 0, 0, 0,
- 0, 0, 0, 1);
-
- ShaderFill fill(pPostProcessShader);
- fill.SetTexture(0, pSceneColorTex);
- RenderWithAlpha(&fill, pFullScreenVertexBuffer, NULL, view, 0, 4, Prim_TriangleStrip);
-}
-
-bool CollisionModel::TestPoint(const Vector3f& p) const
-{
- for(unsigned i = 0; i < Planes.GetSize(); i++)
- if(Planes[i].TestSide(p) > 0)
- {
- return 0;
- }
-
- return 1;
-}
-
-bool CollisionModel::TestRay(const Vector3f& origin, const Vector3f& norm, float& len, Planef* ph) const
-{
- if(TestPoint(origin))
- {
- len = 0;
- *ph = Planes[0];
- return true;
- }
- Vector3f fullMove = origin + norm * len;
+ Render(&fill, pDistortionMeshVertexBuffer[eyeNum], pDistortionMeshIndexBuffer[eyeNum], dummy, 0, DistortionMeshNumTris[eyeNum] * 3, Prim_Triangles, true);
+ }
+ }
+ else
+ {
+ if ( PostProcessingType == PostProcess_PixelDistortion )
+ {
+ float r, g, b, a;
+ DistortionClearColor.GetRGBA(&r, &g, &b, &a);
+ Clear(r, g, b, a);
+
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight;
+
+ // Always use the half-FB viewport, not the "current scene" VP which may be totally different.
+ SetViewport(stereoParams.DistortionViewport);
+
+ // TODO: precalc a bunch of things to make the shader faster.
+ // Note that the shader currently doesn't use Distortion.K[0], it hardwires it to 1.0.
+ pPostProcessShader->SetUniform4f("HmdWarpParam",
+ 1.0f,
+ stereoParams.Distortion.Lens.K[1],
+ stereoParams.Distortion.Lens.K[2],
+ stereoParams.Distortion.Lens.K[3]);
+ // We now only support one distortion type for shaders.
+ OVR_ASSERT ( stereoParams.Distortion.Lens.Eqn == Distortion_RecipPoly4 );
+
+ pPostProcessShader->SetUniform3f("DistortionClearColor",
+ DistortionClearColor.R,
+ DistortionClearColor.G,
+ DistortionClearColor.B );
+
+ // These are stored as deltas off the "main" distortion coefficients, but
+ // in the shader we use them as absolute values.
+ pPostProcessShader->SetUniform4f("ChromAbParam",
+ stereoParams.Distortion.Lens.ChromaticAberration[0] + 1.0f,
+ stereoParams.Distortion.Lens.ChromaticAberration[1],
+ stereoParams.Distortion.Lens.ChromaticAberration[2] + 1.0f,
+ stereoParams.Distortion.Lens.ChromaticAberration[3]);
+
+ // From [-1,1] space (for a single eye), offset by LensCenter, scaled to TanEyeAngle space.
+ // Done this way so that the shader can do a multiply-add, rather than a subtract-then-multiply.
+ Vector2f localTanEyeAngleOffset = -stereoParams.Distortion.LensCenter.EntrywiseMultiply(stereoParams.Distortion.TanEyeAngleScale);
+ pPostProcessShader->SetUniform2f("TanEyeAngleScale", stereoParams.Distortion.TanEyeAngleScale.x,
+ stereoParams.Distortion.TanEyeAngleScale.y);
+ pPostProcessShader->SetUniform2f("TanEyeAngleOffset", localTanEyeAngleOffset.x, localTanEyeAngleOffset.y);
+
+ // From TanEyeAngle space to the source the app rendered the standard projective scene to.
+ pPostProcessShader->SetUniform2f("EyeToSourceUVScale", stereoParams.EyeToSourceUV.Scale.x, stereoParams.EyeToSourceUV.Scale.y );
+ pPostProcessShader->SetUniform2f("EyeToSourceUVOffset", stereoParams.EyeToSourceUV.Offset.x, stereoParams.EyeToSourceUV.Offset.y );
+ pPostProcessShader->SetUniform2f("EyeToSourceNDCScale", stereoParams.EyeToSourceNDC.Scale.x, stereoParams.EyeToSourceNDC.Scale.y );
+ pPostProcessShader->SetUniform2f("EyeToSourceNDCOffset", stereoParams.EyeToSourceNDC.Offset.x, stereoParams.EyeToSourceNDC.Offset.y );
+
+ // Fade out towards the last bit of the edge, rather than having a sharp edge that attracts the eye.
+ pPostProcessShader->SetUniform1f("EdgeFadeScale", 1.0f / FadeOutBorderFraction );
+
+ // Vertex texture coordinates are (0,0) to (1,1). This moves them to (-1,-1),(1,1)
+ Matrix4f texm(2, 0, 0, -1,
+ 0, 2, 0, -1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 1);
+ pPostProcessShader->SetUniform4x4f("Texm", texm);
+
+ // Input vertices are (0,0) to (1,1). This moves them to (-1,-1),(1,1), i.e. filling the viewport (which will be set to the correct half of the screen).
+ Matrix4f view(2, 0, 0, -1,
+ 0, 2, 0, -1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 1);
+ ShaderFill fill(pPostProcessShader);
+
+ if ( ( pSourceTextureRight != NULL ) && ( eyeNum == 1 ) )
+ {
+ fill.SetTexture ( 0, pSourceTextureRight );
+ }
+ else
+ {
+ fill.SetTexture ( 0, pSourceTextureLeftOrOnly );
+ }
+ Render(&fill, pFullScreenVertexBuffer, NULL, view, 0, 4, Prim_TriangleStrip);
+ }
+ }
+ else if ( PostProcessingType == PostProcess_NoDistortion )
+ {
+ // Just splat the thing on the framebuffer with no distortion.
+ Clear ( 0.0f, 0.4f, 0.0f, 1.0f, 1.0f );
+ // 1:1 mapping to screen pixels.
+ Matrix4f ortho;
+ ortho.SetIdentity();
+ ortho.M[0][0] = 1.0f;
+ ortho.M[0][3] = 0.0f;
+ ortho.M[1][1] = -1.0f;
+ ortho.M[1][3] = 0.0f;
+ ortho.M[2][2] = 0;
+ SetProjection(ortho);
+ int rtWidth = pSourceTextureLeftOrOnly->GetWidth();
+ int rtHeight = pSourceTextureLeftOrOnly->GetHeight();
+
+ for ( int eyeNum = 0; eyeNum < 2; eyeNum++ )
+ {
+ const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight;
+ SetViewport ( stereoParams.DistortionViewport );
- int crossing = -1;
- float cdot1 = 0, cdot2 = 0;
+ Ptr<Texture> pTex;
+ if ( ( pSourceTextureRight != NULL ) && ( eyeNum == 1 ) )
+ {
+ pTex = pSourceTextureRight;
+ }
+ else
+ {
+ pTex = pSourceTextureLeftOrOnly;
+ }
- for(unsigned i = 0; i < Planes.GetSize(); ++i)
- {
- float dot2 = Planes[i].TestSide(fullMove);
- if(dot2 > 0)
- {
- return false;
- }
- float dot1 = Planes[i].TestSide(origin);
- if(dot1 > 0)
- {
- if(dot2 <= 0)
- {
- //assert(crossing==-1);
- if(crossing == -1)
- {
- crossing = i;
- cdot2 = dot2;
- cdot1 = dot1;
+ float ul = (float)( stereoParams.RenderedViewport.x ) / (float)rtWidth;
+ float ur = (float)( stereoParams.RenderedViewport.x + stereoParams.RenderedViewport.w ) / (float)rtWidth;
+ float vt = (float)( stereoParams.RenderedViewport.y ) / (float)rtHeight;
+ float vb = (float)( stereoParams.RenderedViewport.y + stereoParams.RenderedViewport.h ) / (float)rtHeight;
+ FillTexturedRect (
+ -1.0f, -1.0f, 1.0f, 1.0f,
+ ul, vt, ur, vb,
+ Color(255,255,255,255), pTex );
}
- else
+ }
+ else
+ {
+ OVR_ASSERT ( !"Unknown distortion type" );
+ }
+ }
+ }
+
+ bool CollisionModel::TestPoint(const Vector3f& p) const
+ {
+ for(unsigned i = 0; i < Planes.GetSize(); i++)
+ if(Planes[i].TestSide(p) > 0)
+ {
+ return 0;
+ }
+
+ return 1;
+ }
+
+ bool CollisionModel::TestRay(const Vector3f& origin, const Vector3f& norm, float& len, Planef* ph) const
+ {
+ if(TestPoint(origin))
+ {
+ len = 0;
+ *ph = Planes[0];
+ return true;
+ }
+ Vector3f fullMove = origin + norm * len;
+
+ int crossing = -1;
+ float cdot1 = 0, cdot2 = 0;
+
+ for(unsigned i = 0; i < Planes.GetSize(); ++i)
+ {
+ float dot2 = Planes[i].TestSide(fullMove);
+ if(dot2 > 0)
+ {
+ return false;
+ }
+ float dot1 = Planes[i].TestSide(origin);
+ if(dot1 > 0)
+ {
+ if(dot2 <= 0)
{
- if(dot2 > cdot2)
+ //OVR_ASSERT(crossing==-1);
+ if(crossing == -1)
{
crossing = i;
cdot2 = dot2;
cdot1 = dot1;
}
+ else
+ {
+ if(dot2 > cdot2)
+ {
+ crossing = i;
+ cdot2 = dot2;
+ cdot1 = dot1;
+ }
+ }
}
- }
- }
- }
-
- if(crossing < 0)
- {
- return false;
- }
-
- assert(TestPoint(origin + norm * len));
-
- len = len * cdot1 / (cdot1 - cdot2) - 0.05f;
- if(len < 0)
- {
- len = 0;
- }
- float tp = Planes[crossing].TestSide(origin + norm * len);
- OVR_ASSERT(fabsf(tp) < 0.05f + Mathf::Tolerance);
- OVR_UNUSED(tp);
-
- if(ph)
- {
- *ph = Planes[crossing];
- }
- return true;
-}
-
-int GetNumMipLevels(int w, int h)
-{
- int n = 1;
- while(w > 1 || h > 1)
- {
- w >>= 1;
- h >>= 1;
- n++;
- }
- return n;
-}
-
-void FilterRgba2x2(const UByte* src, int w, int h, UByte* dest)
-{
- for(int j = 0; j < (h & ~1); j += 2)
- {
- const UByte* psrc = src + (w * j * 4);
- UByte* pdest = dest + ((w >> 1) * (j >> 1) * 4);
-
- for(int i = 0; i < w >> 1; i++, psrc += 8, pdest += 4)
- {
- pdest[0] = (((int)psrc[0]) + psrc[4] + psrc[w * 4 + 0] + psrc[w * 4 + 4]) >> 2;
- pdest[1] = (((int)psrc[1]) + psrc[5] + psrc[w * 4 + 1] + psrc[w * 4 + 5]) >> 2;
- pdest[2] = (((int)psrc[2]) + psrc[6] + psrc[w * 4 + 2] + psrc[w * 4 + 6]) >> 2;
- pdest[3] = (((int)psrc[3]) + psrc[7] + psrc[w * 4 + 3] + psrc[w * 4 + 7]) >> 2;
- }
- }
-}
-
-int GetTextureSize(int format, int w, int h)
-{
- switch (format & Texture_TypeMask)
- {
- case Texture_R: return w*h;
- case Texture_RGBA: return w*h*4;
- case Texture_DXT1: {
- int bw = (w+3)/4, bh = (h+3)/4;
- return bw * bh * 8;
- }
- case Texture_DXT3:
- case Texture_DXT5: {
- int bw = (w+3)/4, bh = (h+3)/4;
- return bw * bh * 16;
- }
-
- default:
- OVR_ASSERT(0);
- }
- return 0;
-}
+ }
+ }
+
+ if(crossing < 0)
+ {
+ return false;
+ }
+
+ OVR_ASSERT(TestPoint(origin + norm * len));
+
+ len = len * cdot1 / (cdot1 - cdot2) - 0.05f;
+ if(len < 0)
+ {
+ len = 0;
+ }
+ float tp = Planes[crossing].TestSide(origin + norm * len);
+ OVR_ASSERT(fabsf(tp) < 0.05f + Mathf::Tolerance);
+ OVR_UNUSED(tp);
+
+ if(ph)
+ {
+ *ph = Planes[crossing];
+ }
+ return true;
+ }
+
+ int GetNumMipLevels(int w, int h)
+ {
+ int n = 1;
+ while(w > 1 || h > 1)
+ {
+ w >>= 1;
+ h >>= 1;
+ n++;
+ }
+ return n;
+ }
+
+ void FilterRgba2x2(const UByte* src, int w, int h, UByte* dest)
+ {
+ for(int j = 0; j < (h & ~1); j += 2)
+ {
+ const UByte* psrc = src + (w * j * 4);
+ UByte* pdest = dest + ((w >> 1) * (j >> 1) * 4);
+
+ for(int i = 0; i < w >> 1; i++, psrc += 8, pdest += 4)
+ {
+ pdest[0] = (((int)psrc[0]) + psrc[4] + psrc[w * 4 + 0] + psrc[w * 4 + 4]) >> 2;
+ pdest[1] = (((int)psrc[1]) + psrc[5] + psrc[w * 4 + 1] + psrc[w * 4 + 5]) >> 2;
+ pdest[2] = (((int)psrc[2]) + psrc[6] + psrc[w * 4 + 2] + psrc[w * 4 + 6]) >> 2;
+ pdest[3] = (((int)psrc[3]) + psrc[7] + psrc[w * 4 + 3] + psrc[w * 4 + 7]) >> 2;
+ }
+ }
+ }
+
+ int GetTextureSize(int format, int w, int h)
+ {
+ switch (format & Texture_TypeMask)
+ {
+ case Texture_R: return w*h;
+ case Texture_RGBA: return w*h*4;
+ case Texture_DXT1: {
+ int bw = (w+3)/4, bh = (h+3)/4;
+ return bw * bh * 8;
+ }
+ case Texture_DXT3:
+ case Texture_DXT5: {
+ int bw = (w+3)/4, bh = (h+3)/4;
+ return bw * bh * 16;
+ }
+
+ default:
+ OVR_ASSERT(0);
+ }
+ return 0;
+ }
}}
diff --git a/Samples/CommonSrc/Render/Render_Device.h b/Samples/CommonSrc/Render/Render_Device.h
index 028f282..f8a6dff 100644
--- a/Samples/CommonSrc/Render/Render_Device.h
+++ b/Samples/CommonSrc/Render/Render_Device.h
@@ -28,24 +28,31 @@ limitations under the License.
#include "Kernel/OVR_RefCount.h"
#include "Kernel/OVR_String.h"
#include "Kernel/OVR_File.h"
+#include "OVR_CAPI.h"
-#include "Util/Util_Render_Stereo.h"
+#include "OVR_Stereo.h"
namespace OVR { namespace Render {
-using namespace OVR::Util::Render;
-
class RenderDevice;
struct Font;
//-----------------------------------------------------------------------------------
+enum ShaderStage
+{
+ Shader_Vertex = 0,
+ Shader_Geometry = 1,
+ Shader_Fragment = 2,
+ Shader_Pixel = 2,
+ Shader_Count = 3,
+};
+
enum PrimitiveType
{
Prim_Triangles,
Prim_Lines,
Prim_TriangleStrip,
- Prim_Points,
Prim_Unknown,
Prim_Count
};
@@ -64,36 +71,32 @@ public:
virtual void Set(PrimitiveType prim = Prim_Unknown) const = 0;
virtual void Unset() const {}
- virtual void SetTexture(int i, class Texture* tex) { OVR_UNUSED2(i,tex); }
- virtual Texture* GetTexture(int i) { OVR_UNUSED(i); return 0; }
-};
-
-enum ShaderStage
-{
- Shader_Vertex = 0,
- Shader_Geometry = 1,
- Shader_Fragment = 2,
- Shader_Pixel = 2,
- Shader_Count = 3,
+ virtual void SetTexture(int i, class Texture* tex, ShaderStage stage = Shader_Pixel) { OVR_UNUSED3(i,tex,stage); }
+ virtual Texture* GetTexture(int i, ShaderStage stage = Shader_Pixel) { OVR_UNUSED2(i,stage); return 0; }
};
enum BuiltinShaders
{
- VShader_MV = 0,
- VShader_MVP = 1,
- VShader_PostProcess = 2,
- VShader_Count = 3,
-
- FShader_Solid = 0,
- FShader_Gouraud = 1,
- FShader_Texture = 2,
- FShader_AlphaTexture = 3,
- FShader_PostProcess = 4,
- FShader_PostProcessWithChromAb = 5,
- FShader_LitGouraud = 6,
- FShader_LitTexture = 7,
- FShader_MultiTexture = 8,
- FShader_Count = 9,
+ VShader_MV = 0,
+ VShader_MVP ,
+ VShader_PostProcess ,
+ VShader_PostProcessMesh ,
+ VShader_PostProcessMeshTimewarp ,
+ VShader_PostProcessMeshPositionalTimewarp ,
+ VShader_Count ,
+
+ FShader_Solid = 0,
+ FShader_Gouraud ,
+ FShader_Texture ,
+ FShader_AlphaTexture ,
+ FShader_PostProcessWithChromAb ,
+ FShader_LitGouraud ,
+ FShader_LitTexture ,
+ FShader_MultiTexture ,
+ FShader_PostProcessMeshWithChromAb ,
+ FShader_PostProcessMeshWithChromAbTimewarp ,
+ FShader_PostProcessMeshWithChromAbPositionalTimewarp ,
+ FShader_Count ,
};
@@ -119,6 +122,8 @@ enum TextureFormat
{
Texture_RGBA = 0x100,
Texture_R = 0x200,
+ Texture_A = 0x400,
+ Texture_BGRA = 0x800,
Texture_DXT1 = 0x1100,
Texture_DXT3 = 0x1200,
Texture_DXT5 = 0x1300,
@@ -126,8 +131,9 @@ enum TextureFormat
Texture_TypeMask = 0xff00,
Texture_Compressed = 0x1000,
Texture_SamplesMask = 0x00ff,
- Texture_RenderTarget = 0x10000,
- Texture_GenMipmaps = 0x20000,
+ Texture_RenderTarget = 0x10000,
+ Texture_SampleDepth = 0x20000,
+ Texture_GenMipmaps = 0x40000,
};
enum SampleMode
@@ -145,16 +151,14 @@ enum SampleMode
Sample_Count =13,
};
-// A vector with a dummy w component for alignment in uniform buffers (and for float colors).
-// The w component is not used in any calculations.
-struct Vector4f : public Vector3f
+struct Color4f
{
- float w;
+ float r, g, b, a;
- Vector4f() : w(1) {}
- Vector4f(const Vector3f& v) : Vector3f(v), w(1) {}
- Vector4f(float r, float g, float b, float a) : Vector3f(r,g,b), w(a) {}
+ Color4f() : r(0), g(0), b(0), a(1) {}
+ Color4f(const Vector3f& v) : r(v.x), g(v.y), b(v.z), a(1) {}
+ Color4f(float ir, float ig, float ib, float ia) : r(ir), g(ig), b(ib), a(ia) {}
};
@@ -231,24 +235,34 @@ public:
const float v[] = {x,y};
return SetUniform(name, 2, v);
}
+ bool SetUniform3f(const char* name, float x, float y, float z)
+ {
+ const float v[] = {x,y,z};
+ return SetUniform(name, 3, v);
+ }
bool SetUniform4f(const char* name, float x, float y, float z, float w = 1)
{
const float v[] = {x,y,z,w};
return SetUniform(name, 4, v);
}
- bool SetUniformv(const char* name, const Vector3f& v)
+ bool SetUniform4fv(const char* name, const Vector3f& v)
{
const float a[] = {v.x,v.y,v.z,1};
return SetUniform(name, 4, a);
}
- bool SetUniform4fv(const char* name, int n, const Vector4f* v)
+ bool SetUniform4fvArray(const char* name, int n, const Color4f* v)
{
- return SetUniform(name, 4*n, &v[0].x);
+ return SetUniform(name, 4*n, &v[0].r);
}
virtual bool SetUniform4x4f(const char* name, const Matrix4f& m)
{
return SetUniform(name, 16, &m.M[0][0]);
}
+ virtual bool SetUniform3x3f(const char* name, const Matrix4f& m)
+ {
+ // float3x3 is actually stored the same way as float4x3, with the last items ignored by the code.
+ return SetUniform(name, 12, &m.M[0][0]);
+ }
};
class ShaderSetMatrixTranspose : public ShaderSet
@@ -265,6 +279,7 @@ class ShaderFill : public Fill
{
Ptr<ShaderSet> Shaders;
Ptr<Texture> Textures[8];
+ Ptr<Texture> VtxTextures[8];
public:
ShaderFill(ShaderSet* sh) : Shaders(sh) { }
@@ -272,8 +287,28 @@ public:
void Set(PrimitiveType prim) const;
ShaderSet* GetShaders() { return Shaders; }
- virtual void SetTexture(int i, class Texture* tex) { if (i < 8) Textures[i] = tex; }
- virtual Texture* GetTexture(int i) { if (i < 8) return Textures[i]; else return 0; }
+ virtual void SetTexture(int i, class Texture* tex, ShaderStage stage = Shader_Pixel)
+ {
+ if (i < 8)
+ {
+ if(stage == Shader_Pixel) Textures[i] = tex;
+ else if(stage == Shader_Vertex) VtxTextures[i] = tex;
+ else OVR_ASSERT(false);
+ }
+ }
+ virtual Texture* GetTexture(int i, ShaderStage stage = Shader_Pixel)
+ {
+ if (i < 8)
+ {
+ if(stage == Shader_Pixel) return Textures[i];
+ else if(stage == Shader_Vertex) return VtxTextures[i];
+ else OVR_ASSERT(false); return 0;
+ }
+ else
+ {
+ return 0;
+ }
+ }
};
/* Buffer for vertex or index data. Some renderers require separate buffers, so that
@@ -313,6 +348,10 @@ public:
virtual void SetSampleMode(int sm) = 0;
virtual void Set(int slot, ShaderStage stage = Shader_Fragment) const = 0;
+
+ virtual ovrTexture Get_ovrTexture() = 0;
+
+ virtual void* GetInternalImplementation() { return NULL; };
};
@@ -379,7 +418,7 @@ public:
{
if (!MatCurrent)
{
- Mat = Rot;
+ Mat = Matrix4f(Rot);
Mat = Matrix4f::Translation(Pos) * Mat;
MatCurrent = 1;
}
@@ -413,18 +452,27 @@ struct Vertex
}
};
+struct DistortionVertex
+{
+ Vector2f Pos;
+ Vector2f TexR;
+ Vector2f TexG;
+ Vector2f TexB;
+ Color Col;
+};
+
// this is stored in a uniform buffer, don't change it without fixing all renderers
struct LightingParams
{
- Vector4f Ambient;
- Vector4f LightPos[8];
- Vector4f LightColor[8];
+ Color4f Ambient;
+ Color4f LightPos[8]; // Not actually colours, but we need the extra element of padding.
+ Color4f LightColor[8];
float LightCount;
int Version;
LightingParams() : LightCount(0), Version(0) {}
- void Update(const Matrix4f& view, const Vector4f* SceneLightPos);
+ void Update(const Matrix4f& view, const Vector3f* SceneLightPos);
void Set(ShaderSet* s) const;
};
@@ -472,10 +520,12 @@ public:
UInt16 AddVertex(const Vertex& v)
{
- assert(!VertexBuffer && !IndexBuffer);
- UInt16 index = (UInt16)Vertices.GetSize();
- Vertices.PushBack(v);
- return index;
+ OVR_ASSERT(!VertexBuffer && !IndexBuffer);
+ UPInt size = Vertices.GetSize();
+ OVR_ASSERT(size <= USHRT_MAX); // We only use a short to store vert indices.
+ UInt16 index = (UInt16) size;
+ Vertices.PushBack(v);
+ return index;
}
UInt16 AddVertex(const Vector3f& v, const Color& c, float u_ = 0, float v_ = 0)
{
@@ -528,6 +578,9 @@ public:
float z1, float z2, Color zcolor);
+ // Adds box at specified location to current vertices.
+ void AddBox(Color c, Vector3f origin, Vector3f size);
+
// Uses texture coordinates for exactly covering each surface once.
static Model* CreateBox(Color c, Vector3f origin, Vector3f size);
@@ -575,18 +628,18 @@ class Scene
{
public:
Container World;
- Vector4f LightPos[8];
+ Vector3f LightPos[8];
LightingParams Lighting;
Array<Ptr<Model> > Models;
public:
void Render(RenderDevice* ren, const Matrix4f& view);
- void SetAmbient(Vector4f color)
+ void SetAmbient(Color4f color)
{
Lighting.Ambient = color;
}
- void AddLight(Vector3f pos, Vector4f color)
+ void AddLight(Vector3f pos, Color4f color)
{
int n = (int)Lighting.LightCount;
OVR_ASSERT(n < 8);
@@ -599,7 +652,7 @@ public:
{
World.Clear();
Models.Clear();
- Lighting.Ambient = Vector4f(0.0f, 0.0f, 0.0f, 0.0f);
+ Lighting.Ambient = Color4f(0.0f, 0.0f, 0.0f, 0.0f);
Lighting.LightCount = 0;
}
@@ -624,11 +677,15 @@ enum RenderCaps
};
// Post-processing type to apply to scene after rendering. PostProcess_Distortion
-// applied distortion as described by DistortionConfig.
+// applied distortion as described by DistortionRenderDesc.
enum PostProcessType
{
PostProcess_None,
- PostProcess_Distortion
+ PostProcess_PixelDistortion,
+ PostProcess_MeshDistortion,
+ PostProcess_MeshDistortionTimewarp,
+ PostProcess_MeshDistortionPositionalTimewarp,
+ PostProcess_NoDistortion,
};
enum DisplayMode
@@ -688,29 +745,27 @@ class RenderDevice : public RefCountBase<RenderDevice>
protected:
int WindowWidth, WindowHeight;
RendererParams Params;
- Viewport VP;
+ Recti VP;
Matrix4f Proj;
Ptr<Buffer> pTextVertexBuffer;
-
// For rendering with lens warping
- PostProcessType CurPostProcess;
- Ptr<Texture> pSceneColorTex;
- int SceneColorTexW;
- int SceneColorTexH;
+ PostProcessType PostProcessingType;
+
Ptr<ShaderSet> pPostProcessShader;
Ptr<Buffer> pFullScreenVertexBuffer;
- float SceneRenderScale;
- DistortionConfig Distortion;
Color DistortionClearColor;
- UPInt TotalTextureMemoryUsage;
+ UPInt TotalTextureMemoryUsage;
+ float FadeOutBorderFraction;
+
+ int DistortionMeshNumTris[2];
+ Ptr<Buffer> pDistortionMeshVertexBuffer[2];
+ Ptr<Buffer> pDistortionMeshIndexBuffer[2];
// For lighting on platforms with uniform buffers
Ptr<Buffer> LightingBuffer;
- void FinishScene1();
-
public:
enum CompareFunc
{
@@ -728,41 +783,43 @@ public:
virtual void Init() {}
- virtual void Shutdown() {}
+ virtual void Shutdown();
virtual bool SetParams(const RendererParams&) { return 0; }
const RendererParams& GetParams() const { return Params; }
-
+ // Returns details needed by CAPI distortion rendering.
+ virtual ovrRenderAPIConfig Get_ovrRenderAPIConfig() const = 0;
+
// StereoParams apply Viewport, Projection and Distortion simultaneously,
// doing full configuration for one eye.
void ApplyStereoParams(const StereoEyeParams& params)
{
- SetViewport(params.VP);
- SetProjection(params.Projection);
- if (params.pDistortion)
- SetDistortionConfig(*params.pDistortion, params.Eye);
+ SetViewport(params.RenderedViewport);
+ SetProjection(params.RenderedProjection);
}
+ void ApplyStereoParams(const Recti& vp, const Matrix4f& projection)
+ {
+ SetViewport(vp);
+ SetProjection(projection);
+ }
// Apply "orthographic" stereo parameters used for rendering 2D HUD overlays.
- void ApplyStereoParams2D(const StereoEyeParams& params)
+ void ApplyStereoParams2D(StereoEyeParams const &params, Matrix4f const &ortho)
{
- SetViewport(params.VP);
- SetProjection(params.OrthoProjection);
- if (params.pDistortion)
- SetDistortionConfig(*params.pDistortion, params.Eye);
+ SetViewport(params.RenderedViewport);
+ SetProjection(ortho);
}
+
- virtual void SetViewport(const Viewport& vp);
- void SetViewport(int x, int y, int w, int h) { SetViewport(Viewport(x,y,w,h)); }
- //virtual void SetScissor(int x, int y, int w, int h) = 0;
- // Set viewport ignoring any adjustments used for the stereo mode.
- virtual void SetRealViewport(const Viewport& vp) { SetMultipleViewports(1, &vp); }
- virtual void SetMultipleViewports(int n, const Viewport* vps) { OVR_UNUSED2(n, vps); }
+ virtual void SetViewport(const Recti& vp) = 0;
+ void SetViewport(int x, int y, int w, int h) { SetViewport(Recti(x,y,w,h)); }
- virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1, float depth = 1) = 0;
+ virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1,
+ float depth = 1,
+ bool clearColor = true, bool clearDepth = true) = 0;
virtual void Rect(float left, float top, float right, float bottom) = 0;
inline void Clear(const Color &c, float depth = 1)
@@ -773,9 +830,9 @@ public:
}
virtual bool IsFullscreen() const { return Params.Fullscreen != Display_Window; }
- virtual void Present() = 0;
+ virtual void Present ( bool withVsync ) = 0;
// Waits for rendering to complete; important for reducing latency.
- virtual void ForceFlushGPU() { }
+ virtual void WaitUntilGpuIdle() { }
// Resources
virtual Buffer* CreateBuffer() { return NULL; }
@@ -789,12 +846,24 @@ public:
// Rendering
+
// Begin drawing directly to the currently selected render target, no post-processing.
virtual void BeginRendering() {}
- // Begin drawing the primary scene. This will have post-processing applied (if enabled)
- // during FinishScene.
- virtual void BeginScene(PostProcessType pp = PostProcess_None); //StereoDisplay disp = Stereo_Center);
- // Postprocess the scene and return to the screen render target.
+ // Begin drawing the primary scene, starting up whatever post-processing may be needed.
+ virtual void BeginScene(PostProcessType pp = PostProcess_None);
+ // Call when any of the stereo options change, so precalculation can happen.
+ virtual void PrecalculatePostProcess(PostProcessType pptype,
+ const StereoEyeParams &stereoParamsLeft, const StereoEyeParams &stereoParamsRight,
+ const HmdRenderInfo &hmdRenderInfo );
+ // Perform postprocessing
+ 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);
+ // Finish scene.
virtual void FinishScene();
// Texture must have been created with Texture_RenderTarget. Use NULL for the default render target.
@@ -818,31 +887,25 @@ 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) = 0;
+ const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles, bool useDistortionVertex = false) = 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;
// Returns width of text in same units as drawing. If strsize is not null, stores width and height.
- float MeasureText(const Font* font, const char* str, float size, float* strsize = NULL);
+ // Can optionally return char-range selection rectangle.
+ float MeasureText(const Font* font, const char* str, float size, float strsize[2] = NULL,
+ const UPInt charRange[2] = 0, Vector2f charRangeRect[2] = 0);
virtual void RenderText(const Font* font, const char* str, float x, float y, float size, Color c);
virtual void FillRect(float left, float top, float right, float bottom, Color c);
+ virtual void RenderLines ( int NumLines, Color c, float *x, float *y, float *z = NULL );
+ virtual void FillTexturedRect(float left, float top, float right, float bottom, float ul, float vt, float ur, float vb, Color c, Ptr<Texture> tex);
virtual void FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm);
virtual void RenderImage(float left, float top, float right, float bottom, ShaderFill* image, unsigned char alpha=255);
virtual Fill *CreateSimpleFill(int flags = Fill::F_Solid) = 0;
Fill * CreateTextureFill(Texture* tex, bool useAlpha = false);
- // PostProcess distortion
- void SetSceneRenderScale(float ss);
-
- void SetDistortionConfig(const DistortionConfig& config, StereoEye eye = StereoEye_Left)
- {
- Distortion = config;
- if (eye == StereoEye_Right)
- Distortion.XCenterOffset = -Distortion.XCenterOffset;
- }
-
// Sets the color that is applied around distortion.
void SetDistortionClearColor(Color clearColor)
{
@@ -851,7 +914,12 @@ public:
// Don't call these directly, use App/Platform instead
virtual bool SetFullscreen(DisplayMode fullscreen) { OVR_UNUSED(fullscreen); return false; }
- virtual void SetWindowSize(int w, int h) { WindowWidth = w; WindowHeight = h; }
+ virtual void SetWindowSize(int w, int h)
+ {
+ WindowWidth = w;
+ WindowHeight = h;
+ VP = Recti( 0, 0, WindowWidth, WindowHeight );
+ }
UPInt GetTotalTextureMemoryUsage() const
{
@@ -860,8 +928,10 @@ public:
enum PostProcessShader
{
- PostProcessShader_Distortion = 0,
- PostProcessShader_DistortionAndChromAb = 1,
+ PostProcessShader_DistortionAndChromAb = 0,
+ PostProcessShader_MeshDistortionAndChromAb,
+ PostProcessShader_MeshDistortionAndChromAbTimewarp,
+ PostProcessShader_MeshDistortionAndChromAbPositionalTimewarp,
PostProcessShader_Count
};
@@ -875,6 +945,16 @@ public:
PostProcessShaderRequested = newShader;
}
+ void SetFadeOutBorderFraction ( float newVal )
+ {
+ FadeOutBorderFraction = newVal;
+ }
+
+ // GPU Profiling
+ // using (void) to avoid "unused param" warnings
+ virtual void BeginGpuEvent(const char* markerText, UInt32 markerColor) { (void)markerText; (void)markerColor; }
+ virtual void EndGpuEvent() { }
+
protected:
// Stereo & post-processing
virtual bool initPostProcessSupport(PostProcessType pptype);
@@ -887,6 +967,34 @@ private:
PostProcessShader PostProcessShaderActive;
};
+//-----------------------------------------------------------------------------------
+// GPU profile marker helper to encapsulate a given scope block
+class AutoGpuProf
+{
+public:
+ AutoGpuProf(RenderDevice* device, const char* markerText, UInt32 color)
+ : mDevice(device)
+ { device->BeginGpuEvent(markerText, color); }
+
+ // Generates random color if one is not provided
+ AutoGpuProf(RenderDevice* device, const char* markerText)
+ : mDevice(device)
+ {
+ UInt32 color = ((rand() & 0xFF) << 24) +
+ ((rand() & 0xFF) << 16) +
+ ((rand() & 0xFF) << 8) +
+ (rand() & 0xFF);
+ device->BeginGpuEvent(markerText, color);
+ }
+
+ ~AutoGpuProf() { mDevice->EndGpuEvent(); }
+
+private:
+ RenderDevice* mDevice;
+ AutoGpuProf() { };
+};
+//-----------------------------------------------------------------------------------
+
int GetNumMipLevels(int w, int h);
int GetTextureSize(int format, int w, int h);
diff --git a/Samples/CommonSrc/Render/Render_GL_Device.cpp b/Samples/CommonSrc/Render/Render_GL_Device.cpp
index aaf1f0e..4b3ddec 100644
--- a/Samples/CommonSrc/Render/Render_GL_Device.cpp
+++ b/Samples/CommonSrc/Render/Render_GL_Device.cpp
@@ -23,9 +23,122 @@ limitations under the License.
#include "../Render/Render_GL_Device.h"
#include "Kernel/OVR_Log.h"
+#include "OVR_CAPI_GL.h"
namespace OVR { namespace Render { namespace GL {
+// GL Hooks for PC.
+#if defined(OVR_OS_WIN32)
+
+PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;
+PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
+PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
+PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
+PFNGLDELETESHADERPROC glDeleteShader;
+PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
+PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
+PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
+PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
+PFNGLACTIVETEXTUREPROC glActiveTexture;
+PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
+PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
+PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
+PFNGLBINDBUFFERPROC glBindBuffer;
+PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv;
+PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
+PFNGLDELETEBUFFERSPROC glDeleteBuffers;
+PFNGLBUFFERDATAPROC glBufferData;
+PFNGLGENBUFFERSPROC glGenBuffers;
+PFNGLMAPBUFFERPROC glMapBuffer;
+PFNGLUNMAPBUFFERPROC glUnmapBuffer;
+PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
+PFNGLGETSHADERIVPROC glGetShaderiv;
+PFNGLCOMPILESHADERPROC glCompileShader;
+PFNGLSHADERSOURCEPROC glShaderSource;
+PFNGLCREATESHADERPROC glCreateShader;
+PFNGLCREATEPROGRAMPROC glCreateProgram;
+PFNGLATTACHSHADERPROC glAttachShader;
+PFNGLDETACHSHADERPROC glDetachShader;
+PFNGLDELETEPROGRAMPROC glDeleteProgram;
+PFNGLUNIFORM1IPROC glUniform1i;
+PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
+PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
+PFNGLUSEPROGRAMPROC glUseProgram;
+PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
+PFNGLGETPROGRAMIVPROC glGetProgramiv;
+PFNGLLINKPROGRAMPROC glLinkProgram;
+PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
+PFNGLUNIFORM4FVPROC glUniform4fv;
+PFNGLUNIFORM3FVPROC glUniform3fv;
+PFNGLUNIFORM2FVPROC glUniform2fv;
+PFNGLUNIFORM1FVPROC glUniform1fv;
+PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
+PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
+PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
+PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT;
+PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
+
+PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
+
+void InitGLExtensions()
+{
+ if (glGenFramebuffersEXT)
+ 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");
+}
+
+#endif
static const char* StdVertexShaderSrc =
@@ -157,6 +270,53 @@ static const char* MultiTextureFragShaderSrc =
" gl_FragColor = color2;\n"
"}\n";
+static const char* PostProcessMeshFragShaderSrc =
+ "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.a = 1.0;\n"
+ "}\n";
+
+
static const char* PostProcessVertexShaderSrc =
"uniform mat4 View;\n"
"uniform mat4 Texm;\n"
@@ -167,85 +327,275 @@ static const char* PostProcessVertexShaderSrc =
"{\n"
" gl_Position = View * Position;\n"
" oTexCoord = vec2(Texm * vec4(TexCoord,0,1));\n"
- " oTexCoord.y = 1.0-oTexCoord.y;\n"
+ "}\n";
+
+static const char* PostProcessMeshVertexShaderSrc =
+ "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";
+
+static const char* PostProcessMeshTimewarpVertexShaderSrc =
+ "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";
+
+static const char* PostProcessMeshPositionalTimewarpVertexShaderSrc =
+ "#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"
+ "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(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"
+ " 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";
static const char* PostProcessFragShaderSrc =
"uniform vec2 LensCenter;\n"
"uniform vec2 ScreenCenter;\n"
- "uniform vec2 Scale;\n"
- "uniform vec2 ScaleIn;\n"
+ "uniform vec2 EyeToSourceUVScale;\n"
+ "uniform vec2 EyeToSourceNDCScale;\n"
"uniform vec4 HmdWarpParam;\n"
- "uniform sampler2D Texture0;\n"
+ "uniform sampler2D Texture1;\n"
+
"varying vec2 oTexCoord;\n"
- "\n"
+
"vec2 HmdWarp(vec2 in01)\n"
"{\n"
- " vec2 theta = (in01 - LensCenter) * ScaleIn;\n" // Scales to [-1, 1]
+ " 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 + Scale * theta1;\n"
+ " return LensCenter + EyeToSourceUVScale * theta1;\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(Texture0, tc);\n"
+ " gl_FragColor = texture2D(Texture1, tc);\n"
"}\n";
// Shader with lens distortion and chromatic aberration correction.
-static const char* PostProcessFullFragShaderSrc =
- "uniform vec2 LensCenter;\n"
- "uniform vec2 ScreenCenter;\n"
- "uniform vec2 Scale;\n"
- "uniform vec2 ScaleIn;\n"
+static const char* PostProcessFragShaderWithChromAbSrc =
+ "uniform sampler2D Texture;\n"
+ "uniform vec3 DistortionClearColor;\n"
+ "uniform float EdgeFadeScale;\n"
+ "uniform vec2 EyeToSourceUVScale;\n"
+ "uniform vec2 EyeToSourceUVOffset;\n"
+ "uniform vec2 EyeToSourceNDCScale;\n"
+ "uniform vec2 EyeToSourceNDCOffset;\n"
+ "uniform vec2 TanEyeAngleScale;\n"
+ "uniform vec2 TanEyeAngleOffset;\n"
"uniform vec4 HmdWarpParam;\n"
"uniform vec4 ChromAbParam;\n"
- "uniform sampler2D Texture0;\n"
+
+ "varying vec4 oPosition;\n"
"varying vec2 oTexCoord;\n"
- "\n"
- // Scales input texture coordinates for distortion.
- // ScaleIn maps texture coordinates to Scales to ([-1, 1]), although top/bottom will be
- // larger due to aspect ratio.
- "void main()\n"
+
+ "void main()\n"
"{\n"
- " vec2 theta = (oTexCoord - LensCenter) * ScaleIn;\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"
- " \n"
- " // Detect whether blue texture coordinates are out of range since these will scaled out the furthest.\n"
- " vec2 thetaBlue = theta1 * (ChromAbParam.z + ChromAbParam.w * rSq);\n"
- " vec2 tcBlue = LensCenter + Scale * thetaBlue;\n"
- " if (!all(equal(clamp(tcBlue, ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)), tcBlue)))\n"
+ // Input oTexCoord is [-1,1] across the half of the screen used for a single eye.
+ " vec2 TanEyeAngleDistorted = oTexCoord * TanEyeAngleScale + TanEyeAngleOffset;\n" // Scales to tan(thetaX),tan(thetaY), but still distorted (i.e. only the center is correct)
+ " float RadiusSq = TanEyeAngleDistorted.x * TanEyeAngleDistorted.x + TanEyeAngleDistorted.y * TanEyeAngleDistorted.y;\n"
+ " float Distort = 1.0 / ( 1.0 + RadiusSq * ( HmdWarpParam.y + RadiusSq * ( HmdWarpParam.z + RadiusSq * ( HmdWarpParam.w ) ) ) );\n"
+ " float DistortR = Distort * ( ChromAbParam.x + RadiusSq * ChromAbParam.y );\n"
+ " float DistortG = Distort;\n"
+ " float DistortB = Distort * ( ChromAbParam.z + RadiusSq * ChromAbParam.w );\n"
+ " vec2 TanEyeAngleR = DistortR * TanEyeAngleDistorted;\n"
+ " vec2 TanEyeAngleG = DistortG * TanEyeAngleDistorted;\n"
+ " vec2 TanEyeAngleB = DistortB * TanEyeAngleDistorted;\n"
+
+ // These are now in "TanEyeAngle" space.
+ // The vectors (TanEyeAngleRGB.x, TanEyeAngleRGB.y, 1.0) are real-world vectors pointing from the eye to where the components of the pixel appear to be.
+ // If you had a raytracer, you could just use them directly.
+
+ // 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"
+ " vec2 SourceCoordG = TanEyeAngleG * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " SourceCoordG.y = 1 - SourceCoordG.y;\n"
+ " vec2 SourceCoordB = TanEyeAngleB * EyeToSourceUVScale + EyeToSourceUVOffset;\n"
+ " SourceCoordB.y = 1 - 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"
+ " if ( EdgeFadeIn < 0.0 )\n"
" {\n"
- " gl_FragColor = vec4(0);\n"
- " return;\n"
+ " gl_FragColor = vec4(DistortionClearColor.r, DistortionClearColor.g, DistortionClearColor.b, 1.0);\n"
+ " return;\n"
" }\n"
- " \n"
- " // Now do blue texture lookup.\n"
- " float blue = texture2D(Texture0, tcBlue).b;\n"
- " \n"
- " // Do green lookup (no scaling).\n"
- " vec2 tcGreen = LensCenter + Scale * theta1;\n"
- " vec4 center = texture2D(Texture0, tcGreen);\n"
- " \n"
- " // Do red scale and lookup.\n"
- " vec2 thetaRed = theta1 * (ChromAbParam.x + ChromAbParam.y * rSq);\n"
- " vec2 tcRed = LensCenter + Scale * thetaRed;\n"
- " float red = texture2D(Texture0, tcRed).r;\n"
- " \n"
- " gl_FragColor = vec4(red, center.g, blue, center.a);\n"
+ " EdgeFadeIn = clamp ( EdgeFadeIn, 0.0, 1.0 );\n"
+
+ // Actually do the lookups.
+ " float ResultR = texture2D(Texture, SourceCoordR).r;\n"
+ " 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"
"}\n";
+
+
static const char* VShaderSrcs[VShader_Count] =
{
DirectVertexShaderSrc,
StdVertexShaderSrc,
- PostProcessVertexShaderSrc
+ PostProcessVertexShaderSrc,
+ PostProcessMeshVertexShaderSrc,
+ PostProcessMeshTimewarpVertexShaderSrc,
+ PostProcessMeshPositionalTimewarpVertexShaderSrc
};
static const char* FShaderSrcs[FShader_Count] =
{
@@ -253,16 +603,17 @@ static const char* FShaderSrcs[FShader_Count] =
GouraudFragShaderSrc,
TextureFragShaderSrc,
AlphaTextureFragShaderSrc,
- PostProcessFragShaderSrc,
- PostProcessFullFragShaderSrc,
+ PostProcessFragShaderWithChromAbSrc,
LitSolidFragShaderSrc,
LitTextureFragShaderSrc,
- MultiTextureFragShaderSrc
+ MultiTextureFragShaderSrc,
+ PostProcessMeshFragShaderSrc,
+ PostProcessMeshTimewarpFragShaderSrc,
+ PostProcessMeshPositionalTimewarpFragShaderSrc
};
-
-RenderDevice::RenderDevice(const RendererParams& p)
+RenderDevice::RenderDevice(const RendererParams&)
{
for (int i = 0; i < VShader_Count; i++)
VertexShaders[i] = *new Shader(this, Shader_Vertex, VShaderSrcs[i]);
@@ -278,6 +629,37 @@ RenderDevice::RenderDevice(const RendererParams& p)
glGenFramebuffersEXT(1, &CurrentFbo);
}
+RenderDevice::~RenderDevice()
+{
+ Shutdown();
+}
+
+void RenderDevice::Shutdown()
+{
+ // Release any other resources first.
+ OVR::Render::RenderDevice::Shutdown();
+
+ // This runs before the subclass's Shutdown(), where the context, etc, may be deleted.
+
+ glDeleteFramebuffersEXT(1, &CurrentFbo);
+
+ for (int i = 0; i < VShader_Count; ++i)
+ VertexShaders[i].Clear();
+
+ for (int i = 0; i < FShader_Count; ++i)
+ FragShaders[i].Clear();
+
+ DefaultFill.Clear();
+ DepthBuffers.Clear();
+}
+
+
+void RenderDevice::FillTexturedRect(float left, float top, float right, float bottom, float ul, float vt, float ur, float vb, Color c, Ptr<OVR::Render::Texture> tex)
+{
+ Render::RenderDevice::FillTexturedRect(left, top, right, bottom, ul, vb, ur, vt, c, tex);
+}
+
+
Shader *RenderDevice::LoadBuiltinShader(ShaderStage stage, int shader)
{
switch (stage)
@@ -323,7 +705,7 @@ void RenderDevice::SetDepthMode(bool enable, bool write, CompareFunc func)
glDisable(GL_DEPTH_TEST);
}
-void RenderDevice::SetRealViewport(const Viewport& vp)
+void RenderDevice::SetViewport(const Recti& vp)
{
int wh;
if (CurRenderTarget)
@@ -332,30 +714,38 @@ void RenderDevice::SetRealViewport(const Viewport& vp)
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);
+ //glEnable(GL_SCISSOR_TEST);
+ //glScissor(vp.x, wh-vp.y-vp.h, vp.w, vp.h);
}
-void RenderDevice::Clear(float r, float g, float b, float a, float depth)
+void RenderDevice::WaitUntilGpuIdle()
{
- glClearColor(r,g,b,a);
- glClearDepth(depth);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glFlush();
+ glFinish();
}
-RBuffer* RenderDevice::GetDepthBuffer(int w, int h, int ms)
+void RenderDevice::Clear(float r, float g, float b, float a, float depth, bool clearColor /*= true*/, bool clearDepth /*= true*/)
+{
+ glClearColor(r,g,b,a);
+ glClearDepth(depth);
+ glClear(
+ ( clearColor ? ( GL_COLOR_BUFFER_BIT ) : 0 ) |
+ ( clearDepth ? ( GL_DEPTH_BUFFER_BIT ) : 0 )
+ );
+}
+
+Texture* RenderDevice::GetDepthBuffer(int w, int h, int ms)
{
for (unsigned i = 0; i < DepthBuffers.GetSize(); i++)
- if (w == DepthBuffers[i]->Width && h == DepthBuffers[i]->Height)// && ms == DepthBuffers[i]->Samples)
+ if (w == DepthBuffers[i]->Width && h == DepthBuffers[i]->Height && ms == DepthBuffers[i]->GetSamples())
return DepthBuffers[i];
- //Ptr<Texture> newDepth = *CreateTexture(Texture_Depth|Texture_RenderTarget|ms, w, h, NULL);
- Ptr<RBuffer> newDepth = *new RBuffer(GL_DEPTH24_STENCIL8, w, h); // combined depth stencil
+ Ptr<Texture> newDepth = *CreateTexture(Texture_Depth|Texture_RenderTarget|ms, w, h, NULL);
DepthBuffers.PushBack(newDepth);
return newDepth.GetPtr();
}
-void RenderDevice::SetRenderTarget(Render::Texture* color, Render::Texture*, Render::Texture* stencil)
+void RenderDevice::SetRenderTarget(Render::Texture* color, Render::Texture* depth, Render::Texture* stencil)
{
OVR_UNUSED(stencil);
@@ -365,14 +755,14 @@ void RenderDevice::SetRenderTarget(Render::Texture* color, Render::Texture*, Ren
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
return;
}
- //if (depth == NULL)
- RBuffer* depth = GetDepthBuffer(color->GetWidth(), color->GetHeight(), 0); //CurRenderTarget->Samples);
+
+ 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);
if (depth)
- //glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, ((Texture*)depth)->TexId, 0);
- glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, ((RBuffer*)depth)->BufId);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, ((Texture*)depth)->TexId, 0);
else
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
@@ -404,8 +794,7 @@ Fill* RenderDevice::CreateSimpleFill(int flags)
OVR_UNUSED(flags);
return DefaultFill;
}
-
-
+
void RenderDevice::Render(const Matrix4f& matrix, Model* model)
{
// Store data in buffers if not already
@@ -428,7 +817,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)
+ const Matrix4f& matrix, int offset, int count, PrimitiveType rprim, bool useDistortionVertex/* = false*/)
{
ShaderSet* shaders = (ShaderSet*) ((ShaderFill*)fill)->GetShaders();
@@ -461,15 +850,26 @@ void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Bu
Lighting->Set(shaders);
}
- glBindBuffer(GL_ARRAY_BUFFER, ((Buffer*)vertices)->GLBuffer);
- for (int i = 0; i < 5; i++)
- glEnableVertexAttribArray(i);
-
- 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));
+ glBindBuffer(GL_ARRAY_BUFFER, ((Buffer*)vertices)->GLBuffer);
+ 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));
+ }
if (indices)
{
@@ -482,8 +882,8 @@ void RenderDevice::Render(const Fill* fill, Render::Buffer* vertices, Render::Bu
glDrawArrays(prim, 0, count);
}
- for (int i = 0; i < 5; i++)
- glDisableVertexAttribArray(i);
+ for (int i = 0; i < 5; i++)
+ glDisableVertexAttribArray(i);
}
void RenderDevice::RenderWithAlpha(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices,
@@ -526,7 +926,7 @@ bool Buffer::Data(int use, const void* buffer, size_t size)
return 1;
}
-void* Buffer::Map(size_t start, size_t size, int flags)
+void* Buffer::Map(size_t, size_t, int)
{
int mode = GL_WRITE_ONLY;
//if (flags & Map_Unsynchronized)
@@ -543,7 +943,13 @@ bool Buffer::Unmap(void*)
glBindBuffer(Use, GLBuffer);
int r = glUnmapBuffer(Use);
glBindBuffer(Use, 0);
- return r;
+ return r != 0;
+}
+
+Shader::~Shader()
+{
+ if (GLShader)
+ glDeleteShader(GLShader);
}
bool Shader::Compile(const char* src)
@@ -576,6 +982,24 @@ ShaderSet::~ShaderSet()
glDeleteProgram(Prog);
}
+void ShaderSet::SetShader(Render::Shader *s)
+{
+ Shaders[s->GetStage()] = s;
+ Shader* gls = (Shader*)s;
+ glAttachShader(Prog, gls->GLShader);
+ if (Shaders[Shader_Vertex] && Shaders[Shader_Fragment])
+ Link();
+}
+
+void ShaderSet::UnsetShader(int stage)
+{
+ Shader* gls = (Shader*)(Render::Shader*)Shaders[stage];
+ if (gls)
+ glDetachShader(Prog, gls->GLShader);
+ Shaders[stage] = NULL;
+ Link();
+}
+
bool ShaderSet::Link()
{
glBindAttribLocation(Prog, 0, "Position");
@@ -600,14 +1024,19 @@ bool ShaderSet::Link()
UniformInfo.Clear();
LightingVer = 0;
UsesLighting = 0;
- GLuint i = 0;
- for(;; i++)
+
+ GLint uniformCount = 0;
+ glGetProgramiv(Prog, GL_ACTIVE_UNIFORMS, &uniformCount);
+ OVR_ASSERT(uniformCount >= 0);
+
+ for(GLuint i = 0; i < (GLuint)uniformCount; i++)
{
GLsizei namelen;
GLint size = 0;
GLenum type;
GLchar name[32];
glGetActiveUniform(Prog, i, sizeof(name), &namelen, &size, &type, name);
+
if (size)
{
int l = glGetUniformLocation(Prog, name);
@@ -628,6 +1057,7 @@ bool ShaderSet::Link()
case GL_FLOAT_VEC2: u.Type = 2; break;
case GL_FLOAT_VEC3: u.Type = 3; break;
case GL_FLOAT_VEC4: u.Type = 4; break;
+ case GL_FLOAT_MAT3: u.Type = 12; break;
case GL_FLOAT_MAT4: u.Type = 16; break;
default:
continue;
@@ -645,7 +1075,7 @@ bool ShaderSet::Link()
for (int i = 0; i < 8; i++)
{
char texv[32];
- sprintf(texv, "Texture%d", i);
+ OVR_sprintf(texv, 10, "Texture%d", i);
TexLoc[i] = glGetUniformLocation(Prog, texv);
if (TexLoc[i] < 0)
break;
@@ -664,7 +1094,7 @@ void ShaderSet::Set(PrimitiveType) const
bool ShaderSet::SetUniform(const char* name, int n, const float* v)
{
- for (int i = 0; i < UniformInfo.GetSize(); i++)
+ for (unsigned int i = 0; i < UniformInfo.GetSize(); i++)
if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
{
OVR_ASSERT(UniformInfo[i].Location >= 0);
@@ -675,6 +1105,8 @@ bool ShaderSet::SetUniform(const char* name, int n, const float* v)
case 2: glUniform2fv(UniformInfo[i].Location, n/2, v); break;
case 3: glUniform3fv(UniformInfo[i].Location, n/3, v); break;
case 4: glUniform4fv(UniformInfo[i].Location, n/4, v); break;
+ case 12: glUniformMatrix3fv(UniformInfo[i].Location, 1, 1, v); break;
+ case 16: glUniformMatrix4fv(UniformInfo[i].Location, 1, 1, v); break;
default: OVR_ASSERT(0);
}
return 1;
@@ -686,7 +1118,7 @@ bool ShaderSet::SetUniform(const char* name, int n, const float* v)
bool ShaderSet::SetUniform4x4f(const char* name, const Matrix4f& m)
{
- for (int i = 0; i < UniformInfo.GetSize(); i++)
+ for (unsigned int i = 0; i < UniformInfo.GetSize(); i++)
if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
{
glUseProgram(Prog);
@@ -722,7 +1154,7 @@ void Texture::SetSampleMode(int sm)
case Sample_Linear:
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, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
break;
case Sample_Anisotropic:
@@ -734,7 +1166,7 @@ void Texture::SetSampleMode(int sm)
case Sample_Nearest:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
break;
}
@@ -758,6 +1190,20 @@ void Texture::SetSampleMode(int sm)
glBindTexture(GL_TEXTURE_2D, 0);
}
+ovrTexture Texture::Get_ovrTexture()
+{
+ ovrTexture tex;
+ OVR::Sizei newRTSize(Width, Height);
+
+ ovrGLTextureData* texData = (ovrGLTextureData*)&tex;
+ texData->Header.API = ovrRenderAPI_OpenGL;
+ texData->Header.TextureSize = newRTSize;
+ texData->Header.RenderViewport = Recti(newRTSize);
+ texData->TexId = TexId;
+
+ return tex;
+}
+
Texture* RenderDevice::CreateTexture(int format, int width, int height, const void* data, int mipcount)
{
GLenum glformat, gltype = GL_UNSIGNED_BYTE;
@@ -765,7 +1211,7 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
{
case Texture_RGBA: glformat = GL_RGBA; break;
case Texture_R: glformat = GL_ALPHA; break;
- case Texture_Depth: glformat = GL_DEPTH; gltype = GL_DEPTH_COMPONENT; 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;
case Texture_DXT5: glformat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
@@ -774,7 +1220,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);
- glGetError();
+ OVR_ASSERT(!glGetError());
if (format & Texture_Compressed)
{
@@ -792,6 +1238,8 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
if (h < 1) h = 1;
}
}
+ else if (format & Texture_Depth)
+ glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_DEPTH_COMPONENT, gltype, data);
else
glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, glformat, gltype, data);
@@ -831,12 +1279,6 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
return NewTex;
}
-bool RenderDevice::SetFullscreen(DisplayMode fullscreen)
-{
- Params.Fullscreen = fullscreen;
- return true;
-}
-
RBuffer::RBuffer(GLenum format, GLint w, GLint h)
{
Width = w;
@@ -849,7 +1291,8 @@ RBuffer::RBuffer(GLenum format, GLint w, GLint h)
RBuffer::~RBuffer()
{
- glDeleteRenderbuffersEXT(1, &BufId);
+ if (BufId)
+ glDeleteRenderbuffersEXT(1, &BufId);
}
}}}
diff --git a/Samples/CommonSrc/Render/Render_GL_Device.h b/Samples/CommonSrc/Render/Render_GL_Device.h
index 88eaff4..5d97eef 100644
--- a/Samples/CommonSrc/Render/Render_GL_Device.h
+++ b/Samples/CommonSrc/Render/Render_GL_Device.h
@@ -34,13 +34,76 @@ limitations under the License.
#include <OpenGL/gl.h>
#include <OpenGL/glext.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
#endif
namespace OVR { namespace Render { namespace GL {
+// GL extension Hooks for PC.
+#if defined(OVR_OS_WIN32)
+
+extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT;
+extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
+extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
+extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
+extern PFNGLDELETESHADERPROC glDeleteShader;
+extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
+extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
+extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
+extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
+extern PFNGLACTIVETEXTUREPROC glActiveTexture;
+extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
+extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
+extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
+extern PFNGLBINDBUFFERPROC glBindBuffer;
+extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
+extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
+extern PFNGLBUFFERDATAPROC glBufferData;
+extern PFNGLGENBUFFERSPROC glGenBuffers;
+extern PFNGLMAPBUFFERPROC glMapBuffer;
+extern PFNGLUNMAPBUFFERPROC glUnmapBuffer;
+extern PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
+extern PFNGLGETSHADERIVPROC glGetShaderiv;
+extern PFNGLCOMPILESHADERPROC glCompileShader;
+extern PFNGLSHADERSOURCEPROC glShaderSource;
+extern PFNGLCREATESHADERPROC glCreateShader;
+extern PFNGLCREATEPROGRAMPROC glCreateProgram;
+extern PFNGLATTACHSHADERPROC glAttachShader;
+extern PFNGLDETACHSHADERPROC glDetachShader;
+extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
+extern PFNGLUNIFORM1IPROC glUniform1i;
+extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
+extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
+extern PFNGLUSEPROGRAMPROC glUseProgram;
+extern PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
+extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
+extern PFNGLLINKPROGRAMPROC glLinkProgram;
+extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
+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 void InitGLExtensions();
+
+#endif
+
+
class RenderDevice;
class Buffer : public Render::Buffer
@@ -77,6 +140,7 @@ public:
virtual int GetHeight() const { return Height; }
virtual void SetSampleMode(int);
+ virtual ovrTexture Get_ovrTexture();
virtual void Set(int slot, ShaderStage stage = Shader_Fragment) const;
};
@@ -91,11 +155,8 @@ public:
{
Compile(src);
}
- ~Shader()
- {
- if (GLShader)
- glDeleteShader(GLShader);
- }
+
+ ~Shader();
bool Compile(const char* src);
GLenum GLStage() const
@@ -133,22 +194,8 @@ public:
ShaderSet();
~ShaderSet();
- virtual void SetShader(Render::Shader *s)
- {
- Shaders[s->GetStage()] = s;
- Shader* gls = (Shader*)s;
- glAttachShader(Prog, gls->GLShader);
- if (Shaders[Shader_Vertex] && Shaders[Shader_Fragment])
- Link();
- }
- virtual void UnsetShader(int stage)
- {
- Shader* gls = (Shader*)(Render::Shader*)Shaders[stage];
- if (gls)
- glDetachShader(Prog, gls->GLShader);
- Shaders[stage] = NULL;
- Link();
- }
+ virtual void SetShader(Render::Shader *s);
+ virtual void UnsetShader(int stage);
virtual void Set(PrimitiveType prim) const;
@@ -161,7 +208,7 @@ public:
bool Link();
};
- class RBuffer : public RefCountBase<RBuffer>
+class RBuffer : public RefCountBase<RBuffer>
{
public:
int Width, Height;
@@ -180,28 +227,38 @@ class RenderDevice : public Render::RenderDevice
Matrix4f Proj;
+protected:
Ptr<Texture> CurRenderTarget;
- Array<Ptr<RBuffer> > DepthBuffers;
+ Array<Ptr<Texture> > DepthBuffers;
GLuint CurrentFbo;
const LightingParams* Lighting;
public:
RenderDevice(const RendererParams& p);
+ virtual ~RenderDevice();
- virtual void SetRealViewport(const Viewport& vp);
+ virtual void Shutdown();
+
+ 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();
- virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1, float depth = 1);
+ virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1, float depth = 1,
+ bool clearColor = true, bool clearDepth = true);
virtual void Rect(float left, float top, float right, float bottom) { OVR_UNUSED4(left,top,right,bottom); }
virtual void BeginRendering();
virtual void SetDepthMode(bool enable, bool write, CompareFunc func = Compare_Less);
virtual void SetWorldUniforms(const Matrix4f& proj);
- RBuffer* GetDepthBuffer(int w, int h, int ms);
+ Texture* GetDepthBuffer(int w, int h, int ms);
+ virtual void Present (bool withVsync){OVR_UNUSED(withVsync);};
virtual void SetRenderTarget(Render::Texture* color,
Render::Texture* depth = NULL, Render::Texture* stencil = NULL);
@@ -209,7 +266,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);
+ const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles, bool useDistortionVertex = false);
virtual void RenderWithAlpha(const Fill* fill, Render::Buffer* vertices, Render::Buffer* indices,
const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles);
@@ -222,8 +279,6 @@ public:
virtual Shader *LoadBuiltinShader(ShaderStage stage, int shader);
void SetTexture(Render::ShaderStage, int slot, const Texture* t);
-
- virtual bool SetFullscreen(DisplayMode fullscreen);
};
}}}
diff --git a/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp b/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp
index 4f22a50..1065c98 100644
--- a/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp
+++ b/Samples/CommonSrc/Render/Render_GL_Win32_Device.cpp
@@ -3,7 +3,7 @@
Filename : Render_GL_Win32 Device.cpp
Content : Win32 OpenGL Device implementation
Created : September 10, 2012
-Authors : Andrew Reisse, Michael Antonov
+Authors : Andrew Reisse, Michael Antonov, David Borel
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
@@ -22,16 +22,46 @@ limitations under the License.
************************************************************************************/
#include "Render_GL_Win32_Device.h"
+#include "OVR_CAPI_GL.h"
+
+#include <dwmapi.h>
namespace OVR { namespace Render { namespace GL { namespace Win32 {
+typedef HRESULT (__stdcall *PFNDWMENABLECOMPOSITIONPROC) (UINT);
+
+#pragma warning(disable : 4995)
+PFNDWMENABLECOMPOSITIONPROC DwmEnableComposition;
+
// ***** GL::Win32::RenderDevice
+
+RenderDevice::RenderDevice(const Render::RendererParams& p, HWND win, HDC dc, HGLRC gl)
+ : GL::RenderDevice(p)
+ , Window(win)
+ , WglContext(gl)
+ , GdiDc(dc)
+ , PreFullscreen(0, 0, 0, 0)
+ , HMonitor(0)
+ , FSDesktop(0, 0, 0, 0)
+{
+ OVR_UNUSED(p);
+}
// Implement static initializer function to create this class.
-Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams&, void* oswnd)
+Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* oswnd)
{
HWND hwnd = (HWND)oswnd;
+
+ if (!DwmEnableComposition)
+ {
+ HINSTANCE hInst = LoadLibrary( L"dwmapi.dll" );
+ OVR_ASSERT(hInst);
+ DwmEnableComposition = (PFNDWMENABLECOMPOSITIONPROC)GetProcAddress( hInst, "DwmEnableComposition" );
+ OVR_ASSERT(DwmEnableComposition);
+ }
+
+ DwmEnableComposition(DWM_EC_DISABLECOMPOSITION);
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
@@ -63,18 +93,40 @@ Render::RenderDevice* RenderDevice::CreateDevice(const RendererParams&, void* os
return NULL;
}
- // return new RenderDevice(rp, hwnd, dc, context);
- return 0;
+ InitGLExtensions();
+
+ return new RenderDevice(rp, hwnd, dc, context);
}
+ovrRenderAPIConfig RenderDevice::Get_ovrRenderAPIConfig() const
+{
+ static ovrGLConfig cfg;
+ 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;
-void RenderDevice::Present()
+ return cfg.Config;
+}
+
+void RenderDevice::Present(bool useVsync)
{
- SwapBuffers(GdiDc);
+ BOOL success;
+ int swapInterval = (useVsync) ? 1 : 0;
+ if (wglGetSwapIntervalEXT() != swapInterval)
+ wglSwapIntervalEXT(swapInterval);
+
+ success = SwapBuffers(GdiDc);
+ OVR_ASSERT(success);
}
void RenderDevice::Shutdown()
{
+ //Release any remaining GL resources.
+ GL::RenderDevice::Shutdown();
+
if (WglContext)
{
wglMakeCurrent(NULL,NULL);
@@ -86,5 +138,189 @@ void RenderDevice::Shutdown()
}
}
+bool RenderDevice::SetParams(const RendererParams& newParams)
+{
+ Params = newParams;
+ //TODO: Apply changes now.
+ return true;
+}
+
+BOOL CALLBACK MonitorEnumFunc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData)
+{
+ RenderDevice* renderer = (RenderDevice*)dwData;
+
+ MONITORINFOEX monitor;
+ monitor.cbSize = sizeof(monitor);
+
+ if (::GetMonitorInfo(hMonitor, &monitor) && monitor.szDevice[0])
+ {
+ DISPLAY_DEVICE dispDev;
+ memset(&dispDev, 0, sizeof(dispDev));
+ dispDev.cb = sizeof(dispDev);
+
+ if (::EnumDisplayDevices(monitor.szDevice, 0, &dispDev, 0))
+ {
+ if (strstr(String(dispDev.DeviceName).ToCStr(), renderer->GetParams().Display.MonitorName.ToCStr()))
+ {
+ renderer->HMonitor = hMonitor;
+ renderer->FSDesktop.x = monitor.rcMonitor.left;
+ renderer->FSDesktop.y = monitor.rcMonitor.top;
+ renderer->FSDesktop.w = monitor.rcMonitor.right - monitor.rcMonitor.left;
+ renderer->FSDesktop.h = monitor.rcMonitor.bottom - monitor.rcMonitor.top;
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+bool RenderDevice::SetFullscreen(DisplayMode fullscreen)
+{
+ if (fullscreen == Params.Fullscreen)
+ {
+ return true;
+ }
+
+ if (Params.Fullscreen == Display_FakeFullscreen)
+ {
+ SetWindowLong(Window, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS);
+ SetWindowPos(Window, HWND_NOTOPMOST, PreFullscreen.x, PreFullscreen.y,
+ PreFullscreen.w, PreFullscreen.h, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
+ }
+ else if (Params.Fullscreen == Display_Fullscreen)
+ {
+ {
+ // Find out the name of the device this window
+ // is on (this is for multi-monitor setups)
+ HMONITOR hMonitor = MonitorFromWindow(Window, MONITOR_DEFAULTTOPRIMARY);
+ MONITORINFOEX monInfo;
+ memset(&monInfo, 0, sizeof(MONITORINFOEX));
+ monInfo.cbSize = sizeof(MONITORINFOEX);
+ GetMonitorInfo(hMonitor, &monInfo);
+
+ // Restore the display resolution
+ ChangeDisplaySettingsEx(monInfo.szDevice, NULL, NULL, 0, NULL);
+ //ChangeDisplaySettings(NULL, 0);
+ }
+ {
+ // Restore the window styles
+ DWORD style = (DWORD)GetWindowLongPtr(Window, GWL_STYLE);
+ DWORD exstyle = (DWORD)GetWindowLongPtr(Window, GWL_EXSTYLE);
+ SetWindowLongPtr(Window, GWL_STYLE, style | WS_OVERLAPPEDWINDOW);
+ SetWindowLongPtr(Window, GWL_EXSTYLE, exstyle & (~(WS_EX_APPWINDOW | WS_EX_TOPMOST)));
+
+ MONITORINFOEX monInfo;
+ memset(&monInfo, 0, sizeof(MONITORINFOEX));
+ monInfo.cbSize = sizeof(MONITORINFOEX);
+ GetMonitorInfo(HMonitor, &monInfo);
+
+ // Restore the window size/position
+ SetWindowPos(Window, NULL, PreFullscreen.x, PreFullscreen.y, PreFullscreen.w, PreFullscreen.h,
+ SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOOWNERZORDER | SWP_NOREPOSITION | SWP_NOZORDER);
+ }
+ }
+
+
+ if (!Params.Display.MonitorName.IsEmpty())
+ {
+ EnumDisplayMonitors(0, 0, MonitorEnumFunc, (LPARAM)this);
+ }
+
+ if (fullscreen == Display_FakeFullscreen)
+ {
+ // Get WINDOWPLACEMENT before changing style to get OVERLAPPED coordinates,
+ // which we will restore.
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(wp);
+ GetWindowPlacement(Window, &wp);
+ PreFullscreen.w = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
+ PreFullscreen.h = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
+ PreFullscreen.x = wp.rcNormalPosition.left;
+ PreFullscreen.y = wp.rcNormalPosition.top;
+ // Warning: SetWindowLong sends message computed based on old size (incorrect).
+ // A proper work-around would be to mask that message out during window frame change in Platform.
+ SetWindowLong(Window, GWL_STYLE, WS_OVERLAPPED | WS_VISIBLE | WS_CLIPSIBLINGS);
+ SetWindowPos(Window, NULL, FSDesktop.x, FSDesktop.y, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED);
+
+ // Relocate cursor into the window to avoid losing focus on first click.
+ POINT oldCursor;
+ if (GetCursorPos(&oldCursor) &&
+ ((oldCursor.x < FSDesktop.x) || (oldCursor.x > (FSDesktop.x + PreFullscreen.w)) ||
+ (oldCursor.y < FSDesktop.y) || (oldCursor.x > (FSDesktop.y + PreFullscreen.h))))
+ {
+ // TBD: FullScreen window logic should really be in platform; it causes world rotation
+ // in relative mouse mode.
+ ::SetCursorPos(FSDesktop.x, FSDesktop.y);
+ }
+ }
+ else if (fullscreen == Display_Fullscreen)
+ {
+ // Find out the name of the device this window
+ // is on (this is for multi-monitor setups)
+ MONITORINFOEX monInfo;
+ memset(&monInfo, 0, sizeof(MONITORINFOEX));
+ 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);
+ PreFullscreen.x = rect.left;
+ PreFullscreen.y = rect.top;
+ PreFullscreen.w = rect.right - rect.left;
+ PreFullscreen.h = rect.bottom - rect.top;
+
+ // Save the window style and set it for fullscreen mode
+ DWORD style = (DWORD)GetWindowLongPtr(Window, GWL_STYLE);
+ DWORD exstyle = (DWORD)GetWindowLongPtr(Window, GWL_EXSTYLE);
+ 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;
+ }
+
+ // We need to call GetMonitorInfo() again becase
+ // details may have changed with the resolution
+ GetMonitorInfo(HMonitor, &monInfo);
+
+ // 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);
+ }
+
+ Params.Fullscreen = fullscreen;
+ return true;
+}
+
}}}}
diff --git a/Samples/CommonSrc/Render/Render_GL_Win32_Device.h b/Samples/CommonSrc/Render/Render_GL_Win32_Device.h
index f63b1d0..de81a80 100644
--- a/Samples/CommonSrc/Render/Render_GL_Win32_Device.h
+++ b/Samples/CommonSrc/Render/Render_GL_Win32_Device.h
@@ -3,7 +3,7 @@
Filename : Render_GL_Win32 Device.h
Content : Win32 OpenGL Device implementation header
Created : September 10, 2012
-Authors : Andrew Reisse, Michael Antonov
+Authors : Andrew Reisse, Michael Antonov, David Borel
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
@@ -38,19 +38,29 @@ namespace OVR { namespace Render { namespace GL { namespace Win32 {
// Win32-Specific GL Render Device, used to create OpenGL under Windows.
class RenderDevice : public GL::RenderDevice
{
- HWND Window;
- HGLRC WglContext;
- HDC GdiDc;
+ friend BOOL CALLBACK MonitorEnumFunc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData);
+
+ HWND Window;
+ HGLRC WglContext;
+ HDC GdiDc;
+ Recti PreFullscreen;
+ Recti FSDesktop;
+ HMONITOR HMonitor;
public:
- RenderDevice(const Render::RendererParams& p, HWND win, HDC dc, HGLRC gl)
- : GL::RenderDevice(p), Window(win), WglContext(gl), GdiDc(dc) { OVR_UNUSED(p); }
+ RenderDevice(const Render::RendererParams& p, HWND win, HDC dc, HGLRC gl);
+ virtual ~RenderDevice() { Shutdown(); }
// Implement static initializer function to create this class.
static Render::RenderDevice* CreateDevice(const RendererParams& rp, void* oswnd);
+
+ virtual ovrRenderAPIConfig Get_ovrRenderAPIConfig() const;
virtual void Shutdown();
- virtual void Present();
+ virtual void Present(bool withVsync);
+ bool SetParams(const RendererParams& newParams);
+
+ virtual bool SetFullscreen(DisplayMode fullscreen);
};
diff --git a/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp b/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp
index b2b4b31..5bbdb21 100644
--- a/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp
+++ b/Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp
@@ -5,7 +5,7 @@ Content : A DDS file loader for cross-platform compressed texture support.
Created : March 5, 2013
Authors : Peter Hoff, Dan Goodman, Bryan Croteau
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -75,10 +75,10 @@ Texture* LoadTextureDDS(RenderDevice* ren, File* f)
f->Read((unsigned char*)(&header), sizeof(header));
- int width = header.Width;
+ int width = header.Width;
int height = header.Height;
- int format = 0;
+ int format = Texture_RGBA;
UInt32 mipCount = header.MipMapCount;
if(mipCount <= 0)
diff --git a/Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp b/Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp
index b2b1ac1..5f31250 100644
--- a/Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp
+++ b/Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp
@@ -5,7 +5,7 @@ Content : Imports and exports XML files - implementation
Created : January 21, 2013
Authors : Robotic Arm Software - Peter Hoff, Dan Goodman, Bryan Croteau
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -121,6 +121,7 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend
OVR_DEBUG_LOG_TEXT(("%i models remaining...", modelCount - i));
}
Models.PushBack(*new Model(Prim_Triangles));
+ const char* name = pXmlModel->Attribute("name");
bool isCollisionModel = false;
pXmlModel->QueryBoolAttribute("isCollisionModel", &isCollisionModel);
Models[i]->IsCollisionModel = isCollisionModel;
@@ -129,6 +130,8 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend
Models[i]->Visible = false;
}
+ bool tree_c = (strcmp(name, "tree_C") == 0) || (strcmp(name, "Object03") == 0);
+
//read the vertices
OVR::Array<Vector3f> *vertices = new OVR::Array<Vector3f>();
ParseVectorString(pXmlModel->FirstChildElement("vertices")->FirstChild()->
@@ -137,6 +140,11 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend
for (unsigned int vertexIndex = 0; vertexIndex < vertices->GetSize(); ++vertexIndex)
{
vertices->At(vertexIndex).x *= -1.0f;
+
+ if (tree_c)
+ { // Move the terrace tree closer to the house
+ vertices->At(vertexIndex).z += 0.5;
+ }
}
//read the normals
@@ -237,6 +245,7 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend
// Read the vertex indices for the triangles
const char* indexStr = pXmlModel->FirstChildElement("indices")->
FirstChild()->ToText()->Value();
+
UPInt stringLength = strlen(indexStr);
for(UPInt j = 0; j < stringLength; )
@@ -306,6 +315,8 @@ bool XmlHandler::ReadFile(const char* fileName, OVR::Render::RenderDevice* pRend
float D;
pXmlPlane->QueryFloatAttribute("d", &D);
D -= 0.5f;
+ if (i == 26)
+ D += 0.5f; // tighten the terrace collision so player can move right up to rail
Planef p(norm.z, norm.y, norm.x * -1.0f, D);
cm->Add(p);
pXmlPlane = pXmlPlane->NextSiblingElement("plane");
diff --git a/Samples/CommonSrc/Render/Render_XmlSceneLoader.h b/Samples/CommonSrc/Render/Render_XmlSceneLoader.h
index 694fc2e..7dff174 100644
--- a/Samples/CommonSrc/Render/Render_XmlSceneLoader.h
+++ b/Samples/CommonSrc/Render/Render_XmlSceneLoader.h
@@ -5,7 +5,7 @@ Content : Imports and exports XML files
Created : January 21, 2013
Authors : Robotic Arm Software - Peter Hoff, Dan Goodman, Bryan Croteau
-Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/Samples/LibOVR_Samples_Msvc2010.sln b/Samples/LibOVR_Samples_Msvc2010.sln
deleted file mode 100644
index 41da1d9..0000000
--- a/Samples/LibOVR_Samples_Msvc2010.sln
+++ /dev/null
@@ -1,43 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusWorldDemo", "OculusWorldDemo\OculusWorldDemo_Msvc2010.vcxproj", "{8051B877-2992-4F64-8C3B-FAF88B6D83AA}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SensorBoxTest", "SensorBox\SensorBoxTest_Msvc2010.vcxproj", "{8051B837-2982-4F64-8C3B-FAF88B6D83AB}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusRoomTiny", "OculusRoomTiny\OculusRoomTiny_Msvc2010.vcxproj", "{80523489-2881-4F64-8C3B-FAF88B60ABCD}"
-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
- {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
- {8051B837-2982-4F64-8C3B-FAF88B6D83AB}.Debug|Win32.ActiveCfg = Debug|Win32
- {8051B837-2982-4F64-8C3B-FAF88B6D83AB}.Debug|Win32.Build.0 = Debug|Win32
- {8051B837-2982-4F64-8C3B-FAF88B6D83AB}.Debug|x64.ActiveCfg = Debug|Win32
- {8051B837-2982-4F64-8C3B-FAF88B6D83AB}.Release|Win32.ActiveCfg = Release|Win32
- {8051B837-2982-4F64-8C3B-FAF88B6D83AB}.Release|Win32.Build.0 = Release|Win32
- {8051B837-2982-4F64-8C3B-FAF88B6D83AB}.Release|x64.ActiveCfg = Release|Win32
- {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
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Samples/LibOVR_Samples_VS2010.sln b/Samples/LibOVR_Samples_VS2010.sln
new file mode 100644
index 0000000..182c95e
--- /dev/null
+++ b/Samples/LibOVR_Samples_VS2010.sln
@@ -0,0 +1,35 @@
+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
new file mode 100644
index 0000000..5e2247c
--- /dev/null
+++ b/Samples/LibOVR_Samples_VS2012.sln
@@ -0,0 +1,43 @@
+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
new file mode 100644
index 0000000..42b9e07
--- /dev/null
+++ b/Samples/LibOVR_Samples_VS2013.sln
@@ -0,0 +1,38 @@
+
+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.xcodeproj/OculusRoomTiny-Info.plist b/Samples/LibOVR_With_Samples.xcodeproj/OculusRoomTiny-Info.plist
deleted file mode 100644
index 644e6d8..0000000
--- a/Samples/LibOVR_With_Samples.xcodeproj/OculusRoomTiny-Info.plist
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleDevelopmentRegion</key>
- <string>en</string>
- <key>CFBundleExecutable</key>
- <string>${EXECUTABLE_NAME}</string>
- <key>CFBundleIconFile</key>
- <string></string>
- <key>CFBundleIdentifier</key>
- <string>com.oculusvr.${PRODUCT_NAME:rfc1034identifier}</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleName</key>
- <string>${PRODUCT_NAME}</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleShortVersionString</key>
- <string>1.0</string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>CFBundleVersion</key>
- <string>1</string>
- <key>LSMinimumSystemVersion</key>
- <string>${MACOSX_DEPLOYMENT_TARGET}</string>
- <key>NSHumanReadableCopyright</key>
- <string>Copyright © 2013 Oculus VR. All rights reserved.</string>
- <key>NSMainNibFile</key>
- <string>MainMenu</string>
- <key>NSPrincipalClass</key>
- <string>NSApplication</string>
-</dict>
-</plist>
diff --git a/Samples/LibOVR_With_Samples.xcodeproj/OculusWorldDemo-Info.plist b/Samples/LibOVR_With_Samples.xcodeproj/OculusWorldDemo-Info.plist
deleted file mode 100644
index 23028a1..0000000
--- a/Samples/LibOVR_With_Samples.xcodeproj/OculusWorldDemo-Info.plist
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleDevelopmentRegion</key>
- <string>en</string>
- <key>CFBundleExecutable</key>
- <string>${EXECUTABLE_NAME}</string>
- <key>CFBundleIconFile</key>
- <string>Oculus</string>
- <key>CFBundleIdentifier</key>
- <string>com.oculusvr.${PRODUCT_NAME:rfc1034identifier}</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleName</key>
- <string>${PRODUCT_NAME}</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleShortVersionString</key>
- <string>1.0</string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>CFBundleVersion</key>
- <string>1</string>
- <key>LSMinimumSystemVersion</key>
- <string>${MACOSX_DEPLOYMENT_TARGET}</string>
- <key>NSHumanReadableCopyright</key>
- <string>Copyright © 2013 Oculus VR. All rights reserved.</string>
- <key>NSMainNibFile</key>
- <string>MainMenu</string>
- <key>NSPrincipalClass</key>
- <string>NSApplication</string>
-</dict>
-</plist>
diff --git a/Samples/LibOVR_With_Samples.xcodeproj/SensorBoxTest-Info.plist b/Samples/LibOVR_With_Samples.xcodeproj/SensorBoxTest-Info.plist
deleted file mode 100644
index 23028a1..0000000
--- a/Samples/LibOVR_With_Samples.xcodeproj/SensorBoxTest-Info.plist
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleDevelopmentRegion</key>
- <string>en</string>
- <key>CFBundleExecutable</key>
- <string>${EXECUTABLE_NAME}</string>
- <key>CFBundleIconFile</key>
- <string>Oculus</string>
- <key>CFBundleIdentifier</key>
- <string>com.oculusvr.${PRODUCT_NAME:rfc1034identifier}</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleName</key>
- <string>${PRODUCT_NAME}</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleShortVersionString</key>
- <string>1.0</string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>CFBundleVersion</key>
- <string>1</string>
- <key>LSMinimumSystemVersion</key>
- <string>${MACOSX_DEPLOYMENT_TARGET}</string>
- <key>NSHumanReadableCopyright</key>
- <string>Copyright © 2013 Oculus VR. All rights reserved.</string>
- <key>NSMainNibFile</key>
- <string>MainMenu</string>
- <key>NSPrincipalClass</key>
- <string>NSApplication</string>
-</dict>
-</plist>
diff --git a/Samples/LibOVR_With_Samples.xcodeproj/project.pbxproj b/Samples/LibOVR_With_Samples.xcodeproj/project.pbxproj
deleted file mode 100644
index a2bc2f1..0000000
--- a/Samples/LibOVR_With_Samples.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,1131 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 46;
- objects = {
-
-/* Begin PBXBuildFile section */
- 37973B391739D78B0093BBB8 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4945072216E55A0300B9FF78 /* Cocoa.framework */; };
- 37973B501739E1B60093BBB8 /* OculusRoomModel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37973B4F1739E1B60093BBB8 /* OculusRoomModel.cpp */; };
- 37973B531739E1D20093BBB8 /* RenderTiny_Device.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37973B511739E1D20093BBB8 /* RenderTiny_Device.cpp */; };
- 37973B561739E9230093BBB8 /* RenderTiny_GL_Device.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37973B541739E9230093BBB8 /* RenderTiny_GL_Device.cpp */; };
- 37973B591739E9E80093BBB8 /* OSX_OculusRoomTiny.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37973B581739E9E80093BBB8 /* OSX_OculusRoomTiny.mm */; };
- 37973B5C1739FA620093BBB8 /* libovr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 49A5336D16E544BE0039CB59 /* libovr.a */; };
- 37973B5D1739FA920093BBB8 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 499ED4C516E6A179008EA2ED /* IOKit.framework */; };
- 37973B5E1739FAB60093BBB8 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4945071616E546F700B9FF78 /* OpenGL.framework */; };
- 37973B5F1739FAC80093BBB8 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49DB65F01718B1E10097A8DD /* ApplicationServices.framework */; };
- 37973B601739FAD50093BBB8 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 499ED4C716E6A187008EA2ED /* CoreFoundation.framework */; };
- 439FE6E217BE2E21007EFD34 /* OSX_Gamepad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BB10AEF173C4918009ED618 /* OSX_Gamepad.cpp */; };
- 494506DD16E5461F00B9FF78 /* OVR_Alg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5337116E544E30039CB59 /* OVR_Alg.cpp */; };
- 494506DF16E5461F00B9FF78 /* OVR_Allocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5337316E544E30039CB59 /* OVR_Allocator.cpp */; };
- 494506E216E5461F00B9FF78 /* OVR_Atomic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5337616E544E30039CB59 /* OVR_Atomic.cpp */; };
- 494506E616E5461F00B9FF78 /* OVR_File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5337A16E544E30039CB59 /* OVR_File.cpp */; };
- 494506E816E5461F00B9FF78 /* OVR_FileFILE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5337C16E544E30039CB59 /* OVR_FileFILE.cpp */; };
- 494506EC16E5461F00B9FF78 /* OVR_Log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5338016E544E30039CB59 /* OVR_Log.cpp */; };
- 494506EE16E5461F00B9FF78 /* OVR_Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5338216E544E30039CB59 /* OVR_Math.cpp */; };
- 494506F016E5461F00B9FF78 /* OVR_RefCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5338416E544E30039CB59 /* OVR_RefCount.cpp */; };
- 494506F216E5461F00B9FF78 /* OVR_Std.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5338616E544E30039CB59 /* OVR_Std.cpp */; };
- 494506F416E5461F00B9FF78 /* OVR_String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5338816E544E30039CB59 /* OVR_String.cpp */; };
- 494506F616E5461F00B9FF78 /* OVR_String_FormatUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5338A16E544E30039CB59 /* OVR_String_FormatUtil.cpp */; };
- 494506F716E5461F00B9FF78 /* OVR_String_PathUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5338B16E544E30039CB59 /* OVR_String_PathUtil.cpp */; };
- 494506F916E5461F00B9FF78 /* OVR_SysFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5338D16E544E30039CB59 /* OVR_SysFile.cpp */; };
- 494506FB16E5461F00B9FF78 /* OVR_System.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5338F16E544E30039CB59 /* OVR_System.cpp */; };
- 494506FE16E5461F00B9FF78 /* OVR_ThreadsPthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5339216E544E30039CB59 /* OVR_ThreadsPthread.cpp */; };
- 494506FF16E5461F00B9FF78 /* OVR_Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5339316E544E30039CB59 /* OVR_Timer.cpp */; };
- 4945070216E5461F00B9FF78 /* OVR_UTF8Util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5339616E544E30039CB59 /* OVR_UTF8Util.cpp */; };
- 4945070616E5462A00B9FF78 /* OVR_DeviceHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5339B16E544E30039CB59 /* OVR_DeviceHandle.cpp */; };
- 4945070816E5462A00B9FF78 /* OVR_DeviceImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5339D16E544E30039CB59 /* OVR_DeviceImpl.cpp */; };
- 4945070F16E5462A00B9FF78 /* OVR_SensorFusion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A533A416E544E30039CB59 /* OVR_SensorFusion.cpp */; };
- 4945071116E5462A00B9FF78 /* OVR_ThreadCommandQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A533A616E544E30039CB59 /* OVR_ThreadCommandQueue.cpp */; };
- 4985385E16ECFE92008D0727 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4945072216E55A0300B9FF78 /* Cocoa.framework */; };
- 4985387416ECFED8008D0727 /* Render_Device.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5335016E527820039CB59 /* Render_Device.cpp */; };
- 4985387816ECFED8008D0727 /* Render_GL_Device.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5335416E527820039CB59 /* Render_GL_Device.cpp */; };
- 4985387A16ECFED8008D0727 /* Render_LoadTextureTGA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5335816E527820039CB59 /* Render_LoadTextureTGA.cpp */; };
- 4985388016ECFEE5008D0727 /* Platform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5334216E527820039CB59 /* Platform.cpp */; };
- 4985388616ECFF2D008D0727 /* OculusWorldDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4985388116ECFF23008D0727 /* OculusWorldDemo.cpp */; };
- 4985388716ECFF2D008D0727 /* Player.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4985388216ECFF23008D0727 /* Player.cpp */; };
- 4985388A16ECFF53008D0727 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 499ED4C716E6A187008EA2ED /* CoreFoundation.framework */; };
- 4985388C16ECFF53008D0727 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 499ED4C516E6A179008EA2ED /* IOKit.framework */; };
- 4985388D16ECFF53008D0727 /* IOSurface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 499ED4C916E9880D008EA2ED /* IOSurface.framework */; };
- 4985388E16ECFF53008D0727 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4945071616E546F700B9FF78 /* OpenGL.framework */; };
- 4985389216ED0204008D0727 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4985389116ED0204008D0727 /* tinyxml2.cpp */; };
- 4985389516ED0218008D0727 /* Render_LoadTextureDDS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4985389316ED0218008D0727 /* Render_LoadTextureDDS.cpp */; };
- 4985389716ED1AA7008D0727 /* Assets in Resources */ = {isa = PBXBuildFile; fileRef = 4985389616ED1AA7008D0727 /* Assets */; };
- 49ABA2E91718A38100E288A7 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49ABA2E81718A38100E288A7 /* AudioToolbox.framework */; };
- 49DB65F11718B1E10097A8DD /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49DB65F01718B1E10097A8DD /* ApplicationServices.framework */; };
- 49DB65F71726F0C30097A8DD /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4945072216E55A0300B9FF78 /* Cocoa.framework */; };
- 49DB660F1726F0EA0097A8DD /* OSX_Platform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BBB8902171E2BE200563901 /* OSX_Platform.mm */; };
- 49DB66101726F0EA0097A8DD /* Platform.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5334216E527820039CB59 /* Platform.cpp */; };
- 49DB66111726F0F80097A8DD /* Render_LoadTextureDDS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4985389316ED0218008D0727 /* Render_LoadTextureDDS.cpp */; };
- 49DB66121726F0F80097A8DD /* Render_Device.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5335016E527820039CB59 /* Render_Device.cpp */; };
- 49DB66131726F0F80097A8DD /* Render_GL_Device.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5335416E527820039CB59 /* Render_GL_Device.cpp */; };
- 49DB66141726F0F80097A8DD /* Render_LoadTextureTGA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A5335816E527820039CB59 /* Render_LoadTextureTGA.cpp */; };
- 49DB66171726F1350097A8DD /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49DB65F01718B1E10097A8DD /* ApplicationServices.framework */; };
- 49DB66181726F13B0097A8DD /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 499ED4C516E6A179008EA2ED /* IOKit.framework */; };
- 49DB66191726F1530097A8DD /* libovr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 49A5336D16E544BE0039CB59 /* libovr.a */; };
- 49DB661A1726F1650097A8DD /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4945071616E546F700B9FF78 /* OpenGL.framework */; };
- 9B6DEF851728A6560071E76B /* SensorBoxTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B6DEF841728A6560071E76B /* SensorBoxTest.cpp */; };
- 9BA4DDB61721E12400CF7715 /* OSX_Platform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9BBB8902171E2BE200563901 /* OSX_Platform.mm */; };
- 9BA4DDB81727061100CF7715 /* Oculus.icns in Resources */ = {isa = PBXBuildFile; fileRef = 9BA4DDB71727061100CF7715 /* Oculus.icns */; };
- 9BA4DDB91727083500CF7715 /* Oculus.icns in Resources */ = {isa = PBXBuildFile; fileRef = 9BA4DDB71727061100CF7715 /* Oculus.icns */; };
- 9BAB70F6170E69530006FE98 /* libovr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 49A5336D16E544BE0039CB59 /* libovr.a */; };
- 9BB10AF1173C4918009ED618 /* OSX_Gamepad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BB10AEF173C4918009ED618 /* OSX_Gamepad.cpp */; };
- 9BCE53F916F0293A007A23FF /* OVR_HIDDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BCE53F416F0293A007A23FF /* OVR_HIDDevice.h */; };
- 9BCE53FA16F0293A007A23FF /* OVR_HIDDeviceBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BCE53F516F0293A007A23FF /* OVR_HIDDeviceBase.h */; };
- 9BCE53FB16F0293A007A23FF /* OVR_HIDDeviceImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BCE53F616F0293A007A23FF /* OVR_HIDDeviceImpl.h */; };
- 9BCE53FC16F0293A007A23FF /* OVR_LatencyTestImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BCE53F716F0293A007A23FF /* OVR_LatencyTestImpl.cpp */; };
- 9BCE53FD16F0293A007A23FF /* OVR_LatencyTestImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BCE53F816F0293A007A23FF /* OVR_LatencyTestImpl.h */; };
- 9BCE540016F02A56007A23FF /* OVR_SensorImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BCE53FE16F02A56007A23FF /* OVR_SensorImpl.cpp */; };
- 9BCE540116F02A56007A23FF /* OVR_SensorImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BCE53FF16F02A56007A23FF /* OVR_SensorImpl.h */; };
- 9BCE541616F02ABC007A23FF /* OVR_OSX_DeviceManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BCE53EB16F028A9007A23FF /* OVR_OSX_DeviceManager.cpp */; };
- 9BCE541716F02AD5007A23FF /* OVR_OSX_HIDDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BCE53ED16F028AA007A23FF /* OVR_OSX_HIDDevice.cpp */; };
- 9BCE541816F02ADB007A23FF /* OVR_OSX_DeviceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BCE53EC16F028AA007A23FF /* OVR_OSX_DeviceManager.h */; };
- 9BCE541916F02AE6007A23FF /* OVR_OSX_HIDDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BCE53EE16F028AA007A23FF /* OVR_OSX_HIDDevice.h */; };
- 9BCE541A16F02AEB007A23FF /* OVR_OSX_HMDDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BCE53EF16F028AA007A23FF /* OVR_OSX_HMDDevice.cpp */; };
- 9BCE541B16F02AF1007A23FF /* OVR_OSX_HMDDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BCE53F016F028AA007A23FF /* OVR_OSX_HMDDevice.h */; };
- 9BCE541C16F02B04007A23FF /* OVR_Device.h in Headers */ = {isa = PBXBuildFile; fileRef = 499ED4B216E5703B008EA2ED /* OVR_Device.h */; };
- 9BCE541D16F02B13007A23FF /* OVR_DeviceConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A5339A16E544E30039CB59 /* OVR_DeviceConstants.h */; };
- 9BCE541E16F02B1D007A23FF /* OVR_DeviceHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A5339C16E544E30039CB59 /* OVR_DeviceHandle.h */; };
- 9BCE541F16F02B26007A23FF /* OVR_DeviceImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A5339E16E544E30039CB59 /* OVR_DeviceImpl.h */; };
- 9BCE542016F02B2A007A23FF /* OVR_DeviceMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A5339F16E544E30039CB59 /* OVR_DeviceMessages.h */; };
- 9BCE542216F02B88007A23FF /* OVR_SensorFusion.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A533A516E544E30039CB59 /* OVR_SensorFusion.h */; };
- 9BCE542316F02B91007A23FF /* OVR_ThreadCommandQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A533A716E544E30039CB59 /* OVR_ThreadCommandQueue.h */; };
- 9BCE542516F2694F007A23FF /* OVR_OSX_SensorDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BCE542416F2694E007A23FF /* OVR_OSX_SensorDevice.cpp */; };
- 9BD2A642172069B300C3C389 /* Util_MagCalibration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BD2A640172069B300C3C389 /* Util_MagCalibration.cpp */; };
- 9BD2A643172069B300C3C389 /* Util_MagCalibration.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BD2A641172069B300C3C389 /* Util_MagCalibration.h */; };
- 9BD2A646172069BF00C3C389 /* OVR_SensorFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BD2A644172069BF00C3C389 /* OVR_SensorFilter.cpp */; };
- 9BD2A647172069BF00C3C389 /* OVR_SensorFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BD2A645172069BF00C3C389 /* OVR_SensorFilter.h */; };
- 9BEAD55F17187B8A00A8AA1D /* Util_LatencyTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BEAD55B17187B8A00A8AA1D /* Util_LatencyTest.cpp */; };
- 9BEAD56017187B8A00A8AA1D /* Util_LatencyTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BEAD55C17187B8A00A8AA1D /* Util_LatencyTest.h */; };
- 9BEAD56117187B8A00A8AA1D /* Util_Render_Stereo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BEAD55D17187B8A00A8AA1D /* Util_Render_Stereo.cpp */; };
- 9BEAD56217187B8A00A8AA1D /* Util_Render_Stereo.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BEAD55E17187B8A00A8AA1D /* Util_Render_Stereo.h */; };
- 9BEAD56517187CFF00A8AA1D /* OSX_WavPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BEAD56317187CFF00A8AA1D /* OSX_WavPlayer.cpp */; };
- 9BEAD56717187E7500A8AA1D /* Render_XmlSceneLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BEAD56617187E7500A8AA1D /* Render_XmlSceneLoader.cpp */; };
- C50FA3D0177BB88E00730BB7 /* OVR_JSON.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50FA3CC177BB88E00730BB7 /* OVR_JSON.cpp */; };
- C50FA3D1177BB88E00730BB7 /* OVR_JSON.h in Headers */ = {isa = PBXBuildFile; fileRef = C50FA3CD177BB88E00730BB7 /* OVR_JSON.h */; };
- C50FA3D2177BB88E00730BB7 /* OVR_Profile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C50FA3CE177BB88E00730BB7 /* OVR_Profile.cpp */; };
- C50FA3D3177BB88E00730BB7 /* OVR_Profile.h in Headers */ = {isa = PBXBuildFile; fileRef = C50FA3CF177BB88E00730BB7 /* OVR_Profile.h */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXContainerItemProxy section */
- 37973B5A1739FA100093BBB8 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 49A5332B16E527490039CB59 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 49A5336C16E544BE0039CB59;
- remoteInfo = ovr;
- };
- 4985388F16ECFF5C008D0727 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 49A5332B16E527490039CB59 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 49A5336C16E544BE0039CB59;
- remoteInfo = ovr;
- };
- 49DB660D1726F0CD0097A8DD /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 49A5332B16E527490039CB59 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 49A5336C16E544BE0039CB59;
- remoteInfo = ovr;
- };
-/* End PBXContainerItemProxy section */
-
-/* Begin PBXFileReference section */
- 37973B381739D78B0093BBB8 /* OculusRoomTiny.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OculusRoomTiny.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 37973B4F1739E1B60093BBB8 /* OculusRoomModel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OculusRoomModel.cpp; sourceTree = "<group>"; };
- 37973B511739E1D20093BBB8 /* RenderTiny_Device.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTiny_Device.cpp; sourceTree = "<group>"; };
- 37973B521739E1D20093BBB8 /* RenderTiny_Device.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTiny_Device.h; sourceTree = "<group>"; };
- 37973B541739E9230093BBB8 /* RenderTiny_GL_Device.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTiny_GL_Device.cpp; sourceTree = "<group>"; };
- 37973B551739E9230093BBB8 /* RenderTiny_GL_Device.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTiny_GL_Device.h; sourceTree = "<group>"; };
- 37973B571739E9E80093BBB8 /* OSX_OculusRoomTiny.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSX_OculusRoomTiny.h; sourceTree = "<group>"; };
- 37973B581739E9E80093BBB8 /* OSX_OculusRoomTiny.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OSX_OculusRoomTiny.mm; sourceTree = "<group>"; };
- 4945071616E546F700B9FF78 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
- 4945071816E5474000B9FF78 /* libGL.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libGL.dylib; path = ../../../../../../../opt/X11/lib/libGL.dylib; sourceTree = "<group>"; };
- 4945071A16E5474A00B9FF78 /* libX11.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libX11.dylib; path = ../../../../../../../opt/X11/lib/libX11.dylib; sourceTree = "<group>"; };
- 4945072216E55A0300B9FF78 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
- 4945072516E55A0300B9FF78 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
- 4945072616E55A0300B9FF78 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
- 4945072716E55A0300B9FF78 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
- 4985385D16ECFE92008D0727 /* OculusWorldDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OculusWorldDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 4985388116ECFF23008D0727 /* OculusWorldDemo.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = OculusWorldDemo.cpp; path = OculusWorldDemo/OculusWorldDemo.cpp; sourceTree = "<group>"; };
- 4985388216ECFF23008D0727 /* Player.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Player.cpp; path = OculusWorldDemo/Player.cpp; sourceTree = "<group>"; };
- 4985388316ECFF23008D0727 /* Player.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Player.h; path = OculusWorldDemo/Player.h; sourceTree = "<group>"; };
- 4985389116ED0204008D0727 /* tinyxml2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tinyxml2.cpp; path = ../3rdParty/TinyXml/tinyxml2.cpp; sourceTree = "<group>"; };
- 4985389316ED0218008D0727 /* Render_LoadTextureDDS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Render_LoadTextureDDS.cpp; sourceTree = "<group>"; };
- 4985389616ED1AA7008D0727 /* Assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Assets; path = OculusWorldDemo/Assets; sourceTree = "<group>"; };
- 499ED49B16E57027008EA2ED /* OVR_Alg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_Alg.h; sourceTree = "<group>"; };
- 499ED49C16E57027008EA2ED /* OVR_Allocator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_Allocator.h; sourceTree = "<group>"; };
- 499ED49D16E57027008EA2ED /* OVR_Array.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_Array.h; sourceTree = "<group>"; };
- 499ED49E16E57027008EA2ED /* OVR_Atomic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_Atomic.h; sourceTree = "<group>"; };
- 499ED49F16E57027008EA2ED /* OVR_Color.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_Color.h; sourceTree = "<group>"; };
- 499ED4A016E57027008EA2ED /* OVR_ContainerAllocator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_ContainerAllocator.h; sourceTree = "<group>"; };
- 499ED4A116E57027008EA2ED /* OVR_File.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_File.h; sourceTree = "<group>"; };
- 499ED4A216E57027008EA2ED /* OVR_Hash.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_Hash.h; sourceTree = "<group>"; };
- 499ED4A316E57027008EA2ED /* OVR_KeyCodes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_KeyCodes.h; sourceTree = "<group>"; };
- 499ED4A416E57027008EA2ED /* OVR_List.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_List.h; sourceTree = "<group>"; };
- 499ED4A516E57027008EA2ED /* OVR_Log.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_Log.h; sourceTree = "<group>"; };
- 499ED4A616E57027008EA2ED /* OVR_Math.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_Math.h; sourceTree = "<group>"; };
- 499ED4A716E57027008EA2ED /* OVR_RefCount.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_RefCount.h; sourceTree = "<group>"; };
- 499ED4A816E57027008EA2ED /* OVR_Std.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_Std.h; sourceTree = "<group>"; };
- 499ED4A916E57027008EA2ED /* OVR_String.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_String.h; sourceTree = "<group>"; };
- 499ED4AA16E57027008EA2ED /* OVR_StringHash.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_StringHash.h; sourceTree = "<group>"; };
- 499ED4AB16E57027008EA2ED /* OVR_SysFile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_SysFile.h; sourceTree = "<group>"; };
- 499ED4AC16E57027008EA2ED /* OVR_System.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_System.h; sourceTree = "<group>"; };
- 499ED4AD16E57027008EA2ED /* OVR_Threads.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_Threads.h; sourceTree = "<group>"; };
- 499ED4AE16E57027008EA2ED /* OVR_ThreadsWinAPI.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_ThreadsWinAPI.cpp; sourceTree = "<group>"; };
- 499ED4AF16E57027008EA2ED /* OVR_Timer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_Timer.h; sourceTree = "<group>"; };
- 499ED4B016E57027008EA2ED /* OVR_Types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_Types.h; sourceTree = "<group>"; };
- 499ED4B116E57027008EA2ED /* OVR_UTF8Util.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_UTF8Util.h; sourceTree = "<group>"; };
- 499ED4B216E5703B008EA2ED /* OVR_Device.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OVR_Device.h; sourceTree = "<group>"; };
- 499ED4C516E6A179008EA2ED /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
- 499ED4C716E6A187008EA2ED /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
- 499ED4C916E9880D008EA2ED /* IOSurface.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOSurface.framework; path = System/Library/Frameworks/IOSurface.framework; sourceTree = SDKROOT; };
- 49A5334216E527820039CB59 /* Platform.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Platform.cpp; sourceTree = "<group>"; };
- 49A5334316E527820039CB59 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Platform.h; sourceTree = "<group>"; };
- 49A5334416E527820039CB59 /* Platform_Default.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Platform_Default.h; sourceTree = "<group>"; };
- 49A5335016E527820039CB59 /* Render_Device.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Render_Device.cpp; sourceTree = "<group>"; };
- 49A5335116E527820039CB59 /* Render_Device.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Render_Device.h; sourceTree = "<group>"; };
- 49A5335216E527820039CB59 /* Render_Font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Render_Font.h; sourceTree = "<group>"; };
- 49A5335316E527820039CB59 /* Render_FontEmbed_DejaVu48.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Render_FontEmbed_DejaVu48.h; sourceTree = "<group>"; };
- 49A5335416E527820039CB59 /* Render_GL_Device.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Render_GL_Device.cpp; sourceTree = "<group>"; };
- 49A5335516E527820039CB59 /* Render_GL_Device.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Render_GL_Device.h; sourceTree = "<group>"; };
- 49A5335816E527820039CB59 /* Render_LoadTextureTGA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Render_LoadTextureTGA.cpp; sourceTree = "<group>"; };
- 49A5336D16E544BE0039CB59 /* libovr.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libovr.a; sourceTree = BUILT_PRODUCTS_DIR; };
- 49A5337116E544E30039CB59 /* OVR_Alg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Alg.cpp; sourceTree = "<group>"; };
- 49A5337316E544E30039CB59 /* OVR_Allocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Allocator.cpp; sourceTree = "<group>"; };
- 49A5337616E544E30039CB59 /* OVR_Atomic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Atomic.cpp; sourceTree = "<group>"; };
- 49A5337A16E544E30039CB59 /* OVR_File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_File.cpp; sourceTree = "<group>"; };
- 49A5337C16E544E30039CB59 /* OVR_FileFILE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_FileFILE.cpp; sourceTree = "<group>"; };
- 49A5338016E544E30039CB59 /* OVR_Log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Log.cpp; sourceTree = "<group>"; };
- 49A5338216E544E30039CB59 /* OVR_Math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Math.cpp; sourceTree = "<group>"; };
- 49A5338416E544E30039CB59 /* OVR_RefCount.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_RefCount.cpp; sourceTree = "<group>"; };
- 49A5338616E544E30039CB59 /* OVR_Std.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Std.cpp; sourceTree = "<group>"; };
- 49A5338816E544E30039CB59 /* OVR_String.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_String.cpp; sourceTree = "<group>"; };
- 49A5338A16E544E30039CB59 /* OVR_String_FormatUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_String_FormatUtil.cpp; sourceTree = "<group>"; };
- 49A5338B16E544E30039CB59 /* OVR_String_PathUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_String_PathUtil.cpp; sourceTree = "<group>"; };
- 49A5338D16E544E30039CB59 /* OVR_SysFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_SysFile.cpp; sourceTree = "<group>"; };
- 49A5338F16E544E30039CB59 /* OVR_System.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_System.cpp; sourceTree = "<group>"; };
- 49A5339216E544E30039CB59 /* OVR_ThreadsPthread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_ThreadsPthread.cpp; sourceTree = "<group>"; };
- 49A5339316E544E30039CB59 /* OVR_Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Timer.cpp; sourceTree = "<group>"; };
- 49A5339616E544E30039CB59 /* OVR_UTF8Util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_UTF8Util.cpp; sourceTree = "<group>"; };
- 49A5339A16E544E30039CB59 /* OVR_DeviceConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_DeviceConstants.h; sourceTree = "<group>"; };
- 49A5339B16E544E30039CB59 /* OVR_DeviceHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_DeviceHandle.cpp; sourceTree = "<group>"; };
- 49A5339C16E544E30039CB59 /* OVR_DeviceHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_DeviceHandle.h; sourceTree = "<group>"; };
- 49A5339D16E544E30039CB59 /* OVR_DeviceImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_DeviceImpl.cpp; sourceTree = "<group>"; };
- 49A5339E16E544E30039CB59 /* OVR_DeviceImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_DeviceImpl.h; sourceTree = "<group>"; };
- 49A5339F16E544E30039CB59 /* OVR_DeviceMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_DeviceMessages.h; sourceTree = "<group>"; };
- 49A533A416E544E30039CB59 /* OVR_SensorFusion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_SensorFusion.cpp; sourceTree = "<group>"; };
- 49A533A516E544E30039CB59 /* OVR_SensorFusion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_SensorFusion.h; sourceTree = "<group>"; };
- 49A533A616E544E30039CB59 /* OVR_ThreadCommandQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_ThreadCommandQueue.cpp; sourceTree = "<group>"; };
- 49A533A716E544E30039CB59 /* OVR_ThreadCommandQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_ThreadCommandQueue.h; sourceTree = "<group>"; };
- 49ABA2E81718A38100E288A7 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = ../../../../../../../System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<group>"; };
- 49DB65F01718B1E10097A8DD /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = System/Library/Frameworks/ApplicationServices.framework; sourceTree = SDKROOT; };
- 49DB65F61726F0C30097A8DD /* SensorBoxTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SensorBoxTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 9B22CBB517187F5C0046D43D /* tinyxml2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tinyxml2.h; path = ../3rdParty/TinyXml/tinyxml2.h; sourceTree = "<group>"; };
- 9B6DEF841728A6560071E76B /* SensorBoxTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SensorBoxTest.cpp; path = SensorBox/SensorBoxTest.cpp; sourceTree = "<group>"; };
- 9BA4DDB71727061100CF7715 /* Oculus.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Oculus.icns; sourceTree = "<group>"; };
- 9BB10AEF173C4918009ED618 /* OSX_Gamepad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OSX_Gamepad.cpp; sourceTree = "<group>"; };
- 9BB10AF0173C4918009ED618 /* OSX_Gamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSX_Gamepad.h; sourceTree = "<group>"; };
- 9BB10AF2173C49AC009ED618 /* Gamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Gamepad.h; sourceTree = "<group>"; };
- 9BBB8901171E2BE200563901 /* OSX_Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSX_Platform.h; sourceTree = "<group>"; };
- 9BBB8902171E2BE200563901 /* OSX_Platform.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OSX_Platform.mm; sourceTree = "<group>"; };
- 9BBB8903171E2BE200563901 /* OSX_PlatformObjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSX_PlatformObjc.h; sourceTree = "<group>"; };
- 9BCE53EB16F028A9007A23FF /* OVR_OSX_DeviceManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_OSX_DeviceManager.cpp; sourceTree = "<group>"; };
- 9BCE53EC16F028AA007A23FF /* OVR_OSX_DeviceManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_OSX_DeviceManager.h; sourceTree = "<group>"; };
- 9BCE53ED16F028AA007A23FF /* OVR_OSX_HIDDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_OSX_HIDDevice.cpp; sourceTree = "<group>"; };
- 9BCE53EE16F028AA007A23FF /* OVR_OSX_HIDDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_OSX_HIDDevice.h; sourceTree = "<group>"; };
- 9BCE53EF16F028AA007A23FF /* OVR_OSX_HMDDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_OSX_HMDDevice.cpp; sourceTree = "<group>"; };
- 9BCE53F016F028AA007A23FF /* OVR_OSX_HMDDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_OSX_HMDDevice.h; sourceTree = "<group>"; };
- 9BCE53F416F0293A007A23FF /* OVR_HIDDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_HIDDevice.h; sourceTree = "<group>"; };
- 9BCE53F516F0293A007A23FF /* OVR_HIDDeviceBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_HIDDeviceBase.h; sourceTree = "<group>"; };
- 9BCE53F616F0293A007A23FF /* OVR_HIDDeviceImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_HIDDeviceImpl.h; sourceTree = "<group>"; };
- 9BCE53F716F0293A007A23FF /* OVR_LatencyTestImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_LatencyTestImpl.cpp; sourceTree = "<group>"; };
- 9BCE53F816F0293A007A23FF /* OVR_LatencyTestImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_LatencyTestImpl.h; sourceTree = "<group>"; };
- 9BCE53FE16F02A56007A23FF /* OVR_SensorImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_SensorImpl.cpp; sourceTree = "<group>"; };
- 9BCE53FF16F02A56007A23FF /* OVR_SensorImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_SensorImpl.h; sourceTree = "<group>"; };
- 9BCE542416F2694E007A23FF /* OVR_OSX_SensorDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_OSX_SensorDevice.cpp; sourceTree = "<group>"; };
- 9BD2A640172069B300C3C389 /* Util_MagCalibration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Util_MagCalibration.cpp; path = Util/Util_MagCalibration.cpp; sourceTree = "<group>"; };
- 9BD2A641172069B300C3C389 /* Util_MagCalibration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Util_MagCalibration.h; path = Util/Util_MagCalibration.h; sourceTree = "<group>"; };
- 9BD2A644172069BF00C3C389 /* OVR_SensorFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_SensorFilter.cpp; sourceTree = "<group>"; };
- 9BD2A645172069BF00C3C389 /* OVR_SensorFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_SensorFilter.h; sourceTree = "<group>"; };
- 9BEAD55B17187B8A00A8AA1D /* Util_LatencyTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Util_LatencyTest.cpp; path = Util/Util_LatencyTest.cpp; sourceTree = "<group>"; };
- 9BEAD55C17187B8A00A8AA1D /* Util_LatencyTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Util_LatencyTest.h; path = Util/Util_LatencyTest.h; sourceTree = "<group>"; };
- 9BEAD55D17187B8A00A8AA1D /* Util_Render_Stereo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Util_Render_Stereo.cpp; path = Util/Util_Render_Stereo.cpp; sourceTree = "<group>"; };
- 9BEAD55E17187B8A00A8AA1D /* Util_Render_Stereo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Util_Render_Stereo.h; path = Util/Util_Render_Stereo.h; sourceTree = "<group>"; };
- 9BEAD56317187CFF00A8AA1D /* OSX_WavPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OSX_WavPlayer.cpp; sourceTree = "<group>"; };
- 9BEAD56417187CFF00A8AA1D /* OSX_WavPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSX_WavPlayer.h; sourceTree = "<group>"; };
- 9BEAD56617187E7500A8AA1D /* Render_XmlSceneLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Render_XmlSceneLoader.cpp; sourceTree = "<group>"; };
- 9BEAD56817187E8300A8AA1D /* Render_XmlSceneLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Render_XmlSceneLoader.h; sourceTree = "<group>"; };
- C50FA3CC177BB88E00730BB7 /* OVR_JSON.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_JSON.cpp; sourceTree = "<group>"; };
- C50FA3CD177BB88E00730BB7 /* OVR_JSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_JSON.h; sourceTree = "<group>"; };
- C50FA3CE177BB88E00730BB7 /* OVR_Profile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Profile.cpp; sourceTree = "<group>"; };
- C50FA3CF177BB88E00730BB7 /* OVR_Profile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Profile.h; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 37973B351739D78B0093BBB8 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 37973B601739FAD50093BBB8 /* CoreFoundation.framework in Frameworks */,
- 37973B5F1739FAC80093BBB8 /* ApplicationServices.framework in Frameworks */,
- 37973B5E1739FAB60093BBB8 /* OpenGL.framework in Frameworks */,
- 37973B5D1739FA920093BBB8 /* IOKit.framework in Frameworks */,
- 37973B391739D78B0093BBB8 /* Cocoa.framework in Frameworks */,
- 37973B5C1739FA620093BBB8 /* libovr.a in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 4985385A16ECFE92008D0727 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 49DB65F11718B1E10097A8DD /* ApplicationServices.framework in Frameworks */,
- 49ABA2E91718A38100E288A7 /* AudioToolbox.framework in Frameworks */,
- 4985388A16ECFF53008D0727 /* CoreFoundation.framework in Frameworks */,
- 4985388C16ECFF53008D0727 /* IOKit.framework in Frameworks */,
- 4985388D16ECFF53008D0727 /* IOSurface.framework in Frameworks */,
- 4985388E16ECFF53008D0727 /* OpenGL.framework in Frameworks */,
- 4985385E16ECFE92008D0727 /* Cocoa.framework in Frameworks */,
- 9BAB70F6170E69530006FE98 /* libovr.a in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 49A5336A16E544BE0039CB59 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 49DB65F31726F0C30097A8DD /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 49DB661A1726F1650097A8DD /* OpenGL.framework in Frameworks */,
- 49DB66191726F1530097A8DD /* libovr.a in Frameworks */,
- 49DB66181726F13B0097A8DD /* IOKit.framework in Frameworks */,
- 49DB66171726F1350097A8DD /* ApplicationServices.framework in Frameworks */,
- 49DB65F71726F0C30097A8DD /* Cocoa.framework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 37973B3A1739D78B0093BBB8 /* OculusRoomTiny */ = {
- isa = PBXGroup;
- children = (
- 37973B571739E9E80093BBB8 /* OSX_OculusRoomTiny.h */,
- 37973B581739E9E80093BBB8 /* OSX_OculusRoomTiny.mm */,
- 37973B541739E9230093BBB8 /* RenderTiny_GL_Device.cpp */,
- 37973B551739E9230093BBB8 /* RenderTiny_GL_Device.h */,
- 37973B511739E1D20093BBB8 /* RenderTiny_Device.cpp */,
- 37973B521739E1D20093BBB8 /* RenderTiny_Device.h */,
- 37973B4F1739E1B60093BBB8 /* OculusRoomModel.cpp */,
- );
- path = OculusRoomTiny;
- sourceTree = "<group>";
- };
- 4945072116E55A0300B9FF78 /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- 4945072216E55A0300B9FF78 /* Cocoa.framework */,
- 4945072416E55A0300B9FF78 /* Other Frameworks */,
- );
- name = Frameworks;
- sourceTree = "<group>";
- };
- 4945072416E55A0300B9FF78 /* Other Frameworks */ = {
- isa = PBXGroup;
- children = (
- 4945072516E55A0300B9FF78 /* AppKit.framework */,
- 4945072616E55A0300B9FF78 /* CoreData.framework */,
- 4945072716E55A0300B9FF78 /* Foundation.framework */,
- );
- name = "Other Frameworks";
- sourceTree = "<group>";
- };
- 49A5332A16E527490039CB59 = {
- isa = PBXGroup;
- children = (
- 9BA4DDB71727061100CF7715 /* Oculus.icns */,
- 49DB65F01718B1E10097A8DD /* ApplicationServices.framework */,
- 49ABA2E81718A38100E288A7 /* AudioToolbox.framework */,
- 9B22CBB417187F380046D43D /* 3rdParty */,
- 9B6DEF831728A60A0071E76B /* SensorBox */,
- 9B22CBB317187EC70046D43D /* OculusWorldDemo */,
- 4985389616ED1AA7008D0727 /* Assets */,
- 37973B3A1739D78B0093BBB8 /* OculusRoomTiny */,
- 49A5333416E527490039CB59 /* Products */,
- 49A533A816E544E30039CB59 /* Src */,
- 49A5334116E527820039CB59 /* Platform */,
- 49A5334916E527820039CB59 /* Render */,
- 4945071816E5474000B9FF78 /* libGL.dylib */,
- 4945071A16E5474A00B9FF78 /* libX11.dylib */,
- 4945072116E55A0300B9FF78 /* Frameworks */,
- 499ED4C716E6A187008EA2ED /* CoreFoundation.framework */,
- 4945071616E546F700B9FF78 /* OpenGL.framework */,
- 499ED4C516E6A179008EA2ED /* IOKit.framework */,
- 499ED4C916E9880D008EA2ED /* IOSurface.framework */,
- );
- sourceTree = "<group>";
- };
- 49A5333416E527490039CB59 /* Products */ = {
- isa = PBXGroup;
- children = (
- 49A5336D16E544BE0039CB59 /* libovr.a */,
- 4985385D16ECFE92008D0727 /* OculusWorldDemo.app */,
- 49DB65F61726F0C30097A8DD /* SensorBoxTest.app */,
- 37973B381739D78B0093BBB8 /* OculusRoomTiny.app */,
- );
- name = Products;
- sourceTree = "<group>";
- };
- 49A5334116E527820039CB59 /* Platform */ = {
- isa = PBXGroup;
- children = (
- 9BB10AF2173C49AC009ED618 /* Gamepad.h */,
- 9BB10AEF173C4918009ED618 /* OSX_Gamepad.cpp */,
- 9BB10AF0173C4918009ED618 /* OSX_Gamepad.h */,
- 9BEAD56317187CFF00A8AA1D /* OSX_WavPlayer.cpp */,
- 9BEAD56417187CFF00A8AA1D /* OSX_WavPlayer.h */,
- 9BBB8901171E2BE200563901 /* OSX_Platform.h */,
- 9BBB8902171E2BE200563901 /* OSX_Platform.mm */,
- 9BBB8903171E2BE200563901 /* OSX_PlatformObjc.h */,
- 49A5334216E527820039CB59 /* Platform.cpp */,
- 49A5334316E527820039CB59 /* Platform.h */,
- 49A5334416E527820039CB59 /* Platform_Default.h */,
- );
- name = Platform;
- path = CommonSrc/Platform;
- sourceTree = "<group>";
- };
- 49A5334916E527820039CB59 /* Render */ = {
- isa = PBXGroup;
- children = (
- 9BEAD56817187E8300A8AA1D /* Render_XmlSceneLoader.h */,
- 9BEAD56617187E7500A8AA1D /* Render_XmlSceneLoader.cpp */,
- 4985389316ED0218008D0727 /* Render_LoadTextureDDS.cpp */,
- 49A5335016E527820039CB59 /* Render_Device.cpp */,
- 49A5335116E527820039CB59 /* Render_Device.h */,
- 49A5335216E527820039CB59 /* Render_Font.h */,
- 49A5335316E527820039CB59 /* Render_FontEmbed_DejaVu48.h */,
- 49A5335416E527820039CB59 /* Render_GL_Device.cpp */,
- 49A5335516E527820039CB59 /* Render_GL_Device.h */,
- 49A5335816E527820039CB59 /* Render_LoadTextureTGA.cpp */,
- );
- name = Render;
- path = CommonSrc/Render;
- sourceTree = "<group>";
- };
- 49A5339816E544E30039CB59 /* Kernel */ = {
- isa = PBXGroup;
- children = (
- 499ED49B16E57027008EA2ED /* OVR_Alg.h */,
- 499ED49C16E57027008EA2ED /* OVR_Allocator.h */,
- 499ED49D16E57027008EA2ED /* OVR_Array.h */,
- 499ED49E16E57027008EA2ED /* OVR_Atomic.h */,
- 499ED49F16E57027008EA2ED /* OVR_Color.h */,
- 499ED4A016E57027008EA2ED /* OVR_ContainerAllocator.h */,
- 499ED4A116E57027008EA2ED /* OVR_File.h */,
- 499ED4A216E57027008EA2ED /* OVR_Hash.h */,
- 499ED4A316E57027008EA2ED /* OVR_KeyCodes.h */,
- 499ED4A416E57027008EA2ED /* OVR_List.h */,
- 499ED4A516E57027008EA2ED /* OVR_Log.h */,
- 499ED4A616E57027008EA2ED /* OVR_Math.h */,
- 499ED4A716E57027008EA2ED /* OVR_RefCount.h */,
- 499ED4A816E57027008EA2ED /* OVR_Std.h */,
- 499ED4A916E57027008EA2ED /* OVR_String.h */,
- 499ED4AA16E57027008EA2ED /* OVR_StringHash.h */,
- 499ED4AB16E57027008EA2ED /* OVR_SysFile.h */,
- 499ED4AC16E57027008EA2ED /* OVR_System.h */,
- 499ED4AD16E57027008EA2ED /* OVR_Threads.h */,
- 499ED4AE16E57027008EA2ED /* OVR_ThreadsWinAPI.cpp */,
- 499ED4AF16E57027008EA2ED /* OVR_Timer.h */,
- 499ED4B016E57027008EA2ED /* OVR_Types.h */,
- 499ED4B116E57027008EA2ED /* OVR_UTF8Util.h */,
- 49A5337116E544E30039CB59 /* OVR_Alg.cpp */,
- 49A5337316E544E30039CB59 /* OVR_Allocator.cpp */,
- 49A5337616E544E30039CB59 /* OVR_Atomic.cpp */,
- 49A5337A16E544E30039CB59 /* OVR_File.cpp */,
- 49A5337C16E544E30039CB59 /* OVR_FileFILE.cpp */,
- 49A5338016E544E30039CB59 /* OVR_Log.cpp */,
- 49A5338216E544E30039CB59 /* OVR_Math.cpp */,
- 49A5338416E544E30039CB59 /* OVR_RefCount.cpp */,
- 49A5338616E544E30039CB59 /* OVR_Std.cpp */,
- 49A5338816E544E30039CB59 /* OVR_String.cpp */,
- 49A5338A16E544E30039CB59 /* OVR_String_FormatUtil.cpp */,
- 49A5338B16E544E30039CB59 /* OVR_String_PathUtil.cpp */,
- 49A5338D16E544E30039CB59 /* OVR_SysFile.cpp */,
- 49A5338F16E544E30039CB59 /* OVR_System.cpp */,
- 49A5339216E544E30039CB59 /* OVR_ThreadsPthread.cpp */,
- 49A5339316E544E30039CB59 /* OVR_Timer.cpp */,
- 49A5339616E544E30039CB59 /* OVR_UTF8Util.cpp */,
- );
- path = Kernel;
- sourceTree = "<group>";
- };
- 49A533A816E544E30039CB59 /* Src */ = {
- isa = PBXGroup;
- children = (
- C50FA3CC177BB88E00730BB7 /* OVR_JSON.cpp */,
- C50FA3CD177BB88E00730BB7 /* OVR_JSON.h */,
- C50FA3CE177BB88E00730BB7 /* OVR_Profile.cpp */,
- C50FA3CF177BB88E00730BB7 /* OVR_Profile.h */,
- 9BD2A644172069BF00C3C389 /* OVR_SensorFilter.cpp */,
- 9BD2A645172069BF00C3C389 /* OVR_SensorFilter.h */,
- 9BEAD55A17187B5500A8AA1D /* Util */,
- 49A5339816E544E30039CB59 /* Kernel */,
- 9BCE542416F2694E007A23FF /* OVR_OSX_SensorDevice.cpp */,
- 9BCE53EB16F028A9007A23FF /* OVR_OSX_DeviceManager.cpp */,
- 9BCE53EC16F028AA007A23FF /* OVR_OSX_DeviceManager.h */,
- 9BCE53ED16F028AA007A23FF /* OVR_OSX_HIDDevice.cpp */,
- 9BCE53EE16F028AA007A23FF /* OVR_OSX_HIDDevice.h */,
- 9BCE53EF16F028AA007A23FF /* OVR_OSX_HMDDevice.cpp */,
- 9BCE53F016F028AA007A23FF /* OVR_OSX_HMDDevice.h */,
- 499ED4B216E5703B008EA2ED /* OVR_Device.h */,
- 49A5339A16E544E30039CB59 /* OVR_DeviceConstants.h */,
- 49A5339B16E544E30039CB59 /* OVR_DeviceHandle.cpp */,
- 49A5339C16E544E30039CB59 /* OVR_DeviceHandle.h */,
- 49A5339D16E544E30039CB59 /* OVR_DeviceImpl.cpp */,
- 49A5339E16E544E30039CB59 /* OVR_DeviceImpl.h */,
- 49A5339F16E544E30039CB59 /* OVR_DeviceMessages.h */,
- 9BCE53FE16F02A56007A23FF /* OVR_SensorImpl.cpp */,
- 9BCE53FF16F02A56007A23FF /* OVR_SensorImpl.h */,
- 9BCE53F416F0293A007A23FF /* OVR_HIDDevice.h */,
- 9BCE53F516F0293A007A23FF /* OVR_HIDDeviceBase.h */,
- 9BCE53F616F0293A007A23FF /* OVR_HIDDeviceImpl.h */,
- 9BCE53F716F0293A007A23FF /* OVR_LatencyTestImpl.cpp */,
- 9BCE53F816F0293A007A23FF /* OVR_LatencyTestImpl.h */,
- 49A533A416E544E30039CB59 /* OVR_SensorFusion.cpp */,
- 49A533A516E544E30039CB59 /* OVR_SensorFusion.h */,
- 49A533A616E544E30039CB59 /* OVR_ThreadCommandQueue.cpp */,
- 49A533A716E544E30039CB59 /* OVR_ThreadCommandQueue.h */,
- );
- name = Src;
- path = ../LibOVR/Src;
- sourceTree = "<group>";
- };
- 9B22CBB317187EC70046D43D /* OculusWorldDemo */ = {
- isa = PBXGroup;
- children = (
- 4985388216ECFF23008D0727 /* Player.cpp */,
- 4985388316ECFF23008D0727 /* Player.h */,
- 4985388116ECFF23008D0727 /* OculusWorldDemo.cpp */,
- );
- name = OculusWorldDemo;
- sourceTree = "<group>";
- };
- 9B22CBB417187F380046D43D /* 3rdParty */ = {
- isa = PBXGroup;
- children = (
- 9B22CBB517187F5C0046D43D /* tinyxml2.h */,
- 4985389116ED0204008D0727 /* tinyxml2.cpp */,
- );
- name = 3rdParty;
- sourceTree = "<group>";
- };
- 9B6DEF831728A60A0071E76B /* SensorBox */ = {
- isa = PBXGroup;
- children = (
- 9B6DEF841728A6560071E76B /* SensorBoxTest.cpp */,
- );
- name = SensorBox;
- sourceTree = "<group>";
- };
- 9BEAD55A17187B5500A8AA1D /* Util */ = {
- isa = PBXGroup;
- children = (
- 9BD2A640172069B300C3C389 /* Util_MagCalibration.cpp */,
- 9BD2A641172069B300C3C389 /* Util_MagCalibration.h */,
- 9BEAD55B17187B8A00A8AA1D /* Util_LatencyTest.cpp */,
- 9BEAD55C17187B8A00A8AA1D /* Util_LatencyTest.h */,
- 9BEAD55D17187B8A00A8AA1D /* Util_Render_Stereo.cpp */,
- 9BEAD55E17187B8A00A8AA1D /* Util_Render_Stereo.h */,
- );
- name = Util;
- sourceTree = "<group>";
- };
-/* End PBXGroup section */
-
-/* Begin PBXHeadersBuildPhase section */
- 49A5336B16E544BE0039CB59 /* Headers */ = {
- isa = PBXHeadersBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 9BCE53F916F0293A007A23FF /* OVR_HIDDevice.h in Headers */,
- 9BCE53FA16F0293A007A23FF /* OVR_HIDDeviceBase.h in Headers */,
- 9BCE53FB16F0293A007A23FF /* OVR_HIDDeviceImpl.h in Headers */,
- 9BCE53FD16F0293A007A23FF /* OVR_LatencyTestImpl.h in Headers */,
- 9BCE540116F02A56007A23FF /* OVR_SensorImpl.h in Headers */,
- 9BCE541816F02ADB007A23FF /* OVR_OSX_DeviceManager.h in Headers */,
- 9BCE541916F02AE6007A23FF /* OVR_OSX_HIDDevice.h in Headers */,
- 9BCE541B16F02AF1007A23FF /* OVR_OSX_HMDDevice.h in Headers */,
- 9BCE541C16F02B04007A23FF /* OVR_Device.h in Headers */,
- 9BCE541D16F02B13007A23FF /* OVR_DeviceConstants.h in Headers */,
- 9BCE541E16F02B1D007A23FF /* OVR_DeviceHandle.h in Headers */,
- 9BCE541F16F02B26007A23FF /* OVR_DeviceImpl.h in Headers */,
- 9BCE542016F02B2A007A23FF /* OVR_DeviceMessages.h in Headers */,
- 9BCE542216F02B88007A23FF /* OVR_SensorFusion.h in Headers */,
- 9BCE542316F02B91007A23FF /* OVR_ThreadCommandQueue.h in Headers */,
- 9BEAD56017187B8A00A8AA1D /* Util_LatencyTest.h in Headers */,
- 9BEAD56217187B8A00A8AA1D /* Util_Render_Stereo.h in Headers */,
- 9BD2A643172069B300C3C389 /* Util_MagCalibration.h in Headers */,
- 9BD2A647172069BF00C3C389 /* OVR_SensorFilter.h in Headers */,
- C50FA3D1177BB88E00730BB7 /* OVR_JSON.h in Headers */,
- C50FA3D3177BB88E00730BB7 /* OVR_Profile.h in Headers */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXHeadersBuildPhase section */
-
-/* Begin PBXNativeTarget section */
- 37973B371739D78B0093BBB8 /* OculusRoomTiny */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 37973B4E1739D7930093BBB8 /* Build configuration list for PBXNativeTarget "OculusRoomTiny" */;
- buildPhases = (
- 37973B341739D78B0093BBB8 /* Sources */,
- 37973B351739D78B0093BBB8 /* Frameworks */,
- 37973B361739D78B0093BBB8 /* Resources */,
- );
- buildRules = (
- );
- dependencies = (
- 37973B5B1739FA100093BBB8 /* PBXTargetDependency */,
- );
- name = OculusRoomTiny;
- productName = OculusRoomTiny;
- productReference = 37973B381739D78B0093BBB8 /* OculusRoomTiny.app */;
- productType = "com.apple.product-type.application";
- };
- 4985385C16ECFE92008D0727 /* OculusWorldDemo */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 4985387116ECFE92008D0727 /* Build configuration list for PBXNativeTarget "OculusWorldDemo" */;
- buildPhases = (
- 4985385916ECFE92008D0727 /* Sources */,
- 4985385A16ECFE92008D0727 /* Frameworks */,
- 4985385B16ECFE92008D0727 /* Resources */,
- );
- buildRules = (
- );
- dependencies = (
- 4985389016ECFF5C008D0727 /* PBXTargetDependency */,
- );
- name = OculusWorldDemo;
- productName = OculusWorldDemo;
- productReference = 4985385D16ECFE92008D0727 /* OculusWorldDemo.app */;
- productType = "com.apple.product-type.application";
- };
- 49A5336C16E544BE0039CB59 /* ovr */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 49A5336E16E544BE0039CB59 /* Build configuration list for PBXNativeTarget "ovr" */;
- buildPhases = (
- 49A5336916E544BE0039CB59 /* Sources */,
- 49A5336A16E544BE0039CB59 /* Frameworks */,
- 49A5336B16E544BE0039CB59 /* Headers */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = ovr;
- productName = ovr;
- productReference = 49A5336D16E544BE0039CB59 /* libovr.a */;
- productType = "com.apple.product-type.library.static";
- };
- 49DB65F51726F0C30097A8DD /* SensorBoxTest */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 49DB660C1726F0C30097A8DD /* Build configuration list for PBXNativeTarget "SensorBoxTest" */;
- buildPhases = (
- 49DB65F21726F0C30097A8DD /* Sources */,
- 49DB65F31726F0C30097A8DD /* Frameworks */,
- 49DB65F41726F0C30097A8DD /* Resources */,
- );
- buildRules = (
- );
- dependencies = (
- 49DB660E1726F0CD0097A8DD /* PBXTargetDependency */,
- );
- name = SensorBoxTest;
- productName = SensorBoxTest;
- productReference = 49DB65F61726F0C30097A8DD /* SensorBoxTest.app */;
- productType = "com.apple.product-type.application";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 49A5332B16E527490039CB59 /* Project object */ = {
- isa = PBXProject;
- attributes = {
- LastUpgradeCheck = 0460;
- ORGANIZATIONNAME = "Oculus VR";
- };
- buildConfigurationList = 49A5332E16E527490039CB59 /* Build configuration list for PBXProject "LibOVR_With_Samples" */;
- compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
- hasScannedForEncodings = 0;
- knownRegions = (
- en,
- );
- mainGroup = 49A5332A16E527490039CB59;
- productRefGroup = 49A5333416E527490039CB59 /* Products */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 49A5336C16E544BE0039CB59 /* ovr */,
- 4985385C16ECFE92008D0727 /* OculusWorldDemo */,
- 49DB65F51726F0C30097A8DD /* SensorBoxTest */,
- 37973B371739D78B0093BBB8 /* OculusRoomTiny */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- 37973B361739D78B0093BBB8 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 4985385B16ECFE92008D0727 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 4985389716ED1AA7008D0727 /* Assets in Resources */,
- 9BA4DDB81727061100CF7715 /* Oculus.icns in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 49DB65F41726F0C30097A8DD /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 9BA4DDB91727083500CF7715 /* Oculus.icns in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- 37973B341739D78B0093BBB8 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 37973B501739E1B60093BBB8 /* OculusRoomModel.cpp in Sources */,
- 37973B531739E1D20093BBB8 /* RenderTiny_Device.cpp in Sources */,
- 37973B561739E9230093BBB8 /* RenderTiny_GL_Device.cpp in Sources */,
- 37973B591739E9E80093BBB8 /* OSX_OculusRoomTiny.mm in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 4985385916ECFE92008D0727 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 4985388616ECFF2D008D0727 /* OculusWorldDemo.cpp in Sources */,
- 4985388716ECFF2D008D0727 /* Player.cpp in Sources */,
- 4985388016ECFEE5008D0727 /* Platform.cpp in Sources */,
- 4985387416ECFED8008D0727 /* Render_Device.cpp in Sources */,
- 4985387816ECFED8008D0727 /* Render_GL_Device.cpp in Sources */,
- 4985387A16ECFED8008D0727 /* Render_LoadTextureTGA.cpp in Sources */,
- 4985389216ED0204008D0727 /* tinyxml2.cpp in Sources */,
- 4985389516ED0218008D0727 /* Render_LoadTextureDDS.cpp in Sources */,
- 9BEAD56517187CFF00A8AA1D /* OSX_WavPlayer.cpp in Sources */,
- 9BEAD56717187E7500A8AA1D /* Render_XmlSceneLoader.cpp in Sources */,
- 9BA4DDB61721E12400CF7715 /* OSX_Platform.mm in Sources */,
- 9BB10AF1173C4918009ED618 /* OSX_Gamepad.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 49A5336916E544BE0039CB59 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 4945070616E5462A00B9FF78 /* OVR_DeviceHandle.cpp in Sources */,
- 4945070816E5462A00B9FF78 /* OVR_DeviceImpl.cpp in Sources */,
- 4945070F16E5462A00B9FF78 /* OVR_SensorFusion.cpp in Sources */,
- 4945071116E5462A00B9FF78 /* OVR_ThreadCommandQueue.cpp in Sources */,
- 494506DD16E5461F00B9FF78 /* OVR_Alg.cpp in Sources */,
- 494506DF16E5461F00B9FF78 /* OVR_Allocator.cpp in Sources */,
- 494506E216E5461F00B9FF78 /* OVR_Atomic.cpp in Sources */,
- 494506E616E5461F00B9FF78 /* OVR_File.cpp in Sources */,
- 494506E816E5461F00B9FF78 /* OVR_FileFILE.cpp in Sources */,
- 494506EC16E5461F00B9FF78 /* OVR_Log.cpp in Sources */,
- 494506EE16E5461F00B9FF78 /* OVR_Math.cpp in Sources */,
- 494506F016E5461F00B9FF78 /* OVR_RefCount.cpp in Sources */,
- 494506F216E5461F00B9FF78 /* OVR_Std.cpp in Sources */,
- 494506F416E5461F00B9FF78 /* OVR_String.cpp in Sources */,
- 494506F616E5461F00B9FF78 /* OVR_String_FormatUtil.cpp in Sources */,
- 494506F716E5461F00B9FF78 /* OVR_String_PathUtil.cpp in Sources */,
- 494506F916E5461F00B9FF78 /* OVR_SysFile.cpp in Sources */,
- 494506FB16E5461F00B9FF78 /* OVR_System.cpp in Sources */,
- 494506FE16E5461F00B9FF78 /* OVR_ThreadsPthread.cpp in Sources */,
- 494506FF16E5461F00B9FF78 /* OVR_Timer.cpp in Sources */,
- 4945070216E5461F00B9FF78 /* OVR_UTF8Util.cpp in Sources */,
- 9BCE53FC16F0293A007A23FF /* OVR_LatencyTestImpl.cpp in Sources */,
- 9BCE540016F02A56007A23FF /* OVR_SensorImpl.cpp in Sources */,
- 9BCE541616F02ABC007A23FF /* OVR_OSX_DeviceManager.cpp in Sources */,
- 9BCE541716F02AD5007A23FF /* OVR_OSX_HIDDevice.cpp in Sources */,
- 9BCE541A16F02AEB007A23FF /* OVR_OSX_HMDDevice.cpp in Sources */,
- 9BCE542516F2694F007A23FF /* OVR_OSX_SensorDevice.cpp in Sources */,
- 9BEAD55F17187B8A00A8AA1D /* Util_LatencyTest.cpp in Sources */,
- 9BEAD56117187B8A00A8AA1D /* Util_Render_Stereo.cpp in Sources */,
- 9BD2A642172069B300C3C389 /* Util_MagCalibration.cpp in Sources */,
- 9BD2A646172069BF00C3C389 /* OVR_SensorFilter.cpp in Sources */,
- C50FA3D0177BB88E00730BB7 /* OVR_JSON.cpp in Sources */,
- C50FA3D2177BB88E00730BB7 /* OVR_Profile.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 49DB65F21726F0C30097A8DD /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 439FE6E217BE2E21007EFD34 /* OSX_Gamepad.cpp in Sources */,
- 49DB66111726F0F80097A8DD /* Render_LoadTextureDDS.cpp in Sources */,
- 49DB66121726F0F80097A8DD /* Render_Device.cpp in Sources */,
- 49DB66131726F0F80097A8DD /* Render_GL_Device.cpp in Sources */,
- 49DB66141726F0F80097A8DD /* Render_LoadTextureTGA.cpp in Sources */,
- 49DB660F1726F0EA0097A8DD /* OSX_Platform.mm in Sources */,
- 49DB66101726F0EA0097A8DD /* Platform.cpp in Sources */,
- 9B6DEF851728A6560071E76B /* SensorBoxTest.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXTargetDependency section */
- 37973B5B1739FA100093BBB8 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 49A5336C16E544BE0039CB59 /* ovr */;
- targetProxy = 37973B5A1739FA100093BBB8 /* PBXContainerItemProxy */;
- };
- 4985389016ECFF5C008D0727 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 49A5336C16E544BE0039CB59 /* ovr */;
- targetProxy = 4985388F16ECFF5C008D0727 /* PBXContainerItemProxy */;
- };
- 49DB660E1726F0CD0097A8DD /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 49A5336C16E544BE0039CB59 /* ovr */;
- targetProxy = 49DB660D1726F0CD0097A8DD /* PBXContainerItemProxy */;
- };
-/* End PBXTargetDependency section */
-
-/* Begin XCBuildConfiguration section */
- 37973B4C1739D78C0093BBB8 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LIBRARY = "libstdc++";
- COMBINE_HIDPI_IMAGES = YES;
- CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
- GCC_PRECOMPILE_PREFIX_HEADER = NO;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- HEADER_SEARCH_PATHS = (
- ../LibOVR/Src,
- ../LibOVR/Include,
- );
- INFOPLIST_FILE = "LibOVR_With_Samples.xcodeproj/OculusRoomTiny-Info.plist";
- MACOSX_DEPLOYMENT_TARGET = 10.6;
- ONLY_ACTIVE_ARCH = NO;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SYMROOT = OculusRoomTiny/MacOS/Debug;
- WRAPPER_EXTENSION = app;
- };
- name = Debug;
- };
- 37973B4D1739D78C0093BBB8 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LIBRARY = "libstdc++";
- COMBINE_HIDPI_IMAGES = YES;
- CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
- GCC_PRECOMPILE_PREFIX_HEADER = NO;
- HEADER_SEARCH_PATHS = (
- ../LibOVR/Src,
- ../LibOVR/Include,
- );
- INFOPLIST_FILE = "LibOVR_With_Samples.xcodeproj/OculusRoomTiny-Info.plist";
- MACOSX_DEPLOYMENT_TARGET = 10.6;
- ONLY_ACTIVE_ARCH = NO;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SYMROOT = OculusRoomTiny/MacOS/Release;
- WRAPPER_EXTENSION = app;
- };
- name = Release;
- };
- 4985387216ECFE92008D0727 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_64_BIT)";
- COMBINE_HIDPI_IMAGES = YES;
- CONFIGURATION_BUILD_DIR = OculusWorldDemo/MacOS/Debug;
- GCC_PRECOMPILE_PREFIX_HEADER = NO;
- GCC_PREFIX_HEADER = "";
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = (
- "DEBUG=1",
- "$(inherited)",
- );
- HEADER_SEARCH_PATHS = (
- ../LibOVR/Src,
- ../LibOVR/Include,
- CommonSrc,
- ../3rdParty/TinyXml,
- );
- INFOPLIST_FILE = "LibOVR_With_Samples.xcodeproj/OculusWorldDemo-Info.plist";
- PRODUCT_NAME = "$(TARGET_NAME)";
- SYMROOT = OculusWorldDemo/MacOS/Debug;
- WRAPPER_EXTENSION = app;
- };
- name = Debug;
- };
- 4985387316ECFE92008D0727 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_64_BIT)";
- COMBINE_HIDPI_IMAGES = YES;
- CONFIGURATION_BUILD_DIR = OculusWorldDemo/MacOS/Release;
- GCC_PRECOMPILE_PREFIX_HEADER = NO;
- GCC_PREFIX_HEADER = "";
- HEADER_SEARCH_PATHS = (
- ../LibOVR/Src,
- ../LibOVR/Include,
- CommonSrc,
- ../3rdParty/TinyXml,
- );
- INFOPLIST_FILE = "LibOVR_With_Samples.xcodeproj/OculusWorldDemo-Info.plist";
- PRODUCT_NAME = "$(TARGET_NAME)";
- SYMROOT = OculusWorldDemo/MacOS/Release;
- WRAPPER_EXTENSION = app;
- };
- name = Release;
- };
- 49A5333A16E527490039CB59 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(ARCHS_STANDARD_64_BIT)";
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libstdc++";
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CONFIGURATION_BUILD_DIR = ../LibOVR/Lib/MacOS/Debug;
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = dwarf;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_CPP_EXCEPTIONS = NO;
- GCC_ENABLE_CPP_RTTI = NO;
- GCC_ENABLE_OBJC_EXCEPTIONS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- OVR_BUILD_DEBUG,
- "$(inherited)",
- );
- GCC_SYMBOLS_PRIVATE_EXTERN = NO;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = (
- ../LibOVR/Src,
- ../LibOVR/Include,
- CommonSrc,
- );
- LIBRARY_SEARCH_PATHS = "../LibOVR/Lib/MacOS/$(CONFIGURATION)";
- MACOSX_DEPLOYMENT_TARGET = 10.6;
- ONLY_ACTIVE_ARCH = NO;
- SDKROOT = macosx;
- SUPPORTED_PLATFORMS = macosx;
- };
- name = Debug;
- };
- 49A5333B16E527490039CB59 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(ARCHS_STANDARD_64_BIT)";
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libstdc++";
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CONFIGURATION_BUILD_DIR = ../LibOVR/Lib/MacOS/Release;
- COPY_PHASE_STRIP = YES;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_ENABLE_CPP_EXCEPTIONS = NO;
- GCC_ENABLE_CPP_RTTI = NO;
- GCC_ENABLE_OBJC_EXCEPTIONS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = (
- ../LibOVR/Src,
- ../LibOVR/Include,
- CommonSrc,
- );
- LIBRARY_SEARCH_PATHS = "../LibOVR/Lib/MacOS/$(CONFIGURATION)";
- MACOSX_DEPLOYMENT_TARGET = 10.6;
- ONLY_ACTIVE_ARCH = NO;
- SDKROOT = macosx;
- SUPPORTED_PLATFORMS = macosx;
- };
- name = Release;
- };
- 49A5336F16E544BE0039CB59 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
- COMBINE_HIDPI_IMAGES = YES;
- EXECUTABLE_PREFIX = lib;
- GCC_ENABLE_CPP_EXCEPTIONS = NO;
- GCC_ENABLE_CPP_RTTI = NO;
- GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
- LIBRARY_SEARCH_PATHS = (
- "../LIbOVR/MacOS/$(CONFIGURATION)",
- "\"$(SRCROOT)/../LibOVR/Lib/MacOS/Debug\"",
- "\"$(SRCROOT)/../LibOVR/Lib/MacOS/LibOVR_With_Samples.build/Debug/ovr.build/Objects-normal/i386\"",
- "\"$(SRCROOT)/../LibOVR/Lib/MacOS/LibOVR_With_Samples.build/Debug/ovr.build/Objects-normal/x86_64\"",
- "\"$(SRCROOT)/../LibOVR/Lib/MacOS/LibOVR_With_Samples.build/Release/ovr.build/Objects-normal/i386\"",
- "\"$(SRCROOT)/../LibOVR/Lib/MacOS/LibOVR_With_Samples.build/Release/ovr.build/Objects-normal/x86_64\"",
- "\"$(SRCROOT)/../LibOVR/Lib/MacOS/Release\"",
- "\"$(SRCROOT)/../LibOVR/Lib/Win32\"",
- "\"$(SRCROOT)/../LibOVR/Lib/x64\"",
- );
- PRODUCT_NAME = "$(TARGET_NAME)";
- SYMROOT = ../LibOVR/Lib/MacOS;
- };
- name = Debug;
- };
- 49A5337016E544BE0039CB59 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
- COMBINE_HIDPI_IMAGES = YES;
- EXECUTABLE_PREFIX = lib;
- GCC_ENABLE_CPP_EXCEPTIONS = NO;
- GCC_ENABLE_CPP_RTTI = NO;
- LIBRARY_SEARCH_PATHS = (
- "../LIbOVR/MacOS/$(CONFIGURATION)",
- "\"$(SRCROOT)/../LibOVR/Lib/MacOS/Debug\"",
- "\"$(SRCROOT)/../LibOVR/Lib/MacOS/LibOVR_With_Samples.build/Debug/ovr.build/Objects-normal/i386\"",
- "\"$(SRCROOT)/../LibOVR/Lib/MacOS/LibOVR_With_Samples.build/Debug/ovr.build/Objects-normal/x86_64\"",
- "\"$(SRCROOT)/../LibOVR/Lib/MacOS/LibOVR_With_Samples.build/Release/ovr.build/Objects-normal/i386\"",
- "\"$(SRCROOT)/../LibOVR/Lib/MacOS/LibOVR_With_Samples.build/Release/ovr.build/Objects-normal/x86_64\"",
- "\"$(SRCROOT)/../LibOVR/Lib/MacOS/Release\"",
- "\"$(SRCROOT)/../LibOVR/Lib/Win32\"",
- "\"$(SRCROOT)/../LibOVR/Lib/x64\"",
- );
- PRODUCT_NAME = "$(TARGET_NAME)";
- SYMROOT = ../LibOVR/Lib/MacOS;
- };
- name = Release;
- };
- 49DB660A1726F0C30097A8DD /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LIBRARY = "libstdc++";
- COMBINE_HIDPI_IMAGES = YES;
- CONFIGURATION_BUILD_DIR = Samples/SensorBoxTest/MacOS/Debug;
- GCC_PRECOMPILE_PREFIX_HEADER = NO;
- GCC_PREFIX_HEADER = "";
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- INFOPLIST_FILE = "LibOVR_With_Samples.xcodeproj/SensorBoxTest-Info.plist";
- MACOSX_DEPLOYMENT_TARGET = 10.6;
- ONLY_ACTIVE_ARCH = NO;
- PRODUCT_NAME = "$(TARGET_NAME)";
- WRAPPER_EXTENSION = app;
- };
- name = Debug;
- };
- 49DB660B1726F0C30097A8DD /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CLANG_CXX_LIBRARY = "libstdc++";
- COMBINE_HIDPI_IMAGES = YES;
- CONFIGURATION_BUILD_DIR = Samples/SensorBoxTest/MacOS/Release;
- GCC_PRECOMPILE_PREFIX_HEADER = NO;
- GCC_PREFIX_HEADER = "";
- INFOPLIST_FILE = "LibOVR_With_Samples.xcodeproj/SensorBoxTest-Info.plist";
- MACOSX_DEPLOYMENT_TARGET = 10.6;
- ONLY_ACTIVE_ARCH = NO;
- PRODUCT_NAME = "$(TARGET_NAME)";
- WRAPPER_EXTENSION = app;
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 37973B4E1739D7930093BBB8 /* Build configuration list for PBXNativeTarget "OculusRoomTiny" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 37973B4C1739D78C0093BBB8 /* Debug */,
- 37973B4D1739D78C0093BBB8 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 4985387116ECFE92008D0727 /* Build configuration list for PBXNativeTarget "OculusWorldDemo" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 4985387216ECFE92008D0727 /* Debug */,
- 4985387316ECFE92008D0727 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 49A5332E16E527490039CB59 /* Build configuration list for PBXProject "LibOVR_With_Samples" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 49A5333A16E527490039CB59 /* Debug */,
- 49A5333B16E527490039CB59 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 49A5336E16E544BE0039CB59 /* Build configuration list for PBXNativeTarget "ovr" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 49A5336F16E544BE0039CB59 /* Debug */,
- 49A5337016E544BE0039CB59 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 49DB660C1726F0C30097A8DD /* Build configuration list for PBXNativeTarget "SensorBoxTest" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 49DB660A1726F0C30097A8DD /* Debug */,
- 49DB660B1726F0C30097A8DD /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 49A5332B16E527490039CB59 /* Project object */;
-}
diff --git a/Samples/LibOVR_With_Samples.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Samples/LibOVR_With_Samples.xcodeproj/project.xcworkspace/contents.xcworkspacedata
deleted file mode 100644
index 1a80571..0000000
--- a/Samples/LibOVR_With_Samples.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Workspace
- version = "1.0">
- <FileRef
- location = "self:LibOVR_With_Samples.xcodeproj">
- </FileRef>
-</Workspace>
diff --git a/Samples/LibOVR_With_Samples.xcodeproj/project.xcworkspace/xcuserdata/Nate.xcuserdatad/UserInterfaceState.xcuserstate b/Samples/LibOVR_With_Samples.xcodeproj/project.xcworkspace/xcuserdata/Nate.xcuserdatad/UserInterfaceState.xcuserstate
deleted file mode 100644
index be3c4ab..0000000
--- a/Samples/LibOVR_With_Samples.xcodeproj/project.xcworkspace/xcuserdata/Nate.xcuserdatad/UserInterfaceState.xcuserstate
+++ /dev/null
Binary files differ
diff --git a/Samples/LibOVR_With_Samples.xcodeproj/project.xcworkspace/xcuserdata/Nate.xcuserdatad/WorkspaceSettings.xcsettings b/Samples/LibOVR_With_Samples.xcodeproj/project.xcworkspace/xcuserdata/Nate.xcuserdatad/WorkspaceSettings.xcsettings
deleted file mode 100644
index 5202989..0000000
--- a/Samples/LibOVR_With_Samples.xcodeproj/project.xcworkspace/xcuserdata/Nate.xcuserdatad/WorkspaceSettings.xcsettings
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>BuildLocationStyle</key>
- <string>UseTargetSettings</string>
- <key>CustomBuildLocationType</key>
- <string>RelativeToDerivedData</string>
- <key>DerivedDataLocationStyle</key>
- <string>Default</string>
- <key>IssueFilterStyle</key>
- <string>ShowActiveSchemeOnly</string>
- <key>LiveSourceIssuesEnabled</key>
- <true/>
- <key>SnapshotAutomaticallyBeforeSignificantChanges</key>
- <true/>
- <key>SnapshotLocationStyle</key>
- <string>Default</string>
-</dict>
-</plist>
diff --git a/Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/OculusRoomTiny.xcscheme b/Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/OculusRoomTiny.xcscheme
deleted file mode 100644
index ca15d67..0000000
--- a/Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/OculusRoomTiny.xcscheme
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Scheme
- LastUpgradeVersion = "0460"
- version = "1.3">
- <BuildAction
- parallelizeBuildables = "YES"
- buildImplicitDependencies = "YES">
- <BuildActionEntries>
- <BuildActionEntry
- buildForTesting = "YES"
- buildForRunning = "YES"
- buildForProfiling = "YES"
- buildForArchiving = "YES"
- buildForAnalyzing = "YES">
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "37973B371739D78B0093BBB8"
- BuildableName = "OculusRoomTiny.app"
- BlueprintName = "OculusRoomTiny"
- ReferencedContainer = "container:LibOVR_With_Samples.xcodeproj">
- </BuildableReference>
- </BuildActionEntry>
- </BuildActionEntries>
- </BuildAction>
- <TestAction
- selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
- selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- shouldUseLaunchSchemeArgsEnv = "YES"
- buildConfiguration = "Debug">
- <Testables>
- </Testables>
- <MacroExpansion>
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "37973B371739D78B0093BBB8"
- BuildableName = "OculusRoomTiny.app"
- BlueprintName = "OculusRoomTiny"
- ReferencedContainer = "container:LibOVR_With_Samples.xcodeproj">
- </BuildableReference>
- </MacroExpansion>
- </TestAction>
- <LaunchAction
- selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
- selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- launchStyle = "0"
- useCustomWorkingDirectory = "NO"
- buildConfiguration = "Debug"
- ignoresPersistentStateOnLaunch = "NO"
- debugDocumentVersioning = "YES"
- allowLocationSimulation = "YES">
- <BuildableProductRunnable>
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "37973B371739D78B0093BBB8"
- BuildableName = "OculusRoomTiny.app"
- BlueprintName = "OculusRoomTiny"
- ReferencedContainer = "container:LibOVR_With_Samples.xcodeproj">
- </BuildableReference>
- </BuildableProductRunnable>
- <AdditionalOptions>
- </AdditionalOptions>
- </LaunchAction>
- <ProfileAction
- shouldUseLaunchSchemeArgsEnv = "YES"
- savedToolIdentifier = ""
- useCustomWorkingDirectory = "NO"
- buildConfiguration = "Release"
- debugDocumentVersioning = "YES">
- <BuildableProductRunnable>
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "37973B371739D78B0093BBB8"
- BuildableName = "OculusRoomTiny.app"
- BlueprintName = "OculusRoomTiny"
- ReferencedContainer = "container:LibOVR_With_Samples.xcodeproj">
- </BuildableReference>
- </BuildableProductRunnable>
- </ProfileAction>
- <AnalyzeAction
- buildConfiguration = "Debug">
- </AnalyzeAction>
- <ArchiveAction
- buildConfiguration = "Release"
- revealArchiveInOrganizer = "YES">
- </ArchiveAction>
-</Scheme>
diff --git a/Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/OculusWorldDemo.xcscheme b/Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/OculusWorldDemo.xcscheme
deleted file mode 100644
index df712e0..0000000
--- a/Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/OculusWorldDemo.xcscheme
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Scheme
- LastUpgradeVersion = "0460"
- version = "1.3">
- <BuildAction
- parallelizeBuildables = "YES"
- buildImplicitDependencies = "YES">
- <BuildActionEntries>
- <BuildActionEntry
- buildForTesting = "YES"
- buildForRunning = "YES"
- buildForProfiling = "YES"
- buildForArchiving = "YES"
- buildForAnalyzing = "YES">
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "4985385C16ECFE92008D0727"
- BuildableName = "OculusWorldDemo.app"
- BlueprintName = "OculusWorldDemo"
- ReferencedContainer = "container:LibOVR_With_Samples.xcodeproj">
- </BuildableReference>
- </BuildActionEntry>
- </BuildActionEntries>
- </BuildAction>
- <TestAction
- selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
- selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- shouldUseLaunchSchemeArgsEnv = "YES"
- buildConfiguration = "Debug">
- <Testables>
- </Testables>
- <MacroExpansion>
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "4985385C16ECFE92008D0727"
- BuildableName = "OculusWorldDemo.app"
- BlueprintName = "OculusWorldDemo"
- ReferencedContainer = "container:LibOVR_With_Samples.xcodeproj">
- </BuildableReference>
- </MacroExpansion>
- </TestAction>
- <LaunchAction
- selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
- selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- launchStyle = "0"
- useCustomWorkingDirectory = "NO"
- buildConfiguration = "Debug"
- ignoresPersistentStateOnLaunch = "NO"
- debugDocumentVersioning = "YES"
- allowLocationSimulation = "YES">
- <BuildableProductRunnable>
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "4985385C16ECFE92008D0727"
- BuildableName = "OculusWorldDemo.app"
- BlueprintName = "OculusWorldDemo"
- ReferencedContainer = "container:LibOVR_With_Samples.xcodeproj">
- </BuildableReference>
- </BuildableProductRunnable>
- <AdditionalOptions>
- </AdditionalOptions>
- </LaunchAction>
- <ProfileAction
- shouldUseLaunchSchemeArgsEnv = "YES"
- savedToolIdentifier = ""
- useCustomWorkingDirectory = "NO"
- buildConfiguration = "Release"
- debugDocumentVersioning = "YES">
- <BuildableProductRunnable>
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "4985385C16ECFE92008D0727"
- BuildableName = "OculusWorldDemo.app"
- BlueprintName = "OculusWorldDemo"
- ReferencedContainer = "container:LibOVR_With_Samples.xcodeproj">
- </BuildableReference>
- </BuildableProductRunnable>
- </ProfileAction>
- <AnalyzeAction
- buildConfiguration = "Debug">
- </AnalyzeAction>
- <ArchiveAction
- buildConfiguration = "Release"
- revealArchiveInOrganizer = "YES">
- </ArchiveAction>
-</Scheme>
diff --git a/Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/SensorBoxTest.xcscheme b/Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/SensorBoxTest.xcscheme
deleted file mode 100644
index 355208d..0000000
--- a/Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/SensorBoxTest.xcscheme
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Scheme
- LastUpgradeVersion = "0460"
- version = "1.3">
- <BuildAction
- parallelizeBuildables = "YES"
- buildImplicitDependencies = "YES">
- <BuildActionEntries>
- <BuildActionEntry
- buildForTesting = "YES"
- buildForRunning = "YES"
- buildForProfiling = "YES"
- buildForArchiving = "YES"
- buildForAnalyzing = "YES">
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "49DB65F51726F0C30097A8DD"
- BuildableName = "SensorBoxTest.app"
- BlueprintName = "SensorBoxTest"
- ReferencedContainer = "container:LibOVR_With_Samples.xcodeproj">
- </BuildableReference>
- </BuildActionEntry>
- </BuildActionEntries>
- </BuildAction>
- <TestAction
- selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
- selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- shouldUseLaunchSchemeArgsEnv = "YES"
- buildConfiguration = "Debug">
- <Testables>
- </Testables>
- <MacroExpansion>
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "49DB65F51726F0C30097A8DD"
- BuildableName = "SensorBoxTest.app"
- BlueprintName = "SensorBoxTest"
- ReferencedContainer = "container:LibOVR_With_Samples.xcodeproj">
- </BuildableReference>
- </MacroExpansion>
- </TestAction>
- <LaunchAction
- selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
- selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- launchStyle = "0"
- useCustomWorkingDirectory = "NO"
- buildConfiguration = "Debug"
- ignoresPersistentStateOnLaunch = "NO"
- debugDocumentVersioning = "YES"
- allowLocationSimulation = "YES">
- <BuildableProductRunnable>
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "49DB65F51726F0C30097A8DD"
- BuildableName = "SensorBoxTest.app"
- BlueprintName = "SensorBoxTest"
- ReferencedContainer = "container:LibOVR_With_Samples.xcodeproj">
- </BuildableReference>
- </BuildableProductRunnable>
- <AdditionalOptions>
- </AdditionalOptions>
- </LaunchAction>
- <ProfileAction
- shouldUseLaunchSchemeArgsEnv = "YES"
- savedToolIdentifier = ""
- useCustomWorkingDirectory = "NO"
- buildConfiguration = "Release"
- debugDocumentVersioning = "YES">
- <BuildableProductRunnable>
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "49DB65F51726F0C30097A8DD"
- BuildableName = "SensorBoxTest.app"
- BlueprintName = "SensorBoxTest"
- ReferencedContainer = "container:LibOVR_With_Samples.xcodeproj">
- </BuildableReference>
- </BuildableProductRunnable>
- </ProfileAction>
- <AnalyzeAction
- buildConfiguration = "Debug">
- </AnalyzeAction>
- <ArchiveAction
- buildConfiguration = "Release"
- revealArchiveInOrganizer = "YES">
- </ArchiveAction>
-</Scheme>
diff --git a/Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/ovr.xcscheme b/Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/ovr.xcscheme
deleted file mode 100644
index d032bda..0000000
--- a/Samples/LibOVR_With_Samples.xcodeproj/xcshareddata/xcschemes/ovr.xcscheme
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Scheme
- LastUpgradeVersion = "0460"
- version = "1.3">
- <BuildAction
- parallelizeBuildables = "YES"
- buildImplicitDependencies = "YES">
- <BuildActionEntries>
- <BuildActionEntry
- buildForTesting = "YES"
- buildForRunning = "YES"
- buildForProfiling = "YES"
- buildForArchiving = "YES"
- buildForAnalyzing = "YES">
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "49A5336C16E544BE0039CB59"
- BuildableName = "libovr.a"
- BlueprintName = "ovr"
- ReferencedContainer = "container:LibOVR_With_Samples.xcodeproj">
- </BuildableReference>
- </BuildActionEntry>
- </BuildActionEntries>
- </BuildAction>
- <TestAction
- selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
- selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- shouldUseLaunchSchemeArgsEnv = "YES"
- buildConfiguration = "Debug">
- <Testables>
- </Testables>
- </TestAction>
- <LaunchAction
- selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
- selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- launchStyle = "0"
- useCustomWorkingDirectory = "NO"
- buildConfiguration = "Debug"
- ignoresPersistentStateOnLaunch = "NO"
- debugDocumentVersioning = "YES"
- allowLocationSimulation = "YES">
- <AdditionalOptions>
- </AdditionalOptions>
- </LaunchAction>
- <ProfileAction
- shouldUseLaunchSchemeArgsEnv = "YES"
- savedToolIdentifier = ""
- useCustomWorkingDirectory = "NO"
- buildConfiguration = "Release"
- debugDocumentVersioning = "YES">
- </ProfileAction>
- <AnalyzeAction
- buildConfiguration = "Debug">
- </AnalyzeAction>
- <ArchiveAction
- buildConfiguration = "Release"
- revealArchiveInOrganizer = "YES">
- </ArchiveAction>
-</Scheme>
diff --git a/Samples/LibOVR_With_Samples.xcodeproj/xcuserdata/Nate.xcuserdatad/xcschemes/xcschememanagement.plist b/Samples/LibOVR_With_Samples.xcodeproj/xcuserdata/Nate.xcuserdatad/xcschemes/xcschememanagement.plist
deleted file mode 100644
index 58dbb85..0000000
--- a/Samples/LibOVR_With_Samples.xcodeproj/xcuserdata/Nate.xcuserdatad/xcschemes/xcschememanagement.plist
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>SuppressBuildableAutocreation</key>
- <dict>
- <key>37973B371739D78B0093BBB8</key>
- <dict>
- <key>primary</key>
- <true/>
- </dict>
- <key>4985385C16ECFE92008D0727</key>
- <dict>
- <key>primary</key>
- <true/>
- </dict>
- <key>49A5336C16E544BE0039CB59</key>
- <dict>
- <key>primary</key>
- <true/>
- </dict>
- <key>49DB65F51726F0C30097A8DD</key>
- <dict>
- <key>primary</key>
- <true/>
- </dict>
- </dict>
-</dict>
-</plist>
diff --git a/Samples/LibOVR_With_Samples_Msvc2010.sln b/Samples/LibOVR_With_Samples_Msvc2010.sln
deleted file mode 100644
index a874b38..0000000
--- a/Samples/LibOVR_With_Samples_Msvc2010.sln
+++ /dev/null
@@ -1,67 +0,0 @@
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibOVR", "..\LibOVR\Projects\Win32\LibOVR_Msvc2010.vcxproj", "{934B40C7-F40A-4E4C-97A7-B9659BE0A441}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusWorldDemo", "OculusWorldDemo\OculusWorldDemo_Msvc2010.vcxproj", "{8051B877-2992-4F64-8C3B-FAF88B6D83AA}"
- ProjectSection(ProjectDependencies) = postProject
- {934B40C7-F40A-4E4C-97A7-B9659BE0A441} = {934B40C7-F40A-4E4C-97A7-B9659BE0A441}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SensorBoxTest", "SensorBox\SensorBoxTest_Msvc2010.vcxproj", "{8051B837-2982-4F64-8C3B-FAF88B6D83AB}"
- ProjectSection(ProjectDependencies) = postProject
- {934B40C7-F40A-4E4C-97A7-B9659BE0A441} = {934B40C7-F40A-4E4C-97A7-B9659BE0A441}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusRoomTiny", "OculusRoomTiny\OculusRoomTiny_Msvc2010.vcxproj", "{80523489-2881-4F64-8C3B-FAF88B60ABCD}"
- ProjectSection(ProjectDependencies) = postProject
- {934B40C7-F40A-4E4C-97A7-B9659BE0A441} = {934B40C7-F40A-4E4C-97A7-B9659BE0A441}
- EndProjectSection
-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
- {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
- {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
- {8051B837-2982-4F64-8C3B-FAF88B6D83AB}.Debug|Win32.ActiveCfg = Debug|Win32
- {8051B837-2982-4F64-8C3B-FAF88B6D83AB}.Debug|Win32.Build.0 = Debug|Win32
- {8051B837-2982-4F64-8C3B-FAF88B6D83AB}.Debug|x64.ActiveCfg = Debug|Win32
- {8051B837-2982-4F64-8C3B-FAF88B6D83AB}.Release|Win32.ActiveCfg = Release|Win32
- {8051B837-2982-4F64-8C3B-FAF88B6D83AB}.Release|Win32.Build.0 = Release|Win32
- {8051B837-2982-4F64-8C3B-FAF88B6D83AB}.Release|x64.ActiveCfg = Release|Win32
- {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
- {9ABD1D70-F80B-466F-B097-821EBAA00ED6}.Debug|Win32.ActiveCfg = Debug|Win32
- {9ABD1D70-F80B-466F-B097-821EBAA00ED6}.Debug|Win32.Build.0 = Debug|Win32
- {9ABD1D70-F80B-466F-B097-821EBAA00ED6}.Debug|x64.ActiveCfg = Debug|Win32
- {9ABD1D70-F80B-466F-B097-821EBAA00ED6}.Release|Win32.ActiveCfg = Release|Win32
- {9ABD1D70-F80B-466F-B097-821EBAA00ED6}.Release|Win32.Build.0 = Release|Win32
- {9ABD1D70-F80B-466F-B097-821EBAA00ED6}.Release|x64.ActiveCfg = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/Samples/LibOVR_With_Samples_VS2010.sln b/Samples/LibOVR_With_Samples_VS2010.sln
new file mode 100644
index 0000000..36888ff
--- /dev/null
+++ b/Samples/LibOVR_With_Samples_VS2010.sln
@@ -0,0 +1,51 @@
+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}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusRoomTiny", "OculusRoomTiny\Projects\Win\VS2010\OculusRoomTiny.vcxproj", "{6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}"
+ ProjectSection(ProjectDependencies) = postProject
+ {720F6C5E-6DCF-495A-B25E-10540EA081A2} = {720F6C5E-6DCF-495A-B25E-10540EA081A2}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusWorldDemo", "OculusWorldDemo\Projects\Win\VS2010\OculusWorldDemo.vcxproj", "{456DA1F5-7D65-4B77-8336-277F3921639B}"
+ ProjectSection(ProjectDependencies) = postProject
+ {720F6C5E-6DCF-495A-B25E-10540EA081A2} = {720F6C5E-6DCF-495A-B25E-10540EA081A2}
+ EndProjectSection
+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
+ {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
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Samples/LibOVR_With_Samples_VS2012.sln b/Samples/LibOVR_With_Samples_VS2012.sln
new file mode 100644
index 0000000..cc3b3a7
--- /dev/null
+++ b/Samples/LibOVR_With_Samples_VS2012.sln
@@ -0,0 +1,63 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibOVR", "..\LibOVR\Projects\Win32\VS2012\LibOVR.vcxproj", "{CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusWorldDemo", "OculusWorldDemo\Projects\Win\VS2012\OculusWorldDemo.vcxproj", "{4F8C2B89-7CF1-4763-8EEF-E969FB760E32}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C} = {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusRoomTiny", "OculusRoomTiny\Projects\Win\VS2012\OculusRoomTiny.vcxproj", "{5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}"
+ ProjectSection(ProjectDependencies) = postProject
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C} = {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}
+ EndProjectSection
+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
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}.Debug|Win32.Build.0 = Debug|Win32
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}.Debug|Win32.Deploy.0 = Debug|Win32
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}.Debug|x64.ActiveCfg = Debug|x64
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}.Debug|x64.Build.0 = Debug|x64
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}.Debug|x64.Deploy.0 = Debug|x64
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}.Release|Win32.ActiveCfg = Release|Win32
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}.Release|Win32.Build.0 = Release|Win32
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}.Release|Win32.Deploy.0 = Release|Win32
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}.Release|x64.ActiveCfg = Release|x64
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}.Release|x64.Build.0 = Release|x64
+ {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C}.Release|x64.Deploy.0 = Release|x64
+ {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_With_Samples_VS2013.sln b/Samples/LibOVR_With_Samples_VS2013.sln
new file mode 100644
index 0000000..975fa48
--- /dev/null
+++ b/Samples/LibOVR_With_Samples_VS2013.sln
@@ -0,0 +1,53 @@
+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}") = "LibOVR", "..\LibOVR\Projects\Win32\VS2013\LibOVR.vcxproj", "{EA50E705-5113-49E5-B105-2512EDC8DDC6}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusRoomTiny", "OculusRoomTiny\Projects\Win\VS2013\OculusRoomTiny.vcxproj", "{394FF596-A90B-4C95-888B-B743834ED15B}"
+ ProjectSection(ProjectDependencies) = postProject
+ {EA50E705-5113-49E5-B105-2512EDC8DDC6} = {EA50E705-5113-49E5-B105-2512EDC8DDC6}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OculusWorldDemo", "OculusWorldDemo\Projects\Win\VS2013\OculusWorldDemo.vcxproj", "{CA4E4127-1BAD-447C-BFF9-5AF940EEC376}"
+ ProjectSection(ProjectDependencies) = postProject
+ {EA50E705-5113-49E5-B105-2512EDC8DDC6} = {EA50E705-5113-49E5-B105-2512EDC8DDC6}
+ EndProjectSection
+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
+ {EA50E705-5113-49E5-B105-2512EDC8DDC6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {EA50E705-5113-49E5-B105-2512EDC8DDC6}.Debug|Win32.Build.0 = Debug|Win32
+ {EA50E705-5113-49E5-B105-2512EDC8DDC6}.Debug|x64.ActiveCfg = Debug|x64
+ {EA50E705-5113-49E5-B105-2512EDC8DDC6}.Debug|x64.Build.0 = Debug|x64
+ {EA50E705-5113-49E5-B105-2512EDC8DDC6}.Release|Win32.ActiveCfg = Release|Win32
+ {EA50E705-5113-49E5-B105-2512EDC8DDC6}.Release|Win32.Build.0 = Release|Win32
+ {EA50E705-5113-49E5-B105-2512EDC8DDC6}.Release|x64.ActiveCfg = Release|x64
+ {EA50E705-5113-49E5-B105-2512EDC8DDC6}.Release|x64.Build.0 = Release|x64
+ {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/OculusRoomTiny/OSX_OculusRoomTiny.mm b/Samples/OculusRoomTiny/OSX_OculusRoomTiny.mm
deleted file mode 100644
index 7c5d81f..0000000
--- a/Samples/OculusRoomTiny/OSX_OculusRoomTiny.mm
+++ /dev/null
@@ -1,861 +0,0 @@
-/************************************************************************************
-
- Filename : OSX_OculusRoomTiny.mm
- Content : Simplest possible first-person view test application for Oculus Rift
- Created : May 7, 2013
- Authors : Michael Antonov, Andrew Reisse, Artem Bolgar
-
- Copyright : Copyright 2013 Oculus, Inc. All Rights reserved.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- *************************************************************************************/
-
-#import "OSX_OculusRoomTiny.h"
-#include "RenderTiny_GL_Device.h"
-
-#include "Kernel/OVR_KeyCodes.h"
-
-using namespace OVR;
-
-//-------------------------------------------------------------------------------------
-// ***** OculusRoomTiny Class
-
-// Static pApp simplifies routing the window function.
-OculusRoomTinyApp* OculusRoomTinyApp::pApp = 0;
-
-
-OculusRoomTinyApp::OculusRoomTinyApp(OVRApp* nsapp)
- : pRender(0),
- LastUpdate(0),
- NsApp(nsapp),
- Quit(0),
-
- // Initial location
- EyePos(0.0f, 1.6f, -5.0f),
- EyeYaw(YawInitial), EyePitch(0), EyeRoll(0),
- LastSensorYaw(0),
- SConfig(),
- PostProcess(PostProcess_Distortion),
- ShiftDown(false),
- ControlDown(false)
-{
- pApp = this;
-
- Width = 1280;
- Height = 800;
-
- StartupTicks = OVR::Timer::GetTicks();
-
- MoveForward = MoveBack = MoveLeft = MoveRight = 0;
-}
-
-OculusRoomTinyApp::~OculusRoomTinyApp()
-{
- RemoveHandlerFromDevices();
- pSensor.Clear();
- pHMD.Clear();
- destroyWindow();
- pApp = 0;
-}
-
-
-int OculusRoomTinyApp::OnStartup(const char* args)
-{
- OVR_UNUSED(args);
-
-
- // *** Oculus HMD & Sensor Initialization
-
- // Create DeviceManager and first available HMDDevice from it.
- // Sensor object is created from the HMD, to ensure that it is on the
- // correct device.
-
- pManager = *DeviceManager::Create();
-
- // We'll handle it's messages in this case.
- pManager->SetMessageHandler(this);
-
- CFOptionFlags detectionResult;
- const char* detectionMessage;
-
- do
- {
- // Release Sensor/HMD in case this is a retry.
- pSensor.Clear();
- pHMD.Clear();
- RenderParams.MonitorName.Clear();
-
- pHMD = *pManager->EnumerateDevices<HMDDevice>().CreateDevice();
- if (pHMD)
- {
- pSensor = *pHMD->GetSensor();
-
- // This will initialize HMDInfo with information about configured IPD,
- // screen size and other variables needed for correct projection.
- // We pass HMD DisplayDeviceName into the renderer to select the
- // correct monitor in full-screen mode.
- if (pHMD->GetDeviceInfo(&HMDInfo))
- {
- RenderParams.MonitorName = HMDInfo.DisplayDeviceName;
- RenderParams.DisplayId = HMDInfo.DisplayId;
- SConfig.SetHMDInfo(HMDInfo);
- }
- }
- else
- {
- // If we didn't detect an HMD, try to create the sensor directly.
- // This is useful for debugging sensor interaction; it is not needed in
- // a shipping app.
- pSensor = *pManager->EnumerateDevices<SensorDevice>().CreateDevice();
- }
-
-
- // If there was a problem detecting the Rift, display appropriate message.
- detectionResult = kCFUserNotificationAlternateResponse;
-
- if (!pHMD && !pSensor)
- detectionMessage = "Oculus Rift not detected.";
- else if (!pHMD)
- detectionMessage = "Oculus Sensor detected; HMD Display not detected.";
- else if (!pSensor)
- detectionMessage = "Oculus HMD Display detected; Sensor not detected.";
- else if (HMDInfo.DisplayDeviceName[0] == '\0')
- detectionMessage = "Oculus Sensor detected; HMD display EDID not detected.";
- else
- detectionMessage = 0;
-
- if (detectionMessage)
- {
- String messageText(detectionMessage);
- messageText += "\n\n"
- "Press 'Try Again' to run retry detection.\n"
- "Press 'Continue' to run full-screen anyway.";
-
- CFStringRef headerStrRef = CFStringCreateWithCString(NULL, "Oculus Rift Detection", kCFStringEncodingMacRoman);
- CFStringRef messageStrRef = CFStringCreateWithCString(NULL, messageText, kCFStringEncodingMacRoman);
-
- //launch the message box
- CFUserNotificationDisplayAlert(0,
- kCFUserNotificationNoteAlertLevel,
- NULL, NULL, NULL,
- headerStrRef, // header text
- messageStrRef, // message text
- CFSTR("Try again"),
- CFSTR("Continue"),
- CFSTR("Cancel"),
- &detectionResult);
-
- //Clean up the strings
- CFRelease(headerStrRef);
- CFRelease(messageStrRef);
-
- if (detectionResult == kCFUserNotificationCancelResponse ||
- detectionResult == kCFUserNotificationOtherResponse)
- return 1;
- }
-
- } while (detectionResult != kCFUserNotificationAlternateResponse);
-
-
- if (HMDInfo.HResolution > 0)
- {
- Width = HMDInfo.HResolution;
- Height = HMDInfo.VResolution;
- }
-
-
- if (!setupWindow())
- return 1;
-
- if (pSensor)
- {
- // We need to attach sensor to SensorFusion object for it to receive
- // body frame messages and update orientation. SFusion.GetOrientation()
- // is used in OnIdle() to orient the view.
- SFusion.AttachToSensor(pSensor);
- SFusion.SetDelegateMessageHandler(this);
- SFusion.SetPredictionEnabled(true);
- }
-
-
- // *** Initialize Rendering
-
- // Enable multi-sampling by default.
- RenderParams.Multisample = 4;
- RenderParams.Fullscreen = false;//true; //?
-
- // Setup Graphics.
- pRender = *OSX::RenderDevice::CreateDevice(RenderParams, (void*)View);
- if (!pRender)
- return 1;
-
-
- // *** Configure Stereo settings.
-
- SConfig.SetFullViewport(Viewport(0,0, Width, Height));
- SConfig.SetStereoMode(Stereo_LeftRight_Multipass);
-
- // Configure proper Distortion Fit.
- // For 7" screen, fit to touch left side of the view, leaving a bit of invisible
- // screen on the top (saves on rendering cost).
- // For smaller screens (5.5"), fit to the top.
- if (HMDInfo.HScreenSize > 0.0f)
- {
- if (HMDInfo.HScreenSize > 0.140f) // 7"
- SConfig.SetDistortionFitPointVP(-1.0f, 0.0f);
- else
- SConfig.SetDistortionFitPointVP(0.0f, 1.0f);
- }
-
- pRender->SetSceneRenderScale(SConfig.GetDistortionScale());
-
- SConfig.Set2DAreaFov(DegreeToRad(85.0f));
-
-
- // *** Populate Room Scene
-
- // This creates lights and models.
- PopulateRoomScene(&Scene, pRender);
-
-
- LastUpdate = GetAppTime();
- return 0;
-}
-
-void OculusRoomTinyApp::OnMessage(const Message& msg)
-{
- if (msg.Type == Message_DeviceAdded && msg.pDevice == pManager)
- {
- LogText("DeviceManager reported device added.\n");
- }
- else if (msg.Type == Message_DeviceRemoved && msg.pDevice == pManager)
- {
- LogText("DeviceManager reported device removed.\n");
- }
- else if (msg.Type == Message_DeviceAdded && msg.pDevice == pSensor)
- {
- LogText("Sensor reported device added.\n");
- }
- else if (msg.Type == Message_DeviceRemoved && msg.pDevice == pSensor)
- {
- LogText("Sensor reported device removed.\n");
- }
-}
-
-bool OculusRoomTinyApp::setupWindow()
-{
- NSRect winrect;
- winrect.origin.x = 0;
- winrect.origin.y = 1000;
- winrect.size.width = Width;
- winrect.size.height = Height;
- NSWindow* win = [[NSWindow alloc] initWithContentRect:winrect styleMask:NSTitledWindowMask|NSClosableWindowMask backing:NSBackingStoreBuffered defer:NO];
-
- OVRView* view = [[OVRView alloc] initWithFrame:winrect];
- [win setContentView:view];
- [win setAcceptsMouseMovedEvents:YES];
- [win setDelegate:view];
- [view setApp:pApp];
- Win = win;
- View = view;
-
- const char* title = "OculusRoomTiny";
- [((NSWindow*)Win) setTitle:[[NSString alloc] initWithBytes:title length:strlen(title) encoding:NSUTF8StringEncoding]];
-
- [NSCursor hide];
- [view warpMouseToCenter];
- CGAssociateMouseAndMouseCursorPosition(false);
-
- SetFullscreen(RenderParams, true);
- return true;
-}
-
-void OculusRoomTinyApp::destroyWindow()
-{
- SetFullscreen(RenderParams, false);
- [((NSWindow*)Win) close];
-}
-
-void OculusRoomTinyApp::OnMouseMove(int x, int y, int modifiers)
-{
- OVR_UNUSED(modifiers);
-
- // Mouse motion here is always relative.
- int dx = x, dy = y;
- const float maxPitch = ((3.1415f/2)*0.98f);
-
- // Apply to rotation. Subtract for right body frame rotation,
- // since yaw rotation is positive CCW when looking down on XZ plane.
- EyeYaw -= (Sensitivity * dx)/ 360.0f;
-
- if (!pSensor)
- {
- EyePitch -= (Sensitivity * dy)/ 360.0f;
-
- if (EyePitch > maxPitch)
- EyePitch = maxPitch;
- if (EyePitch < -maxPitch)
- EyePitch = -maxPitch;
- }
-}
-
-
-void OculusRoomTinyApp::OnKey(unsigned vk, bool down)
-{
- switch (vk)
- {
- case 'Q':
- if (down && ControlDown)
- Exit();;
- break;
- case Key_Escape:
- if (!down)
- Exit();
- break;
-
- // Handle player movement keys.
- // We just update movement state here, while the actual translation is done in OnIdle()
- // based on time.
- case 'W': MoveForward = down ? (MoveForward | 1) : (MoveForward & ~1); break;
- case 'S': MoveBack = down ? (MoveBack | 1) : (MoveBack & ~1); break;
- case 'A': MoveLeft = down ? (MoveLeft | 1) : (MoveLeft & ~1); break;
- case 'D': MoveRight = down ? (MoveRight | 1) : (MoveRight & ~1); break;
- case Key_Up: MoveForward = down ? (MoveForward | 2) : (MoveForward & ~2); break;
- case Key_Down: MoveBack = down ? (MoveBack | 2) : (MoveBack & ~2); break;
-
- case 'R':
- SFusion.Reset();
- break;
-
- case 'P':
- if (down)
- {
- // Toggle chromatic aberration correction on/off.
- RenderDevice::PostProcessShader shader = pRender->GetPostProcessShader();
-
- if (shader == RenderDevice::PostProcessShader_Distortion)
- {
- pRender->SetPostProcessShader(RenderDevice::PostProcessShader_DistortionAndChromAb);
- }
- else if (shader == RenderDevice::PostProcessShader_DistortionAndChromAb)
- {
- pRender->SetPostProcessShader(RenderDevice::PostProcessShader_Distortion);
- }
- else
- OVR_ASSERT(false);
- }
- break;
-
- // Switch rendering modes/distortion.
- case Key_F1:
- SConfig.SetStereoMode(Stereo_None);
- PostProcess = PostProcess_None;
- break;
- case Key_F2:
- SConfig.SetStereoMode(Stereo_LeftRight_Multipass);
- PostProcess = PostProcess_None;
- break;
- case Key_F3:
- SConfig.SetStereoMode(Stereo_LeftRight_Multipass);
- PostProcess = PostProcess_Distortion;
- break;
-
- // Stereo IPD adjustments, in meter (default IPD is 64mm).
- case '+':
- case '=':
- if (down)
- SConfig.SetIPD(SConfig.GetIPD() + 0.0005f * (ShiftDown ? 5.0f : 1.0f));
- break;
- case '-':
- case '_':
- if (down)
- SConfig.SetIPD(SConfig.GetIPD() - 0.0005f * (ShiftDown ? 5.0f : 1.0f));
- break;
-
- // Holding down Shift key accelerates adjustment velocity.
- case Key_Shift:
- ShiftDown = down;
- break;
- case Key_Meta:
- ControlDown = down;
- break;
- }
-}
-
-
-void OculusRoomTinyApp::OnIdle()
-{
- double curtime = GetAppTime();
- float dt = float(curtime - LastUpdate);
- LastUpdate = curtime;
-
-
- // Handle Sensor motion.
- // We extract Yaw, Pitch, Roll instead of directly using the orientation
- // to allow "additional" yaw manipulation with mouse/controller.
- if (pSensor)
- {
- Quatf hmdOrient = SFusion.GetOrientation();
- float yaw = 0.0f;
-
- hmdOrient.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &EyePitch, &EyeRoll);
-
- EyeYaw += (yaw - LastSensorYaw);
- LastSensorYaw = yaw;
- }
-
-
- if (!pSensor)
- {
- const float maxPitch = ((3.1415f/2)*0.98f);
- if (EyePitch > maxPitch)
- EyePitch = maxPitch;
- if (EyePitch < -maxPitch)
- EyePitch = -maxPitch;
- }
-
- // Handle keyboard movement.
- // This translates EyePos based on Yaw vector direction and keys pressed.
- // Note that Pitch and Roll do not affect movement (they only affect view).
- if (MoveForward || MoveBack || MoveLeft || MoveRight)
- {
- Vector3f localMoveVector(0,0,0);
- Matrix4f yawRotate = Matrix4f::RotationY(EyeYaw);
-
- if (MoveForward)
- localMoveVector = ForwardVector;
- else if (MoveBack)
- localMoveVector = -ForwardVector;
-
- if (MoveRight)
- localMoveVector += RightVector;
- else if (MoveLeft)
- localMoveVector -= RightVector;
-
- // Normalize vector so we don't move faster diagonally.
- localMoveVector.Normalize();
- Vector3f orientationVector = yawRotate.Transform(localMoveVector);
- orientationVector *= MoveSpeed * dt * (ShiftDown ? 3.0f : 1.0f);
-
- EyePos += orientationVector;
- }
-
- // Rotate and position View Camera, using YawPitchRoll in BodyFrame coordinates.
- //
- Matrix4f rollPitchYaw = Matrix4f::RotationY(EyeYaw) * Matrix4f::RotationX(EyePitch) *
- Matrix4f::RotationZ(EyeRoll);
- Vector3f up = rollPitchYaw.Transform(UpVector);
- Vector3f forward = rollPitchYaw.Transform(ForwardVector);
-
-
- // Minimal head modelling.
- float headBaseToEyeHeight = 0.15f; // Vertical height of eye from base of head
- float headBaseToEyeProtrusion = 0.09f; // Distance forward of eye from base of head
-
- Vector3f eyeCenterInHeadFrame(0.0f, headBaseToEyeHeight, -headBaseToEyeProtrusion);
- Vector3f shiftedEyePos = EyePos + rollPitchYaw.Transform(eyeCenterInHeadFrame);
- shiftedEyePos.y -= eyeCenterInHeadFrame.y; // Bring the head back down to original height
-
- ViewMat = Matrix4f::LookAtRH(shiftedEyePos, shiftedEyePos + forward, up);
-
- // This is what transformation would be without head modeling.
- // View = Matrix4f::LookAtRH(EyePos, EyePos + forward, up);
-
- switch(SConfig.GetStereoMode())
- {
- case Stereo_None:
- Render(SConfig.GetEyeRenderParams(StereoEye_Center));
- break;
-
- case Stereo_LeftRight_Multipass:
- Render(SConfig.GetEyeRenderParams(StereoEye_Left));
- Render(SConfig.GetEyeRenderParams(StereoEye_Right));
- break;
- }
-
- pRender->Present();
- // Force GPU to flush the scene, resulting in the lowest possible latency.
- pRender->ForceFlushGPU();
-}
-
-
-// Render the scene for one eye.
-void OculusRoomTinyApp::Render(const StereoEyeParams& stereo)
-{
- pRender->BeginScene(PostProcess);
-
- // Apply Viewport/Projection for the eye.
- pRender->ApplyStereoParams(stereo);
- pRender->Clear();
- pRender->SetDepthMode(true, true);
-
- Scene.Render(pRender, stereo.ViewAdjust * ViewMat);
-
- pRender->FinishScene();
-}
-
-void OculusRoomTinyApp::Exit()
-{
- [NsApp stop:nil];
- Quit = true;
-}
-
-bool OculusRoomTinyApp::SetFullscreen(const RenderTiny::RendererParams& rp, int fullscreen)
-{
- if (fullscreen == RenderTiny::Display_Window)
- [(OVRView*)View exitFullScreenModeWithOptions:nil];
- else
- {
- NSScreen* usescreen = [NSScreen mainScreen];
- NSArray* screens = [NSScreen screens];
- for (int i = 0; i < [screens count]; i++)
- {
- NSScreen* s = (NSScreen*)[screens objectAtIndex:i];
- CGDirectDisplayID disp = [OVRView displayFromScreen:s];
-
- if (disp == rp.DisplayId)
- usescreen = s;
- }
-
- [(OVRView*)View enterFullScreenMode:usescreen withOptions:nil];
- }
-
- if (pRender)
- pRender->SetFullscreen((RenderTiny::DisplayMode)fullscreen);
- return 1;
-}
-
-//-------------------------------------------------------------------------------------
-// ***** OS X-Specific Logic
-
-@implementation OVRApp
-
-- (void)dealloc
-{
- [super dealloc];
-}
-
-- (void)run
-{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- _running = YES;
- OculusRoomTinyApp* app;
-
- // Initializes LibOVR. This LogMask_All enables maximum logging.
- // Custom allocator can also be specified here.
- OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All));
-
- int exitCode = 0;
- do
- {
- {
- using namespace OVR;
-
- // CreateApplication must be the first call since it does OVR::System::Initialize.
- app = new OculusRoomTinyApp(self);
- // The platform attached to an app will be deleted by DestroyApplication.
-
- [self setApp:app];
-
- const char* argv[] = {"OVRApp"};
- exitCode = app->OnStartup(argv[0]);
- if (exitCode)
- break;
- }
- [self finishLaunching];
- [pool drain];
-
- while ([self isRunning])
- {
- pool = [[NSAutoreleasePool alloc] init];
- NSEvent* event = [self nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES];
- if (event)
- {
- [self sendEvent:event];
- }
- _App->OnIdle();
- [pool drain];
- }
- } while(0);
-
- delete app;
-
- // No OVR functions involving memory are allowed after this.
- OVR::System::Destroy();
-}
-
-@end
-
-static int KeyMap[][2] =
-{
- { NSDeleteFunctionKey, OVR::Key_Delete },
- { '\t', OVR::Key_Tab },
- { '\n', OVR::Key_Return },
- { NSPauseFunctionKey, OVR::Key_Pause },
- { 27, OVR::Key_Escape },
- { 127, OVR::Key_Backspace },
- { ' ', OVR::Key_Space },
- { NSPageUpFunctionKey, OVR::Key_PageUp },
- { NSPageDownFunctionKey, OVR::Key_PageDown },
- { NSNextFunctionKey, OVR::Key_PageDown },
- { NSEndFunctionKey, OVR::Key_End },
- { NSHomeFunctionKey, OVR::Key_Home },
- { NSLeftArrowFunctionKey, OVR::Key_Left },
- { NSUpArrowFunctionKey, OVR::Key_Up },
- { NSRightArrowFunctionKey, OVR::Key_Right },
- { NSDownArrowFunctionKey, OVR::Key_Down },
- { NSInsertFunctionKey, OVR::Key_Insert },
- { NSDeleteFunctionKey, OVR::Key_Delete },
- { NSHelpFunctionKey, OVR::Key_Insert },
-};
-
-
-static KeyCode MapToKeyCode(wchar_t vk)
-{
- unsigned key = Key_None;
-
- if ((vk >= 'a') && (vk <= 'z'))
- {
- key = vk - 'a' + Key_A;
- }
- else if ((vk >= ' ') && (vk <= '~'))
- {
- key = vk;
- }
- else if ((vk >= '0') && (vk <= '9'))
- {
- key = vk - '0' + Key_Num0;
- }
- else if ((vk >= NSF1FunctionKey) && (vk <= NSF15FunctionKey))
- {
- key = vk - NSF1FunctionKey + Key_F1;
- }
- else
- {
- for (unsigned i = 0; i< (sizeof(KeyMap) / sizeof(KeyMap[1])); i++)
- {
- if (vk == KeyMap[i][0])
- {
- key = KeyMap[i][1];
- break;
- }
- }
- }
-
- return (KeyCode)key;
-}
-
-@implementation OVRView
-
--(BOOL) acceptsFirstResponder
-{
- return YES;
-}
--(BOOL) acceptsFirstMouse:(NSEvent *)ev
-{
- return YES;
-}
-
-+(CGDirectDisplayID) displayFromScreen:(NSScreen *)s
-{
- NSNumber* didref = (NSNumber*)[[s deviceDescription] objectForKey:@"NSScreenNumber"];
- CGDirectDisplayID disp = (CGDirectDisplayID)[didref longValue];
- return disp;
-}
-
--(void) warpMouseToCenter
-{
- NSPoint w;
- w.x = _App->GetWidth()/2.0f;
- w.y = _App->GetHeight()/2.0f;
- w = [[self window] convertBaseToScreen:w];
- CGDirectDisplayID disp = [OVRView displayFromScreen:[[self window] screen]];
- CGPoint p = {w.x, CGDisplayPixelsHigh(disp)-w.y};
- CGDisplayMoveCursorToPoint(disp, p);
-}
-
--(void) keyDown:(NSEvent*)ev
-{
- NSString* chars = [ev charactersIgnoringModifiers];
- if ([chars length])
- {
- wchar_t ch = [chars characterAtIndex:0];
- OVR::KeyCode key = MapToKeyCode(ch);
- _App->OnKey(key, true);
- }
-}
--(void) keyUp:(NSEvent*)ev
-{
- NSString* chars = [ev charactersIgnoringModifiers];
- if ([chars length])
- {
- wchar_t ch = [chars characterAtIndex:0];
- OVR::KeyCode key = MapToKeyCode(ch);
- _App->OnKey(key, false);
-
- }
-}
-
-
--(void)flagsChanged:(NSEvent *)ev
-{
- static const OVR::KeyCode ModifierKeys[] = {OVR::Key_None, OVR::Key_Shift, OVR::Key_Control, OVR::Key_Alt, OVR::Key_Meta};
-
- unsigned long cmods = [ev modifierFlags];
- if ((cmods & 0xffff0000) != _Modifiers)
- {
- uint32_t mods = 0;
- if (cmods & NSShiftKeyMask)
- mods |= 0x01;
- if (cmods & NSControlKeyMask)
- mods |= 0x02;
- if (cmods & NSAlternateKeyMask)
- mods |= 0x04;
- if (cmods & NSCommandKeyMask)
- mods |= 0x08;
-
- for (int i = 1; i <= 4; i++)
- {
- unsigned long m = (1 << (16+i));
- if ((cmods & m) != (_Modifiers & m))
- {
- if (cmods & m)
- _App->OnKey(ModifierKeys[i], true);
- else
- _App->OnKey(ModifierKeys[i], false);
- }
- }
- _Modifiers = cmods & 0xffff0000;
- }
-}
-
--(void)ProcessMouse:(NSEvent*)ev
-{
- switch ([ev type])
- {
- case NSLeftMouseDragged:
- case NSRightMouseDragged:
- case NSOtherMouseDragged:
- case NSMouseMoved:
- {
- int dx = [ev deltaX];
- int dy = [ev deltaY];
-
- if (dx != 0 || dy != 0)
- {
- _App->OnMouseMove(dx, dy, 0);
- [self warpMouseToCenter];
- }
- }
- break;
- case NSLeftMouseDown:
- case NSRightMouseDown:
- case NSOtherMouseDown:
- break;
- }
-}
-
--(void) mouseMoved:(NSEvent*)ev
-{
- [self ProcessMouse:ev];
-}
--(void) mouseDragged:(NSEvent*)ev
-{
- [self ProcessMouse:ev];
-}
-
--(void) mouseDown:(NSEvent*)ev
-{
- [self warpMouseToCenter];
- CGAssociateMouseAndMouseCursorPosition(false);
- [NSCursor hide];
-}
-
-//-(void)
-
--(id) initWithFrame:(NSRect)frameRect
-{
- NSOpenGLPixelFormatAttribute attr[] =
- {NSOpenGLPFAWindow, NSOpenGLPFADoubleBuffer, NSOpenGLPFADepthSize, 24, nil};
-
- NSOpenGLPixelFormat *pf = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attr] autorelease];
-
- self = [super initWithFrame:frameRect pixelFormat:pf];
- GLint swap = 0;
- [[self openGLContext] setValues:&swap forParameter:NSOpenGLCPSwapInterval];
- //[self setWantsBestResolutionOpenGLSurface:YES];
- return self;
-}
-
--(BOOL)windowShouldClose:(id)sender
-{
- _App->Exit();
- return 1;
-}
-
-@end
-
-// GL OSX-specific logic
-namespace OSX {
-
- RenderDevice::RenderDevice(const RendererParams& p, void* osview, void* context)
- : GL::RenderDevice(p), Context(context)
- {
- OVRView* view = (OVRView*)osview;
- NSRect bounds = [view bounds];
- WindowWidth = bounds.size.width;
- WindowHeight= bounds.size.height;
-
- }
-
- RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* osview)
- {
- OVRView* view = (OVRView*)osview;
- NSOpenGLContext *context = [view openGLContext];
- if (!context)
- return NULL;
-
- [context makeCurrentContext];
- [[view window] makeKeyAndOrderFront:nil];
-
- return new OSX::RenderDevice(rp, osview, context);
- }
-
- void RenderDevice::Present()
- {
- NSOpenGLContext *context = (NSOpenGLContext*)Context;
- [context flushBuffer];
- }
-
- void RenderDevice::Shutdown()
- {
- Context = NULL;
- }
-
- bool RenderDevice::SetFullscreen(DisplayMode fullscreen)
- {
- Params.Fullscreen = fullscreen;
- return 1;
- }
-
-}
-
-
-int main(int argc, char *argv[])
-{
- NSApplication* nsapp = [OVRApp sharedApplication];
- [nsapp run];
- return 0;
-}
-
diff --git a/Samples/OculusRoomTiny/OSX_OculusRoomTiny.h b/Samples/OculusRoomTiny/OSX_OculusRoomTiny2.h
index 280fda5..ff5ad5e 100644
--- a/Samples/OculusRoomTiny/OSX_OculusRoomTiny.h
+++ b/Samples/OculusRoomTiny/OSX_OculusRoomTiny2.h
@@ -5,7 +5,7 @@
Created : May 7, 2013
Authors : Michael Antonov, Andrew Reisse, Artem Bolgar
- Copyright : Copyright 2013 Oculus, Inc. All Rights reserved.
+ Copyright : Copyright 2012 Oculus, Inc. All Rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/Samples/OculusRoomTiny/OculusRoomModel.cpp b/Samples/OculusRoomTiny/OculusRoomModel.cpp
index e12751a..f425be0 100644
--- a/Samples/OculusRoomTiny/OculusRoomModel.cpp
+++ b/Samples/OculusRoomTiny/OculusRoomModel.cpp
@@ -4,7 +4,7 @@ Filename : OculusRoomModel.cpp
Content : Creates a simple room scene from hard-coded geometry
Created : October 4, 2012
-Copyright : Copyright 2012-2013 Oculus, Inc. All Rights reserved.
+Copyright : Copyright 2012 Oculus, Inc. All Rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -20,11 +20,7 @@ limitations under the License.
*************************************************************************************/
-#include "RenderTiny_Device.h"
-
-using namespace OVR;
-using namespace OVR::RenderTiny;
-
+#include "RenderTiny_D3D11_Device.h"
//-------------------------------------------------------------------------------------
// ***** Room Model
diff --git a/Samples/OculusRoomTiny/OculusRoomTiny.rc b/Samples/OculusRoomTiny/OculusRoomTiny2.rc
index 49a6a5a..49a6a5a 100644
--- a/Samples/OculusRoomTiny/OculusRoomTiny.rc
+++ b/Samples/OculusRoomTiny/OculusRoomTiny2.rc
Binary files differ
diff --git a/Samples/OculusRoomTiny/OculusRoomTiny_Msvc2010.vcxproj.filters b/Samples/OculusRoomTiny/OculusRoomTiny_Msvc2010.vcxproj.filters
deleted file mode 100644
index 3c09bd5..0000000
--- a/Samples/OculusRoomTiny/OculusRoomTiny_Msvc2010.vcxproj.filters
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <ClCompile Include="OculusRoomModel.cpp" />
- <ClCompile Include="RenderTiny_D3D1X_Device.cpp" />
- <ClCompile Include="RenderTiny_Device.cpp" />
- <ClCompile Include="Win32_OculusRoomTiny.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="RenderTiny_Device.h" />
- <ClInclude Include="RenderTiny_D3D1X_Device.h" />
- <ClInclude Include="Win32_OculusRoomTiny.h" />
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="OculusRoomTiny.rc" />
- </ItemGroup>
-</Project> \ No newline at end of file
diff --git a/Samples/OculusRoomTiny/OculusRoomTiny_Msvc2010.vcxproj b/Samples/OculusRoomTiny/Projects/Win/VS2010/OculusRoomTiny.vcxproj
index 4bc37a8..d6bb3e7 100644
--- a/Samples/OculusRoomTiny/OculusRoomTiny_Msvc2010.vcxproj
+++ b/Samples/OculusRoomTiny/Projects/Win/VS2010/OculusRoomTiny.vcxproj
@@ -19,7 +19,7 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{80523489-2881-4F64-8C3B-FAF88B60ABCD}</ProjectGuid>
+ <ProjectGuid>{6C6ECAC4-DB5C-4301-8371-9C7CC8C623C2}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>OculusRoomTiny</RootNamespace>
<ProjectName>OculusRoomTiny</ProjectName>
@@ -65,23 +65,27 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
- <IntDir>$(Configuration)\Obj\</IntDir>
- <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2010/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2010/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusRoomTiny</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
- <IntDir>$(Configuration)\Obj\</IntDir>
- <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2010/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2010/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusRoomTiny</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
- <IntDir>$(Configuration)\Obj\</IntDir>
- <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2010/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2010/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusRoomTiny</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
- <IntDir>$(Configuration)\Obj\</IntDir>
- <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2010/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2010/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusRoomTiny</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@@ -90,16 +94,17 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>../../LibOVR/Include;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>libovrd.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>../../LibOVR/Lib/Win32;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovrd.lib;d3dx11.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/$(Platform)/VS2010/;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -109,16 +114,17 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>../../LibOVR/Include;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>libovr64d.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>../../LibOVR/Lib/x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <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>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2010/;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -130,7 +136,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>../../LibOVR/Include;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
@@ -140,8 +146,8 @@
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalLibraryDirectories>../../LibOVR/Lib/Win32;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- <AdditionalDependencies>libovr.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2010/;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovr.lib;dxguid.lib;dxgi.lib;d3dx11.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'">
@@ -153,7 +159,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>../../LibOVR/Include;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
@@ -163,23 +169,19 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalLibraryDirectories>../../LibOVR/Lib/x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- <AdditionalDependencies>libovr64.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2010/;$(DXSDK_DIR)/Lib/x64;../../../../../3rdParty/Point Grey Research/FlyCapture2/lib64;%(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>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="OculusRoomModel.cpp" />
- <ClCompile Include="RenderTiny_D3D1X_Device.cpp" />
- <ClCompile Include="RenderTiny_Device.cpp" />
- <ClCompile Include="Win32_OculusRoomTiny.cpp" />
+ <ClCompile Include="../../../Win32_DistortionMesh.cpp" />
+ <ClCompile Include="../../../OculusRoomModel.cpp" />
+ <ClCompile Include="../../../RenderTiny_D3D11_Device.cpp" />
+ <ClCompile Include="../../../Win32_OculusRoomTiny.cpp" />
+ <ClCompile Include="../../../Win32_OculusRoomTiny_Util.cpp" />
</ItemGroup>
<ItemGroup>
- <ClInclude Include="RenderTiny_D3D1X_Device.h" />
- <ClInclude Include="RenderTiny_Device.h" />
- <ClInclude Include="Win32_OculusRoomTiny.h" />
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="OculusRoomTiny.rc" />
+ <ClInclude Include="../../../RenderTiny_D3D11_Device.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
diff --git a/Samples/OculusRoomTiny/Projects/Win/VS2010/OculusRoomTiny.vcxproj.filters b/Samples/OculusRoomTiny/Projects/Win/VS2010/OculusRoomTiny.vcxproj.filters
new file mode 100644
index 0000000..8c02afc
--- /dev/null
+++ b/Samples/OculusRoomTiny/Projects/Win/VS2010/OculusRoomTiny.vcxproj.filters
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="../../../OculusRoomModel.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="../../../Win32_OculusRoomTiny_Util.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="../../../RenderTiny_D3D11_Device.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="../../../Win32_DistortionMesh.cpp" />
+ <ClCompile Include="../../../Win32_OculusRoomTiny.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="../../../RenderTiny_D3D11_Device.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Util">
+ <UniqueIdentifier>{0750679b-ec1e-44c8-a78b-05d9e58a3588}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Samples/OculusWorldDemo/OculusWorldDemo_Msvc2010.vcxproj b/Samples/OculusRoomTiny/Projects/Win/VS2012/OculusRoomTiny.vcxproj
index a881ab8..b547f70 100644
--- a/Samples/OculusWorldDemo/OculusWorldDemo_Msvc2010.vcxproj
+++ b/Samples/OculusRoomTiny/Projects/Win/VS2012/OculusRoomTiny.vcxproj
@@ -19,33 +19,37 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
- <ProjectGuid>{8051B877-2992-4F64-8C3B-FAF88B6D83AA}</ProjectGuid>
+ <ProjectGuid>{5736727A-FEB0-49C0-B63A-36BF0FEB4FF3}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
- <RootNamespace>OculusWorldDemo</RootNamespace>
- <ProjectName>OculusWorldDemo</ProjectName>
+ <RootNamespace>OculusRoomTiny</RootNamespace>
+ <ProjectName>OculusRoomTiny</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -65,23 +69,27 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
- <IntDir>$(Configuration)\Obj\</IntDir>
- <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2012/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2012/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusRookTiny</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
- <IntDir>$(Configuration)\Obj\</IntDir>
- <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2012/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2012/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusRookTiny</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
- <IntDir>$(Configuration)\Obj\</IntDir>
- <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2012/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2012/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusRookTiny</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
- <IntDir>$(Configuration)\Obj\</IntDir>
- <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2012/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2012/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusRookTiny</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@@ -90,16 +98,17 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>../../LibOVR/Include;../../3rdParty/TinyXml;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../3rdParty/glext;../../../../../LibOVR/Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>libovrd.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>../../LibOVR/Lib/Win32;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <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>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(PlatformName)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -109,16 +118,17 @@
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>../../LibOVR/Include;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../3rdParty/glext;../../../../../LibOVR/Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>libovr64d.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>../../LibOVR/Lib/x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <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>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(PlatformName)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -130,18 +140,20 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>../../LibOVR/Include;../../3rdParty/TinyXml;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../3rdParty/glext;../../../../../LibOVR/Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalLibraryDirectories>../../LibOVR/Lib/Win32;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- <AdditionalDependencies>libovr.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(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>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -153,57 +165,31 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>../../LibOVR/Include;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../3rdParty/glext;../../../../../LibOVR/Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
- <AdditionalLibraryDirectories>../../LibOVR/Lib/x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- <AdditionalDependencies>libovr64.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(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>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
- <ClCompile Include="..\CommonSrc\Platform\Platform.cpp" />
- <ClCompile Include="..\CommonSrc\Platform\Win32_Gamepad.cpp" />
- <ClCompile Include="..\CommonSrc\Platform\Win32_Platform.cpp" />
- <ClCompile Include="..\CommonSrc\Render\Render_LoadTextureDDS.cpp" />
- <ClCompile Include="..\CommonSrc\Render\Render_LoadTextureTGA.cpp" />
- <ClCompile Include="..\CommonSrc\Render\Render_Device.cpp" />
- <ClCompile Include="..\CommonSrc\Render\Render_D3D10_Device.cpp" />
- <ClCompile Include="..\CommonSrc\Render\Render_D3D11_Device.cpp" />
- <ClCompile Include="..\CommonSrc\Render\Render_D3D1X_Device.cpp">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClCompile>
- <ClCompile Include="..\..\3rdParty\TinyXml\tinyxml2.cpp" />
- <ClCompile Include="..\CommonSrc\Render\Render_XmlSceneLoader.cpp" />
- <ClCompile Include="OculusWorldDemo.cpp" />
- <ClCompile Include="Player.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\CommonSrc\Platform\Gamepad.h" />
- <ClInclude Include="..\CommonSrc\Platform\Platform.h" />
- <ClInclude Include="..\CommonSrc\Platform\Platform_Default.h" />
- <ClInclude Include="..\CommonSrc\Platform\Win32_Gamepad.h" />
- <ClInclude Include="..\CommonSrc\Platform\Win32_Platform.h" />
- <ClInclude Include="..\CommonSrc\Render\Render_Font.h" />
- <ClInclude Include="..\CommonSrc\Render\Render_Device.h" />
- <ClInclude Include="..\CommonSrc\Render\Render_D3D10_Device.h" />
- <ClInclude Include="..\CommonSrc\Render\Render_D3D11_Device.h" />
- <ClInclude Include="..\CommonSrc\Render\Render_D3D1X_Device.h" />
- <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" />
- <ClInclude Include="..\CommonSrc\Render\Render_XmlSceneLoader.h" />
- <ClInclude Include="Player.h" />
+ <ClCompile Include="../../../Win32_DistortionMesh.cpp" />
+ <ClCompile Include="../../../OculusRoomModel.cpp" />
+ <ClCompile Include="../../../RenderTiny_D3D11_Device.cpp" />
+ <ClCompile Include="../../../Win32_OculusRoomTiny.cpp" />
+ <ClCompile Include="../../../Win32_OculusRoomTiny_Util.cpp" />
</ItemGroup>
<ItemGroup>
- <ResourceCompile Include="OculusWorldDemo.rc" />
+ <ClInclude Include="../../../RenderTiny_D3D11_Device.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
diff --git a/Samples/OculusRoomTiny/Projects/Win/VS2012/OculusRoomTiny.vcxproj.filters b/Samples/OculusRoomTiny/Projects/Win/VS2012/OculusRoomTiny.vcxproj.filters
new file mode 100644
index 0000000..0847db0
--- /dev/null
+++ b/Samples/OculusRoomTiny/Projects/Win/VS2012/OculusRoomTiny.vcxproj.filters
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="../../../Win32_DistortionMesh.cpp" />
+ <ClCompile Include="../../../Win32_OculusRoomTiny.cpp" />
+ <ClCompile Include="../../../OculusRoomModel.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="../../../RenderTiny_D3D11_Device.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="../../../Win32_OculusRoomTiny_Util.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Util">
+ <UniqueIdentifier>{0750679b-ec1e-44c8-a78b-05d9e58a3588}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="../../../RenderTiny_D3D11_Device.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Samples/OculusRoomTiny/Projects/Win/VS2013/OculusRoomTiny.vcxproj b/Samples/OculusRoomTiny/Projects/Win/VS2013/OculusRoomTiny.vcxproj
new file mode 100644
index 0000000..e09a883
--- /dev/null
+++ b/Samples/OculusRoomTiny/Projects/Win/VS2013/OculusRoomTiny.vcxproj
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{394FF596-A90B-4C95-888B-B743834ED15B}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>OculusRoomTiny</RootNamespace>
+ <ProjectName>OculusRoomTiny</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2013/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2013/$(Configuration)/$(PlatformName)/</OutDir>
+ <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
+ <LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);</LibraryPath>
+ <TargetName>OculusRoomTiny</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2013/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2013/$(Configuration)/$(PlatformName)/</OutDir>
+ <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
+ <LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);</LibraryPath>
+ <TargetName>OculusRoomTiny</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2013/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2013/$(Configuration)/$(PlatformName)/</OutDir>
+ <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
+ <LibraryPath>$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);</LibraryPath>
+ <TargetName>OculusRoomTiny</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2013/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2013/$(Configuration)/$(PlatformName)/</OutDir>
+ <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
+ <LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);</LibraryPath>
+ <TargetName>OculusRoomTiny</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <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>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/Win32/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;_WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <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>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/x64/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <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>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>_WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <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>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="../../../OculusRoomModel.cpp" />
+ <ClCompile Include="..\..\..\RenderTiny_D3D11_Device.cpp" />
+ <ClCompile Include="..\..\..\Win32_DistortionMesh.cpp" />
+ <ClCompile Include="..\..\..\Win32_OculusRoomTiny.cpp" />
+ <ClCompile Include="..\..\..\Win32_OculusRoomTiny_Util.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="../../../OculusRoomTiny2.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\RenderTiny_D3D11_Device.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Samples/OculusRoomTiny/Projects/Win/VS2013/OculusRoomTiny.vcxproj.filters b/Samples/OculusRoomTiny/Projects/Win/VS2013/OculusRoomTiny.vcxproj.filters
new file mode 100644
index 0000000..6df3291
--- /dev/null
+++ b/Samples/OculusRoomTiny/Projects/Win/VS2013/OculusRoomTiny.vcxproj.filters
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="..\..\..\Win32_DistortionMesh.cpp" />
+ <ClCompile Include="..\..\..\Win32_OculusRoomTiny.cpp" />
+ <ClCompile Include="../../../OculusRoomModel.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\RenderTiny_D3D11_Device.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Win32_OculusRoomTiny_Util.cpp">
+ <Filter>Util</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="../../../OculusRoomTiny2.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Util">
+ <UniqueIdentifier>{aa2ef577-a403-4088-a39c-0a87a96151a9}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\RenderTiny_D3D11_Device.h">
+ <Filter>Util</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Samples/OculusRoomTiny/RenderTiny_D3D1X_Device.cpp b/Samples/OculusRoomTiny/RenderTiny_D3D11_Device.cpp
index a1a567a..964c81c 100644
--- a/Samples/OculusRoomTiny/RenderTiny_D3D1X_Device.cpp
+++ b/Samples/OculusRoomTiny/RenderTiny_D3D11_Device.cpp
@@ -1,6 +1,6 @@
/************************************************************************************
-Filename : RenderTiny_D3D1x.cpp
+Filename : RenderTiny_D3D11.cpp
Content : RenderDevice implementation for D3DX10/11.
Created : September 10, 2012
Authors : Andrew Reisse
@@ -21,24 +21,24 @@ limitations under the License.
************************************************************************************/
+#include "RenderTiny_D3D11_Device.h"
#include "Kernel/OVR_Log.h"
-#include "Kernel/OVR_Std.h"
+#include <d3dcompiler.h>
+
-#include "RenderTiny_D3D1X_Device.h"
-#include <d3dcompiler.h>
-namespace OVR { namespace RenderTiny { namespace D3D10 {
+namespace OVR { namespace RenderTiny {
//-------------------------------------------------------------------------------------
// Vertex format
-static D3D1x_(INPUT_ELEMENT_DESC) ModelVertexDesc[] =
+static D3D11_INPUT_ELEMENT_DESC ModelVertexDesc[] =
{
- {"Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, Pos), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
- {"Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(Vertex, C), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
- {"TexCoord", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(Vertex, U), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
- {"Normal", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, Norm), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
+ {"Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, Pos), D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(Vertex, C), D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"TexCoord", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(Vertex, U), D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"Normal", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, Norm), D3D11_INPUT_PER_VERTEX_DATA, 0},
};
// These shaders are used to render the world, including lit vertex-colored and textured geometry.
@@ -124,6 +124,7 @@ static const char* TexturePixelShaderSrc =
"}\n";
+
#define LIGHTING_COMMON \
"cbuffer Lighting : register(b1)\n" \
"{\n" \
@@ -171,122 +172,25 @@ static const char* LitTexturePixelShaderSrc =
"}\n";
-//-------------------------------------------------------------------------------------
-// ***** Distortion Post-process Shaders
-
-static const char* PostProcessVertexShaderSrc =
- "float4x4 View : register(c4);\n"
- "float4x4 Texm : register(c8);\n"
- "void main(in float4 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord : TEXCOORD0,\n"
- " out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float2 oTexCoord : TEXCOORD0)\n"
- "{\n"
- " oPosition = mul(View, Position);\n"
- " oTexCoord = mul(Texm, float4(TexCoord,0,1));\n"
- " oColor = Color;\n"
- "}\n";
-
-// Shader with just lens distortion correction.
-static const char* PostProcessPixelShaderSrc =
- "Texture2D Texture : register(t0);\n"
- "SamplerState Linear : register(s0);\n"
- "float2 LensCenter;\n"
- "float2 ScreenCenter;\n"
- "float2 Scale;\n"
- "float2 ScaleIn;\n"
- "float4 HmdWarpParam;\n"
- "\n"
-
- // Scales input texture coordinates for distortion.
- // ScaleIn maps texture coordinates to Scales to ([-1, 1]), although top/bottom will be
- // larger due to aspect ratio.
- "float2 HmdWarp(float2 in01)\n"
- "{\n"
- " float2 theta = (in01 - LensCenter) * ScaleIn;\n" // Scales to [-1, 1]
- " float rSq = theta.x * theta.x + theta.y * theta.y;\n"
- " float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
- " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
- " return LensCenter + Scale * theta1;\n"
- "}\n"
-
- "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n"
- " in float2 oTexCoord : TEXCOORD0) : SV_Target\n"
- "{\n"
- " float2 tc = HmdWarp(oTexCoord);\n"
- " if (any(clamp(tc, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tc))\n"
- " return 0;\n"
- " return Texture.Sample(Linear, tc);\n"
- "}\n";
-
-// Shader with lens distortion and chromatic aberration correction.
-static const char* PostProcessPixelShaderWithChromAbSrc =
- "Texture2D Texture : register(t0);\n"
- "SamplerState Linear : register(s0);\n"
- "float2 LensCenter;\n"
- "float2 ScreenCenter;\n"
- "float2 Scale;\n"
- "float2 ScaleIn;\n"
- "float4 HmdWarpParam;\n"
- "float4 ChromAbParam;\n"
- "\n"
-
- // Scales input texture coordinates for distortion.
- // ScaleIn maps texture coordinates to Scales to ([-1, 1]), although top/bottom will be
- // larger due to aspect ratio.
- "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n"
- " in float2 oTexCoord : TEXCOORD0) : SV_Target\n"
- "{\n"
- " float2 theta = (oTexCoord - LensCenter) * ScaleIn;\n" // Scales to [-1, 1]
- " float rSq= theta.x * theta.x + theta.y * theta.y;\n"
- " float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
- " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
- " \n"
- " // Detect whether blue texture coordinates are out of range since these will scaled out the furthest.\n"
- " float2 thetaBlue = theta1 * (ChromAbParam.z + ChromAbParam.w * rSq);\n"
- " float2 tcBlue = LensCenter + Scale * thetaBlue;\n"
- " if (any(clamp(tcBlue, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tcBlue))\n"
- " return 0;\n"
- " \n"
- " // Now do blue texture lookup.\n"
- " float blue = Texture.Sample(Linear, tcBlue).b;\n"
- " \n"
- " // Do green lookup (no scaling).\n"
- " float2 tcGreen = LensCenter + Scale * theta1;\n"
- " float green = Texture.Sample(Linear, tcGreen).g;\n"
- " \n"
- " // Do red scale and lookup.\n"
- " float2 thetaRed = theta1 * (ChromAbParam.x + ChromAbParam.y * rSq);\n"
- " float2 tcRed = LensCenter + Scale * thetaRed;\n"
- " float red = Texture.Sample(Linear, tcRed).r;\n"
- " \n"
- " return float4(red, green, blue, 1);\n"
- "}\n";
-
-
static const char* VShaderSrcs[VShader_Count] =
{
DirectVertexShaderSrc,
- StdVertexShaderSrc,
- PostProcessVertexShaderSrc
+ StdVertexShaderSrc
+
};
static const char* FShaderSrcs[FShader_Count] =
{
SolidPixelShaderSrc,
GouraudPixelShaderSrc,
TexturePixelShaderSrc,
- PostProcessPixelShaderSrc,
- PostProcessPixelShaderWithChromAbSrc,
LitSolidPixelShaderSrc,
- LitTexturePixelShaderSrc
+ LitTexturePixelShaderSrc
};
//-------------------------------------------------------------------------------------
// ***** Buffer
-Buffer::~Buffer()
-{
-}
-
bool Buffer::Data(int use, const void *buffer, size_t size)
{
if (D3DBuffer && Size >= size)
@@ -318,33 +222,33 @@ bool Buffer::Data(int use, const void *buffer, size_t size)
Dynamic = 0;
}
- D3D1x_(BUFFER_DESC) desc;
+ D3D11_BUFFER_DESC desc;
memset(&desc, 0, sizeof(desc));
if (use & Buffer_ReadOnly)
{
- desc.Usage = D3D1x_(USAGE_IMMUTABLE);
+ desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.CPUAccessFlags = 0;
}
else
{
- desc.Usage = D3D1x_(USAGE_DYNAMIC);
- desc.CPUAccessFlags = D3D1x_(CPU_ACCESS_WRITE);
+ desc.Usage = D3D11_USAGE_DYNAMIC;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
Dynamic = 1;
}
switch(use & Buffer_TypeMask)
{
- case Buffer_Vertex: desc.BindFlags = D3D1x_(BIND_VERTEX_BUFFER); break;
- case Buffer_Index: desc.BindFlags = D3D1x_(BIND_INDEX_BUFFER); break;
+ case Buffer_Vertex: desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; break;
+ case Buffer_Index: desc.BindFlags = D3D11_BIND_INDEX_BUFFER; break;
case Buffer_Uniform:
- desc.BindFlags = D3D1x_(BIND_CONSTANT_BUFFER);
+ desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
size += ((size + 15) & ~15) - size;
break;
}
desc.ByteWidth = (unsigned)size;
- D3D1x_(SUBRESOURCE_DATA) sr;
+ D3D11_SUBRESOURCE_DATA sr;
sr.pSysMem = buffer;
sr.SysMemPitch = 0;
sr.SysMemSlicePitch = 0;
@@ -361,55 +265,56 @@ bool Buffer::Data(int use, const void *buffer, size_t size)
void* Buffer::Map(size_t start, size_t size, int flags)
{
- OVR_UNUSED(size);
-
- D3D1x_(MAP) mapFlags = D3D1x_(MAP_WRITE);
- if (flags & Map_Discard)
- mapFlags = D3D1x_(MAP_WRITE_DISCARD);
- if (flags & Map_Unsynchronized)
- mapFlags = D3D1x_(MAP_WRITE_NO_OVERWRITE);
-
- void* map = 0;
- if (SUCCEEDED(D3DBuffer->Map(mapFlags, 0, &map)))
- return ((char*)map) + start;
- return NULL;
+ OVR_UNUSED(size);
+
+ D3D11_MAP mapFlags = D3D11_MAP_WRITE;
+ if (flags & Map_Discard)
+ mapFlags = D3D11_MAP_WRITE_DISCARD;
+ if (flags & Map_Unsynchronized)
+ mapFlags = D3D11_MAP_WRITE_NO_OVERWRITE;
+
+ D3D11_MAPPED_SUBRESOURCE map;
+ if (SUCCEEDED(Ren->Context->Map(D3DBuffer, 0, mapFlags, 0, &map)))
+ return ((char*)map.pData) + start;
+ else
+ return NULL;
}
bool Buffer::Unmap(void *m)
{
- OVR_UNUSED(m);
+ OVR_UNUSED(m);
- D3DBuffer->Unmap();
- return true;
+ Ren->Context->Unmap(D3DBuffer, 0);
+ return true;
}
//-------------------------------------------------------------------------------------
// Shaders
-template<> bool Shader<RenderTiny::Shader_Vertex, ID3D10VertexShader>::Load(void* shader, size_t size)
+template<> bool Shader<Shader_Vertex, ID3D11VertexShader>::Load(void* shader, size_t size)
{
- return SUCCEEDED(Ren->Device->CreateVertexShader(shader, size, &D3DShader));
+ return SUCCEEDED(Ren->Device->CreateVertexShader(shader, size, NULL, &D3DShader));
}
-template<> bool Shader<RenderTiny::Shader_Pixel, ID3D10PixelShader>::Load(void* shader, size_t size)
+template<> bool Shader<Shader_Pixel, ID3D11PixelShader>::Load(void* shader, size_t size)
{
- return SUCCEEDED(Ren->Device->CreatePixelShader(shader, size, &D3DShader));
+ return SUCCEEDED(Ren->Device->CreatePixelShader(shader, size, NULL, &D3DShader));
}
-template<> void Shader<RenderTiny::Shader_Vertex, ID3D10VertexShader>::Set(PrimitiveType) const
+template<> void Shader<Shader_Vertex, ID3D11VertexShader>::Set(PrimitiveType) const
{
- Ren->Context->VSSetShader(D3DShader);
+ Ren->Context->VSSetShader(D3DShader, NULL, 0);
}
-template<> void Shader<RenderTiny::Shader_Pixel, ID3D10PixelShader>::Set(PrimitiveType) const
+template<> void Shader<Shader_Pixel, ID3D11PixelShader>::Set(PrimitiveType) const
{
- Ren->Context->PSSetShader(D3DShader);
+ Ren->Context->PSSetShader(D3DShader, NULL, 0);
}
-template<> void Shader<RenderTiny::Shader_Vertex, ID3D1xVertexShader>::SetUniformBuffer(RenderTiny::Buffer* buffer, int i)
+template<> void Shader<Shader_Vertex, ID3D11VertexShader>::SetUniformBuffer(Buffer* buffer, int i)
{
Ren->Context->VSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef());
}
-template<> void Shader<RenderTiny::Shader_Pixel, ID3D1xPixelShader>::SetUniformBuffer(RenderTiny::Buffer* buffer, int i)
+template<> void Shader<Shader_Pixel, ID3D11PixelShader>::SetUniformBuffer(Buffer* buffer, int i)
{
Ren->Context->PSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef());
}
@@ -419,9 +324,10 @@ template<> void Shader<RenderTiny::Shader_Pixel, ID3D1xPixelShader>::SetUniformB
// ***** Shader Base
ShaderBase::ShaderBase(RenderDevice* r, ShaderStage stage)
- : RenderTiny::Shader(stage), Ren(r), UniformData(0)
+ : Stage(stage), Ren(r), UniformData(0)
{
}
+
ShaderBase::~ShaderBase()
{
if (UniformData)
@@ -441,12 +347,32 @@ bool ShaderBase::SetUniform(const char* name, int n, const float* v)
return 0;
}
+bool ShaderBase::SetUniformBool(const char* name, int n, const bool* v)
+{
+ OVR_UNUSED(n);
+
+ for(unsigned i = 0; i < UniformInfo.GetSize(); i++)
+ {
+ if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
+ {
+ memcpy(UniformData + UniformInfo[i].Offset, v, UniformInfo[i].Size);
+ return 1;
+ }
+ }
+ return 0;
+}
+
void ShaderBase::InitUniforms(ID3D10Blob* s)
{
- ID3D10ShaderReflection* ref = NULL;
- D3D10ReflectShader(s->GetBufferPointer(), s->GetBufferSize(), &ref);
- ID3D10ShaderReflectionConstantBuffer* buf = ref->GetConstantBufferByIndex(0);
- D3D10_SHADER_BUFFER_DESC bufd;
+ InitUniforms(s->GetBufferPointer(), s->GetBufferSize());
+}
+
+void ShaderBase::InitUniforms(void* s, size_t size)
+{
+ ID3D11ShaderReflection* ref = NULL;
+ D3DReflect(s, size, IID_ID3D11ShaderReflection, (void**) &ref);
+ ID3D11ShaderReflectionConstantBuffer* buf = ref->GetConstantBufferByIndex(0);
+ D3D11_SHADER_BUFFER_DESC bufd;
if (FAILED(buf->GetDesc(&bufd)))
{
UniformsSize = 0;
@@ -460,10 +386,10 @@ void ShaderBase::InitUniforms(ID3D10Blob* s)
for(unsigned i = 0; i < bufd.Variables; i++)
{
- ID3D10ShaderReflectionVariable* var = buf->GetVariableByIndex(i);
+ ID3D11ShaderReflectionVariable* var = buf->GetVariableByIndex(i);
if (var)
{
- D3D10_SHADER_VARIABLE_DESC vd;
+ D3D11_SHADER_VARIABLE_DESC vd;
if (SUCCEEDED(var->GetDesc(&vd)))
{
Uniform u;
@@ -488,6 +414,12 @@ void ShaderBase::UpdateBuffer(Buffer* buf)
}
+
+
+
+
+
+
//-------------------------------------------------------------------------------------
// ***** Texture
//
@@ -502,7 +434,7 @@ Texture::~Texture()
{
}
-void Texture::Set(int slot, RenderTiny::ShaderStage stage) const
+void Texture::Set(int slot, ShaderStage stage) const
{
Ren->SetTexture(stage, slot, this);
}
@@ -513,6 +445,155 @@ void Texture::SetSampleMode(int sm)
}
+void Model::Render(const Matrix4f& ltw, RenderDevice* ren)
+{
+ if (Visible)
+ {
+ Matrix4f m = ltw * GetMatrix();
+ ren->Render(m, this);
+ }
+}
+
+void Container::Render(const Matrix4f& ltw, RenderDevice* ren)
+{
+ Matrix4f m = ltw * GetMatrix();
+ for(unsigned i = 0; i < Nodes.GetSize(); i++)
+ {
+ Nodes[i]->Render(m, ren);
+ }
+}
+
+void Scene::Render(RenderDevice* ren, const Matrix4f& view)
+{
+ Lighting.Update(view, LightPos);
+
+ ren->SetLighting(&Lighting);
+
+ World.Render(view, ren);
+}
+
+
+
+UInt16 CubeIndices[] =
+{
+ 0, 1, 3,
+ 3, 1, 2,
+
+ 5, 4, 6,
+ 6, 4, 7,
+
+ 8, 9, 11,
+ 11, 9, 10,
+
+ 13, 12, 14,
+ 14, 12, 15,
+
+ 16, 17, 19,
+ 19, 17, 18,
+
+ 21, 20, 22,
+ 22, 20, 23
+};
+
+
+void Model::AddSolidColorBox(float x1, float y1, float z1,
+ float x2, float y2, float z2,
+ Color c)
+{
+ float t;
+
+ if(x1 > x2)
+ {
+ t = x1;
+ x1 = x2;
+ x2 = t;
+ }
+ if(y1 > y2)
+ {
+ t = y1;
+ y1 = y2;
+ y2 = t;
+ }
+ if(z1 > z2)
+ {
+ t = z1;
+ z1 = z2;
+ z2 = t;
+ }
+
+ // 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)
+ };
+
+
+ UInt16 startIndex = GetNextVertexIndex();
+
+ enum
+ {
+ CubeVertexCount = sizeof(CubeVertices) / sizeof(CubeVertices[0]),
+ CubeIndexCount = sizeof(CubeIndices) / sizeof(CubeIndices[0])
+ };
+
+ for(int v = 0; v < CubeVertexCount; v++)
+ {
+ AddVertex(Vertex(CubeVertices[v][0], c, CubeVertices[v][1].x, CubeVertices[v][1].y, CubeVertices[v][2]));
+ }
+
+ // Renumber indices
+ for(int i = 0; i < CubeIndexCount / 3; i++)
+ {
+ AddTriangle(CubeIndices[i * 3] + startIndex,
+ CubeIndices[i * 3 + 1] + startIndex,
+ CubeIndices[i * 3 + 2] + startIndex);
+ }
+}
+
+
+//-------------------------------------------------------------------------------------
+
+
+void ShaderFill::Set(PrimitiveType prim) const
+{
+ Shaders->Set(prim);
+ for(int i = 0; i < 8; i++)
+ {
+ if(Textures[i])
+ {
+ Textures[i]->Set(i);
+ }
+ }
+}
+
//-------------------------------------------------------------------------------------
// ***** Render Device
@@ -560,11 +641,11 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window)
}
int flags = 0;
+ //int flags = D3D11_CREATE_DEVICE_DEBUG;
- hr = D3D10CreateDevice(Adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D1x_(SDK_VERSION),
- &Device.GetRawRef());
- Context = Device;
- Context->AddRef();
+ hr = D3D11CreateDevice(Adapter, Adapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE,
+ NULL, flags, NULL, 0, D3D11_SDK_VERSION,
+ &Device.GetRawRef(), NULL, &Context.GetRawRef());
if (FAILED(hr))
return;
@@ -575,6 +656,28 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window)
if (Params.Fullscreen)
SwapChain->SetFullscreenState(1, FullscreenOutput);
+ initShadersAndStates();
+}
+
+
+RenderDevice::RenderDevice(const SlaveRendererParams& p)
+{
+ WindowWidth = p.RTSize.w;
+ WindowHeight = p.RTSize.h;
+ Params.Multisample = p.Multisample;
+ Window = 0;
+
+ Context = p.pDeviceContext;
+ Device = p.pDevice; // IN D3D11 this is different
+
+ BackBufferRT = p.pBackBufferRT;
+
+ initShadersAndStates();
+}
+
+// Constructor helper
+void RenderDevice::initShadersAndStates()
+{
CurRenderTarget = NULL;
for(int i = 0; i < Shader_Count; i++)
{
@@ -596,10 +699,10 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window)
SPInt bufferSize = vsData->GetBufferSize();
const void* buffer = vsData->GetBufferPointer();
- ID3D1xInputLayout** objRef = &ModelVertexIL.GetRawRef();
+ ID3D11InputLayout** objRef = &ModelVertexIL.GetRawRef();
- HRESULT validate = Device->CreateInputLayout(ModelVertexDesc, sizeof(ModelVertexDesc)/sizeof(D3D1x_(INPUT_ELEMENT_DESC)),
- buffer, bufferSize, objRef);
+ HRESULT validate = Device->CreateInputLayout(ModelVertexDesc, sizeof(ModelVertexDesc)/sizeof(D3D11_INPUT_ELEMENT_DESC),
+ buffer, bufferSize, objRef);
OVR_UNUSED(validate);
Ptr<ShaderSet> gouraudShaders = *new ShaderSet();
@@ -607,32 +710,57 @@ RenderDevice::RenderDevice(const RendererParams& p, HWND window)
gouraudShaders->SetShader(PixelShaders[FShader_Gouraud]);
DefaultFill = *new ShaderFill(gouraudShaders);
- D3D1x_(BLEND_DESC) bm;
+ D3D11_BLEND_DESC bm;
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.DestBlend = bm.DestBlendAlpha = D3D1x_(BLEND_INV_SRC_ALPHA);
- bm.RenderTargetWriteMask[0] = D3D1x_(COLOR_WRITE_ENABLE_ALL);
+ bm.RenderTarget[0].BlendEnable = true;
+ bm.RenderTarget[0].BlendOp = bm.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+ bm.RenderTarget[0].SrcBlend = bm.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
+ bm.RenderTarget[0].DestBlend = bm.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
+ bm.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
Device->CreateBlendState(&bm, &BlendState.GetRawRef());
- D3D1x_(RASTERIZER_DESC) rs;
+ D3D11_RASTERIZER_DESC rs;
memset(&rs, 0, sizeof(rs));
rs.AntialiasedLineEnable = true;
- rs.CullMode = D3D1x_(CULL_BACK);
+ rs.CullMode = D3D11_CULL_BACK;
rs.DepthClipEnable = true;
- rs.FillMode = D3D1x_(FILL_SOLID);
+ rs.FillMode = D3D11_FILL_SOLID;
Device->CreateRasterizerState(&rs, &Rasterizer.GetRawRef());
QuadVertexBuffer = *CreateBuffer();
- const RenderTiny::Vertex QuadVertices[] =
+ const Vertex QuadVertices[] =
{ Vertex(Vector3f(0, 1, 0)), Vertex(Vector3f(1, 1, 0)),
- Vertex(Vector3f(0, 0, 0)), Vertex(Vector3f(1, 0, 0)) };
+ Vertex(Vector3f(0, 0, 0)), Vertex(Vector3f(1, 0, 0)) };
QuadVertexBuffer->Data(Buffer_Vertex, QuadVertices, sizeof(QuadVertices));
SetDepthMode(0, 0);
}
+void RenderDevice::InitShaders( const char * vertex_shader, const char * pixel_shader, ShaderSet ** pShaders, ID3D11InputLayout ** pVertexIL,
+ D3D11_INPUT_ELEMENT_DESC * DistortionMeshVertexDesc, int num_elements)
+{
+ ID3D10Blob* vsData = CompileShader("vs_4_0", vertex_shader);
+
+ Ptr<VertexShader> vtxShader = *new VertexShader(this, vsData);
+
+ ID3D11InputLayout** objRef = pVertexIL;
+
+ HRESULT validate = Device->CreateInputLayout(
+ DistortionMeshVertexDesc, num_elements,
+ vsData->GetBufferPointer(), vsData->GetBufferSize(), objRef);
+ if(FAILED(validate)) OVR_ASSERT(false);
+
+ (*pShaders) = CreateShaderSet();
+ (*pShaders)->SetShader(vtxShader);
+
+ ID3D10Blob *pShader = CompileShader("ps_4_0", pixel_shader);
+ Ptr<PixelShader> ps = *new PixelShader(this, pShader);
+
+ (*pShaders)->SetShader(ps);
+}
+
+
+
RenderDevice::~RenderDevice()
{
if (SwapChain && Params.Fullscreen)
@@ -642,17 +770,32 @@ RenderDevice::~RenderDevice()
}
+
// Implement static initializer function to create this class.
-RenderTiny::RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* oswnd)
+RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* oswnd)
{
- return new RenderDevice(rp, (HWND)oswnd);
+ RenderDevice* p = new RenderDevice(rp, (HWND)oswnd);
+ if (p)
+ {
+ if (!p->Device)
+ {
+ p->Release();
+ p = 0;
+ }
+ }
+ return p;
+}
+
+RenderDevice* RenderDevice::CreateSlaveDevice(const SlaveRendererParams& srp)
+{
+ return new RenderDevice(srp);
}
// Fallback monitor enumeration in case newly plugged in monitor wasn't detected.
// Added originally for the FactoryTest app.
// New Outputs don't seem to be detected unless adapter is re-created, but that would also
-// require us to re-initialize D3D10 (recreating objects, etc). This bypasses that for "fake"
+// require us to re-initialize D3D11 (recreating objects, etc). This bypasses that for "fake"
// fullscreen modes.
BOOL CALLBACK MonitorEnumFunc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData)
{
@@ -736,7 +879,7 @@ bool RenderDevice::RecreateSwapChain()
scDesc.BufferDesc.Width = WindowWidth;
scDesc.BufferDesc.Height = WindowHeight;
scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
- scDesc.BufferDesc.RefreshRate.Numerator = 60;
+ scDesc.BufferDesc.RefreshRate.Numerator = 0;
scDesc.BufferDesc.RefreshRate.Denominator = 1;
scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scDesc.OutputWindow = Window;
@@ -759,7 +902,7 @@ bool RenderDevice::RecreateSwapChain()
BackBuffer = NULL;
BackBufferRT = NULL;
- HRESULT hr = SwapChain->GetBuffer(0, __uuidof(ID3D1xTexture2D), (void**)&BackBuffer.GetRawRef());
+ HRESULT hr = SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&BackBuffer.GetRawRef());
if (FAILED(hr))
return false;
@@ -786,8 +929,6 @@ bool RenderDevice::SetParams(const RendererParams& newParams)
UpdateMonitorOutputs();
}
- // Cause this to be recreated with the new multisample mode.
- pSceneColorTex = NULL;
return RecreateSwapChain();
}
@@ -807,14 +948,25 @@ bool RenderDevice::SetFullscreen(DisplayMode fullscreen)
return true;
}
-void RenderDevice::SetRealViewport(const Viewport& vp)
+void RenderDevice::SetViewport(const Recti& vp)
+{
+ D3DViewport.Width = (float)vp.w;
+ D3DViewport.Height = (float)vp.h;
+ D3DViewport.MinDepth = 0;
+ D3DViewport.MaxDepth = 1;
+ D3DViewport.TopLeftX = (float)vp.x;
+ D3DViewport.TopLeftY = (float)vp.y;
+ Context->RSSetViewports(1, &D3DViewport);
+}
+
+void RenderDevice::SetFullViewport()
{
- D3DViewport.Width = vp.w;
- D3DViewport.Height = vp.h;
+ D3DViewport.Width = (float)WindowWidth;
+ D3DViewport.Height = (float)WindowHeight;
D3DViewport.MinDepth = 0;
D3DViewport.MaxDepth = 1;
- D3DViewport.TopLeftX = vp.x;
- D3DViewport.TopLeftY = vp.y;
+ D3DViewport.TopLeftX = 0;
+ D3DViewport.TopLeftY = 0;
Context->RSSetViewports(1, &D3DViewport);
}
@@ -835,18 +987,18 @@ void RenderDevice::SetDepthMode(bool enable, bool write, CompareFunc func)
return;
}
- D3D1x_(DEPTH_STENCIL_DESC) dss;
+ D3D11_DEPTH_STENCIL_DESC dss;
memset(&dss, 0, sizeof(dss));
dss.DepthEnable = enable;
switch(func)
{
- case Compare_Always: dss.DepthFunc = D3D1x_(COMPARISON_ALWAYS); break;
- case Compare_Less: dss.DepthFunc = D3D1x_(COMPARISON_LESS); break;
- case Compare_Greater: dss.DepthFunc = D3D1x_(COMPARISON_GREATER); break;
+ case Compare_Always: dss.DepthFunc = D3D11_COMPARISON_ALWAYS; break;
+ case Compare_Less: dss.DepthFunc = D3D11_COMPARISON_LESS; break;
+ case Compare_Greater: dss.DepthFunc = D3D11_COMPARISON_GREATER; break;
default:
- assert(0);
+ OVR_ASSERT(0);
}
- dss.DepthWriteMask = write ? D3D1x_(DEPTH_WRITE_MASK_ALL) : D3D1x_(DEPTH_WRITE_MASK_ZERO);
+ dss.DepthWriteMask = write ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
Device->CreateDepthStencilState(&dss, &DepthStates[index].GetRawRef());
Context->OMSetDepthStencilState(DepthStates[index], 0);
CurDepthState = DepthStates[index];
@@ -879,21 +1031,21 @@ void RenderDevice::Clear(float r, float g, float b, float a, float depth)
// Needed for each eye to do its own clear, since ClearRenderTargetView doesn't honor viewport.
// Save state that is affected by clearing this way
- ID3D1xDepthStencilState* oldDepthState = CurDepthState;
+ ID3D11DepthStencilState* oldDepthState = CurDepthState;
StandardUniformData clearUniforms;
SetDepthMode(true, true, Compare_Always);
Context->IASetInputLayout(ModelVertexIL);
- Context->GSSetShader(NULL);
+ Context->GSSetShader(NULL, NULL, 0);
- ID3D1xShaderResourceView* sv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ ID3D11ShaderResourceView* sv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
if (MaxTextureSet[Shader_Fragment])
{
Context->PSSetShaderResources(0, MaxTextureSet[Shader_Fragment], sv);
}
- ID3D1xBuffer* vertexBuffer = QuadVertexBuffer->GetBuffer();
+ ID3D11Buffer* vertexBuffer = QuadVertexBuffer->GetBuffer();
UINT vertexStride = sizeof(Vertex);
UINT vertexOffset = 0;
Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
@@ -904,9 +1056,9 @@ void RenderDevice::Clear(float r, float g, float b, float a, float depth)
-1, -1, depth, 1);
UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, &clearUniforms, sizeof(clearUniforms));
- ID3D1xBuffer* vertexConstants = UniformBuffers[Shader_Vertex]->GetBuffer();
+ ID3D11Buffer* vertexConstants = UniformBuffers[Shader_Vertex]->GetBuffer();
Context->VSSetConstantBuffers(0, 1, &vertexConstants);
- Context->IASetPrimitiveTopology(D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP));
+ Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
VertexShaders[VShader_MV]->Set(Prim_TriangleStrip);
PixelShaders[FShader_Solid]->Set(Prim_TriangleStrip);
@@ -950,7 +1102,8 @@ ID3D10Blob* RenderDevice::CompileShader(const char* profile, const char* src, co
return shader;
}
-void RenderDevice::SetCommonUniformBuffer(int i, RenderTiny::Buffer* buffer)
+
+void RenderDevice::SetCommonUniformBuffer(int i, Buffer* buffer)
{
CommonUniforms[i] = (Buffer*)buffer;
@@ -958,7 +1111,7 @@ void RenderDevice::SetCommonUniformBuffer(int i, RenderTiny::Buffer* buffer)
Context->VSSetConstantBuffers(1, 1, &CommonUniforms[1]->D3DBuffer.GetRawRef());
}
-RenderTiny::Shader *RenderDevice::LoadBuiltinShader(ShaderStage stage, int shader)
+ShaderBase *RenderDevice::LoadBuiltinShader(ShaderStage stage, int shader)
{
switch(stage)
{
@@ -972,32 +1125,32 @@ RenderTiny::Shader *RenderDevice::LoadBuiltinShader(ShaderStage stage, int shade
}
-ID3D1xSamplerState* RenderDevice::GetSamplerState(int sm)
+ID3D11SamplerState* RenderDevice::GetSamplerState(int sm)
{
if (SamplerStates[sm])
return SamplerStates[sm];
- D3D1x_(SAMPLER_DESC) ss;
+ D3D11_SAMPLER_DESC ss;
memset(&ss, 0, sizeof(ss));
if (sm & Sample_Clamp)
- ss.AddressU = ss.AddressV = ss.AddressW = D3D1x_(TEXTURE_ADDRESS_CLAMP);
+ ss.AddressU = ss.AddressV = ss.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
else if (sm & Sample_ClampBorder)
- ss.AddressU = ss.AddressV = ss.AddressW = D3D1x_(TEXTURE_ADDRESS_BORDER);
+ ss.AddressU = ss.AddressV = ss.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
else
- ss.AddressU = ss.AddressV = ss.AddressW = D3D1x_(TEXTURE_ADDRESS_WRAP);
+ ss.AddressU = ss.AddressV = ss.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
if (sm & Sample_Nearest)
{
- ss.Filter = D3D1x_(FILTER_MIN_MAG_MIP_POINT);
+ ss.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
}
else if (sm & Sample_Anisotropic)
{
- ss.Filter = D3D1x_(FILTER_ANISOTROPIC);
+ ss.Filter = D3D11_FILTER_ANISOTROPIC;
ss.MaxAnisotropy = 8;
}
else
{
- ss.Filter = D3D1x_(FILTER_MIN_MAG_MIP_LINEAR);
+ ss.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
}
ss.MaxLOD = 15;
Device->CreateSamplerState(&ss, &SamplerStates[sm].GetRawRef());
@@ -1005,12 +1158,12 @@ ID3D1xSamplerState* RenderDevice::GetSamplerState(int sm)
}
-void RenderDevice::SetTexture(RenderTiny::ShaderStage stage, int slot, const Texture* t)
+void RenderDevice::SetTexture(ShaderStage stage, int slot, const Texture* t)
{
if (MaxTextureSet[stage] <= slot)
MaxTextureSet[stage] = slot + 1;
- ID3D1xShaderResourceView* sv = t ? t->TexSv : NULL;
+ ID3D11ShaderResourceView* sv = t ? t->TexSv : NULL;
switch(stage)
{
case Shader_Fragment:
@@ -1027,6 +1180,16 @@ void RenderDevice::SetTexture(RenderTiny::ShaderStage stage, int slot, const Tex
}
}
+// Placeholder texture to come in externally in slave rendering mode
+Texture* RenderDevice::CreatePlaceholderTexture(int format)
+{
+ Texture* newTex = new Texture(this, format, 0, 0);
+ newTex->Samples = 1;
+
+ return newTex;
+}
+
+
Texture* RenderDevice::CreateTexture(int format, int width, int height, const void* data, int mipcount)
{
OVR_UNUSED(mipcount);
@@ -1056,7 +1219,7 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
Texture* NewTex = new Texture(this, format, width, height);
NewTex->Samples = samples;
- D3D1x_(TEXTURE2D_DESC) dsDesc;
+ D3D11_TEXTURE2D_DESC dsDesc;
dsDesc.Width = width;
dsDesc.Height = height;
dsDesc.MipLevels = (format == (Texture_RGBA | Texture_GenMipmaps) && data) ? GetNumMipLevels(width, height) : 1;
@@ -1064,8 +1227,8 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
dsDesc.Format = d3dformat;
dsDesc.SampleDesc.Count = samples;
dsDesc.SampleDesc.Quality = 0;
- dsDesc.Usage = D3D1x_(USAGE_DEFAULT);
- dsDesc.BindFlags = D3D1x_(BIND_SHADER_RESOURCE);
+ dsDesc.Usage = D3D11_USAGE_DEFAULT;
+ dsDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
dsDesc.CPUAccessFlags = 0;
dsDesc.MiscFlags = 0;
@@ -1073,11 +1236,11 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
{
if ((format & Texture_TypeMask) == Texture_Depth)
{ // We don't use depth textures, and creating them in d3d10 requires different options.
- dsDesc.BindFlags = D3D1x_(BIND_DEPTH_STENCIL);
+ dsDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
}
else
{
- dsDesc.BindFlags |= D3D1x_(BIND_RENDER_TARGET);
+ dsDesc.BindFlags |= D3D11_BIND_RENDER_TARGET;
}
}
@@ -1088,7 +1251,7 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
NewTex->Release();
return NULL;
}
- if (dsDesc.BindFlags & D3D1x_(BIND_SHADER_RESOURCE))
+ if (dsDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE)
{
Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef());
}
@@ -1147,6 +1310,15 @@ Texture* RenderDevice::CreateTexture(int format, int width, int height, const vo
return NewTex;
}
+ShaderFill* RenderDevice::CreateTextureFill(Texture* t)
+{
+ ShaderSet* shaders = CreateShaderSet();
+ shaders->SetShader(LoadBuiltinShader(Shader_Vertex, VShader_MVP));
+ shaders->SetShader(LoadBuiltinShader(Shader_Fragment, FShader_Texture));
+ ShaderFill* f = new ShaderFill(*shaders);
+ f->SetTexture(0, t);
+ return f;
+}
// Rendering
@@ -1155,8 +1327,36 @@ void RenderDevice::BeginRendering()
Context->RSSetState(Rasterizer);
}
-void RenderDevice::SetRenderTarget(RenderTiny::Texture* colorTex,
- RenderTiny::Texture* depth, RenderTiny::Texture* stencil)
+void RenderDevice::SetLighting(const LightingParams* lt)
+{
+ if (!LightingBuffer)
+ LightingBuffer = *CreateBuffer();
+
+ LightingBuffer->Data(Buffer_Uniform, lt, sizeof(LightingParams));
+ SetCommonUniformBuffer(1, LightingBuffer);
+}
+
+void RenderDevice::SetProjection(const Matrix4f& proj)
+{
+ Proj = proj;
+ SetWorldUniforms(proj);
+}
+
+void RenderDevice::BeginScene()
+{
+ BeginRendering();
+ SetViewport(VP);
+ SetWorldUniforms(Proj);
+}
+
+void RenderDevice::FinishScene()
+{
+ SetRenderTarget(0);
+}
+
+void RenderDevice::SetRenderTarget(Texture* colorTex,
+ Texture* depth,
+ Texture* stencil)
{
OVR_UNUSED(stencil);
@@ -1180,7 +1380,7 @@ void RenderDevice::SetRenderTarget(RenderTiny::Texture* colorTex,
depth = GetDepthBuffer(colorTex->GetWidth(), colorTex->GetHeight(), CurRenderTarget->Samples);
}
- ID3D1xShaderResourceView* sv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ ID3D11ShaderResourceView* sv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
if (MaxTextureSet[Shader_Fragment])
{
Context->PSSetShaderResources(0, MaxTextureSet[Shader_Fragment], sv);
@@ -1199,7 +1399,7 @@ void RenderDevice::SetWorldUniforms(const Matrix4f& proj)
}
-void RenderDevice::Render(const Matrix4f& matrix, Model* model)
+void RenderDevice::Render(const Matrix4f& view, Model* model)
{
// Store data in buffers if not already
if (!model->VertexBuffer)
@@ -1217,19 +1417,32 @@ void RenderDevice::Render(const Matrix4f& matrix, Model* model)
Render(model->Fill ? model->Fill : DefaultFill,
model->VertexBuffer, model->IndexBuffer,
- matrix, 0, (unsigned)model->Indices.GetSize(), model->GetPrimType());
+ view, 0, (unsigned)model->Indices.GetSize(), model->GetPrimType());
}
-void RenderDevice::Render(const ShaderFill* fill, RenderTiny::Buffer* vertices, RenderTiny::Buffer* indices,
- const Matrix4f& matrix, int offset, int count, PrimitiveType rprim)
+
+//Cut down one for ORT for simplicity
+void RenderDevice::Render(const ShaderFill* fill, Buffer* vertices, Buffer* indices)
{
- Context->IASetInputLayout(ModelVertexIL);
+ Render(fill, vertices, indices, Matrix4f(), 0, (int)vertices->GetSize(), Prim_Triangles, false);
+}
+
+
+void RenderDevice::Render(const ShaderFill* fill, Buffer* vertices, Buffer* indices,
+ const Matrix4f& matrix, int offset, int count, PrimitiveType rprim, bool updateUniformData)
+{
+
+ if(((ShaderFill*)fill)->GetInputLayout() != NULL)
+ Context->IASetInputLayout((ID3D11InputLayout*)((ShaderFill*)fill)->GetInputLayout());
+ else
+ Context->IASetInputLayout(ModelVertexIL);
+
if (indices)
{
Context->IASetIndexBuffer(((Buffer*)indices)->GetBuffer(), DXGI_FORMAT_R16_UINT, 0);
}
- ID3D1xBuffer* vertexBuffer = ((Buffer*)vertices)->GetBuffer();
+ ID3D11Buffer* vertexBuffer = ((Buffer*)vertices)->GetBuffer();
UINT vertexStride = sizeof(Vertex);
UINT vertexOffset = offset;
Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
@@ -1240,11 +1453,15 @@ void RenderDevice::Render(const ShaderFill* fill, RenderTiny::Buffer* vertices,
unsigned char* vertexData = vshader->UniformData;
if (vertexData)
{
- StandardUniformData* stdUniforms = (StandardUniformData*) vertexData;
- stdUniforms->View = matrix.Transposed();
- stdUniforms->Proj = StdUniforms.Proj;
- UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, vertexData, vshader->UniformsSize);
- vshader->SetUniformBuffer(UniformBuffers[Shader_Vertex]);
+ // TODO: some VSes don't start with StandardUniformData!
+ if ( updateUniformData )
+ {
+ StandardUniformData* stdUniforms = (StandardUniformData*) vertexData;
+ stdUniforms->View = matrix.Transposed();
+ stdUniforms->Proj = StdUniforms.Proj;
+ }
+ UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, vertexData, vshader->UniformsSize);
+ vshader->SetUniformBuffer(UniformBuffers[Shader_Vertex]);
}
for(int i = Shader_Vertex + 1; i < Shader_Count; i++)
@@ -1254,20 +1471,20 @@ void RenderDevice::Render(const ShaderFill* fill, RenderTiny::Buffer* vertices,
((ShaderBase*)shaders->GetShader(i))->SetUniformBuffer(UniformBuffers[i]);
}
- D3D1x_(PRIMITIVE_TOPOLOGY) prim;
+ D3D11_PRIMITIVE_TOPOLOGY prim;
switch(rprim)
{
case Prim_Triangles:
- prim = D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ prim = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
break;
case Prim_Lines:
- prim = D3D1x_(PRIMITIVE_TOPOLOGY_LINELIST);
+ prim = D3D11_PRIMITIVE_TOPOLOGY_LINELIST;
break;
case Prim_TriangleStrip:
- prim = D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+ prim = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
break;
default:
- assert(0);
+ OVR_ASSERT(0);
return;
}
Context->IASetPrimitiveTopology(prim);
@@ -1285,27 +1502,55 @@ void RenderDevice::Render(const ShaderFill* fill, RenderTiny::Buffer* vertices,
}
-void RenderDevice::Present()
+void RenderDevice::Present(bool vsyncEnabled)
{
- SwapChain->Present(0, 0);
+ SwapChain->Present(vsyncEnabled ? 1 : 0, 0);
}
-void RenderDevice::ForceFlushGPU()
+void RenderDevice::WaitUntilGpuIdle()
{
- D3D1x_QUERY_DESC queryDesc = { D3D1x_(QUERY_EVENT), 0 };
- Ptr<ID3D1xQuery> query;
+ // Flush and Stall CPU while waiting for GPU to complete rendering all of the queued draw calls
+ D3D11_QUERY_DESC queryDesc = { D3D11_QUERY_EVENT, 0 };
+ Ptr<ID3D11Query> query;
BOOL done = FALSE;
if (Device->CreateQuery(&queryDesc, &query.GetRawRef()) == S_OK)
{
- // Begin() not used for EVENT query.
- query->End();
- // GetData will returns S_OK for both done == TRUE or FALSE.
- // Exit on failure to avoid infinite loop.
+ Context->End(query);
do { }
- while(!done && !FAILED(query->GetData(&done, sizeof(BOOL), 0)));
+ while(!done && !FAILED(Context->GetData(query, &done, sizeof(BOOL), 0)));
+ }
+}
+
+
+int GetNumMipLevels(int w, int h)
+{
+ int n = 1;
+ while(w > 1 || h > 1)
+ {
+ w >>= 1;
+ h >>= 1;
+ n++;
+ }
+ return n;
+}
+
+void FilterRgba2x2(const UByte* src, int w, int h, UByte* dest)
+{
+ for(int j = 0; j < (h & ~1); j += 2)
+ {
+ const UByte* psrc = src + (w * j * 4);
+ UByte* pdest = dest + ((w >> 1) * (j >> 1) * 4);
+
+ for(int i = 0; i < w >> 1; i++, psrc += 8, pdest += 4)
+ {
+ pdest[0] = (((int)psrc[0]) + psrc[4] + psrc[w * 4 + 0] + psrc[w * 4 + 4]) >> 2;
+ pdest[1] = (((int)psrc[1]) + psrc[5] + psrc[w * 4 + 1] + psrc[w * 4 + 5]) >> 2;
+ pdest[2] = (((int)psrc[2]) + psrc[6] + psrc[w * 4 + 2] + psrc[w * 4 + 6]) >> 2;
+ pdest[3] = (((int)psrc[3]) + psrc[7] + psrc[w * 4 + 3] + psrc[w * 4 + 7]) >> 2;
+ }
}
}
-}}}
+}}
diff --git a/Samples/OculusRoomTiny/RenderTiny_Device.h b/Samples/OculusRoomTiny/RenderTiny_D3D11_Device.h
index 878450d..f4ec71a 100644
--- a/Samples/OculusRoomTiny/RenderTiny_Device.h
+++ b/Samples/OculusRoomTiny/RenderTiny_D3D11_Device.h
@@ -1,9 +1,9 @@
/************************************************************************************
-Filename : RenderTiny_Device.h
-Content : Minimal possible renderer for RoomTiny sample
-Created : September 6, 2012
-Authors : Andrew Reisse, Michael Antonov
+Filename : RenderTiny_D3D11_Device.h
+Content : RenderDevice implementation header for D3DX10.
+Created : September 10, 2012
+Authors : Andrew Reisse
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
@@ -21,23 +21,20 @@ limitations under the License.
************************************************************************************/
-#ifndef OVR_RenderTiny_Device_h
-#define OVR_RenderTiny_Device_h
+#ifndef INC_RenderTiny_D3D11_Device_h
+#define INC_RenderTiny_D3D11_Device_h
#include "Kernel/OVR_Math.h"
#include "Kernel/OVR_Array.h"
-#include "Kernel/OVR_RefCount.h"
#include "Kernel/OVR_String.h"
-#include "Kernel/OVR_File.h"
#include "Kernel/OVR_Color.h"
-
-#include "Util/Util_Render_Stereo.h"
+#include <d3d11.h>
namespace OVR { namespace RenderTiny {
-using namespace OVR::Util::Render;
class RenderDevice;
+class Buffer;
//-----------------------------------------------------------------------------------
@@ -66,16 +63,13 @@ enum BuiltinShaders
{
VShader_MV = 0,
VShader_MVP = 1,
- VShader_PostProcess = 2,
- VShader_Count = 3,
+ VShader_Count = 2,
FShader_Solid = 0,
FShader_Gouraud = 1,
FShader_Texture = 2,
- FShader_PostProcess = 3,
- FShader_PostProcessWithChromAb = 4,
- FShader_LitGouraud = 5,
- FShader_LitTexture = 6,
+ FShader_LitGouraud = 3,
+ FShader_LitTexture = 4,
FShader_Count
};
@@ -124,20 +118,9 @@ enum SampleMode
Sample_Count =13,
};
-// A vector with a dummy w component for alignment in uniform buffers (and for float colors).
-// The w component is not used in any calculations.
-struct Vector4f : public Vector3f
-{
- float w;
-
- Vector4f() : w(1) {}
- Vector4f(const Vector3f& v) : Vector3f(v), w(1) {}
- Vector4f(float r, float g, float b, float a) : Vector3f(r,g,b), w(a) {}
-};
-
// Base class for vertex and pixel shaders. Stored in ShaderSet.
-class Shader : public RefCountBase<Shader>
+class ShaderBase : public RefCountBase<ShaderBase>
{
friend class ShaderSet;
@@ -145,31 +128,92 @@ protected:
ShaderStage Stage;
public:
- Shader(ShaderStage s) : Stage(s) {}
- virtual ~Shader() {}
+ RenderDevice* Ren;
+ unsigned char* UniformData;
+ int UniformsSize;
+
+ enum VarType
+ {
+ VARTYPE_FLOAT,
+ VARTYPE_INT,
+ VARTYPE_BOOL,
+ };
+
+ struct Uniform
+ {
+ String Name;
+ VarType Type;
+ int Offset, Size;
+ };
+ Array<Uniform> UniformInfo;
+
+ ShaderBase(RenderDevice* r, ShaderStage stage);
+ ShaderBase(ShaderStage s) : Stage(s) {}
+
+ ~ShaderBase();
ShaderStage GetStage() const { return Stage; }
virtual void Set(PrimitiveType) const { }
virtual void SetUniformBuffer(class Buffer* buffers, int i = 0) { OVR_UNUSED2(buffers, i); }
+
+ void InitUniforms(ID3D10Blob* s);
+ void InitUniforms(void* s, size_t sizeS);
+ virtual bool SetUniform(const char* name, int n, const float* v);
+ virtual bool SetUniformBool(const char* name, int n, const bool* v);
-protected:
- virtual bool SetUniform(const char* name, int n, const float* v) { OVR_UNUSED3(name, n, v); return false; }
+ void UpdateBuffer(Buffer* b);
};
+template<ShaderStage SStage, class D3DShaderType>
+class Shader : public ShaderBase
+{
+public:
+ D3DShaderType* D3DShader;
+
+ Shader(RenderDevice* r, D3DShaderType* s) : ShaderBase(r, SStage), D3DShader(s) {}
+ Shader(RenderDevice* r, ID3D10Blob* s) : ShaderBase(r, SStage)
+ {
+ Load(s);
+ InitUniforms(s);
+ }
+ Shader(RenderDevice* r, void* s, size_t size) : ShaderBase(r, SStage)
+ {
+ Load(s, size);
+ InitUniforms(s, size);
+ }
+ ~Shader()
+ {
+ if (D3DShader)
+ D3DShader->Release();
+ }
+ bool Load(ID3D10Blob* shader)
+ {
+ return Load(shader->GetBufferPointer(), shader->GetBufferSize());
+ }
+
+ // These functions have specializations.
+ bool Load(void* shader, size_t size);
+ void Set(PrimitiveType prim) const;
+ void SetUniformBuffer(Buffer* buffers, int i = 0);
+};
+
+typedef Shader<Shader_Vertex, ID3D11VertexShader> VertexShader;
+typedef Shader<Shader_Fragment, ID3D11PixelShader> PixelShader;
+
// A group of shaders, one per stage.
// A ShaderSet is applied to a RenderDevice for rendering with a given fill.
class ShaderSet : public RefCountBase<ShaderSet>
{
- protected:
- Ptr<Shader> Shaders[Shader_Count];
+protected:
+ Ptr<ShaderBase> Shaders[Shader_Count];
public:
ShaderSet() { }
~ShaderSet() { }
- virtual void SetShader(Shader *s)
+ virtual void SetShader(ShaderBase *s)
{
Shaders[s->GetStage()] = s;
}
@@ -177,7 +221,7 @@ public:
{
Shaders[stage] = NULL;
}
- Shader* GetShader(int stage) { return Shaders[stage]; }
+ ShaderBase* GetShader(int stage) { return Shaders[stage]; }
virtual void Set(PrimitiveType prim) const
{
@@ -208,6 +252,11 @@ public:
const float v[] = {x,y};
return SetUniform(name, 2, v);
}
+ bool SetUniform3f(const char* name, float x, float y, float z)
+ {
+ const float v[] = {x,y,z};
+ return SetUniform(name, 3, v);
+ }
bool SetUniform4f(const char* name, float x, float y, float z, float w = 1)
{
const float v[] = {x,y,z,w};
@@ -236,18 +285,22 @@ class ShaderFill : public RefCountBase<ShaderFill>
{
Ptr<ShaderSet> Shaders;
Ptr<class Texture> Textures[8];
+ void* InputLayout; // HACK this should be abstracted
public:
- ShaderFill(ShaderSet* sh) : Shaders(sh) { }
- ShaderFill(ShaderSet& sh) : Shaders(sh) { }
+ ShaderFill(ShaderSet* sh) : Shaders(sh) { InputLayout = NULL; }
+ ShaderFill(ShaderSet& sh) : Shaders(sh) { InputLayout = NULL; }
ShaderSet* GetShaders() { return Shaders; }
+
+ void* GetInputLayout() { return InputLayout; }
+
virtual void Set(PrimitiveType prim = Prim_Unknown) const;
virtual void SetTexture(int i, class Texture* tex) { if (i < 8) Textures[i] = tex; }
+ void SetInputLayout(void* newIL) { InputLayout = (void*)newIL; }
};
-
// Buffer for vertex or index data. Some renderers require separate buffers, so that
// is recommended. Some renderers cannot have high-performance buffers which are readable,
// so reading in Map should not be relied on.
@@ -263,31 +316,72 @@ public:
class Buffer : public RefCountBase<Buffer>
{
public:
+ RenderDevice* Ren;
+ Ptr<ID3D11Buffer> D3DBuffer;
+ size_t Size;
+ int Use;
+ bool Dynamic;
+
+public:
+ Buffer(RenderDevice* r) : Ren(r), Size(0), Use(0) {}
virtual ~Buffer() {}
- virtual size_t GetSize() = 0;
- virtual void* Map(size_t start, size_t size, int flags = 0) = 0;
- virtual bool Unmap(void *m) = 0;
+ ID3D11Buffer* GetBuffer()
+ {
+ return D3DBuffer;
+ }
+ virtual size_t GetSize()
+ {
+ return Size;
+ }
+ virtual void* Map(size_t start, size_t size, int flags = 0);
+ virtual bool Unmap(void *m);
// Allocates a buffer, optionally filling it with data.
- virtual bool Data(int use, const void* buffer, size_t size) = 0;
+ virtual bool Data(int use, const void* buffer, size_t size);
};
class Texture : public RefCountBase<Texture>
{
public:
- virtual ~Texture() {}
+ RenderDevice* Ren;
+ Ptr<ID3D11Texture2D> Tex;
+ Ptr<ID3D11ShaderResourceView> TexSv;
+ Ptr<ID3D11RenderTargetView> TexRtv;
+ Ptr<ID3D11DepthStencilView> TexDsv;
+ mutable Ptr<ID3D11SamplerState> Sampler;
+ int Width, Height;
+ int Samples;
+
+ Texture(RenderDevice* r, int fmt, int w, int h);
+ virtual ~Texture();
+
+ virtual int GetWidth() const { return Width; }
+ virtual int GetHeight() const { return Height; }
+ virtual int GetSamples() const { return Samples; }
+
+ virtual void SetSampleMode(int sm);
+
+ // Updates texture to point to specified resources
+ // - used for slave rendering.
+ void UpdatePlaceholderTexture(ID3D11Texture2D* texture, ID3D11ShaderResourceView* psrv)
+ {
+ Tex = texture;
+ TexSv = psrv;
+ TexRtv.Clear();
+ TexDsv.Clear();
+
+ D3D11_TEXTURE2D_DESC desc;
+ texture->GetDesc(&desc);
+ Width = desc.Width;
+ Height= desc.Height;
+ }
- virtual int GetWidth() const = 0;
- virtual int GetHeight() const = 0;
- virtual int GetSamples() const { return 1; }
- virtual void SetSampleMode(int sm) = 0;
- virtual void Set(int slot, ShaderStage stage = Shader_Fragment) const = 0;
+ virtual void Set(int slot, ShaderStage stage = Shader_Fragment) const;
};
-
//-----------------------------------------------------------------------------------
// Node is a base class for geometry in a Scene, it contains base position
@@ -300,7 +394,7 @@ class Node : public RefCountBase<Node>
Quatf Rot;
mutable Matrix4f Mat;
- mutable bool MatCurrent;
+ mutable bool MatCurrent;
public:
Node() : Pos(Vector3f(0)), MatCurrent(1) { }
@@ -334,14 +428,14 @@ public:
{
if (!MatCurrent)
{
- Mat = Rot;
+ Mat = Matrix4f(Rot);
Mat = Matrix4f::Translation(Pos) * Mat;
MatCurrent = 1;
}
return Mat;
}
- virtual void Render(const Matrix4f& ltw, RenderDevice* ren) { OVR_UNUSED2(ltw, ren); }
+ virtual void Render(const Matrix4f& ltw, RenderDevice* ren) { OVR_UNUSED2(ltw, ren); }
};
@@ -355,19 +449,20 @@ struct Vertex
Vector3f Norm;
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)
+ float u = 0, float v = 0, Vector3f n = Vector3f(1,0,0))
+ : Pos(p), C(c), U(u), V(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)
+ float u = 0, float v = 0) : Pos(x,y,z), C(c), U(u), V(v)
{ }
-
+
bool operator==(const Vertex& b) const
{
return Pos == b.Pos && C == b.C && U == b.U && V == b.V;
}
};
+
// LightingParams are stored in a uniform buffer, don't change it without fixing all renderers
// Scene contains a set of LightingParams that is uses for rendering.
struct LightingParams
@@ -397,9 +492,9 @@ struct LightingParams
s->SetUniform4fv("LightPos", (int)LightCount, LightPos);
s->SetUniform4fv("LightColor", (int)LightCount, LightColor);
}
-
};
+
//-----------------------------------------------------------------------------------
// Model is a triangular mesh with a fill that can be added to scene.
@@ -430,7 +525,7 @@ public:
// Node implementation.
virtual NodeType GetType() const { return Node_Model; }
virtual void Render(const Matrix4f& ltw, RenderDevice* ren);
-
+
// Returns the index next added vertex will have.
UInt16 GetNextVertexIndex() const
@@ -440,7 +535,7 @@ public:
UInt16 AddVertex(const Vertex& v)
{
- assert(!VertexBuffer && !IndexBuffer);
+ OVR_ASSERT(!VertexBuffer && !IndexBuffer);
UInt16 index = (UInt16)Vertices.GetSize();
Vertices.PushBack(v);
return index;
@@ -455,8 +550,8 @@ public:
// Uses texture coordinates for uniform world scaling (must use a repeat sampler).
void AddSolidColorBox(float x1, float y1, float z1,
- float x2, float y2, float z2,
- Color c);
+ float x2, float y2, float z2,
+ Color c);
};
@@ -468,18 +563,18 @@ public:
Container() { }
~Container() { }
-
+
virtual NodeType GetType() const { return Node_Container; }
virtual void Render(const Matrix4f& ltw, RenderDevice* ren);
void Add(Node *n) { Nodes.PushBack(n); }
- void Clear() { Nodes.Clear(); }
+ void Clear() { Nodes.Clear(); }
};
// Scene combines a collection of model
-class Scene
+class Scene : public NewOverrideBase
{
public:
Container World;
@@ -493,7 +588,7 @@ public:
{
Lighting.Ambient = color;
}
-
+
void AddLight(Vector3f pos, Vector4f color)
{
int n = (int)Lighting.LightCount;
@@ -503,31 +598,23 @@ public:
Lighting.LightCount++;
}
- void Clear()
- {
- World.Clear();
- Lighting.Ambient = Vector4f(0.0f, 0.0f, 0.0f, 0.0f);
- Lighting.LightCount = 0;
- }
- };
+ void Clear()
+ {
+ World.Clear();
+ Lighting.Ambient = Vector4f(0.0f, 0.0f, 0.0f, 0.0f);
+ Lighting.LightCount = 0;
+ }
+};
//-----------------------------------------------------------------------------------
-// Post-processing type to apply to scene after rendering. PostProcess_Distortion
-// applied distortion as described by DistortionConfig.
-enum PostProcessType
-{
- PostProcess_None,
- PostProcess_Distortion
-};
-
enum DisplayMode
{
Display_Window = 0,
Display_Fullscreen = 1
};
-
+
// Rendering parameters used by RenderDevice::CreateDevice.
struct RendererParams
@@ -541,47 +628,28 @@ struct RendererParams
long DisplayId;
RendererParams(int ms = 1) : Multisample(ms), Fullscreen(0) {}
-
+
bool IsDisplaySet() const
{
return MonitorName.GetLength() || DisplayId;
}
};
+class RenderDevice : public RefCountBase<RenderDevice>
+{
-//-----------------------------------------------------------------------------------
-// ***** RenderDevice
-
-// Rendering device abstraction.
-// Provides platform-independent part of implementation, with platform-specific
-// part being in a separate derived class/file, such as D3D10::RenderDevice.
-//
-class RenderDevice : public RefCountBase<RenderDevice>
-{
protected:
int WindowWidth, WindowHeight;
RendererParams Params;
- Viewport VP;
+ Recti VP;
Matrix4f Proj;
Ptr<Buffer> pTextVertexBuffer;
- // For rendering with lens warping
- PostProcessType CurPostProcess;
- Ptr<Texture> pSceneColorTex; // Distortion render target, both eyes.
- int SceneColorTexW;
- int SceneColorTexH;
- Ptr<ShaderSet> pPostProcessShader;
- Ptr<Buffer> pFullScreenVertexBuffer;
- float SceneRenderScale;
- DistortionConfig Distortion;
-
// For lighting on platforms with uniform buffers
Ptr<Buffer> LightingBuffer;
- void FinishScene1();
-
public:
enum CompareFunc
{
@@ -590,127 +658,153 @@ public:
Compare_Greater = 2,
Compare_Count
};
- RenderDevice();
- virtual ~RenderDevice() { Shutdown(); }
- // This static function is implemented in each derived class
- // to support a specific renderer type.
- //static RenderDevice* CreateDevice(const RendererParams& rp, void* oswnd);
+ Ptr<IDXGIFactory> DXGIFactory;
+ HWND Window;
+ Ptr<ID3D11Device> Device;
+ Ptr<ID3D11DeviceContext> Context;
+ Ptr<IDXGISwapChain> SwapChain;
+ Ptr<IDXGIAdapter> Adapter;
+ Ptr<IDXGIOutput> FullscreenOutput;
+ int FSDesktopX, FSDesktopY;
- virtual void Init() {}
- virtual void Shutdown() {}
- virtual bool SetParams(const RendererParams&) { return 0; }
+ Ptr<ID3D11Texture2D> BackBuffer;
+ Ptr<ID3D11RenderTargetView> BackBufferRT;
+ Ptr<Texture> CurRenderTarget;
+ Ptr<Texture> CurDepthBuffer;
+ Ptr<ID3D11RasterizerState> Rasterizer;
+ Ptr<ID3D11BlendState> BlendState;
+ D3D11_VIEWPORT D3DViewport;
- const RendererParams& GetParams() const { return Params; }
+ Ptr<ID3D11DepthStencilState> DepthStates[1 + 2 * Compare_Count];
+ Ptr<ID3D11DepthStencilState> CurDepthState;
+ Ptr<ID3D11InputLayout> ModelVertexIL;
-
- // StereoParams apply Viewport, Projection and Distortion simultaneously,
- // doing full configuration for one eye.
- void ApplyStereoParams(const StereoEyeParams& params)
- {
- SetViewport(params.VP);
- SetProjection(params.Projection);
- if (params.pDistortion)
- SetDistortionConfig(*params.pDistortion, params.Eye);
- }
+ Ptr<ID3D11SamplerState> SamplerStates[Sample_Count];
+
+ struct StandardUniformData
+ {
+ Matrix4f Proj;
+ Matrix4f View;
+ } StdUniforms;
+ Ptr<Buffer> UniformBuffers[Shader_Count];
+ int MaxTextureSet[Shader_Count];
- virtual void SetViewport(const Viewport& vp);
- void SetViewport(int x, int y, int w, int h) { SetViewport(Viewport(x,y,w,h)); }
+ Ptr<VertexShader> VertexShaders[VShader_Count];
+ Ptr<PixelShader> PixelShaders[FShader_Count];
+ Ptr<Buffer> CommonUniforms[8];
+ Ptr<ShaderFill> DefaultFill;
- // PostProcess distortion
- void SetSceneRenderScale(float ss);
+ Ptr<Buffer> QuadVertexBuffer;
- void SetDistortionConfig(const DistortionConfig& config, StereoEye eye = StereoEye_Left)
+ Array<Ptr<Texture> > DepthBuffers;
+
+public:
+
+ // Slave parameters are used to create a renderer that uses an externally
+ // specified device.
+ struct SlaveRendererParams
{
- Distortion = config;
- if (eye == StereoEye_Right)
- Distortion.XCenterOffset = -Distortion.XCenterOffset;
- }
-
+ ID3D11Device* pDevice;
+ ID3D11DeviceContext* pDeviceContext;
+ ID3D11RenderTargetView* pBackBufferRT;
+ Sizei RTSize;
+ int Multisample;
+ };
+
+ RenderDevice();
+ RenderDevice(const RendererParams& p, HWND window);
+ RenderDevice(const SlaveRendererParams& p);
+ virtual ~RenderDevice();
+
+ // Implement static initializer function to create this class.
+ // Creates a new rendering device
+ static RenderDevice* CreateDevice(const RendererParams& rp, void* oswnd);
+
+ // Creates a "slave" renderer existing device.
+ static RenderDevice* CreateSlaveDevice(const SlaveRendererParams& srp);
+
+
+
+ // Constructor helper
+ void initShadersAndStates();
+ void InitShaders( const char * vertex_shader, const char * pixel_shader, ShaderSet ** pShaders, ID3D11InputLayout ** pVertexIL,
+ D3D11_INPUT_ELEMENT_DESC * DistortionMeshVertexDesc, int num_elements);
+
+
+
+ void UpdateMonitorOutputs();
+
+ void SetViewport(int x, int y, int w, int h) { SetViewport(Recti(x,y,w,h)); }
// Set viewport ignoring any adjustments used for the stereo mode.
- virtual void SetRealViewport(const Viewport& vp) = 0;
+ virtual void SetViewport(const Recti& vp);
+ virtual void SetFullViewport();
+
+ virtual bool SetParams(const RendererParams& newParams);
+ const RendererParams& GetParams() const { return Params; }
+
+ virtual void Present(bool vsyncEnabled);
- virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1, float depth = 1) = 0;
-
- virtual bool IsFullscreen() const { return Params.Fullscreen != Display_Window; }
- virtual void Present() = 0;
// Waits for rendering to complete; important for reducing latency.
- virtual void ForceFlushGPU() { }
+ virtual void WaitUntilGpuIdle();
+
+ // Don't call these directly, use App/Platform instead
+ virtual bool SetFullscreen(DisplayMode fullscreen);
+
+ virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1, float depth = 1);
// Resources
- virtual Buffer* CreateBuffer() { return NULL; }
- virtual Texture* CreateTexture(int format, int width, int height, const void* data, int mipcount=1)
- { OVR_UNUSED5(format,width,height,data, mipcount); return NULL; }
-
+ virtual Buffer* CreateBuffer();
+ virtual Texture* CreateTexture(int format, int width, int height, const void* data, int mipcount=1);
+
+ // Placeholder texture to come in externally
+ virtual Texture* CreatePlaceholderTexture(int format);
virtual ShaderSet* CreateShaderSet() { return new ShaderSet; }
- virtual Shader* LoadBuiltinShader(ShaderStage stage, int shader) = 0;
- // Rendering
+ Texture* GetDepthBuffer(int w, int h, int ms);
// Begin drawing directly to the currently selected render target, no post-processing.
- virtual void BeginRendering() {}
- // Begin drawing the primary scene. This will have post-processing applied (if enabled)
- // during FinishScene.
- virtual void BeginScene(PostProcessType pp = PostProcess_None);
- // Postprocess the scene and return to the screen render target.
+ virtual void BeginRendering();
+
+ // Begin drawing the primary scene, starting up whatever post-processing may be needed.
+ virtual void BeginScene();
virtual void FinishScene();
// Texture must have been created with Texture_RenderTarget. Use NULL for the default render target.
// 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); }
- 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;
+ virtual void SetRenderTarget(Texture* color,
+ Texture* depth = NULL,
+ Texture* stencil = NULL);
+ virtual void SetDepthMode(bool enable, bool write, CompareFunc func = Compare_Less);
+ virtual void SetProjection(const Matrix4f& proj);
+ virtual void SetWorldUniforms(const Matrix4f& proj);
+ // The index 0 is reserved for non-buffer uniforms, and so cannot be used with this function.
+ virtual void SetCommonUniformBuffer(int i, Buffer* buffer);
// The data is not copied, it must remain valid until the end of the frame
virtual void SetLighting(const LightingParams* light);
- // The index 0 is reserved for non-buffer uniforms, and so cannot be used with this function.
- virtual void SetCommonUniformBuffer(int i, Buffer* buffer) { OVR_UNUSED2(i, buffer); }
-
virtual Matrix4f GetProjection() const { return Proj; }
// This is a View matrix only, it will be combined with the projection matrix from SetProjection
- virtual void Render(const Matrix4f& matrix, Model* model) = 0;
- // offset is in bytes; indices can be null.
+ virtual void Render(const Matrix4f& view, Model* model);
+ virtual void Render(const ShaderFill* fill, Buffer* vertices, Buffer* indices);
virtual void Render(const ShaderFill* fill, Buffer* vertices, Buffer* indices,
- const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles) = 0;
+ const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles, bool updateUniformData = true);
- virtual ShaderFill *CreateSimpleFill() = 0;
+ virtual ShaderFill *CreateSimpleFill() { return DefaultFill; }
ShaderFill * CreateTextureFill(Texture* tex);
-
- // Don't call these directly, use App/Platform instead
- virtual bool SetFullscreen(DisplayMode fullscreen) { OVR_UNUSED(fullscreen); return false; }
-
-
- enum PostProcessShader
- {
- PostProcessShader_Distortion = 0,
- PostProcessShader_DistortionAndChromAb = 1,
- PostProcessShader_Count
- };
-
- PostProcessShader GetPostProcessShader()
- {
- return PostProcessShaderActive;
- }
+ virtual ShaderBase *LoadBuiltinShader(ShaderStage stage, int shader);
- void SetPostProcessShader(PostProcessShader newShader)
- {
- PostProcessShaderRequested = newShader;
- }
+ bool RecreateSwapChain();
+ virtual ID3D10Blob* CompileShader(const char* profile, const char* src, const char* mainName = "main");
+
+ ID3D11SamplerState* GetSamplerState(int sm);
-protected:
- // Stereo & post-processing
- virtual bool initPostProcessSupport(PostProcessType pptype);
-
-private:
- PostProcessShader PostProcessShaderRequested;
- PostProcessShader PostProcessShaderActive;
+ void SetTexture(ShaderStage stage, int slot, const Texture* t);
};
int GetNumMipLevels(int w, int h);
@@ -719,6 +813,12 @@ int GetNumMipLevels(int w, int h);
// Image size must be a power of 2.
void FilterRgba2x2(const UByte* src, int w, int h, UByte* dest);
-}} // OVR::RenderTiny
+}}
+
+
+//Anything including this file, uses these
+using namespace OVR;
+using namespace OVR::RenderTiny;
+
#endif
diff --git a/Samples/OculusRoomTiny/RenderTiny_D3D1X_Device.h b/Samples/OculusRoomTiny/RenderTiny_D3D1X_Device.h
deleted file mode 100644
index 1438611..0000000
--- a/Samples/OculusRoomTiny/RenderTiny_D3D1X_Device.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/************************************************************************************
-
-Filename : RenderTiny_D3D1X_Device.h
-Content : RenderDevice implementation header for D3DX10.
-Created : September 10, 2012
-Authors : Andrew Reisse
-
-Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#ifndef INC_RenderTiny_D3D1X_Device_h
-#define INC_RenderTiny_D3D1X_Device_h
-
-#include "Kernel/OVR_String.h"
-#include "Kernel/OVR_Array.h"
-
-#include "RenderTiny_Device.h"
-#include <Windows.h>
-
-#define _OVR_RENDERER_D3D10
-#include <d3d10.h>
-
-namespace OVR { namespace RenderTiny { namespace D3D10 {
-
-class RenderDevice;
-class Buffer;
-
-typedef ID3D10Device ID3D1xDevice;
-typedef ID3D10Device ID3D1xDeviceContext;
-typedef ID3D10RenderTargetView ID3D1xRenderTargetView;
-typedef ID3D10Texture2D ID3D1xTexture2D;
-typedef ID3D10ShaderResourceView ID3D1xShaderResourceView;
-typedef ID3D10DepthStencilView ID3D1xDepthStencilView;
-typedef ID3D10DepthStencilState ID3D1xDepthStencilState;
-typedef ID3D10InputLayout ID3D1xInputLayout;
-typedef ID3D10Buffer ID3D1xBuffer;
-typedef ID3D10VertexShader ID3D1xVertexShader;
-typedef ID3D10PixelShader ID3D1xPixelShader;
-typedef ID3D10GeometryShader ID3D1xGeometryShader;
-typedef ID3D10BlendState ID3D1xBlendState;
-typedef ID3D10RasterizerState ID3D1xRasterizerState;
-typedef ID3D10SamplerState ID3D1xSamplerState;
-typedef ID3D10Query ID3D1xQuery;
-typedef ID3D10Blob ID3D1xBlob;
-typedef D3D10_VIEWPORT D3D1x_VIEWPORT;
-typedef D3D10_QUERY_DESC D3D1x_QUERY_DESC;
-#define D3D1x_(x) D3D10_##x
-#define ID3D1x(x) ID3D10##x
-
-
-
-class ShaderBase : public RenderTiny::Shader
-{
-public:
- RenderDevice* Ren;
- unsigned char* UniformData;
- int UniformsSize;
-
- struct Uniform
- {
- String Name;
- int Offset, Size;
- };
- Array<Uniform> UniformInfo;
-
- ShaderBase(RenderDevice* r, ShaderStage stage);
- ~ShaderBase();
-
- void InitUniforms(ID3D10Blob* s);
- bool SetUniform(const char* name, int n, const float* v);
-
- void UpdateBuffer(Buffer* b);
-};
-
-template<RenderTiny::ShaderStage SStage, class D3DShaderType>
-class Shader : public ShaderBase
-{
-public:
- D3DShaderType* D3DShader;
-
- Shader(RenderDevice* r, D3DShaderType* s) : ShaderBase(r, SStage), D3DShader(s) {}
- Shader(RenderDevice* r, ID3D1xBlob* s) : ShaderBase(r, SStage)
- {
- Load(s);
- InitUniforms(s);
- }
- ~Shader()
- {
- if (D3DShader)
- D3DShader->Release();
- }
- bool Load(ID3D1xBlob* shader)
- {
- return Load(shader->GetBufferPointer(), shader->GetBufferSize());
- }
-
- // These functions have specializations.
- bool Load(void* shader, size_t size);
- void Set(PrimitiveType prim) const;
- void SetUniformBuffer(RenderTiny::Buffer* buffers, int i = 0);
-};
-
-typedef Shader<RenderTiny::Shader_Vertex, ID3D1xVertexShader> VertexShader;
-typedef Shader<RenderTiny::Shader_Fragment, ID3D1xPixelShader> PixelShader;
-
-
-class Buffer : public RenderTiny::Buffer
-{
-public:
- RenderDevice* Ren;
- Ptr<ID3D1xBuffer> D3DBuffer;
- size_t Size;
- int Use;
- bool Dynamic;
-
-public:
- Buffer(RenderDevice* r) : Ren(r), Size(0), Use(0) {}
- ~Buffer();
-
- ID3D1xBuffer* GetBuffer()
- {
- return D3DBuffer;
- }
-
- virtual size_t GetSize()
- {
- return Size;
- }
- virtual void* Map(size_t start, size_t size, int flags = 0);
- virtual bool Unmap(void *m);
- virtual bool Data(int use, const void* buffer, size_t size);
-};
-
-class Texture : public RenderTiny::Texture
-{
-public:
- RenderDevice* Ren;
- Ptr<ID3D1xTexture2D> Tex;
- Ptr<ID3D1xShaderResourceView> TexSv;
- Ptr<ID3D1xRenderTargetView> TexRtv;
- Ptr<ID3D1xDepthStencilView> TexDsv;
- mutable Ptr<ID3D1xSamplerState> Sampler;
- int Width, Height;
- int Samples;
-
- Texture(RenderDevice* r, int fmt, int w, int h);
- ~Texture();
-
- virtual int GetWidth() const
- {
- return Width;
- }
- virtual int GetHeight() const
- {
- return Height;
- }
- virtual int GetSamples() const
- {
- return Samples;
- }
-
- virtual void SetSampleMode(int sm);
-
- virtual void Set(int slot, RenderTiny::ShaderStage stage = RenderTiny::Shader_Fragment) const;
-};
-
-class RenderDevice : public RenderTiny::RenderDevice
-{
-public:
- Ptr<IDXGIFactory> DXGIFactory;
- HWND Window;
-
- Ptr<ID3D1xDevice> Device;
- Ptr<ID3D1xDeviceContext> Context;
- Ptr<IDXGISwapChain> SwapChain;
- Ptr<IDXGIAdapter> Adapter;
- Ptr<IDXGIOutput> FullscreenOutput;
- int FSDesktopX, FSDesktopY;
-
- Ptr<ID3D1xTexture2D> BackBuffer;
- Ptr<ID3D1xRenderTargetView> BackBufferRT;
- Ptr<Texture> CurRenderTarget;
- Ptr<Texture> CurDepthBuffer;
- Ptr<ID3D1xRasterizerState> Rasterizer;
- Ptr<ID3D1xBlendState> BlendState;
- D3D1x_VIEWPORT D3DViewport;
-
- Ptr<ID3D1xDepthStencilState> DepthStates[1 + 2 * Compare_Count];
- Ptr<ID3D1xDepthStencilState> CurDepthState;
- Ptr<ID3D1xInputLayout> ModelVertexIL;
-
- Ptr<ID3D1xSamplerState> SamplerStates[Sample_Count];
-
- struct StandardUniformData
- {
- Matrix4f Proj;
- Matrix4f View;
- } StdUniforms;
- Ptr<Buffer> UniformBuffers[Shader_Count];
- int MaxTextureSet[Shader_Count];
-
- Ptr<VertexShader> VertexShaders[VShader_Count];
- Ptr<PixelShader> PixelShaders[FShader_Count];
- Ptr<Buffer> CommonUniforms[8];
- Ptr<ShaderFill> DefaultFill;
-
- Ptr<Buffer> QuadVertexBuffer;
-
- Array<Ptr<Texture> > DepthBuffers;
-
-public:
- RenderDevice(const RendererParams& p, HWND window);
- ~RenderDevice();
-
- // Implement static initializer function to create this class.
- static RenderTiny::RenderDevice* CreateDevice(const RendererParams& rp, void* oswnd);
-
- void UpdateMonitorOutputs();
-
- virtual void SetRealViewport(const Viewport& vp);
- virtual bool SetParams(const RendererParams& newParams);
-
- virtual void Present();
- virtual void ForceFlushGPU();
-
- virtual bool SetFullscreen(DisplayMode fullscreen);
-
- virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1, float depth = 1);
-
- virtual Buffer* CreateBuffer();
- virtual Texture* CreateTexture(int format, int width, int height, const void* data, int mipcount=1);
-
- Texture* GetDepthBuffer(int w, int h, int ms);
-
- virtual void BeginRendering();
- virtual void SetRenderTarget(RenderTiny::Texture* color,
- RenderTiny::Texture* depth = NULL, RenderTiny::Texture* stencil = NULL);
- virtual void SetDepthMode(bool enable, bool write, CompareFunc func = Compare_Less);
- virtual void SetWorldUniforms(const Matrix4f& proj);
- virtual void SetCommonUniformBuffer(int i, RenderTiny::Buffer* buffer);
-
- virtual void Render(const Matrix4f& matrix, Model* model);
- virtual void Render(const ShaderFill* fill, RenderTiny::Buffer* vertices, RenderTiny::Buffer* indices,
- const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles);
-
- virtual ShaderFill *CreateSimpleFill() { return DefaultFill; }
-
- virtual RenderTiny::Shader *LoadBuiltinShader(ShaderStage stage, int shader);
-
- bool RecreateSwapChain();
- virtual ID3D10Blob* CompileShader(const char* profile, const char* src, const char* mainName = "main");
-
- ID3D1xSamplerState* GetSamplerState(int sm);
-
- void SetTexture(RenderTiny::ShaderStage stage, int slot, const Texture* t);
-};
-
-}}} // Render::D3D10
-
-#endif
diff --git a/Samples/OculusRoomTiny/RenderTiny_Device.cpp b/Samples/OculusRoomTiny/RenderTiny_Device.cpp
deleted file mode 100644
index 2c363c2..0000000
--- a/Samples/OculusRoomTiny/RenderTiny_Device.cpp
+++ /dev/null
@@ -1,442 +0,0 @@
-/************************************************************************************
-
-Filename : RenderTiny_Device.cpp
-Content : Platform renderer for simple scene graph - implementation
-Created : September 6, 2012
-Authors : Andrew Reisse
-
-Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#include "RenderTiny_Device.h"
-
-#include "Kernel/OVR_Log.h"
-
-namespace OVR { namespace RenderTiny {
-
-void Model::Render(const Matrix4f& ltw, RenderDevice* ren)
-{
- if (Visible)
- {
- Matrix4f m = ltw * GetMatrix();
- ren->Render(m, this);
- }
-}
-
-void Container::Render(const Matrix4f& ltw, RenderDevice* ren)
-{
- Matrix4f m = ltw * GetMatrix();
- for(unsigned i = 0; i < Nodes.GetSize(); i++)
- {
- Nodes[i]->Render(m, ren);
- }
-}
-
-void Scene::Render(RenderDevice* ren, const Matrix4f& view)
-{
- Lighting.Update(view, LightPos);
-
- ren->SetLighting(&Lighting);
-
- World.Render(view, ren);
-}
-
-
-
-UInt16 CubeIndices[] =
-{
- 0, 1, 3,
- 3, 1, 2,
-
- 5, 4, 6,
- 6, 4, 7,
-
- 8, 9, 11,
- 11, 9, 10,
-
- 13, 12, 14,
- 14, 12, 15,
-
- 16, 17, 19,
- 19, 17, 18,
-
- 21, 20, 22,
- 22, 20, 23
-};
-
-
-void Model::AddSolidColorBox(float x1, float y1, float z1,
- float x2, float y2, float z2,
- Color c)
-{
- float t;
-
- if(x1 > x2)
- {
- t = x1;
- x1 = x2;
- x2 = t;
- }
- if(y1 > y2)
- {
- t = y1;
- y1 = y2;
- y2 = t;
- }
- if(z1 > z2)
- {
- t = z1;
- z1 = z2;
- z2 = t;
- }
-
- // 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)
- };
-
-
- UInt16 startIndex = GetNextVertexIndex();
-
- enum
- {
- CubeVertexCount = sizeof(CubeVertices) / sizeof(CubeVertices[0]),
- CubeIndexCount = sizeof(CubeIndices) / sizeof(CubeIndices[0])
- };
-
- for(int v = 0; v < CubeVertexCount; v++)
- {
- AddVertex(Vertex(CubeVertices[v][0], c, CubeVertices[v][1].x, CubeVertices[v][1].y, CubeVertices[v][2]));
- }
-
- // Renumber indices
- for(int i = 0; i < CubeIndexCount / 3; i++)
- {
- AddTriangle(CubeIndices[i * 3] + startIndex,
- CubeIndices[i * 3 + 1] + startIndex,
- CubeIndices[i * 3 + 2] + startIndex);
- }
-}
-
-
-//-------------------------------------------------------------------------------------
-
-
-void ShaderFill::Set(PrimitiveType prim) const
-{
- Shaders->Set(prim);
- for(int i = 0; i < 8; i++)
- {
- if(Textures[i])
- {
- Textures[i]->Set(i);
- }
- }
-}
-
-
-
-//-------------------------------------------------------------------------------------
-// ***** Rendering
-
-
-RenderDevice::RenderDevice()
- : CurPostProcess(PostProcess_None),
- SceneColorTexW(0), SceneColorTexH(0),
- SceneRenderScale(1),
- Distortion(1.0f, 0.18f, 0.115f),
- PostProcessShaderActive(PostProcessShader_DistortionAndChromAb)
-{
- PostProcessShaderRequested = PostProcessShaderActive;
-}
-
-ShaderFill* RenderDevice::CreateTextureFill(RenderTiny::Texture* t)
-{
- ShaderSet* shaders = CreateShaderSet();
- shaders->SetShader(LoadBuiltinShader(Shader_Vertex, VShader_MVP));
- shaders->SetShader(LoadBuiltinShader(Shader_Fragment, FShader_Texture));
- ShaderFill* f = new ShaderFill(*shaders);
- f->SetTexture(0, t);
- return f;
-}
-
-void RenderDevice::SetLighting(const LightingParams* lt)
-{
- if (!LightingBuffer)
- LightingBuffer = *CreateBuffer();
-
- LightingBuffer->Data(Buffer_Uniform, lt, sizeof(LightingParams));
- SetCommonUniformBuffer(1, LightingBuffer);
-}
-
-
-
-void RenderDevice::SetSceneRenderScale(float ss)
-{
- SceneRenderScale = ss;
- pSceneColorTex = NULL;
-}
-
-void RenderDevice::SetViewport(const Viewport& vp)
-{
- VP = vp;
-
- if (CurPostProcess == PostProcess_Distortion)
- {
- Viewport svp = vp;
- svp.w = (int)ceil(SceneRenderScale * vp.w);
- svp.h = (int)ceil(SceneRenderScale * vp.h);
- svp.x = (int)ceil(SceneRenderScale * vp.x);
- svp.y = (int)ceil(SceneRenderScale * vp.y);
- SetRealViewport(svp);
- }
- else
- {
- SetRealViewport(vp);
- }
-}
-
-
-bool RenderDevice::initPostProcessSupport(PostProcessType pptype)
-{
- if (pptype != PostProcess_Distortion)
- return true;
-
-
- if (PostProcessShaderRequested != PostProcessShaderActive)
- {
- pPostProcessShader.Clear();
- PostProcessShaderActive = PostProcessShaderRequested;
- }
-
- if (!pPostProcessShader)
- {
- Shader *vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcess);
-
- Shader *ppfs = NULL;
- if (PostProcessShaderActive == PostProcessShader_Distortion)
- {
- ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcess);
- }
- else if (PostProcessShaderActive == PostProcessShader_DistortionAndChromAb)
- {
- ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessWithChromAb);
- }
- else
- OVR_ASSERT(false);
-
- pPostProcessShader = *CreateShaderSet();
- pPostProcessShader->SetShader(vs);
- pPostProcessShader->SetShader(ppfs);
- }
-
-
- int texw = (int)ceil(SceneRenderScale * WindowWidth),
- texh = (int)ceil(SceneRenderScale * WindowHeight);
-
- // If pSceneColorTex is already created and is of correct size, we are done.
- // It's important to check width/height in case window size changed.
- if (pSceneColorTex && (texw == SceneColorTexW) && (texh == SceneColorTexH))
- {
- return true;
- }
-
- pSceneColorTex = *CreateTexture(Texture_RGBA | Texture_RenderTarget | Params.Multisample,
- texw, texh, NULL);
- if (!pSceneColorTex)
- {
- return false;
- }
- SceneColorTexW = texw;
- SceneColorTexH = texh;
- pSceneColorTex->SetSampleMode(Sample_ClampBorder | Sample_Linear);
-
-
- if (!pFullScreenVertexBuffer)
- {
- pFullScreenVertexBuffer = *CreateBuffer();
- const RenderTiny::Vertex QuadVertices[] =
- {
- Vertex(Vector3f(0, 1, 0), Color(1, 1, 1, 1), 0, 0),
- Vertex(Vector3f(1, 1, 0), Color(1, 1, 1, 1), 1, 0),
- 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));
- }
- return true;
-}
-
-void RenderDevice::SetProjection(const Matrix4f& proj)
-{
- Proj = proj;
- SetWorldUniforms(proj);
-}
-
-void RenderDevice::BeginScene(PostProcessType pptype)
-{
- BeginRendering();
-
- if ((pptype != PostProcess_None) && initPostProcessSupport(pptype))
- {
- CurPostProcess = pptype;
- }
- else
- {
- CurPostProcess = PostProcess_None;
- }
-
- if (CurPostProcess == PostProcess_Distortion)
- {
- SetRenderTarget(pSceneColorTex);
- SetViewport(VP);
- }
- else
- {
- SetRenderTarget(0);
- }
-
- SetWorldUniforms(Proj);
-}
-
-void RenderDevice::FinishScene()
-{
- if (CurPostProcess == PostProcess_None)
- return;
-
- SetRenderTarget(0);
- SetRealViewport(VP);
- FinishScene1();
-
- CurPostProcess = PostProcess_None;
-}
-
-
-
-void RenderDevice::FinishScene1()
-{
- // Clear with black
- Clear(0.0f, 0.0f, 0.0f, 1.0f);
-
- float w = float(VP.w) / float(WindowWidth),
- h = float(VP.h) / float(WindowHeight),
- x = float(VP.x) / float(WindowWidth),
- y = float(VP.y) / float(WindowHeight);
-
- float as = float(VP.w) / float(VP.h);
-
- // We are using 1/4 of DistortionCenter offset value here, since it is
- // relative to [-1,1] range that gets mapped to [0, 0.5].
- pPostProcessShader->SetUniform2f("LensCenter",
- x + (w + Distortion.XCenterOffset * 0.5f)*0.5f, y + h*0.5f);
- pPostProcessShader->SetUniform2f("ScreenCenter", x + w*0.5f, y + h*0.5f);
-
- // MA: This is more correct but we would need higher-res texture vertically; we should adopt this
- // once we have asymmetric input texture scale.
- float scaleFactor = 1.0f / Distortion.Scale;
-
- pPostProcessShader->SetUniform2f("Scale", (w/2) * scaleFactor, (h/2) * scaleFactor * as);
- pPostProcessShader->SetUniform2f("ScaleIn", (2/w), (2/h) / as);
-
- pPostProcessShader->SetUniform4f("HmdWarpParam",
- Distortion.K[0], Distortion.K[1], Distortion.K[2], Distortion.K[3]);
-
- if (PostProcessShaderRequested == PostProcessShader_DistortionAndChromAb)
- {
- pPostProcessShader->SetUniform4f("ChromAbParam",
- Distortion.ChromaticAberration[0],
- Distortion.ChromaticAberration[1],
- Distortion.ChromaticAberration[2],
- Distortion.ChromaticAberration[3]);
- }
-
- Matrix4f texm(w, 0, 0, x,
- 0, h, 0, y,
- 0, 0, 0, 0,
- 0, 0, 0, 1);
- pPostProcessShader->SetUniform4x4f("Texm", texm);
-
- Matrix4f view(2, 0, 0, -1,
- 0, 2, 0, -1,
- 0, 0, 0, 0,
- 0, 0, 0, 1);
-
- ShaderFill fill(pPostProcessShader);
- fill.SetTexture(0, pSceneColorTex);
- Render(&fill, pFullScreenVertexBuffer, NULL, view, 0, 4, Prim_TriangleStrip);
-}
-
-
-int GetNumMipLevels(int w, int h)
-{
- int n = 1;
- while(w > 1 || h > 1)
- {
- w >>= 1;
- h >>= 1;
- n++;
- }
- return n;
-}
-
-void FilterRgba2x2(const UByte* src, int w, int h, UByte* dest)
-{
- for(int j = 0; j < (h & ~1); j += 2)
- {
- const UByte* psrc = src + (w * j * 4);
- UByte* pdest = dest + ((w >> 1) * (j >> 1) * 4);
-
- for(int i = 0; i < w >> 1; i++, psrc += 8, pdest += 4)
- {
- pdest[0] = (((int)psrc[0]) + psrc[4] + psrc[w * 4 + 0] + psrc[w * 4 + 4]) >> 2;
- pdest[1] = (((int)psrc[1]) + psrc[5] + psrc[w * 4 + 1] + psrc[w * 4 + 5]) >> 2;
- pdest[2] = (((int)psrc[2]) + psrc[6] + psrc[w * 4 + 2] + psrc[w * 4 + 6]) >> 2;
- pdest[3] = (((int)psrc[3]) + psrc[7] + psrc[w * 4 + 3] + psrc[w * 4 + 7]) >> 2;
- }
- }
-}
-
-
-}}
diff --git a/Samples/OculusRoomTiny/RenderTiny_GL_Device.cpp b/Samples/OculusRoomTiny/RenderTiny_GL_Device.cpp
deleted file mode 100644
index 07460c3..0000000
--- a/Samples/OculusRoomTiny/RenderTiny_GL_Device.cpp
+++ /dev/null
@@ -1,784 +0,0 @@
-/************************************************************************************
-
-Filename : RenderTiny_GL_Device.cpp
-Content : RenderDevice implementation for OpenGL (tiny version)
-Created : September 10, 2012
-Authors : Andrew Reisse, Artem Bolgar
-
-Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#include "RenderTiny_GL_Device.h"
-#include "Kernel/OVR_Log.h"
-
-namespace OVR { namespace RenderTiny { namespace GL {
-
-
-
-static const char* StdVertexShaderSrc =
- "uniform mat4 Proj;\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 vec3 oVPos;\n"
- "void main()\n"
- "{\n"
- " gl_Position = Proj * (View * Position);\n"
- " oNormal = vec3(View * vec4(Normal,0));\n"
- " oVPos = vec3(View * Position);\n"
- " oTexCoord = TexCoord;\n"
- " oColor = Color;\n"
- "}\n";
-
-static const char* DirectVertexShaderSrc =
- "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"
- "void main()\n"
- "{\n"
- " gl_Position = View * Position;\n"
- " oTexCoord = TexCoord;\n"
- " oColor = Color;\n"
- " oNormal = vec3(View * vec4(Normal,0));\n"
- "}\n";
-
-static const char* SolidFragShaderSrc =
- "uniform vec4 Color;\n"
- "void main()\n"
- "{\n"
- " gl_FragColor = Color;\n"
- "}\n";
-
-static const char* GouraudFragShaderSrc =
- "varying vec4 oColor;\n"
- "void main()\n"
- "{\n"
- " gl_FragColor = oColor;\n"
- "}\n";
-
-static const char* TextureFragShaderSrc =
- "uniform sampler2D Texture0;\n"
- "varying vec4 oColor;\n"
- "varying vec2 oTexCoord;\n"
- "void main()\n"
- "{\n"
- " gl_FragColor = oColor * texture2D(Texture0, oTexCoord);\n"
- " if (gl_FragColor.a < 0.4)\n"
- " discard;\n"
- "}\n";
-
-#define LIGHTING_COMMON \
- "uniform vec3 Ambient;\n" \
- "uniform vec4 LightPos[8];\n" \
- "uniform vec4 LightColor[8];\n" \
- "uniform float LightCount;\n" \
- "varying vec4 oColor;\n" \
- "varying vec2 oTexCoord;\n" \
- "varying vec3 oNormal;\n" \
- "varying vec3 oVPos;\n" \
- "vec4 DoLight()\n" \
- "{\n" \
- " vec3 norm = normalize(oNormal);\n" \
- " vec3 light = Ambient;\n" \
- " for (int i = 0; i < int(LightCount); i++)\n" \
- " {\n" \
- " vec3 ltp = (LightPos[i].xyz - oVPos);\n" \
- " float ldist = length(ltp);\n" \
- " ltp = normalize(ltp);\n" \
- " light += clamp(LightColor[i].rgb * oColor.rgb * (dot(norm, ltp) / ldist), 0.0,1.0);\n" \
- " }\n" \
- " return vec4(light, oColor.a);\n" \
- "}\n"
-
-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
- "void main()\n"
- "{\n"
- " gl_FragColor = DoLight() * texture2D(Texture0, oTexCoord);\n"
- "}\n";
-
-static const char* PostProcessVertexShaderSrc =
- "uniform mat4 View;\n"
- "uniform mat4 Texm;\n"
- "attribute vec4 Position;\n"
- "attribute vec2 TexCoord;\n"
- "varying vec2 oTexCoord;\n"
- "void main()\n"
- "{\n"
- " gl_Position = View * Position;\n"
- " oTexCoord = vec2(Texm * vec4(TexCoord,0,1));\n"
- " oTexCoord.y = 1.0-oTexCoord.y;\n"
- "}\n";
-
-static const char* PostProcessFragShaderSrc =
- "uniform vec2 LensCenter;\n"
- "uniform vec2 ScreenCenter;\n"
- "uniform vec2 Scale;\n"
- "uniform vec2 ScaleIn;\n"
- "uniform vec4 HmdWarpParam;\n"
- "uniform sampler2D Texture0;\n"
- "varying vec2 oTexCoord;\n"
- "\n"
- "vec2 HmdWarp(vec2 in01)\n"
- "{\n"
- " vec2 theta = (in01 - LensCenter) * ScaleIn;\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 + Scale * theta1;\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(Texture0, tc);\n"
- "}\n";
-
-// Shader with lens distortion and chromatic aberration correction.
-static const char* PostProcessFullFragShaderSrc =
- "uniform vec2 LensCenter;\n"
- "uniform vec2 ScreenCenter;\n"
- "uniform vec2 Scale;\n"
- "uniform vec2 ScaleIn;\n"
- "uniform vec4 HmdWarpParam;\n"
- "uniform vec4 ChromAbParam;\n"
- "uniform sampler2D Texture0;\n"
- "varying vec2 oTexCoord;\n"
- "\n"
- // Scales input texture coordinates for distortion.
- // ScaleIn maps texture coordinates to Scales to ([-1, 1]), although top/bottom will be
- // larger due to aspect ratio.
- "void main()\n"
- "{\n"
- " vec2 theta = (oTexCoord - LensCenter) * ScaleIn;\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"
- " \n"
- " // Detect whether blue texture coordinates are out of range since these will scaled out the furthest.\n"
- " vec2 thetaBlue = theta1 * (ChromAbParam.z + ChromAbParam.w * rSq);\n"
- " vec2 tcBlue = LensCenter + Scale * thetaBlue;\n"
- " if (!all(equal(clamp(tcBlue, ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)), tcBlue)))\n"
- " {\n"
- " gl_FragColor = vec4(0);\n"
- " return;\n"
- " }\n"
- " \n"
- " // Now do blue texture lookup.\n"
- " float blue = texture2D(Texture0, tcBlue).b;\n"
- " \n"
- " // Do green lookup (no scaling).\n"
- " vec2 tcGreen = LensCenter + Scale * theta1;\n"
- " vec4 center = texture2D(Texture0, tcGreen);\n"
- " \n"
- " // Do red scale and lookup.\n"
- " vec2 thetaRed = theta1 * (ChromAbParam.x + ChromAbParam.y * rSq);\n"
- " vec2 tcRed = LensCenter + Scale * thetaRed;\n"
- " float red = texture2D(Texture0, tcRed).r;\n"
- " \n"
- " gl_FragColor = vec4(red, center.g, blue, 1);\n"
- "}\n";
-
-static const char* VShaderSrcs[VShader_Count] =
-{
- DirectVertexShaderSrc,
- StdVertexShaderSrc,
- PostProcessVertexShaderSrc
-};
-static const char* FShaderSrcs[FShader_Count] =
-{
- SolidFragShaderSrc,
- GouraudFragShaderSrc,
- TextureFragShaderSrc,
- PostProcessFragShaderSrc,
- PostProcessFullFragShaderSrc,
- LitSolidFragShaderSrc,
- LitTextureFragShaderSrc
-};
-
-
-
-RenderDevice::RenderDevice(const RendererParams& p)
-{
- for (int i = 0; i < VShader_Count; i++)
- VertexShaders[i] = *new Shader(this, Shader_Vertex, VShaderSrcs[i]);
-
- for (int i = 0; i < FShader_Count; i++)
- 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);
-}
-
-Shader *RenderDevice::LoadBuiltinShader(ShaderStage stage, int shader)
-{
- switch (stage)
- {
- case Shader_Vertex: return VertexShaders[shader];
- case Shader_Fragment: return FragShaders[shader];
- default:
- return NULL;
- }
-}
-
-
-void RenderDevice::BeginRendering()
-{
- 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)
-{
- if (enable)
- {
- glEnable(GL_DEPTH_TEST);
- glDepthMask(write);
- switch (func)
- {
- case Compare_Always: glDepthFunc(GL_ALWAYS); break;
- case Compare_Less: glDepthFunc(GL_LESS); break;
- case Compare_Greater: glDepthFunc(GL_GREATER); break;
- default: assert(0);
- }
- }
- else
- glDisable(GL_DEPTH_TEST);
-}
-
-void RenderDevice::SetRealViewport(const Viewport& 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);
-}
-
-void RenderDevice::Clear(float r, float g, float b, float a, float depth)
-{
- glClearColor(r,g,b,a);
- glClearDepth(depth);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-}
-
-RBuffer* RenderDevice::GetDepthBuffer(int w, int h, int ms)
-{
- for (unsigned i = 0; i < DepthBuffers.GetSize(); i++)
- if (w == DepthBuffers[i]->Width && h == DepthBuffers[i]->Height)// && ms == DepthBuffers[i]->Samples)
- return DepthBuffers[i];
-
- //Ptr<Texture> newDepth = *CreateTexture(Texture_Depth|Texture_RenderTarget|ms, w, h, NULL);
- Ptr<RBuffer> newDepth = *new RBuffer(GL_DEPTH24_STENCIL8, w, h); // combined depth stencil
- DepthBuffers.PushBack(newDepth);
- return newDepth.GetPtr();
-}
-
-void RenderDevice::SetRenderTarget(RenderTiny::Texture* color, RenderTiny::Texture*, RenderTiny::Texture* stencil)
-{
- OVR_UNUSED(stencil);
-
- CurRenderTarget = (Texture*)color;
- if (color == NULL)
- {
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- return;
- }
- //if (depth == NULL)
- RBuffer* depth = GetDepthBuffer(color->GetWidth(), color->GetHeight(), 0); //CurRenderTarget->Samples);
-
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, CurrentFbo);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, ((Texture*)color)->TexId, 0);
- if (depth)
- //glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, ((Texture*)depth)->TexId, 0);
- glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, ((RBuffer*)depth)->BufId);
- else
- glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
-
- GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
- if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
- OVR_DEBUG_LOG(("framebuffer not complete: %x", status));
-}
-
-
-void RenderDevice::SetWorldUniforms(const Matrix4f& proj)
-{
- Proj = proj.Transposed();
-}
-
-void RenderDevice::SetTexture(RenderTiny::ShaderStage, int slot, const Texture* t)
-{
- glActiveTexture(GL_TEXTURE0 + slot);
- glBindTexture(GL_TEXTURE_2D, ((Texture*)t)->TexId);
- glActiveTexture(GL_TEXTURE0);
-}
-
-Buffer* RenderDevice::CreateBuffer()
-{
- return new Buffer(this);
-}
-
-void RenderDevice::Render(const Matrix4f& matrix, Model* model)
-{
- // Store data in buffers if not already
- if (!model->VertexBuffer)
- {
- Ptr<RenderTiny::Buffer> vb = *CreateBuffer();
- vb->Data(Buffer_Vertex, &model->Vertices[0], model->Vertices.GetSize() * sizeof(Vertex));
- model->VertexBuffer = vb;
- }
- if (!model->IndexBuffer)
- {
- Ptr<RenderTiny::Buffer> ib = *CreateBuffer();
- ib->Data(Buffer_Index, &model->Indices[0], model->Indices.GetSize() * 2);
- model->IndexBuffer = ib;
- }
-
- Render(model->Fill ? (const ShaderFill*)model->Fill : (const ShaderFill*)DefaultFill,
- model->VertexBuffer, model->IndexBuffer,
- matrix, 0, (int)model->Indices.GetSize(), model->GetPrimType());
-}
-
-void RenderDevice::Render(const ShaderFill* fill, RenderTiny::Buffer* vertices, RenderTiny::Buffer* indices,
- const Matrix4f& matrix, int offset, int count, PrimitiveType rprim)
-{
- ShaderSet* shaders = (ShaderSet*) ((ShaderFill*)fill)->GetShaders();
-
- GLenum prim;
- switch (rprim)
- {
- case Prim_Triangles:
- prim = GL_TRIANGLES;
- break;
- case Prim_Lines:
- prim = GL_LINES;
- break;
- case Prim_TriangleStrip:
- prim = GL_TRIANGLE_STRIP;
- break;
- default:
- assert(0);
- return;
- }
-
- fill->Set();
- if (shaders->ProjLoc >= 0)
- glUniformMatrix4fv(shaders->ProjLoc, 1, 0, &Proj.M[0][0]);
- if (shaders->ViewLoc >= 0)
- glUniformMatrix4fv(shaders->ViewLoc, 1, 0, &matrix.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 < 4; i++)
- glEnableVertexAttribArray(i);
-
- 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, 3, GL_FLOAT, false, sizeof(Vertex), (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
- {
- glDrawArrays(prim, 0, count);
- }
-
- for (int i = 0; i < 4; i++)
- glDisableVertexAttribArray(i);
-}
-
-void RenderDevice::SetLighting(const LightingParams* lt)
-{
- Lighting = lt;
-}
-
-Buffer::~Buffer()
-{
- if (GLBuffer)
- glDeleteBuffers(1, &GLBuffer);
-}
-
-bool Buffer::Data(int use, const void* buffer, size_t size)
-{
- switch (use & Buffer_TypeMask)
- {
- case Buffer_Index: Use = GL_ELEMENT_ARRAY_BUFFER; break;
- default: Use = GL_ARRAY_BUFFER; break;
- }
-
- if (!GLBuffer)
- glGenBuffers(1, &GLBuffer);
-
- int mode = GL_DYNAMIC_DRAW;
- if (use & Buffer_ReadOnly)
- mode = GL_STATIC_DRAW;
-
- glBindBuffer(Use, GLBuffer);
- glBufferData(Use, size, buffer, mode);
- glBindBuffer(Use, 0);
- return 1;
-}
-
-void* Buffer::Map(size_t start, size_t size, int flags)
-{
- int mode = GL_WRITE_ONLY;
- //if (flags & Map_Unsynchronized)
- // mode |= GL_MAP_UNSYNCHRONIZED;
-
- glBindBuffer(Use, GLBuffer);
- void* v = glMapBuffer(Use, mode);
- glBindBuffer(Use, 0);
- return v;
-}
-
-bool Buffer::Unmap(void*)
-{
- glBindBuffer(Use, GLBuffer);
- int r = glUnmapBuffer(Use);
- glBindBuffer(Use, 0);
- return r;
-}
-
-bool Shader::Compile(const char* src)
-{
- if (!GLShader)
- GLShader = glCreateShader(GLStage());
-
- glShaderSource(GLShader, 1, &src, 0);
- glCompileShader(GLShader);
- GLint r;
- glGetShaderiv(GLShader, GL_COMPILE_STATUS, &r);
- if (!r)
- {
- GLchar msg[1024];
- glGetShaderInfoLog(GLShader, sizeof(msg), 0, msg);
- if (msg[0])
- OVR_DEBUG_LOG(("Compiling shader\n%s\nfailed: %s\n", src, msg));
- if (!r)
- return 0;
- }
- return 1;
-}
-
-ShaderSet::ShaderSet()
-{
- Prog = glCreateProgram();
-}
-ShaderSet::~ShaderSet()
-{
- glDeleteProgram(Prog);
-}
-
-bool ShaderSet::Link()
-{
- glBindAttribLocation(Prog, 0, "Position");
- glBindAttribLocation(Prog, 1, "Color");
- glBindAttribLocation(Prog, 2, "TexCoord");
- glBindAttribLocation(Prog, 3, "Normal");
-
- glLinkProgram(Prog);
- GLint r;
- glGetProgramiv(Prog, GL_LINK_STATUS, &r);
- if (!r)
- {
- GLchar msg[1024];
- glGetProgramInfoLog(Prog, sizeof(msg), 0, msg);
- OVR_DEBUG_LOG(("Linking shaders failed: %s\n", msg));
- if (!r)
- return 0;
- }
- glUseProgram(Prog);
-
- UniformInfo.Clear();
- LightingVer = 0;
- UsesLighting = 0;
- GLuint i = 0;
- for(;; i++)
- {
- GLsizei namelen;
- GLint size = 0;
- GLenum type;
- GLchar name[32];
- glGetActiveUniform(Prog, i, sizeof(name), &namelen, &size, &type, name);
- if (size)
- {
- int l = glGetUniformLocation(Prog, name);
- char *np = name;
- while (*np)
- {
- if (*np == '[')
- *np = 0;
- np++;
- }
- Uniform u;
- u.Name = name;
- u.Location = l;
- u.Size = size;
- switch (type)
- {
- case GL_FLOAT: u.Type = 1; break;
- case GL_FLOAT_VEC2: u.Type = 2; break;
- case GL_FLOAT_VEC3: u.Type = 3; break;
- case GL_FLOAT_VEC4: u.Type = 4; break;
- case GL_FLOAT_MAT4: u.Type = 16; break;
- default:
- continue;
- }
- UniformInfo.PushBack(u);
- if (!strcmp(name, "LightCount"))
- UsesLighting = 1;
- }
- else
- break;
- }
-
- ProjLoc = glGetUniformLocation(Prog, "Proj");
- ViewLoc = glGetUniformLocation(Prog, "View");
- for (int i = 0; i < 8; i++)
- {
- char texv[32];
- sprintf(texv, "Texture%d", i);
- TexLoc[i] = glGetUniformLocation(Prog, texv);
- if (TexLoc[i] < 0)
- break;
-
- glUniform1i(TexLoc[i], i);
- }
- if (UsesLighting)
- OVR_ASSERT(ProjLoc >= 0 && ViewLoc >= 0);
- return 1;
-}
-
-void ShaderSet::Set(PrimitiveType) const
-{
- glUseProgram(Prog);
-}
-
-bool ShaderSet::SetUniform(const char* name, int n, const float* v)
-{
- for (int i = 0; i < UniformInfo.GetSize(); i++)
- if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
- {
- OVR_ASSERT(UniformInfo[i].Location >= 0);
- glUseProgram(Prog);
- switch (UniformInfo[i].Type)
- {
- case 1: glUniform1fv(UniformInfo[i].Location, n, v); break;
- case 2: glUniform2fv(UniformInfo[i].Location, n/2, v); break;
- case 3: glUniform3fv(UniformInfo[i].Location, n/3, v); break;
- case 4: glUniform4fv(UniformInfo[i].Location, n/4, v); break;
- default: OVR_ASSERT(0);
- }
- return 1;
- }
-
- OVR_DEBUG_LOG(("Warning: uniform %s not present in selected shader", name));
- return 0;
-}
-
-bool ShaderSet::SetUniform4x4f(const char* name, const Matrix4f& m)
-{
- for (int i = 0; i < UniformInfo.GetSize(); i++)
- if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
- {
- glUseProgram(Prog);
- glUniformMatrix4fv(UniformInfo[i].Location, 1, 1, &m.M[0][0]);
- return 1;
- }
-
- OVR_DEBUG_LOG(("Warning: uniform %s not present in selected shader", name));
- return 0;
-}
-
-Texture::Texture(RenderDevice* r, int w, int h) : Ren(r), Width(w), Height(h)
-{
- glGenTextures(1, &TexId);
-}
-
-Texture::~Texture()
-{
- if (TexId)
- glDeleteTextures(1, &TexId);
-}
-
-void Texture::Set(int slot, RenderTiny::ShaderStage stage) const
-{
- Ren->SetTexture(stage, slot, this);
-}
-
-void Texture::SetSampleMode(int sm)
-{
- glBindTexture(GL_TEXTURE_2D, TexId);
- switch (sm & Sample_FilterMask)
- {
- case Sample_Linear:
- 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, 0);
- break;
-
- 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);
- break;
-
- case Sample_Nearest:
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0);
- break;
- }
-
- switch (sm & Sample_AddressMask)
- {
- case Sample_Repeat:
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- break;
-
- case Sample_Clamp:
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- break;
-
- case Sample_ClampBorder:
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
- break;
- }
- glBindTexture(GL_TEXTURE_2D, 0);
-}
-
-Texture* RenderDevice::CreateTexture(int format, int width, int height, const void* data, int mipcount)
-{
- GLenum glformat, gltype = GL_UNSIGNED_BYTE;
- switch(format & Texture_TypeMask)
- {
- case Texture_RGBA: glformat = GL_RGBA; break;
- case Texture_Depth: glformat = GL_DEPTH; gltype = GL_DEPTH_COMPONENT; break;
- default:
- return NULL;
- }
- Texture* NewTex = new Texture(this, width, height);
- glBindTexture(GL_TEXTURE_2D, NewTex->TexId);
- glGetError();
-
- glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, glformat, gltype, data);
- OVR_ASSERT(!glGetError());
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- if (format == (Texture_RGBA|Texture_GenMipmaps)) // not render target
- {
- int srcw = width, srch = height;
- int level = 0;
- UByte* mipmaps = NULL;
- do
- {
- level++;
- int mipw = srcw >> 1; if (mipw < 1) mipw = 1;
- int miph = srch >> 1; if (miph < 1) miph = 1;
- if (mipmaps == NULL)
- mipmaps = (UByte*)OVR_ALLOC(mipw * miph * 4);
- FilterRgba2x2(level == 1 ? (const UByte*)data : mipmaps, srcw, srch, mipmaps);
- glTexImage2D(GL_TEXTURE_2D, level, glformat, mipw, miph, 0, glformat, gltype, mipmaps);
- OVR_ASSERT(!glGetError());
- srcw = mipw;
- srch = miph;
- } while (srcw > 1 || srch > 1);
- if (mipmaps)
- OVR_FREE(mipmaps);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
- OVR_ASSERT(!glGetError());
- }
- else
- {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipcount-1);
- OVR_ASSERT(!glGetError());
- }
-
- OVR_ASSERT(!glGetError());
- glBindTexture(GL_TEXTURE_2D, 0);
- return NewTex;
-}
-
-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);
-}
-
-RBuffer::~RBuffer()
-{
- glDeleteRenderbuffersEXT(1, &BufId);
-}
-
-}}}
diff --git a/Samples/OculusRoomTiny/RenderTiny_GL_Device.h b/Samples/OculusRoomTiny/RenderTiny_GL_Device.h
deleted file mode 100644
index 5d88180..0000000
--- a/Samples/OculusRoomTiny/RenderTiny_GL_Device.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/************************************************************************************
-
-Filename : RenderTiny_GL_Device.h
-Content : RenderDevice implementation header for OpenGL (tiny version)
-Created : September 10, 2012
-Authors : Andrew Reisse, Artem Bolgar
-
-Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#ifndef OVR_Render_GL_Device_h
-#define OVR_Render_GL_Device_h
-
-#include "RenderTiny_Device.h"
-
-#if defined(OVR_OS_WIN32)
-#include <Windows.h>
-#endif
-
-#if defined(OVR_OS_MAC)
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-#else
-#define GL_GLEXT_PROTOTYPES
-#include <GL/gl.h>
-#include <GL/glext.h>
-#endif
-
-namespace OVR { namespace RenderTiny { namespace GL {
-
-class RenderDevice;
-
-class Buffer : public RenderTiny::Buffer
-{
-public:
- RenderDevice* Ren;
- size_t Size;
- GLenum Use;
- GLuint GLBuffer;
-
-public:
- Buffer(RenderDevice* r) : Ren(r), Size(0), Use(0), GLBuffer(0) {}
- ~Buffer();
-
- GLuint GetBuffer() { return GLBuffer; }
-
- virtual size_t GetSize() { return Size; }
- virtual void* Map(size_t start, size_t size, int flags = 0);
- virtual bool Unmap(void *m);
- virtual bool Data(int use, const void* buffer, size_t size);
-};
-
-class Texture : public RenderTiny::Texture
-{
-public:
- RenderDevice* Ren;
- GLuint TexId;
- int Width, Height;
-
- Texture(RenderDevice* r, int w, int h);
- ~Texture();
-
- virtual int GetWidth() const { return Width; }
- virtual int GetHeight() const { return Height; }
-
- virtual void SetSampleMode(int);
-
- virtual void Set(int slot, ShaderStage stage = Shader_Fragment) const;
-};
-
-class Shader : public RenderTiny::Shader
-{
-public:
- GLuint GLShader;
-
- Shader(RenderDevice*, ShaderStage st, GLuint s) : RenderTiny::Shader(st), GLShader(s) {}
- Shader(RenderDevice*, ShaderStage st, const char* src) : RenderTiny::Shader(st), GLShader(0)
- {
- Compile(src);
- }
- ~Shader()
- {
- if (GLShader)
- glDeleteShader(GLShader);
- }
- bool Compile(const char* src);
-
- GLenum GLStage() const
- {
- switch (Stage)
- {
- default: OVR_ASSERT(0); return GL_NONE;
- case Shader_Vertex: return GL_VERTEX_SHADER;
- case Shader_Fragment: return GL_FRAGMENT_SHADER;
- }
- }
-
- //void Set(PrimitiveType prim) const;
- //void SetUniformBuffer(Render::Buffer* buffers, int i = 0);
-};
-
-class ShaderSet : public RenderTiny::ShaderSet
-{
-public:
- GLuint Prog;
-
- struct Uniform
- {
- String Name;
- int Location, Size;
- int Type; // currently number of floats in vector
- };
- Array<Uniform> UniformInfo;
-
- int ProjLoc, ViewLoc;
- int TexLoc[8];
- bool UsesLighting;
- int LightingVer;
-
- ShaderSet();
- ~ShaderSet();
-
- virtual void SetShader(RenderTiny::Shader *s)
- {
- Shaders[s->GetStage()] = s;
- Shader* gls = (Shader*)s;
- glAttachShader(Prog, gls->GLShader);
- if (Shaders[Shader_Vertex] && Shaders[Shader_Fragment])
- Link();
- }
- virtual void UnsetShader(int stage)
- {
- Shader* gls = (Shader*)(RenderTiny::Shader*)Shaders[stage];
- if (gls)
- glDetachShader(Prog, gls->GLShader);
- Shaders[stage] = NULL;
- Link();
- }
-
- virtual void Set(PrimitiveType prim) const;
-
- // Set a uniform (other than the standard matrices). It is undefined whether the
- // uniforms from one shader occupy the same space as those in other shaders
- // (unless a buffer is used, then each buffer is independent).
- virtual bool SetUniform(const char* name, int n, const float* v);
- virtual bool SetUniform4x4f(const char* name, const Matrix4f& m);
-
- bool Link();
-};
-
- class RBuffer : public RefCountBase<RBuffer>
-{
- public:
- int Width, Height;
- GLuint BufId;
-
- RBuffer(GLenum format, GLint w, GLint h);
- ~RBuffer();
-};
-
-class RenderDevice : public RenderTiny::RenderDevice
-{
- Ptr<Shader> VertexShaders[VShader_Count];
- Ptr<Shader> FragShaders[FShader_Count];
-
- Ptr<ShaderFill> DefaultFill;
-
- Matrix4f Proj;
-
- Ptr<Texture> CurRenderTarget;
- Array<Ptr<RBuffer> > DepthBuffers;
- GLuint CurrentFbo;
-
- const LightingParams* Lighting;
-
-
-public:
- RenderDevice(const RendererParams& p);
-
- virtual void SetRealViewport(const Viewport& vp);
-
- //virtual void SetScissor(int x, int y, int w, int h);
-
- virtual void Clear(float r = 0, float g = 0, float b = 0, float a = 1, float depth = 1);
- virtual void Rect(float left, float top, float right, float bottom) { OVR_UNUSED4(left,top,right,bottom); }
-
- virtual void BeginRendering();
- virtual void SetDepthMode(bool enable, bool write, CompareFunc func = Compare_Less);
- virtual void SetWorldUniforms(const Matrix4f& proj);
-
- RBuffer* GetDepthBuffer(int w, int h, int ms);
-
- virtual void SetRenderTarget(RenderTiny::Texture* color,
- RenderTiny::Texture* depth = NULL, RenderTiny::Texture* stencil = NULL);
-
- virtual void SetLighting(const LightingParams* lt);
-
- virtual void Render(const Matrix4f& matrix, Model* model);
- virtual void Render(const ShaderFill* fill, RenderTiny::Buffer* vertices, RenderTiny::Buffer* indices,
- const Matrix4f& matrix, int offset, int count, PrimitiveType prim = Prim_Triangles);
-
- virtual Buffer* CreateBuffer();
- virtual Texture* CreateTexture(int format, int width, int height, const void* data, int mipcount=1);
- virtual ShaderSet* CreateShaderSet() { return new ShaderSet; }
-
- virtual ShaderFill *CreateSimpleFill() { return DefaultFill; }
-
- virtual Shader *LoadBuiltinShader(ShaderStage stage, int shader);
-
- void SetTexture(RenderTiny::ShaderStage, int slot, const Texture* t);
-};
-
-}}}
-
-#endif
diff --git a/Samples/OculusRoomTiny/Win32_DistortionMesh.cpp b/Samples/OculusRoomTiny/Win32_DistortionMesh.cpp
new file mode 100644
index 0000000..3356467
--- /dev/null
+++ b/Samples/OculusRoomTiny/Win32_DistortionMesh.cpp
@@ -0,0 +1,244 @@
+/************************************************************************************
+
+Filename : Win32_DistortionMesh.cpp
+Content : Manual creation and rendering of a distortion mesh
+Created : March 5, 2014
+Authors : Tom Heath, Volga Aksoy
+Copyright : Copyright 2012 Oculus, Inc. All Rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*************************************************************************************/
+
+//-----------------------------------------------------------------------------------
+// If we decide to do our own rendering, then we need to make sure that
+// we are creating the distortion mesh manually using the data provided by the LibOVR SDK
+
+#include "OVR_CAPI.h"
+#include "RenderTiny_D3D11_Device.h"
+
+//-----------------------------------------------------------------------------------
+
+// Contains render data required to render the distortion mesh with the proper shaders
+// NOTE: For *demostration purposes*, the C-style functions in Win32_OculusRoomTiny.cpp
+// actually render the distortion mesh, while this struct only stores the data in a logical group
+struct DistortionRenderData
+{
+ ShaderSet * Shaders;
+ ID3D11InputLayout * VertexIL;
+ Vector2f UVScaleOffset[2][2];
+ Ptr<Buffer> MeshVBs[2];
+ Ptr<Buffer> MeshIBs[2];
+} DistortionData;
+
+//Format for mesh and shaders
+struct DistortionVertex
+{
+ Vector2f Pos;
+ Vector2f TexR;
+ Vector2f TexG;
+ Vector2f TexB;
+ Color Col;
+};
+static D3D11_INPUT_ELEMENT_DESC DistortionMeshVertexDesc[] =
+{
+ {"Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"TexCoord", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"TexCoord", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"TexCoord", 2, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0},
+};
+
+
+
+void DistortionMeshInit(unsigned distortionCaps, ovrHmd HMD,
+ ovrEyeRenderDesc eyeRenderDesc[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);
+
+ // Now parse the vertex data and create a render ready vertex buffer from it
+ DistortionVertex * pVBVerts = (DistortionVertex*)OVR_ALLOC(
+ sizeof(DistortionVertex) * meshData.VertexCount );
+ DistortionVertex * v = pVBVerts;
+ ovrDistortionVertex * ov = meshData.pVertexData;
+ for ( unsigned vertNum = 0; vertNum < meshData.VertexCount; vertNum++ )
+ {
+ v->Pos.x = ov->Pos.x;
+ v->Pos.y = ov->Pos.y;
+ v->TexR = (*(Vector2f*)&ov->TexR);
+ v->TexG = (*(Vector2f*)&ov->TexG);
+ v->TexB = (*(Vector2f*)&ov->TexB);
+ v->Col.R = v->Col.G = v->Col.B = (OVR::UByte)( ov->VignetteFactor * 255.99f );
+ v->Col.A = (OVR::UByte)( ov->TimeWarpFactor * 255.99f );
+ v++; ov++;
+ }
+ //Register this mesh with the renderer
+ DistortionData.MeshVBs[eyeNum] = *pRender->CreateBuffer();
+ DistortionData.MeshVBs[eyeNum]->Data ( Buffer_Vertex, pVBVerts,
+ sizeof(DistortionVertex) * meshData.VertexCount );
+ DistortionData.MeshIBs[eyeNum] = *pRender->CreateBuffer();
+ DistortionData.MeshIBs[eyeNum]->Data ( Buffer_Index, meshData.pIndexData,
+ sizeof(unsigned short) * meshData.IndexCount );
+
+ OVR_FREE ( pVBVerts );
+ ovrHmd_DestroyDistortionMesh( &meshData );
+ }
+
+ // Pixel shader for the mesh
+ //-------------------------------------------------------------------------------------------
+ const char* pixelShader =
+ "Texture2D Texture : register(t0); \n"
+ "SamplerState Linear : register(s0); \n"
+
+ "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR, \n"
+ " in float2 oTexCoord0 : TEXCOORD0, in float2 oTexCoord1 : TEXCOORD1, \n"
+ " in float2 oTexCoord2 : TEXCOORD2) : SV_Target \n"
+ "{ \n"
+ // 3 samples for fixing chromatic aberrations
+ " float ResultR = Texture.Sample(Linear, oTexCoord0.xy).r; \n"
+ " float ResultG = Texture.Sample(Linear, oTexCoord1.xy).g; \n"
+ " float ResultB = Texture.Sample(Linear, oTexCoord2.xy).b; \n"
+ " return float4(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor.b, 1.0); \n"
+ "}";
+
+
+ // Choose the vertex shader, according to if you have timewarp enabled
+ if (distortionCaps & ovrDistortion_TimeWarp)
+ { // TIMEWARP
+ //--------------------------------------------------------------------------------------------
+ const char* vertexShader =
+ "float2 EyeToSourceUVScale; \n"
+ "float2 EyeToSourceUVOffset; \n"
+ "float4x4 EyeRotationStart; \n"
+ "float4x4 EyeRotationEnd; \n"
+ "float2 TimewarpTexCoord(float2 TexCoord, float4x4 rotMat) \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 3x3 timewarp rotation to these vectors.
+ " float3 transformed = float3( mul ( rotMat, float4(TexCoord.xy, 1, 1) ).xyz); \n"
+ // Project them back onto the Z=1 plane of the rendered images.
+ " float2 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)
+ " return(EyeToSourceUVScale * flattened + EyeToSourceUVOffset); \n"
+ "} \n"
+ "void main(in float2 Position : POSITION, in float4 Color : COLOR0, \n"
+ " in float2 TexCoord0 : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1, \n"
+ " in float2 TexCoord2 : TEXCOORD2, \n"
+ " out float4 oPosition : SV_Position, out float4 oColor : COLOR, \n"
+ " out float2 oTexCoord0 : TEXCOORD0, out float2 oTexCoord1 : TEXCOORD1, \n"
+ " out float2 oTexCoord2 : TEXCOORD2) \n"
+ "{ \n"
+ " float timewarpLerpFactor = Color.a; \n"
+ " float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, timewarpLerpFactor);\n"
+ " oTexCoord0 = TimewarpTexCoord(TexCoord0,lerpedEyeRot); \n"
+ " oTexCoord1 = TimewarpTexCoord(TexCoord1,lerpedEyeRot); \n"
+ " oTexCoord2 = TimewarpTexCoord(TexCoord2,lerpedEyeRot); \n"
+ " oPosition = float4(Position.xy, 0.5, 1.0); \n"
+ " oColor = Color.r; /*For vignette fade*/ \n"
+ "}";
+
+ pRender->InitShaders(vertexShader, pixelShader, &DistortionData.Shaders,
+ &DistortionData.VertexIL,DistortionMeshVertexDesc,5);
+ }
+ else
+ {
+ //-------------------------------------------------------------------------------------------
+ const char* vertexShader =
+ "float2 EyeToSourceUVScale; \n"
+ "float2 EyeToSourceUVOffset; \n"
+ "void main(in float2 Position : POSITION, in float4 Color : COLOR0, \n"
+ " in float2 TexCoord0 : TEXCOORD0, in float2 TexCoord1 : TEXCOORD1, \n"
+ " in float2 TexCoord2 : TEXCOORD2, \n"
+ " out float4 oPosition : SV_Position, out float4 oColor : COLOR, \n"
+ " out float2 oTexCoord0 : TEXCOORD0, out float2 oTexCoord1 : TEXCOORD1, \n"
+ " out float2 oTexCoord2 : TEXCOORD2) \n"
+ "{ \n"
+ // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye)
+ " oTexCoord0 = EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset; \n"
+ " oTexCoord1 = EyeToSourceUVScale * TexCoord1 + EyeToSourceUVOffset; \n"
+ " oTexCoord2 = EyeToSourceUVScale * TexCoord2 + EyeToSourceUVOffset; \n"
+ " oPosition = float4(Position.xy, 0.5, 1.0); \n"
+ " oColor = Color.r; /*For vignette fade*/ \n"
+ "}";
+
+ pRender->InitShaders(vertexShader, pixelShader, &DistortionData.Shaders,
+ &DistortionData.VertexIL,DistortionMeshVertexDesc,5);
+ }
+}
+
+
+void DistortionMeshRender(unsigned distortionCaps, ovrHmd HMD,
+ double timwarpTimePoint, ovrPosef eyeRenderPoses[2],
+ RenderDevice* pRender, Texture* pRendertargetTexture)
+{
+ if (distortionCaps & ovrDistortion_TimeWarp)
+ { // TIMEWARP
+ // Wait till time-warp to reduce latency.
+ ovr_WaitTillTime(timwarpTimePoint);
+ }
+
+ // Clear screen
+ pRender->SetRenderTarget(NULL);
+ pRender->SetFullViewport();
+ pRender->Clear(0.0f, 0.0f, 0.0f, 0.0f);
+
+ // Setup shader
+ ShaderFill distortionShaderFill(DistortionData.Shaders);
+ distortionShaderFill.SetTexture(0, pRendertargetTexture);
+ distortionShaderFill.SetInputLayout(DistortionData.VertexIL);
+
+ for(int eyeNum = 0; eyeNum < 2; eyeNum++)
+ {
+ // Setup shader constants
+ DistortionData.Shaders->SetUniform2f("EyeToSourceUVScale",
+ DistortionData.UVScaleOffset[eyeNum][0].x, DistortionData.UVScaleOffset[eyeNum][0].y);
+ DistortionData.Shaders->SetUniform2f("EyeToSourceUVOffset",
+ DistortionData.UVScaleOffset[eyeNum][1].x, DistortionData.UVScaleOffset[eyeNum][1].y);
+
+ if (distortionCaps & ovrDistortion_TimeWarp)
+ { // TIMEWARP - Additional shader constants required
+ ovrMatrix4f timeWarpMatrices[2];
+ ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, eyeRenderPoses[eyeNum], timeWarpMatrices);
+ DistortionData.Shaders->SetUniform4x4f("EyeRotationStart", Matrix4f(timeWarpMatrices[0]));
+ DistortionData.Shaders->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1]));
+ }
+ // Perform distortion
+ pRender->Render(&distortionShaderFill,
+ DistortionData.MeshVBs[eyeNum], DistortionData.MeshIBs[eyeNum]);
+ }
+
+ pRender->SetRenderTarget(NULL);
+}
+
+
+void DistortionMeshRelease(void)
+{
+ for(int eyeNum = 0; eyeNum < 2; eyeNum++)
+ {
+ DistortionData.MeshVBs[eyeNum].Clear();
+ DistortionData.MeshIBs[eyeNum].Clear();
+ }
+ if (DistortionData.Shaders)
+ {
+ DistortionData.Shaders->UnsetShader(Shader_Vertex);
+ DistortionData.Shaders->UnsetShader(Shader_Pixel);
+ }
+}
+
diff --git a/Samples/OculusRoomTiny/Win32_OculusRoomTiny.cpp b/Samples/OculusRoomTiny/Win32_OculusRoomTiny.cpp
index c27723f..5300537 100644
--- a/Samples/OculusRoomTiny/Win32_OculusRoomTiny.cpp
+++ b/Samples/OculusRoomTiny/Win32_OculusRoomTiny.cpp
@@ -1,6 +1,6 @@
/************************************************************************************
-Filename : Win32_OculusRoomTiny.cpp
+Filename : Win32_OculusRoomTiny2.cpp
Content : First-person view test application for Oculus Rift
Created : October 4, 2012
Authors : Michael Antonov, Andrew Reisse
@@ -18,695 +18,273 @@ 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 "Win32_OculusRoomTiny.h"
-#include "RenderTiny_D3D1X_Device.h"
-
//-------------------------------------------------------------------------------------
-// ***** OculusRoomTiny Class
-
-// Static pApp simplifies routing the window function.
-OculusRoomTinyApp* OculusRoomTinyApp::pApp = 0;
-
-
-OculusRoomTinyApp::OculusRoomTinyApp(HINSTANCE hinst)
- : pRender(0),
- LastUpdate(0),
-
- // Win32
- hWnd(NULL),
- hInstance(hinst), Quit(0), MouseCaptured(true),
- hXInputModule(0), pXInputGetState(0),
-
- // Initial location
- EyePos(0.0f, 1.6f, -5.0f),
- EyeYaw(YawInitial), EyePitch(0), EyeRoll(0),
- LastSensorYaw(0),
- SConfig(),
- PostProcess(PostProcess_Distortion),
- ShiftDown(false),
- ControlDown(false)
-{
- pApp = this;
-
- Width = 1280;
- Height = 800;
-
- StartupTicks = OVR::Timer::GetTicks();
- LastPadPacketNo = 0;
+// This app renders a simple flat-shaded room allowing the user to move along the
+// floor and look around with an HMD and mouse/keyboard.
+// The following keys work:
+// 'W', 'S', 'A', 'D', 'F' - Move forward, back; strafe left/right, toggle freeze in timewarp.
+// The world right handed coordinate system is defined as Y -> Up, Z -> Back, X -> Right
+
+//Include the OculusVR SDK
+#include "OVR_CAPI.h"
+
+// ***** Choices and settings
+
+// Whether the SDK performs rendering/distortion, or the app.
+//#define SDK_RENDER 1
+
+const unsigned DistortionCaps = ovrDistortion_Chromatic | ovrDistortion_TimeWarp;
+const bool VSyncEnabled = true;
+const bool FullScreen = true;
+
+// Include Non-SDK supporting Utilities from other files
+#include "RenderTiny_D3D11_Device.h"
+
+RenderDevice * Util_InitWindowAndGraphics (Recti vp, int fullscreen, int multiSampleCount);
+void Util_ReleaseWindowAndGraphics (RenderDevice* pRender);
+bool Util_RespondToControls (float & EyeYaw, Vector3f & EyePos,
+ float deltaTime, Quatf PoseOrientation);
+void PopulateRoomScene (Scene* scene, RenderDevice* render);
+
+//Structures for the application
+ovrHmd HMD;
+ovrHmdDesc HMDDesc;
+ovrEyeRenderDesc EyeRenderDesc[2];
+RenderDevice* pRender;
+Texture* pRendertargetTexture;
+Scene* pRoomScene;
+
+// Specifics for whether the SDK or the app is doing the distortion.
+#if SDK_RENDER
+ #define OVR_D3D_VERSION 11
+ #include "OVR_CAPI_D3D.h"
+ ovrD3D11Texture EyeTexture[2];
+#else
+ void DistortionMeshInit (unsigned distortionCaps, ovrHmd HMD,
+ ovrEyeRenderDesc eyeRenderDesc[2], RenderDevice * pRender);
+ void DistortionMeshRender(unsigned distortionCaps, ovrHmd HMD,
+ double timwarpTimePoint, ovrPosef eyeRenderPoses[2],
+ RenderDevice * pRender, Texture* pRendertargetTexture);
+#endif
- MoveForward = MoveBack = MoveLeft = MoveRight = 0;
- GamepadMove = Vector3f(0);
- GamepadRotate = Vector3f(0);
-}
-
-OculusRoomTinyApp::~OculusRoomTinyApp()
-{
- RemoveHandlerFromDevices();
- pSensor.Clear();
- pHMD.Clear();
- destroyWindow();
- pApp = 0;
-}
-
+//-------------------------------------------------------------------------------------
-int OculusRoomTinyApp::OnStartup(const char* args)
+int Init()
{
- OVR_UNUSED(args);
-
-
- // *** Oculus HMD & Sensor Initialization
-
- // Create DeviceManager and first available HMDDevice from it.
- // Sensor object is created from the HMD, to ensure that it is on the
- // correct device.
-
- pManager = *DeviceManager::Create();
-
- // We'll handle it's messages in this case.
- pManager->SetMessageHandler(this);
-
-
- int detectionResult = IDCONTINUE;
- const char* detectionMessage;
+ // Initializes LibOVR.
+ ovr_Initialize();
- do
+ HMD = ovrHmd_Create(0);
+ if (!HMD)
{
- // Release Sensor/HMD in case this is a retry.
- pSensor.Clear();
- pHMD.Clear();
- RenderParams.MonitorName.Clear();
-
- pHMD = *pManager->EnumerateDevices<HMDDevice>().CreateDevice();
- if (pHMD)
- {
- pSensor = *pHMD->GetSensor();
-
- // This will initialize HMDInfo with information about configured IPD,
- // screen size and other variables needed for correct projection.
- // We pass HMD DisplayDeviceName into the renderer to select the
- // correct monitor in full-screen mode.
- if (pHMD->GetDeviceInfo(&HMDInfo))
- {
- RenderParams.MonitorName = HMDInfo.DisplayDeviceName;
- RenderParams.DisplayId = HMDInfo.DisplayId;
- SConfig.SetHMDInfo(HMDInfo);
- }
- }
- else
- {
- // If we didn't detect an HMD, try to create the sensor directly.
- // This is useful for debugging sensor interaction; it is not needed in
- // a shipping app.
- pSensor = *pManager->EnumerateDevices<SensorDevice>().CreateDevice();
- }
-
-
- // If there was a problem detecting the Rift, display appropriate message.
- detectionResult = IDCONTINUE;
-
- if (!pHMD && !pSensor)
- detectionMessage = "Oculus Rift not detected.";
- else if (!pHMD)
- detectionMessage = "Oculus Sensor detected; HMD Display not detected.";
- else if (!pSensor)
- detectionMessage = "Oculus HMD Display detected; Sensor not detected.";
- else if (HMDInfo.DisplayDeviceName[0] == '\0')
- detectionMessage = "Oculus Sensor detected; HMD display EDID not detected.";
- else
- detectionMessage = 0;
-
- if (detectionMessage)
- {
- String messageText(detectionMessage);
- messageText += "\n\n"
- "Press 'Try Again' to run retry detection.\n"
- "Press 'Continue' to run full-screen anyway.";
-
- detectionResult = ::MessageBoxA(0, messageText.ToCStr(), "Oculus Rift Detection",
- MB_CANCELTRYCONTINUE|MB_ICONWARNING);
-
- if (detectionResult == IDCANCEL)
- return 1;
- }
-
- } while (detectionResult != IDCONTINUE);
-
-
- if (HMDInfo.HResolution > 0)
- {
- Width = HMDInfo.HResolution;
- Height = HMDInfo.VResolution;
+ MessageBoxA(NULL,"Oculus Rift not detected.","", MB_OK);
+ return(1);
}
-
-
- if (!setupWindow())
- return 1;
-
- if (pSensor)
- {
- // We need to attach sensor to SensorFusion object for it to receive
- // body frame messages and update orientation. SFusion.GetOrientation()
- // is used in OnIdle() to orient the view.
- SFusion.AttachToSensor(pSensor);
- SFusion.SetDelegateMessageHandler(this);
- SFusion.SetPredictionEnabled(true);
- }
-
+ //Get more details about the HMD
+ ovrHmd_GetDesc(HMD, &HMDDesc);
+ if (HMDDesc.DisplayDeviceName[0] == '\0')
+ MessageBoxA(NULL,"Rift detected, display not enabled.","", MB_OK);
+
+ //Setup Window and Graphics
+ const int backBufferMultisample = 1;
+ pRender = Util_InitWindowAndGraphics(Recti(HMDDesc.WindowsPos, HMDDesc.Resolution),
+ FullScreen, backBufferMultisample);
+ if (!pRender) return 1;
+
+ //Configure Stereo settings.
+ Sizei recommenedTex0Size = ovrHmd_GetFovTextureSize(HMD, ovrEye_Left, HMDDesc.DefaultEyeFov[0], 1.0f);
+ Sizei recommenedTex1Size = ovrHmd_GetFovTextureSize(HMD, ovrEye_Right, HMDDesc.DefaultEyeFov[1], 1.0f);
+ Sizei RenderTargetSize;
+ RenderTargetSize.w = recommenedTex0Size.w + recommenedTex1Size.w;
+ RenderTargetSize.h = max ( recommenedTex0Size.h, recommenedTex1Size.h );
+
+ const int eyeRenderMultisample = 1;
+ pRendertargetTexture = pRender->CreateTexture(Texture_RGBA | Texture_RenderTarget |
+ eyeRenderMultisample,
+ RenderTargetSize.w, RenderTargetSize.h, NULL);
+ // The actual RT size may be different due to HW limits.
+ RenderTargetSize.w = pRendertargetTexture->GetWidth();
+ RenderTargetSize.h = pRendertargetTexture->GetHeight();
+
+ // 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;
+
+#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.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;
+
+ // Configure d3d11.
+ RenderDevice* render = (RenderDevice*)pRender;
+ ovrD3D11Config d3d11cfg;
+ d3d11cfg.D3D11.Header.API = ovrRenderAPI_D3D11;
+ d3d11cfg.D3D11.Header.RTSize = Sizei(HMDDesc.Resolution.w, HMDDesc.Resolution.h);
+ d3d11cfg.D3D11.Header.Multisample = backBufferMultisample;
+ d3d11cfg.D3D11.pDevice = render->Device;
+ d3d11cfg.D3D11.pDeviceContext = render->Context;
+ d3d11cfg.D3D11.pBackBufferRT = render->BackBufferRT;
+ d3d11cfg.D3D11.pSwapChain = render->SwapChain;
+
+ if (!ovrHmd_ConfigureRendering(HMD, &d3d11cfg.Config,
+ (VSyncEnabled ? 0 : ovrHmdCap_NoVSync), DistortionCaps,
+ eyes, EyeRenderDesc)) return(1);
+#else // !SDK_RENDER
+ EyeRenderDesc[0] = ovrHmd_GetRenderDesc(HMD, eyes[0]);
+ EyeRenderDesc[1] = ovrHmd_GetRenderDesc(HMD, eyes[1]);
- // *** Initialize Rendering
-
- // Enable multi-sampling by default.
- RenderParams.Multisample = 4;
- RenderParams.Fullscreen = true;
-
- // Setup Graphics.
- pRender = *RenderTiny::D3D10::RenderDevice::CreateDevice(RenderParams, (void*)hWnd);
- if (!pRender)
- return 1;
-
-
- // *** Configure Stereo settings.
-
- SConfig.SetFullViewport(Viewport(0,0, Width, Height));
- SConfig.SetStereoMode(Stereo_LeftRight_Multipass);
-
- // Configure proper Distortion Fit.
- // For 7" screen, fit to touch left side of the view, leaving a bit of invisible
- // screen on the top (saves on rendering cost).
- // For smaller screens (5.5"), fit to the top.
- if (HMDInfo.HScreenSize > 0.0f)
- {
- if (HMDInfo.HScreenSize > 0.140f) // 7"
- SConfig.SetDistortionFitPointVP(-1.0f, 0.0f);
- else
- SConfig.SetDistortionFitPointVP(0.0f, 1.0f);
- }
+ // Create our own distortion mesh and shaders
+ DistortionMeshInit(DistortionCaps, HMD, EyeRenderDesc, pRender);
+#endif
- pRender->SetSceneRenderScale(SConfig.GetDistortionScale());
-
- SConfig.Set2DAreaFov(DegreeToRad(85.0f));
-
-
- // *** Populate Room Scene
+ // 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);
// This creates lights and models.
- PopulateRoomScene(&Scene, pRender);
+ pRoomScene = new Scene;
+ PopulateRoomScene(pRoomScene, pRender);
-
- LastUpdate = GetAppTime();
return 0;
}
-void OculusRoomTinyApp::OnMessage(const Message& msg)
-{
- if (msg.Type == Message_DeviceAdded && msg.pDevice == pManager)
- {
- LogText("DeviceManager reported device added.\n");
- }
- else if (msg.Type == Message_DeviceRemoved && msg.pDevice == pManager)
- {
- LogText("DeviceManager reported device removed.\n");
- }
- else if (msg.Type == Message_DeviceAdded && msg.pDevice == pSensor)
- {
- LogText("Sensor reported device added.\n");
- }
- else if (msg.Type == Message_DeviceRemoved && msg.pDevice == pSensor)
- {
- LogText("Sensor reported device removed.\n");
- }
-}
-
-
-void OculusRoomTinyApp::OnGamepad(float padLx, float padLy, float padRx, float padRy)
-{
- GamepadMove = Vector3f(padLx * padLx * (padLx > 0 ? 1 : -1),
- 0,
- padLy * padLy * (padLy > 0 ? -1 : 1));
- GamepadRotate = Vector3f(2 * padRx, -2 * padRy, 0);
-}
-
-void OculusRoomTinyApp::OnMouseMove(int x, int y, int modifiers)
-{
- OVR_UNUSED(modifiers);
-
- // Mouse motion here is always relative.
- int dx = x, dy = y;
- const float maxPitch = ((3.1415f/2)*0.98f);
-
- // Apply to rotation. Subtract for right body frame rotation,
- // since yaw rotation is positive CCW when looking down on XZ plane.
- EyeYaw -= (Sensitivity * dx)/ 360.0f;
-
- if (!pSensor)
- {
- EyePitch -= (Sensitivity * dy)/ 360.0f;
-
- if (EyePitch > maxPitch)
- EyePitch = maxPitch;
- if (EyePitch < -maxPitch)
- EyePitch = -maxPitch;
- }
-}
-
-void OculusRoomTinyApp::OnKey(unsigned vk, bool down)
-{
- switch (vk)
- {
- case 'Q':
- if (down && ControlDown)
- Quit = true;
- break;
- case VK_ESCAPE:
- if (!down)
- Quit = true;
- break;
-
- // Handle player movement keys.
- // We just update movement state here, while the actual translation is done in OnIdle()
- // based on time.
- case 'W': MoveForward = down ? (MoveForward | 1) : (MoveForward & ~1); break;
- case 'S': MoveBack = down ? (MoveBack | 1) : (MoveBack & ~1); break;
- case 'A': MoveLeft = down ? (MoveLeft | 1) : (MoveLeft & ~1); break;
- case 'D': MoveRight = down ? (MoveRight | 1) : (MoveRight & ~1); break;
- case VK_UP: MoveForward = down ? (MoveForward | 2) : (MoveForward & ~2); break;
- case VK_DOWN: MoveBack = down ? (MoveBack | 2) : (MoveBack & ~2); break;
-
- case 'R':
- SFusion.Reset();
- break;
-
- case 'P':
- if (down)
- {
- // Toggle chromatic aberration correction on/off.
- RenderDevice::PostProcessShader shader = pRender->GetPostProcessShader();
-
- if (shader == RenderDevice::PostProcessShader_Distortion)
- {
- pRender->SetPostProcessShader(RenderDevice::PostProcessShader_DistortionAndChromAb);
- }
- else if (shader == RenderDevice::PostProcessShader_DistortionAndChromAb)
- {
- pRender->SetPostProcessShader(RenderDevice::PostProcessShader_Distortion);
- }
- else
- OVR_ASSERT(false);
- }
- break;
-
- // Switch rendering modes/distortion.
- case VK_F1:
- SConfig.SetStereoMode(Stereo_None);
- PostProcess = PostProcess_None;
- break;
- case VK_F2:
- SConfig.SetStereoMode(Stereo_LeftRight_Multipass);
- PostProcess = PostProcess_None;
- break;
- case VK_F3:
- SConfig.SetStereoMode(Stereo_LeftRight_Multipass);
- PostProcess = PostProcess_Distortion;
- break;
-
- // Stereo IPD adjustments, in meter (default IPD is 64mm).
- case VK_OEM_PLUS:
- case VK_INSERT:
- if (down)
- SConfig.SetIPD(SConfig.GetIPD() + 0.0005f * (ShiftDown ? 5.0f : 1.0f));
- break;
- case VK_OEM_MINUS:
- case VK_DELETE:
- if (down)
- SConfig.SetIPD(SConfig.GetIPD() - 0.0005f * (ShiftDown ? 5.0f : 1.0f));
- break;
-
- // Holding down Shift key accelerates adjustment velocity.
- case VK_SHIFT:
- ShiftDown = down;
- break;
- case VK_CONTROL:
- ControlDown = down;
- break;
- }
-}
-
+//-------------------------------------------------------------------------------------
-void OculusRoomTinyApp::OnIdle()
+void ProcessAndRender()
{
- double curtime = GetAppTime();
- float dt = float(curtime - LastUpdate);
- LastUpdate = curtime;
-
-
- // Handle Sensor motion.
- // We extract Yaw, Pitch, Roll instead of directly using the orientation
- // to allow "additional" yaw manipulation with mouse/controller.
- if (pSensor)
- {
- Quatf hmdOrient = SFusion.GetOrientation();
- float yaw = 0.0f;
-
- hmdOrient.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &EyePitch, &EyeRoll);
-
- EyeYaw += (yaw - LastSensorYaw);
- LastSensorYaw = yaw;
- }
-
-
- // Gamepad rotation.
- EyeYaw -= GamepadRotate.x * dt;
-
- if (!pSensor)
- {
- // Allow gamepad to look up/down, but only if there is no Rift sensor.
- EyePitch -= GamepadRotate.y * dt;
-
- const float maxPitch = ((3.1415f/2)*0.98f);
- if (EyePitch > maxPitch)
- EyePitch = maxPitch;
- if (EyePitch < -maxPitch)
- EyePitch = -maxPitch;
- }
-
- // Handle keyboard movement.
- // This translates EyePos based on Yaw vector direction and keys pressed.
- // Note that Pitch and Roll do not affect movement (they only affect view).
- if (MoveForward || MoveBack || MoveLeft || MoveRight)
- {
- Vector3f localMoveVector(0,0,0);
- Matrix4f yawRotate = Matrix4f::RotationY(EyeYaw);
-
- if (MoveForward)
- localMoveVector = ForwardVector;
- else if (MoveBack)
- localMoveVector = -ForwardVector;
-
- if (MoveRight)
- localMoveVector += RightVector;
- else if (MoveLeft)
- localMoveVector -= RightVector;
-
- // Normalize vector so we don't move faster diagonally.
- localMoveVector.Normalize();
- Vector3f orientationVector = yawRotate.Transform(localMoveVector);
- orientationVector *= MoveSpeed * dt * (ShiftDown ? 3.0f : 1.0f);
+#if SDK_RENDER
+ ovrFrameTiming frameTiming = ovrHmd_BeginFrame(HMD, 0);
+#else
+ ovrFrameTiming frameTiming = ovrHmd_BeginFrameTiming(HMD, 0);
+#endif
- EyePos += orientationVector;
- }
-
- else if (GamepadMove.LengthSq() > 0)
- {
- Matrix4f yawRotate = Matrix4f::RotationY(EyeYaw);
- Vector3f orientationVector = yawRotate.Transform(GamepadMove);
- orientationVector *= MoveSpeed * dt;
- EyePos += orientationVector;
- }
+ //Adjust eye position and rotation from controls, maintaining y position from HMD.
+ 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];
- // Rotate and position View Camera, using YawPitchRoll in BodyFrame coordinates.
- //
- Matrix4f rollPitchYaw = Matrix4f::RotationY(EyeYaw) * Matrix4f::RotationX(EyePitch) *
- Matrix4f::RotationZ(EyeRoll);
- Vector3f up = rollPitchYaw.Transform(UpVector);
- Vector3f forward = rollPitchYaw.Transform(ForwardVector);
+ EyePos.y = ovrHmd_GetFloat(HMD, OVR_KEY_EYE_HEIGHT, EyePos.y);
+ bool freezeEyeRender = Util_RespondToControls(EyeYaw, EyePos,
+ frameTiming.DeltaSeconds, movePose.Orientation);
+ pRender->BeginScene();
- // Minimal head modelling.
- float headBaseToEyeHeight = 0.15f; // Vertical height of eye from base of head
- float headBaseToEyeProtrusion = 0.09f; // Distance forward of eye from base of head
-
- Vector3f eyeCenterInHeadFrame(0.0f, headBaseToEyeHeight, -headBaseToEyeProtrusion);
- Vector3f shiftedEyePos = EyePos + rollPitchYaw.Transform(eyeCenterInHeadFrame);
- shiftedEyePos.y -= eyeCenterInHeadFrame.y; // Bring the head back down to original height
-
- View = Matrix4f::LookAtRH(shiftedEyePos, shiftedEyePos + forward, up);
-
- // This is what transformation would be without head modeling.
- // View = Matrix4f::LookAtRH(EyePos, EyePos + forward, up);
-
- switch(SConfig.GetStereoMode())
+ //Render the two undistorted eye views into their render buffers.
+ if (!freezeEyeRender) // freeze to debug, especially for time warp
{
- case Stereo_None:
- Render(SConfig.GetEyeRenderParams(StereoEye_Center));
- break;
-
- case Stereo_LeftRight_Multipass:
- Render(SConfig.GetEyeRenderParams(StereoEye_Left));
- Render(SConfig.GetEyeRenderParams(StereoEye_Right));
- break;
+ pRender->SetRenderTarget ( pRendertargetTexture );
+ pRender->SetViewport (Recti(0,0, pRendertargetTexture->GetWidth(),
+ pRendertargetTexture->GetHeight() ));
+ pRender->Clear();
+ for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++)
+ {
+ ovrEyeType eye = HMDDesc.EyeRenderOrder[eyeIndex];
+#if SDK_RENDER
+ eyeRenderPose[eye] = ovrHmd_BeginEyeRender(HMD, eye);
+#else
+ eyeRenderPose[eye] = ovrHmd_GetEyePose(HMD, eye);
+#endif
+
+ // Get view matrix
+ Matrix4f rollPitchYaw = Matrix4f::RotationY(EyeYaw);
+ Matrix4f finalRollPitchYaw = rollPitchYaw * Matrix4f(eyeRenderPose[eye].Orientation);
+ Vector3f finalUp = finalRollPitchYaw.Transform(Vector3f(0,1,0));
+ Vector3f finalForward = finalRollPitchYaw.Transform(Vector3f(0,0,-1));
+ Vector3f shiftedEyePos = EyePos + rollPitchYaw.Transform(eyeRenderPose[eye].Position);
+
+ Matrix4f view = Matrix4f::LookAtRH(shiftedEyePos,
+ shiftedEyePos + finalForward, finalUp);
+
+ Matrix4f proj = ovrMatrix4f_Projection(EyeRenderDesc[eye].Desc.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->SetProjection(proj);
+ pRender->SetDepthMode(true, true);
+ pRoomScene->Render(pRender, Matrix4f::Translation(EyeRenderDesc[eye].ViewAdjust) * view);
+
+ #if SDK_RENDER
+ ovrHmd_EndEyeRender(HMD, eye, eyeRenderPose[eye], &EyeTexture[eye].Texture);
+ #endif
+ }
}
-
- pRender->Present();
- // Force GPU to flush the scene, resulting in the lowest possible latency.
- pRender->ForceFlushGPU();
-}
-
-
-// Render the scene for one eye.
-void OculusRoomTinyApp::Render(const StereoEyeParams& stereo)
-{
- pRender->BeginScene(PostProcess);
-
- // Apply Viewport/Projection for the eye.
- pRender->ApplyStereoParams(stereo);
- pRender->Clear();
- pRender->SetDepthMode(true, true);
-
- Scene.Render(pRender, stereo.ViewAdjust * View);
-
pRender->FinishScene();
-}
-
-
-//-------------------------------------------------------------------------------------
-// ***** Win32-Specific Logic
-
-bool OculusRoomTinyApp::setupWindow()
-{
- WNDCLASS wc;
- memset(&wc, 0, sizeof(wc));
- wc.lpszClassName = L"OVRAppWindow";
- wc.style = CS_OWNDC;
- wc.lpfnWndProc = systemWindowProc;
- wc.cbWndExtra = sizeof(OculusRoomTinyApp*);
- RegisterClass(&wc);
-
-
- RECT winSize = { 0, 0, Width, Height };
- AdjustWindowRect(&winSize, WS_POPUP, false);
- hWnd = CreateWindowA("OVRAppWindow", "OculusRoomTiny", WS_POPUP|WS_VISIBLE,
- HMDInfo.DesktopX, HMDInfo.DesktopY,
- winSize.right-winSize.left, winSize.bottom-winSize.top,
- NULL, NULL, hInstance, (LPVOID)this);
-
-
- // Initialize Window center in screen coordinates
- POINT center = { Width / 2, Height / 2 };
- ::ClientToScreen(hWnd, &center);
- WindowCenter = center;
-
-
- return (hWnd != NULL);
+ // Now render the distorted view and finish.
+#if SDK_RENDER
+ // Let OVR do distortion rendering, Present and flush/sync
+ ovrHmd_EndFrame(HMD);
+
+#else
+ DistortionMeshRender(DistortionCaps, HMD, frameTiming.TimewarpPointSeconds,
+ eyeRenderPose, pRender, pRendertargetTexture);
+ pRender->Present( VSyncEnabled );
+ pRender->WaitUntilGpuIdle(); //for lowest latency
+ ovrHmd_EndFrameTiming(HMD);
+#endif
}
-void OculusRoomTinyApp::destroyWindow()
+/*
+void RenderFramePseudoCode()
{
- pRender.Clear();
-
- if (hWnd)
- {
- // Release window resources.
- ::DestroyWindow(hWnd);
- UnregisterClass(L"OVRAppWindow", hInstance);
- hWnd = 0;
- Width = Height = 0;
- }
-}
-
-
-LRESULT CALLBACK OculusRoomTinyApp::systemWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
-{
- if (msg == WM_NCCREATE)
- pApp->hWnd = hwnd;
- return pApp->windowProc(msg, wp, lp);
-}
-
-void OculusRoomTinyApp::giveUsFocus(bool setFocus)
-{
- if (setFocus)
- {
- ::SetCursorPos(WindowCenter.x, WindowCenter.y);
-
- MouseCaptured = true;
- ::SetCapture(hWnd);
- ::ShowCursor(FALSE);
+ovrFrame hmdFrameState = ovrHmd_BeginFrame(hmd);
- }
- else
- {
- MouseCaptured = false;
- ::ReleaseCapture();
- ::ShowCursor(TRUE);
- }
-}
-
-LRESULT OculusRoomTinyApp::windowProc(UINT msg, WPARAM wp, LPARAM lp)
+for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++)
{
- switch (msg)
- {
- case WM_MOUSEMOVE:
- {
- if (MouseCaptured)
- {
- // Convert mouse motion to be relative (report the offset and re-center).
- POINT newPos = { LOWORD(lp), HIWORD(lp) };
- ::ClientToScreen(hWnd, &newPos);
- if ((newPos.x == WindowCenter.x) && (newPos.y == WindowCenter.y))
- break;
- ::SetCursorPos(WindowCenter.x, WindowCenter.y);
-
- LONG dx = newPos.x - WindowCenter.x;
- LONG dy = newPos.y - WindowCenter.y;
- pApp->OnMouseMove(dx, dy, 0);
- }
- }
- break;
-
- case WM_MOVE:
- {
- RECT r;
- GetClientRect(hWnd, &r);
- WindowCenter.x = r.right/2;
- WindowCenter.y = r.bottom/2;
- ::ClientToScreen(hWnd, &WindowCenter);
- }
- break;
-
- case WM_KEYDOWN:
- OnKey((unsigned)wp, true);
- break;
- case WM_KEYUP:
- OnKey((unsigned)wp, false);
- break;
-
- case WM_SETFOCUS:
- giveUsFocus(true);
- break;
-
- case WM_KILLFOCUS:
- giveUsFocus(false);
- break;
-
- case WM_CREATE:
- // Hack to position mouse in fullscreen window shortly after startup.
- SetTimer(hWnd, 0, 100, NULL);
- break;
-
- case WM_TIMER:
- KillTimer(hWnd, 0);
- giveUsFocus(true);
- break;
-
- case WM_QUIT:
- case WM_CLOSE:
- Quit = true;
- return 0;
- }
-
- return DefWindowProc(hWnd, msg, wp, lp);
-}
+ ovrEyeType eye = HMDDesc.EyeRenderOrder[eyeIndex];
+ ovrPosef eyeRenderPose = ovrHmd_BeginEyeRender(hmd, eye);
-static inline float GamepadStick(short in)
-{
- float v;
- if (abs(in) < 9000)
- return 0;
- else if (in > 9000)
- v = (float) in - 9000;
- else
- v = (float) in + 9000;
- return v / (32767 - 9000);
-}
+ RenderGameView(RenderViewports[eye], eyeRenderPose);
-static inline float GamepadTrigger(BYTE in)
-{
- return (in < 30) ? 0.0f : (float(in-30) / 225);
+ ovrHmd_EndEyeRender(hmd, eye, &EyeTexture[eye].Texture);
}
-
-int OculusRoomTinyApp::Run()
-{
- // Loop processing messages until Quit flag is set,
- // rendering game scene inside of OnIdle().
-
- while (!Quit)
- {
- MSG msg;
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else
- {
- // Read game-pad.
- XINPUT_STATE xis;
-
- if (pXInputGetState && !pXInputGetState(0, &xis) &&
- (xis.dwPacketNumber != LastPadPacketNo))
- {
- OnGamepad(GamepadStick(xis.Gamepad.sThumbLX),
- GamepadStick(xis.Gamepad.sThumbLY),
- GamepadStick(xis.Gamepad.sThumbRX),
- GamepadStick(xis.Gamepad.sThumbRY));
- //pad.LT = GamepadTrigger(xis.Gamepad.bLeftTrigger);
- LastPadPacketNo = xis.dwPacketNumber;
- }
-
- pApp->OnIdle();
-
- // Keep sleeping when we're minimized.
- if (IsIconic(hWnd))
- Sleep(10);
- }
- }
-
- return 0;
+// Let OVR do distortion rendering, Present and Flush+Sync.
+ovrHmd_EndFrame(hmd);
}
-
+*/
//-------------------------------------------------------------------------------------
-// ***** Program Startup
-
-int WINAPI WinMain(HINSTANCE hinst, HINSTANCE, LPSTR inArgs, int)
+void Release(void)
{
- int exitCode = 0;
-
- // Initializes LibOVR. This LogMask_All enables maximum logging.
- // Custom allocator can also be specified here.
- OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All));
-
- // Scope to force application destructor before System::Destroy.
+ pRendertargetTexture->Release();
+ pRendertargetTexture = 0;
+ ovrHmd_Destroy(HMD);
+ Util_ReleaseWindowAndGraphics(pRender);
+ pRender = 0;
+ if (pRoomScene)
{
- OculusRoomTinyApp app(hinst);
- //app.hInstance = hinst;
-
- exitCode = app.OnStartup(inArgs);
- if (!exitCode)
- {
- // Processes messages and calls OnIdle() to do rendering.
- exitCode = app.Run();
- }
- }
-
+ delete pRoomScene;
+ pRoomScene = 0;
+ }
// No OVR functions involving memory are allowed after this.
- OVR::System::Destroy();
-
- OVR_DEBUG_STATEMENT(_CrtDumpMemoryLeaks());
- return exitCode;
+ ovr_Shutdown();
}
+
diff --git a/Samples/OculusRoomTiny/Win32_OculusRoomTiny.h b/Samples/OculusRoomTiny/Win32_OculusRoomTiny.h
deleted file mode 100644
index a86dd47..0000000
--- a/Samples/OculusRoomTiny/Win32_OculusRoomTiny.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/************************************************************************************
-
-Filename : OculusRoomTiny.h
-Content : Simplest possible first-person view test application for Oculus Rift
-Created : March 10, 2012
-Authors : Michael Antonov, Andrew Reisse
-
-Copyright : Copyright 2012 Oculus, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-*************************************************************************************/
-#ifndef INC_OculusRoomTiny_h
-#define INC_OculusRoomTiny_h
-
-#include <Windows.h>
-#include <xinput.h>
-
-#include "OVR.h"
-#include "Util/Util_Render_Stereo.h"
-#include "../../LibOVR/Src/Kernel/OVR_Timer.h"
-#include "RenderTiny_D3D1X_Device.h"
-
-using namespace OVR;
-using namespace OVR::RenderTiny;
-
-
-//-------------------------------------------------------------------------------------
-// ***** OculusRoomTiny Description
-
-// This app renders a simple flat-shaded room allowing the user to move along the
-// floor and look around with an HMD, mouse, keyboard and gamepad.
-// By default, the application will start full-screen on Oculus Rift.
-//
-// The following keys work:
-//
-// 'W', 'S', 'A', 'D' - Move forward, back; strafe left/right.
-// F1 - No stereo, no distortion.
-// F2 - Stereo, no distortion.
-// F3 - Stereo and distortion.
-//
-
-// The world RHS coordinate system is defines as follows (as seen in perspective view):
-// Y - Up
-// Z - Back
-// X - Right
-const Vector3f UpVector(0.0f, 1.0f, 0.0f);
-const Vector3f ForwardVector(0.0f, 0.0f, -1.0f);
-const Vector3f RightVector(1.0f, 0.0f, 0.0f);
-
-// We start out looking in the positive Z (180 degree rotation).
-const float YawInitial = 3.141592f;
-const float Sensitivity = 1.0f;
-const float MoveSpeed = 3.0f; // m/s
-
-
-//-------------------------------------------------------------------------------------
-// ***** OculusRoomTiny Application class
-
-// An instance of this class is created on application startup (main/WinMain).
-//
-// It then works as follows:
-//
-// OnStartup - Window, graphics and HMD setup is done here.
-// This function will initialize OVR::DeviceManager and HMD,
-// creating SensorDevice and attaching it to SensorFusion.
-// This needs to be done before obtaining sensor data.
-//
-// OnIdle - Does per-frame processing, processing SensorFusion and
-// movement input and rendering the frame.
-
-class OculusRoomTinyApp : public MessageHandler
-{
-public:
- OculusRoomTinyApp(HINSTANCE hinst);
- ~OculusRoomTinyApp();
-
- // Initializes graphics, Rift input and creates world model.
- virtual int OnStartup(const char* args);
- // Called per frame to sample SensorFucion and render the world.
- virtual void OnIdle();
-
- // Installed for Oculus device messages. Optional.
- virtual void OnMessage(const Message& msg);
-
- // Handle input events for movement.
- virtual void OnGamepad(float padLx, float padLY, float padRx, float padRy);
- virtual void OnMouseMove(int x, int y, int modifiers);
- virtual void OnKey(unsigned vk, bool down);
-
- // Render the view for one eye.
- void Render(const StereoEyeParams& stereo);
-
- // Main application loop.
- int Run();
-
- // Return amount of time passed since application started in seconds.
- double GetAppTime() const
- {
- return (OVR::Timer::GetTicks() - StartupTicks) * (1.0 / (double)OVR::Timer::MksPerSecond);
- }
-
-
-protected:
-
- // Win32 window setup interface.
- LRESULT windowProc(UINT msg, WPARAM wp, LPARAM lp);
- bool setupWindow();
- void destroyWindow();
- // Win32 static function that delegates to WindowProc member function.
- static LRESULT CALLBACK systemWindowProc(HWND window, UINT msg, WPARAM wp, LPARAM lp);
-
- void giveUsFocus(bool setFocus);
-
- static OculusRoomTinyApp* pApp;
-
- // *** Rendering Variables
- Ptr<RenderDevice> pRender;
- RendererParams RenderParams;
- int Width, Height;
-
-
- // *** Win32 System Variables
- HWND hWnd;
- HINSTANCE hInstance;
- POINT WindowCenter; // In desktop coordinates
- bool Quit;
- bool MouseCaptured;
-
- // Dynamically ink to XInput to simplify projects.
- typedef DWORD (WINAPI *PFn_XInputGetState)(DWORD dwUserIndex, XINPUT_STATE* pState);
- PFn_XInputGetState pXInputGetState;
- HMODULE hXInputModule;
- UInt32 LastPadPacketNo;
-
-
- // *** Oculus HMD Variables
-
- Ptr<DeviceManager> pManager;
- Ptr<SensorDevice> pSensor;
- Ptr<HMDDevice> pHMD;
- SensorFusion SFusion;
- OVR::HMDInfo HMDInfo;
-
- // Last update seconds, used for move speed timing.
- double LastUpdate;
- UInt64 StartupTicks;
-
- // Position and look. The following apply:
- Vector3f EyePos;
- float EyeYaw; // Rotation around Y, CCW positive when looking at RHS (X,Z) plane.
- float EyePitch; // Pitch. If sensor is plugged in, only read from sensor.
- float EyeRoll; // Roll, only accessible from Sensor.
- float LastSensorYaw; // Stores previous Yaw value from to support computing delta.
-
- // Movement state; different bits may be set based on the state of keys.
- UByte MoveForward;
- UByte MoveBack;
- UByte MoveLeft;
- UByte MoveRight;
- Vector3f GamepadMove, GamepadRotate;
-
- Matrix4f View;
- RenderTiny::Scene Scene;
-
- // Stereo view parameters.
- StereoConfig SConfig;
- PostProcessType PostProcess;
-
- // Shift accelerates movement/adjustment velocity.
- bool ShiftDown;
- bool ControlDown;
-};
-
-// Adds sample models and lights to the argument scene.
-void PopulateRoomScene(Scene* scene, RenderDevice* render);
-
-
-#endif
diff --git a/Samples/OculusRoomTiny/Win32_OculusRoomTiny_Util.cpp b/Samples/OculusRoomTiny/Win32_OculusRoomTiny_Util.cpp
new file mode 100644
index 0000000..ab0f252
--- /dev/null
+++ b/Samples/OculusRoomTiny/Win32_OculusRoomTiny_Util.cpp
@@ -0,0 +1,254 @@
+/************************************************************************************
+
+Filename : Win32_OculusRoomTiny_Util.cpp
+Content : Win32 system interface & app/graphics initialization ligic
+Created : October 4, 2012
+
+Copyright : Copyright 2012 Oculus, Inc. All Rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*************************************************************************************/
+
+#include "RenderTiny_D3D11_Device.h"
+
+// Win32 System Variables
+HWND hWnd = NULL;
+HINSTANCE hInstance;
+POINT WindowCenter;
+
+// User inputs
+bool Quit = 0;
+UByte MoveForward = 0,
+ MoveBack = 0,
+ MoveLeft = 0,
+ MoveRight = 0;
+
+bool ShiftDown = false,
+ ControlDown = false;
+
+// Freezes the scene during timewarp rendering.
+bool FreezeEyeRender = false;
+
+float AdditionalYawFromMouse = 0;
+
+// Movement speed, in m/s applied during keyboard motion.
+const float MoveSpeed = 3.0f;
+
+// Functions from Win32_OculusRoomTiny.cpp and DistortionMesh.cpp
+int Init();
+void ProcessAndRender();
+void Release();
+void DistortionMeshRelease(void);
+
+
+//-------------------------------------------------------------------------------------
+
+void OnKey(unsigned vk, bool down)
+{
+ switch (vk)
+ {
+ case 'Q': if (down && ControlDown) Quit = true; break;
+ case VK_ESCAPE: if (!down) Quit = true; break;
+
+ case 'W': MoveForward = down ? (MoveForward | 1) : (MoveForward & ~1); break;
+ case 'S': MoveBack = down ? (MoveBack | 1) : (MoveBack & ~1); break;
+ case 'A': MoveLeft = down ? (MoveLeft | 1) : (MoveLeft & ~1); break;
+ case 'D': MoveRight = down ? (MoveRight | 1) : (MoveRight & ~1); break;
+
+ case VK_UP: MoveForward = down ? (MoveForward | 2) : (MoveForward & ~2); break;
+ case VK_DOWN: MoveBack = down ? (MoveBack | 2) : (MoveBack & ~2); break;
+
+ case 'F': FreezeEyeRender = !down ? !FreezeEyeRender : FreezeEyeRender; break;
+
+ case VK_SHIFT: ShiftDown = down; break;
+ case VK_CONTROL:ControlDown = down; break;
+ }
+}
+
+void OnMouseMove(int x)
+{
+ const float Sensitivity = 1.0f;
+ AdditionalYawFromMouse -= (Sensitivity * x)/ 360.0f;
+}
+
+bool Util_RespondToControls(float & EyeYaw, Vector3f & EyePos,
+ float deltaTime, Quatf PoseOrientation)
+{
+ #if 0//Optional debug output
+ char debugString[1000];
+ sprintf_s(debugString,"Pos = (%0.2f, %0.2f, %0.2f)\n",EyePos.x,EyePos.y,EyePos.z);
+ OutputDebugStringA(debugString);
+ #endif
+
+ //Mouse rotation
+ EyeYaw += AdditionalYawFromMouse;
+ AdditionalYawFromMouse = 0;
+
+ //Get HeadYaw
+ float HeadPitch, HeadRoll, HeadYaw;
+ PoseOrientation.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&HeadYaw,&HeadPitch, &HeadRoll);
+
+ //Move on Eye pos from controls
+ Vector3f localMoveVector(0,0,0);
+ Matrix4f yawRotate = Matrix4f::RotationY(EyeYaw + HeadYaw);
+
+ if (MoveForward) localMoveVector += Vector3f(0,0,-1);
+ if (MoveBack) localMoveVector += Vector3f(0,0,+1);
+ if (MoveRight) localMoveVector += Vector3f(1,0,0);
+ if (MoveLeft) localMoveVector += Vector3f(-1,0,0);
+
+ Vector3f orientationVector = yawRotate.Transform(localMoveVector);
+
+ orientationVector *= MoveSpeed * deltaTime * (ShiftDown ? 3.0f : 1.0f);
+ EyePos += orientationVector;
+
+ //Some rudimentary limitation of movement, so not to go through walls
+ const float minDistanceToWall = 0.30f;
+ EyePos.x = max(EyePos.x,-10.0f + minDistanceToWall);
+ EyePos.x = min(EyePos.x, 10.0f - minDistanceToWall);
+ EyePos.z = max(EyePos.z,-20.0f + minDistanceToWall);
+
+ //Return if need to freeze or not
+ return(FreezeEyeRender);
+}
+
+
+LRESULT CALLBACK systemWindowProc(HWND arg_hwnd, UINT msg, WPARAM wp, LPARAM lp)
+{
+ switch (msg)
+ {
+ case(WM_NCCREATE): hWnd = arg_hwnd; break;
+
+ case WM_MOUSEMOVE: {
+ // Convert mouse motion to be relative
+ // (report the offset and re-center).
+ POINT newPos = { LOWORD(lp), HIWORD(lp) };
+ ::ClientToScreen(hWnd, &newPos);
+ if ((newPos.x == WindowCenter.x) && (newPos.y == WindowCenter.y))
+ break;
+ ::SetCursorPos(WindowCenter.x, WindowCenter.y);
+ OnMouseMove(newPos.x - WindowCenter.x);
+ break;
+ }
+
+ case WM_MOVE: RECT r;
+ GetClientRect(hWnd, &r);
+ WindowCenter.x = r.right/2;
+ WindowCenter.y = r.bottom/2;
+ ::ClientToScreen(hWnd, &WindowCenter);
+ break;
+
+ case WM_KEYDOWN: OnKey((unsigned)wp, true); break;
+ case WM_KEYUP: OnKey((unsigned)wp, false); break;
+ case WM_CREATE: SetTimer(hWnd, 0, 100, NULL); break;
+ case WM_TIMER: KillTimer(hWnd, 0);
+
+ case WM_SETFOCUS:
+ SetCursorPos(WindowCenter.x, WindowCenter.y);
+ SetCapture(hWnd);
+ ShowCursor(FALSE);
+ break;
+ case WM_KILLFOCUS:
+ ReleaseCapture();
+ ShowCursor(TRUE);
+ break;
+
+ case WM_QUIT:
+ case WM_CLOSE: Quit = true;
+ return 0;
+ }
+
+ return DefWindowProc(hWnd, msg, wp, lp);
+}
+
+
+RenderDevice* Util_InitWindowAndGraphics(Recti vp, int fullscreen, int multiSampleCount)
+{
+ // Window
+ WNDCLASS wc;
+ memset(&wc, 0, sizeof(wc));
+ wc.lpszClassName = L"OVRAppWindow";
+ wc.style = CS_OWNDC;
+ wc.lpfnWndProc = systemWindowProc;
+ wc.cbWndExtra = NULL;
+ RegisterClass(&wc);
+
+ RECT winSize = { 0, 0, vp.w, vp.h };
+ AdjustWindowRect(&winSize, WS_POPUP, false);
+ hWnd = CreateWindowA("OVRAppWindow", "OculusRoomTiny", WS_POPUP |WS_VISIBLE,
+ vp.x, vp.y,
+ winSize.right-winSize.left, winSize.bottom-winSize.top,
+ NULL, NULL, hInstance, NULL);
+
+ POINT center = { vp.w / 2, vp.h / 2 };
+ ::ClientToScreen(hWnd, &center);
+ WindowCenter = center;
+
+ if (!hWnd) return(NULL);
+
+ // Graphics
+ RendererParams renderParams;
+ renderParams.Multisample = multiSampleCount;
+ renderParams.Fullscreen = fullscreen;
+ return (RenderDevice::CreateDevice(renderParams, (void*)hWnd));
+}
+
+
+void Util_ReleaseWindowAndGraphics(RenderDevice * prender)
+{
+ if (prender)
+ prender->Release();
+
+ DistortionMeshRelease();
+
+ if (hWnd)
+ {
+ // Release window resources.
+ ::DestroyWindow(hWnd);
+ UnregisterClass(L"OVRAppWindow", hInstance);
+ }
+}
+
+
+//-------------------------------------------------------------------------------------
+// ***** Program Startup
+//
+int WINAPI WinMain(HINSTANCE hinst, HINSTANCE, LPSTR , int)
+{
+ hInstance = hinst;
+
+ if (!Init())
+ {
+ // Processes messages and calls OnIdle() to do rendering.
+ while (!Quit)
+ {
+ MSG msg;
+ if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ else
+ {
+ ProcessAndRender();
+
+ // Keep sleeping when we're minimized.
+ if (IsIconic(hWnd)) Sleep(10);
+ }
+ }
+ }
+ Release();
+ OVR_DEBUG_STATEMENT(_CrtDumpMemoryLeaks());
+ return (0);
+}
+
diff --git a/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_OculusCube.tga b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_OculusCube.tga
new file mode 100644
index 0000000..be8b5de
--- /dev/null
+++ b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_OculusCube.tga
Binary files differ
diff --git a/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_blueCube.tga b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_blueCube.tga
new file mode 100644
index 0000000..fe4768e
--- /dev/null
+++ b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_blueCube.tga
Binary files differ
diff --git a/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_redCube.tga b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_redCube.tga
new file mode 100644
index 0000000..7b90b82
--- /dev/null
+++ b/Samples/OculusWorldDemo/Assets/Tuscany/Tuscany_redCube.tga
Binary files differ
diff --git a/Samples/OculusWorldDemo/Makefile b/Samples/OculusWorldDemo/Makefile
deleted file mode 100644
index 6015560..0000000
--- a/Samples/OculusWorldDemo/Makefile
+++ /dev/null
@@ -1,135 +0,0 @@
-#############################################################################
-#
-# Filename : Makefile
-# Content : Makefile for building linux OculusWorldDemo
-# Created : 2013
-# Authors : Simon Hallam and Peter Giokaris
-# Copyright : Copyright 2013 OculusVR, Inc. All Rights Reserved
-# Instruction : The g++ compiler and stdndard lib packages need to be
-# installed on the system. Navigate in a shell to the
-# directory where this Makefile is located and enter:
-#
-# make builds the release version for the
-# current architechture
-# make clean delete intermediate release object files
-# and the executabe file
-# make DEBUG=1 builds the debug version for the current
-# architechture
-# make clean DEBUG=1 deletes intermediate debug object files
-# and the executable file
-#
-# Output : Relative to the directory this Makefile lives in, executable
-# files get built at the following locations depending upon the
-# architechture of the system you are running:
-#
-# ./Release/OculusWorldDemo_i386_Release
-# ./Release/OculusWorldDemo_x86_64_Release
-# ./Release/OculusWorldDemo_i386_Debug
-# ./Release/OculusWorldDemo_x86_64_Debug
-#
-#############################################################################
-
-####### Detect system architecture
-
-SYSARCH = i386
-ifeq ($(shell uname -m),x86_64)
-SYSARCH = x86_64
-endif
-
-####### Compiler, tools and options
-
-CXX = g++
-LINK = g++
-MAKE = make
-DELETEFILE = rm -f
-DEFINES = -DQT_WEBKIT -DGL_GLEXT_PROTOTYPES
-
-####### Detect debug or release
-
-DEBUG = 0
-ifeq ($(DEBUG), 1)
- CXXFLAGS = -pipe -DDEBUG -g $(DEFINES)
- LFLAGS =
- RELEASETYPE = Debug
-else
- CXXFLAGS = -pipe -O2 $(DEFINES)
- LFLAGS = -O1
- RELEASETYPE = Release
-endif
-
-####### Paths
-
-LIBOVRPATH = ../../LibOVR
-COMMONSRCPATH = ../CommonSrc
-3RDPARTYPATH = ../../3rdParty
-INCPATH = -I. -I.. -I$(COMMONSRCPATH) -I$(LIBOVRPATH)/Include -I$(LIBOVRPATH)/Src
-OBJPATH = ./Obj/Linux/$(RELEASETYPE)/$(SYSARCH)
-CXX_BUILD = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $(OBJPATH)/
-
-####### Files
-
-LIBS = -L$(LIBOVRPATH)/Lib/Linux/$(RELEASETYPE)/$(SYSARCH) \
- -lovr \
- -ludev \
- -lpthread \
- -lGL \
- -lX11 \
- -lXinerama
-
-OBJECTS = $(OBJPATH)/OculusWorldDemo.o \
- $(OBJPATH)/Player.o \
- $(OBJPATH)/Platform.o \
- $(OBJPATH)/Linux_Platform.o \
- $(OBJPATH)/Linux_Gamepad.o \
- $(OBJPATH)/Render_Device.o \
- $(OBJPATH)/Render_GL_Device.o \
- $(OBJPATH)/Render_LoadTextureDDS.o \
- $(OBJPATH)/Render_LoadTextureTGA.o \
- $(OBJPATH)/Render_XmlSceneLoader.o
-
-TARGET = ./Release/OculusWorldDemo_$(SYSARCH)_$(RELEASETYPE)
-
-####### Rules
-
-all: $(TARGET)
-
-$(TARGET): $(LIBOVRPATH)/Lib/Linux/$(RELEASETYPE)/$(SYSARCH)/libovr.a
- $(MAKE) -C $(LIBOVRPATH) DEBUG=$(DEBUG)
-
-$(TARGET): $(OBJECTS)
- $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS)
-
-$(OBJPATH)/OculusWorldDemo.o: OculusWorldDemo.cpp
- $(CXX_BUILD)OculusWorldDemo.o OculusWorldDemo.cpp
-
-$(OBJPATH)/Player.o: Player.cpp
- $(CXX_BUILD)Player.o Player.cpp
-
-$(OBJPATH)/Platform.o: ../../Samples/CommonSrc/Platform/Platform.cpp
- $(CXX_BUILD)Platform.o ../../Samples/CommonSrc/Platform/Platform.cpp
-
-$(OBJPATH)/Linux_Platform.o: ../../Samples/CommonSrc/Platform/Linux_Platform.cpp
- $(CXX_BUILD)Linux_Platform.o ../../Samples/CommonSrc/Platform/Linux_Platform.cpp
-
-$(OBJPATH)/Linux_Gamepad.o: ../../Samples/CommonSrc/Platform/Linux_Gamepad.cpp
- $(CXX_BUILD)Linux_Gamepad.o ../../Samples/CommonSrc/Platform/Linux_Gamepad.cpp
-
-$(OBJPATH)/Render_Device.o: ../../Samples/CommonSrc/Render/Render_Device.cpp $
- $(CXX_BUILD)Render_Device.o ../../Samples/CommonSrc/Render/Render_Device.cpp
-
-$(OBJPATH)/Render_GL_Device.o: ../../Samples/CommonSrc/Render/Render_GL_Device.cpp
- $(CXX_BUILD)Render_GL_Device.o ../../Samples/CommonSrc/Render/Render_GL_Device.cpp
-
-$(OBJPATH)/Render_LoadTextureDDS.o: ../../Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp
- $(CXX_BUILD)Render_LoadTextureDDS.o ../../Samples/CommonSrc/Render/Render_LoadTextureDDS.cpp
-
-$(OBJPATH)/Render_LoadTextureTGA.o: ../../Samples/CommonSrc/Render/Render_LoadTextureTGA.cpp
- $(CXX_BUILD)Render_LoadTextureTGA.o ../../Samples/CommonSrc/Render/Render_LoadTextureTGA.cpp
-
-$(OBJPATH)/Render_XmlSceneLoader.o: ../../Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp
- $(CXX_BUILD)Render_XmlSceneLoader.o ../../Samples/CommonSrc/Render/Render_XmlSceneLoader.cpp
-
-clean:
- -$(DELETEFILE) $(OBJECTS)
- -$(DELETEFILE) $(TARGET)
-
diff --git a/Samples/OculusWorldDemo/Obj/Linux/Debug/i386/readme b/Samples/OculusWorldDemo/Obj/Linux/Debug/i386/readme
deleted file mode 100644
index c9d0bc0..0000000
--- a/Samples/OculusWorldDemo/Obj/Linux/Debug/i386/readme
+++ /dev/null
@@ -1,2 +0,0 @@
-This document exits to ensure that the required directory structure gets created correctly.
-
diff --git a/Samples/OculusWorldDemo/Obj/Linux/Debug/x86_64/readme b/Samples/OculusWorldDemo/Obj/Linux/Debug/x86_64/readme
deleted file mode 100644
index c9d0bc0..0000000
--- a/Samples/OculusWorldDemo/Obj/Linux/Debug/x86_64/readme
+++ /dev/null
@@ -1,2 +0,0 @@
-This document exits to ensure that the required directory structure gets created correctly.
-
diff --git a/Samples/OculusWorldDemo/Obj/Linux/Release/i386/readme b/Samples/OculusWorldDemo/Obj/Linux/Release/i386/readme
deleted file mode 100644
index c9d0bc0..0000000
--- a/Samples/OculusWorldDemo/Obj/Linux/Release/i386/readme
+++ /dev/null
@@ -1,2 +0,0 @@
-This document exits to ensure that the required directory structure gets created correctly.
-
diff --git a/Samples/OculusWorldDemo/Obj/Linux/Release/x86_64/readme b/Samples/OculusWorldDemo/Obj/Linux/Release/x86_64/readme
deleted file mode 100644
index c9d0bc0..0000000
--- a/Samples/OculusWorldDemo/Obj/Linux/Release/x86_64/readme
+++ /dev/null
@@ -1,2 +0,0 @@
-This document exits to ensure that the required directory structure gets created correctly.
-
diff --git a/Samples/OculusWorldDemo/OculusWorldDemo.cpp b/Samples/OculusWorldDemo/OculusWorldDemo.cpp
index 1a81c8d..e89403f 100644
--- a/Samples/OculusWorldDemo/OculusWorldDemo.cpp
+++ b/Samples/OculusWorldDemo/OculusWorldDemo.cpp
@@ -1,10 +1,10 @@
/************************************************************************************
Filename : OculusWorldDemo.cpp
-Content : First-person view test application for Oculus Rift
+Content : First-person view test application for Oculus Rift - Implementation
Created : October 4, 2012
-Authors : Michael Antonov, Andrew Reisse, Steve LaValle
- Peter Hoff, Dan Goodman, Bryan Croteau
+Authors : Michael Antonov, Andrew Reisse, Steve LaValle, Dov Katz
+ Peter Hoff, Dan Goodman, Bryan Croteau
Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
@@ -22,286 +22,82 @@ limitations under the License.
*************************************************************************************/
-#include "OVR.h"
+#include "OculusWorldDemo.h"
-#include "../CommonSrc/Platform/Platform_Default.h"
-#include "../CommonSrc/Render/Render_Device.h"
-#include "../CommonSrc/Render/Render_XmlSceneLoader.h"
-#include "../CommonSrc/Render/Render_FontEmbed_DejaVu48.h"
-#include "../CommonSrc/Platform/Gamepad.h"
-
-#include <Kernel/OVR_SysFile.h>
-#include <Kernel/OVR_Log.h>
-#include <Kernel/OVR_Timer.h>
-
-#include "Player.h"
-
-// Filename to be loaded by default, searching specified paths.
-#define WORLDDEMO_ASSET_FILE "Tuscany.xml"
-#define WORLDDEMO_ASSET_PATH1 "Assets/Tuscany/"
-#define WORLDDEMO_ASSET_PATH2 "../Assets/Tuscany/"
-// This path allows the shortcut to work.
-#define WORLDDEMO_ASSET_PATH3 "Samples/OculusWorldDemo/Assets/Tuscany/"
-
-
-using namespace OVR;
-using namespace OVR::Platform;
-using namespace OVR::Render;
-
-//-------------------------------------------------------------------------------------
-// ***** OculusWorldDemo Description
-
-// This app renders a simple flat-shaded room allowing the user to move along the
-// floor and look around with an HMD, mouse and keyboard. The following keys work:
-//
-// 'W', 'S', 'A', 'D' and Arrow Keys - Move forward, back; strafe left/right.
-// F1 - No stereo, no distortion.
-// F2 - Stereo, no distortion.
-// F3 - Stereo and distortion.
-// F4 - Toggle MSAA.
-// F9 - Cycle through fullscreen and windowed modes. Necessary for previewing content with Rift.
-//
-// Important Oculus-specific logic can be found at following locations:
-//
-// OculusWorldDemoApp::OnStartup - This function will initialize OVR::DeviceManager and HMD,
-// creating SensorDevice and attaching it to SensorFusion.
-// This needs to be done before obtaining sensor data.
-//
-// OculusWorldDemoApp::OnIdle - Here we poll SensorFusion for orientation, apply it
-// to the scene and handle movement.
-// Stereo rendering is also done here, by delegating to
-// to Render function for each eye.
-//
-
-//-------------------------------------------------------------------------------------
-// ***** OculusWorldDemo Application class
-
-// An instance of this class is created on application startup (main/WinMain).
-// It then works as follows:
-// - Graphics and HMD setup is done OculusWorldDemoApp::OnStartup(). This function
-// also creates the room model from Slab declarations.
-// - Per-frame processing is done in OnIdle(). This function processes
-// sensor and movement input and then renders the frame.
-// - Additional input processing is done in OnMouse, OnKey.
-
-class OculusWorldDemoApp : public Application, public MessageHandler
-{
-public:
- OculusWorldDemoApp();
- ~OculusWorldDemoApp();
-
- virtual int OnStartup(int argc, const char** argv);
- virtual void OnIdle();
-
- virtual void OnMouseMove(int x, int y, int modifiers);
- virtual void OnKey(OVR::KeyCode key, int chr, bool down, int modifiers);
- virtual void OnResize(int width, int height);
-
- virtual void OnMessage(const Message& msg);
-
- void Render(const StereoEyeParams& stereo);
-
- // Sets temporarily displayed message for adjustments
- void SetAdjustMessage(const char* format, ...);
- // Overrides current timeout, in seconds (not the future default value);
- // intended to be called right after SetAdjustMessage.
- void SetAdjustMessageTimeout(float timeout);
-
- // Stereo setting adjustment functions.
- // Called with deltaTime when relevant key is held.
- void AdjustFov(float dt);
- void AdjustAspect(float dt);
- void AdjustIPD(float dt);
- void AdjustEyeHeight(float dt);
-
- void AdjustMotionPrediction(float dt);
-
- void AdjustDistortion(float dt, int kIndex, const char* label);
- void AdjustDistortionK0(float dt) { AdjustDistortion(dt, 0, "K0"); }
- void AdjustDistortionK1(float dt) { AdjustDistortion(dt, 1, "K1"); }
- void AdjustDistortionK2(float dt) { AdjustDistortion(dt, 2, "K2"); }
- void AdjustDistortionK3(float dt) { AdjustDistortion(dt, 3, "K3"); }
-
- void AdjustDistortion(float val, int kIndex);
- void AdjustEsd(float val);
-
- // Adds room model to scene.
- void PopulateScene(const char* fileName);
- void PopulatePreloadScene();
- void ClearScene();
-
- // Magnetometer calibration procedure
- void UpdateManualMagCalibration();
-
-protected:
- RenderDevice* pRender;
- RendererParams RenderParams;
- int Width, Height;
- int Screen;
- int FirstScreenInCycle;
-
- // *** Oculus HMD Variables
- Ptr<DeviceManager> pManager;
- Ptr<SensorDevice> pSensor;
- Ptr<HMDDevice> pHMD;
- Ptr<Profile> pUserProfile;
- SensorFusion SFusion;
- HMDInfo TheHMDInfo;
-
- Ptr<LatencyTestDevice> pLatencyTester;
- Util::LatencyTest LatencyUtil;
-
- double LastUpdate;
- int FPS;
- int FrameCounter;
- double NextFPSUpdate;
-
- Array<Ptr<CollisionModel> > CollisionModels;
- Array<Ptr<CollisionModel> > GroundCollisionModels;
-
- // Loading process displays screenshot in first frame
- // and then proceeds to load until finished.
- enum LoadingStateType
- {
- LoadingState_Frame0,
- LoadingState_DoLoad,
- LoadingState_Finished
- };
-
- // Player
- Player ThePlayer;
- Matrix4f View;
- Scene MainScene;
- Scene LoadingScene;
- Scene GridScene;
- Scene YawMarkGreenScene;
- Scene YawMarkRedScene;
- Scene YawLinesScene;
-
- LoadingStateType LoadingState;
-
- Ptr<ShaderFill> LitSolid, LitTextures[4];
-
- // Stereo view parameters.
- StereoConfig SConfig;
- PostProcessType PostProcess;
-
- // LOD
- String MainFilePath;
- Array<String> LODFilePaths;
- int ConsecutiveLowFPSFrames;
- int CurrentLODFileIndex;
-
- float DistortionK0;
- float DistortionK1;
- float DistortionK2;
- float DistortionK3;
-
- String AdjustMessage;
- double AdjustMessageTimeout;
-
- // Saved distortion state.
- float SavedK0, SavedK1, SavedK2, SavedK3;
- float SavedESD, SavedAspect, SavedEyeDistance;
-
- // Allows toggling color around distortion.
- Color DistortionClearColor;
-
- // Stereo settings adjustment state.
- typedef void (OculusWorldDemoApp::*AdjustFuncType)(float);
- bool ShiftDown;
- AdjustFuncType pAdjustFunc;
- float AdjustDirection;
-
- enum SceneRenderMode
- {
- Scene_World,
- Scene_Grid,
- Scene_Both,
- Scene_YawView
- };
- SceneRenderMode SceneMode;
-
-
- enum TextScreen
- {
- Text_None,
- Text_Orientation,
- Text_Config,
- Text_Help,
- Text_Count
- };
- TextScreen TextScreen;
-
- struct DeviceStatusNotificationDesc
- {
- DeviceHandle Handle;
- MessageType Action;
-
- DeviceStatusNotificationDesc():Action(Message_None) {}
- DeviceStatusNotificationDesc(MessageType mt, const DeviceHandle& dev)
- : Handle(dev), Action(mt) {}
- };
- Array<DeviceStatusNotificationDesc> DeviceStatusNotificationsQueue;
-
-
- Model* CreateModel(Vector3f pos, struct SlabModel* sm);
- Model* CreateBoundingModel(CollisionModel &cm);
- void PopulateLODFileNames();
- void DropLOD();
- void RaiseLOD();
- void CycleDisplay();
- void GamepadStateChanged(const GamepadState& pad);
-};
//-------------------------------------------------------------------------------------
+// ***** OculusWorldDemoApp
OculusWorldDemoApp::OculusWorldDemoApp()
: pRender(0),
- LastUpdate(0),
+ WindowSize(1280,800),
+ ScreenNumber(0),
+ FirstScreenInCycle(0),
+ Hmd(0),
+ StartSensorCaps(0),
+ UsingDebugHmd(false),
LoadingState(LoadingState_Frame0),
+ HaveVisionTracking(false),
+ HmdStatus(0),
+
// Initial location
- SConfig(),
- PostProcess(PostProcess_Distortion),
- DistortionClearColor(0, 0, 0),
-
+ DistortionClearBlue(0),
ShiftDown(false),
- pAdjustFunc(0),
- AdjustDirection(1.0f),
+ CtrlDown(false),
+ HmdSettingsChanged(false),
+
+ // Modifiable options.
+ RendertargetIsSharedByBothEyes(false),
+ DynamicRezScalingEnabled(false),
+ ForceZeroIpd(false),
+ DesiredPixelDensity(1.0f),
+ FovSideTanMax(1.0f), // Updated based on Hmd.
+ TimewarpEnabled(true),
+ TimewarpRenderIntervalInSeconds(0.0f),
+ FreezeEyeUpdate(false),
+ FreezeEyeOneFrameRendered(false),
+ CenterPupilDepthMeters(0.05f),
+ ForceZeroHeadMovement(false),
+ VsyncEnabled(true),
+ MultisampleEnabled(true),
+ IsLowPersistence(true),
+ DynamicPrediction(true),
+ PositionTrackingEnabled(true),
+
+ // Scene state
SceneMode(Scene_World),
- TextScreen(Text_None)
+ GridDisplayMode(GridDisplay_None),
+ GridMode(Grid_Lens),
+ TextScreen(Text_None),
+ BlocksShowType(0),
+ BlocksCenter(0.0f, 0.0f, 0.0f)
{
- Width = 1280;
- Height = 800;
- Screen = 0;
- FirstScreenInCycle = 0;
- FPS = 0;
- FrameCounter = 0;
- NextFPSUpdate = 0;
+ FPS = 0.0f;
+ SecondsPerFrame = 0.0f;
+ FrameCounter = 0;
+ LastFpsUpdate = 0;
- ConsecutiveLowFPSFrames = 0;
- CurrentLODFileIndex = 0;
-
- AdjustMessageTimeout = 0;
+ DistortionClearBlue = false;
}
OculusWorldDemoApp::~OculusWorldDemoApp()
{
- RemoveHandlerFromDevices();
+ CleanupDrawTextFont();
- if(DejaVu.fill)
+ if (Hmd)
{
- DejaVu.fill->Release();
+ ovrHmd_Destroy(Hmd);
+ Hmd = 0;
}
- pLatencyTester.Clear();
- pSensor.Clear();
- pHMD.Clear();
-
+
CollisionModels.ClearAndRelease();
GroundCollisionModels.ClearAndRelease();
+
+ ovr_Shutdown();
}
+
int OculusWorldDemoApp::OnStartup(int argc, const char** argv)
{
@@ -311,106 +107,84 @@ int OculusWorldDemoApp::OnStartup(int argc, const char** argv)
// Sensor object is created from the HMD, to ensure that it is on the
// correct device.
- pManager = *DeviceManager::Create();
+ ovr_Initialize();
- // We'll handle it's messages in this case.
- pManager->SetMessageHandler(this);
+ Hmd = ovrHmd_Create(0);
-
- pHMD = *pManager->EnumerateDevices<HMDDevice>().CreateDevice();
- if (pHMD)
+ if (!Hmd)
{
- pSensor = *pHMD->GetSensor();
-
- // This will initialize HMDInfo with information about configured IPD,
- // screen size and other variables needed for correct projection.
- // We pass HMD DisplayDeviceName into the renderer to select the
- // correct monitor in full-screen mode.
- if(pHMD->GetDeviceInfo(&TheHMDInfo))
- {
- //RenderParams.MonitorName = hmd.DisplayDeviceName;
- SConfig.SetHMDInfo(TheHMDInfo);
+ // If we didn't detect an Hmd, create a simulated one for debugging.
+ Hmd = ovrHmd_CreateDebug(ovrHmd_DK1);
+ UsingDebugHmd = true;
+ if (!Hmd)
+ { // Failed Hmd creation.
+ return 1;
}
-
- // Retrieve relevant profile settings.
- pUserProfile = pHMD->GetProfile();
- if (pUserProfile)
- {
- ThePlayer.UserEyeHeight = pUserProfile->GetEyeHeight();
- ThePlayer.EyePos.y = ThePlayer.UserEyeHeight;
- }
- }
- else
- {
- // If we didn't detect an HMD, try to create the sensor directly.
- // This is useful for debugging sensor interaction; it is not needed in
- // a shipping app.
- pSensor = *pManager->EnumerateDevices<SensorDevice>().CreateDevice();
- }
-
- // Create the Latency Tester device and assign it to the LatencyTesterUtil object.
- pLatencyTester = *pManager->EnumerateDevices<LatencyTestDevice>().CreateDevice();
- if (pLatencyTester)
- {
- LatencyUtil.SetDevice(pLatencyTester);
- }
- // Make the user aware which devices are present.
- if(pHMD == NULL && pSensor == NULL)
- {
- SetAdjustMessage("---------------------------------\nNO HMD DETECTED\nNO SENSOR DETECTED\n---------------------------------");
- }
- else if(pHMD == NULL)
- {
- SetAdjustMessage("----------------------------\nNO HMD DETECTED\n----------------------------");
- }
- else if(pSensor == NULL)
- {
- SetAdjustMessage("---------------------------------\nNO SENSOR DETECTED\n---------------------------------");
- }
- else
- {
- SetAdjustMessage("--------------------------------------------\n"
- "Press F9 for Full-Screen on Rift\n"
- "--------------------------------------------");
}
- // First message should be extra-long.
- SetAdjustMessageTimeout(10.0f);
+ // Get more details about the HMD.
+ ovrHmd_GetDesc(Hmd, &HmdDesc);
+ WindowSize = HmdDesc.Resolution;
- if(TheHMDInfo.HResolution > 0)
- {
- Width = TheHMDInfo.HResolution;
- Height = TheHMDInfo.VResolution;
- }
- if(!pPlatform->SetupWindow(Width, Height))
- {
+ // ***** Setup System Window & rendering.
+
+ if (!SetupWindowAndRendering(argc, argv))
return 1;
- }
- String Title = "Oculus World Demo";
- if(TheHMDInfo.ProductName[0])
- {
- Title += " : ";
- Title += TheHMDInfo.ProductName;
- }
- pPlatform->SetWindowTitle(Title);
+ // Initialize FovSideTanMax, which allows us to change all Fov sides at once - Fov
+ // starts at default and is clamped to this value.
+ FovSideTanLimit = FovPort::Max(HmdDesc.MaxEyeFov[0], HmdDesc.MaxEyeFov[1]).GetMaxSideTan();
+ FovSideTanMax = FovPort::Max(HmdDesc.DefaultEyeFov[0], HmdDesc.DefaultEyeFov[1]).GetMaxSideTan();
- // Report relative mouse motion in OnMouseMove
- pPlatform->SetMouseMode(Mouse_Relative);
+ PositionTrackingEnabled = (HmdDesc.Caps & ovrHmdCap_Position) ? true : false;
+
+
+ // *** Configure HMD Stereo settings.
- if(pSensor)
- {
- // We need to attach sensor to SensorFusion object for it to receive
- // body frame messages and update orientation. SFusion.GetOrientation()
- // is used in OnIdle() to orient the view.
- SFusion.AttachToSensor(pSensor);
+ CalculateHmdValues();
- SFusion.SetDelegateMessageHandler(this);
+ // Query eye height.
+ ThePlayer.UserEyeHeight = ovrHmd_GetFloat(Hmd, OVR_KEY_EYE_HEIGHT, ThePlayer.UserEyeHeight);
+ ThePlayer.BodyPos.y = ThePlayer.UserEyeHeight;
+ // Center pupil for customization; real game shouldn't need to adjust this.
+ CenterPupilDepthMeters = ovrHmd_GetFloat(Hmd, "CenterPupilDepth", 0.0f);
- SFusion.SetPredictionEnabled(true);
- }
+
+ ThePlayer.bMotionRelativeToBody = false; // Default to head-steering for DK1
+
+ if (UsingDebugHmd)
+ Menu.SetPopupMessage("NO HMD DETECTED");
+ else if (!(ovrHmd_GetSensorState(Hmd, 0.0f).StatusFlags & ovrStatus_OrientationTracked))
+ Menu.SetPopupMessage("NO SENSOR DETECTED");
+ else
+ Menu.SetPopupMessage("Press F9 for Full-Screen on Rift");
+ // Give first message 10 sec timeout, add border lines.
+ Menu.SetPopupTimeout(10.0f, true);
+
+ PopulateOptionMenu();
+
+ // *** Identify Scene File & Prepare for Loading
+
+ InitMainFilePath();
+ PopulatePreloadScene();
+
+ LastUpdate = ovr_GetTimeInSeconds();
+
+ return 0;
+}
+
+
+bool OculusWorldDemoApp::SetupWindowAndRendering(int argc, const char** argv)
+{
+ // *** Window creation
+
+ if (!pPlatform->SetupWindow(WindowSize.w, WindowSize.h))
+ return false;
+
+ // Report relative mouse motion in OnMouseMove
+ pPlatform->SetMouseMode(Mouse_Relative);
// *** Initialize Rendering
@@ -430,1332 +204,1065 @@ int OculusWorldDemoApp::OnStartup(int argc, const char** argv)
}
}
+ String title = "Oculus World Demo ";
+ title += graphics;
+
+ if (HmdDesc.ProductName[0])
+ {
+ title += " : ";
+ title += HmdDesc.ProductName;
+ }
+ pPlatform->SetWindowTitle(title);
+
// Enable multi-sampling by default.
- RenderParams.Multisample = 4;
+ RenderParams.Display = DisplayId(HmdDesc.DisplayDeviceName, HmdDesc.DisplayId);
+ RenderParams.Multisample = 1;
+ //RenderParams.Fullscreen = true;
pRender = pPlatform->SetupGraphics(OVR_DEFAULT_RENDER_DEVICE_SET,
graphics, RenderParams);
+ if (!pRender)
+ return false;
+ return true;
+}
+// Custom formatter for Timewarp interval message.
+static String FormatTimewarp(OptionVar* var)
+{
+ char buff[64];
+ float timewarpInterval = *var->AsFloat();
+ OVR_sprintf(buff, sizeof(buff), "%.1fms, %.1ffps",
+ timewarpInterval * 1000.0f,
+ ( timewarpInterval > 0.000001f ) ? 1.0f / timewarpInterval : 10000.0f);
+ return String(buff);
+}
- // *** Configure Stereo settings.
+static String FormatMaxFromSideTan(OptionVar* var)
+{
+ char buff[64];
+ float degrees = 2.0f * atan(*var->AsFloat()) * (180.0f / Math<float>::Pi);
+ OVR_sprintf(buff, sizeof(buff), "%.1f Degrees", degrees);
+ return String(buff);
+}
- SConfig.SetFullViewport(Viewport(0, 0, Width, Height));
- SConfig.SetStereoMode(Stereo_LeftRight_Multipass);
- // Configure proper Distortion Fit.
- // For 7" screen, fit to touch left side of the view, leaving a bit of
- // invisible screen on the top (saves on rendering cost).
- // For smaller screens (5.5"), fit to the top.
- if (TheHMDInfo.HScreenSize > 0.0f)
+void OculusWorldDemoApp::PopulateOptionMenu()
+{
+ // For shortened function member access.
+ typedef OculusWorldDemoApp OWD;
+
+ // *** Scene Content Sub-Menu
+
+ // Test
+ /*
+ Menu.AddEnum("Scene Content.EyePoseMode", &FT_EyePoseState).AddShortcutKey(Key_Y).
+ AddEnumValue("Separate Pose", 0).
+ AddEnumValue("Same Pose", 1).
+ AddEnumValue("Same Pose+TW", 2);
+ */
+
+ // Navigate between scenes.
+ Menu.AddEnum("Scene Content.Rendered Scene ';'", &SceneMode).AddShortcutKey(Key_Semicolon).
+ AddEnumValue("World", Scene_World).
+ AddEnumValue("Cubes", Scene_Cubes).
+ AddEnumValue("Oculus Cubes", Scene_OculusCubes);
+ // Animating blocks
+ Menu.AddEnum("Scene Content.Animated Blocks", &BlocksShowType).
+ AddShortcutKey(Key_B).SetNotify(this, &OWD::BlockShowChange).
+ AddEnumValue("None", 0).
+ AddEnumValue("Horizontal Circle", 1).
+ AddEnumValue("Vertical Circle", 2).
+ AddEnumValue("Bouncing Blocks", 3);
+ // Toggle grid
+ Menu.AddEnum("Scene Content.Grid Display 'G'", &GridDisplayMode).AddShortcutKey(Key_G).
+ AddEnumValue("No Grid", GridDisplay_None).
+ AddEnumValue("Grid Only", GridDisplay_GridOnly).
+ AddEnumValue("Grid And Scene", GridDisplay_GridAndScene);
+ Menu.AddEnum("Scene Content.Grid Mode 'H'", &GridMode).AddShortcutKey(Key_H).
+ AddEnumValue("4-pixel RT-centered", Grid_Rendertarget4).
+ AddEnumValue("16-pixel RT-centered",Grid_Rendertarget16).
+ AddEnumValue("Lens-centered grid", Grid_Lens);
+
+ // *** Scene Content Sub-Menu
+ Menu.AddBool( "Render Target.Share RenderTarget", &RendertargetIsSharedByBothEyes).
+ AddShortcutKey(Key_F8).SetNotify(this, &OWD::HmdSettingChange);
+ Menu.AddBool( "Render Target.Dynamic Res Scaling", &DynamicRezScalingEnabled).
+ AddShortcutKey(Key_F8, ShortcutKey::Shift_RequireOn);
+ Menu.AddBool( "Render Target.Zero IPD 'F7'", &ForceZeroIpd).
+ AddShortcutKey(Key_F7).
+ SetNotify(this, &OWD::HmdSettingChangeFreeRTs);
+ Menu.AddFloat("Render Target.Max Fov", &FovSideTanMax, 0.2f, FovSideTanLimit, 0.02f,
+ "%.1f Degrees", 1.0f, &FormatMaxFromSideTan).
+ SetNotify(this, &OWD::HmdSettingChange).
+ AddShortcutUpKey(Key_I).AddShortcutDownKey(Key_K);
+ Menu.AddFloat("Render Target.Pixel Density", &DesiredPixelDensity, 0.5f, 1.5, 0.025f, "%3.2f", 1.0f).
+ SetNotify(this, &OWD::HmdSettingChange);
+ Menu.AddEnum( "Render Target.Distortion Clear Color", &DistortionClearBlue).
+ SetNotify(this, &OWD::DistortionClearColorChange).
+ AddEnumValue("Black", 0).
+ AddEnumValue("Blue", 1);
+
+ // Timewarp
+ Menu.AddBool( "Timewarp.TimewarpEnabled 'O'", &TimewarpEnabled).AddShortcutKey(Key_O).
+ SetNotify(this, &OWD::HmdSettingChange);
+ Menu.AddBool( "Timewarp.FreezeEyeUpdate 'C'", &FreezeEyeUpdate).AddShortcutKey(Key_C);
+ Menu.AddFloat("Timewarp.RenderIntervalSeconds", &TimewarpRenderIntervalInSeconds,
+ 0.0001f, 1.00f, 0.0001f, "%.1f", 1.0f, &FormatTimewarp).
+ AddShortcutUpKey(Key_J).AddShortcutDownKey(Key_U);
+
+ // First page properties
+ Menu.AddFloat("User Eye Height", &ThePlayer.UserEyeHeight, 0.2f, 2.5f, 0.02f,
+ "%4.2f m").SetNotify(this, &OWD::EyeHeightChange).
+ AddShortcutUpKey(Key_Equal).AddShortcutDownKey(Key_Minus);
+ Menu.AddFloat("Center Pupil Depth", &CenterPupilDepthMeters, 0.0f, 0.2f, 0.001f,
+ "%4.3f m").SetNotify(this, &OWD::CenterPupilDepthChange);
+ Menu.AddBool("Body Relative Motion",&ThePlayer.bMotionRelativeToBody).AddShortcutKey(Key_E);
+ Menu.AddBool("Zero Head Movement", &ForceZeroHeadMovement) .AddShortcutKey(Key_F7, ShortcutKey::Shift_RequireOn);
+ Menu.AddBool("VSync 'V'", &VsyncEnabled) .AddShortcutKey(Key_V).SetNotify(this, &OWD::HmdSettingChange);
+ Menu.AddBool("MultiSample 'F4'", &MultisampleEnabled) .AddShortcutKey(Key_F4).SetNotify(this, &OWD::MultisampleChange);
+
+ // Add DK2 options to menu only for that headset.
+ if (HmdDesc.Caps & ovrHmdCap_Position)
{
- if (TheHMDInfo.HScreenSize > 0.140f) // 7"
- SConfig.SetDistortionFitPointVP(-1.0f, 0.0f);
- else
- SConfig.SetDistortionFitPointVP(0.0f, 1.0f);
+ Menu.AddBool("Low Persistence 'P'", &IsLowPersistence).
+ AddShortcutKey(Key_P).SetNotify(this, &OWD::HmdSettingChange);
+ Menu.AddBool("Dynamic Prediction", &DynamicPrediction).
+ SetNotify(this, &OWD::HmdSettingChange);
+ Menu.AddBool("Positional Tracking 'X'", &PositionTrackingEnabled).
+ AddShortcutKey(Key_X).SetNotify(this, &OWD::HmdSettingChange);
}
+}
- pRender->SetSceneRenderScale(SConfig.GetDistortionScale());
- //pRender->SetSceneRenderScale(1.0f);
- SConfig.Set2DAreaFov(DegreeToRad(85.0f));
+void OculusWorldDemoApp::CalculateHmdValues()
+{
+ // Initialize eye rendering information for ovrHmd_Configure.
+ // The viewport sizes are re-computed in case RenderTargetSize changed due to HW limitations.
+ ovrEyeDesc eyes[2];
+ eyes[0].Eye = ovrEye_Left;
+ eyes[1].Eye = ovrEye_Right;
+ eyes[0].Fov = HmdDesc.DefaultEyeFov[0];
+ eyes[1].Fov = HmdDesc.DefaultEyeFov[1];
+ // Clamp Fov based on our dynamically adjustable FovSideTanMax.
+ // Most apps should use the default, but reducing Fov does reduce rendering cost.
+ eyes[0].Fov = FovPort::Min(eyes[0].Fov, FovPort(FovSideTanMax));
+ eyes[1].Fov = FovPort::Min(eyes[1].Fov, FovPort(FovSideTanMax));
- // *** Identify Scene File & Prepare for Loading
-
- // This creates lights and models.
- if (argc == 2)
- {
- MainFilePath = argv[1];
- PopulateLODFileNames();
+
+ if (ForceZeroIpd)
+ {
+ // ForceZeroIpd does three things:
+ // 1) Sets FOV to maximum symmetrical FOV based on both eyes
+ // 2) Sets eye ViewAdjust values to 0.0 (effective IPD == 0)
+ // 3) Uses only the Left texture for rendering.
+
+ eyes[0].Fov = FovPort::Max(eyes[0].Fov, eyes[1].Fov);
+ eyes[1].Fov = eyes[0].Fov;
+
+ Sizei recommenedTexSize = ovrHmd_GetFovTextureSize(Hmd, ovrEye_Left,
+ eyes[0].Fov, DesiredPixelDensity);
+
+ eyes[0].TextureSize = EnsureRendertargetAtLeastThisBig(Rendertarget_Left, recommenedTexSize);
+ eyes[1].TextureSize = eyes[0].TextureSize;
+ eyes[0].RenderViewport.Pos = Vector2i(0,0);
+ eyes[0].RenderViewport.Size = Sizei::Min(eyes[0].TextureSize, recommenedTexSize);
+ eyes[1].RenderViewport = eyes[0].RenderViewport;
+
+ // Store texture pointers that will be passed for rendering.
+ EyeTexture[0] = RenderTargets[Rendertarget_Left].Tex;
+ EyeTexture[1] = RenderTargets[Rendertarget_Left].Tex;
}
+
else
{
- fprintf(stderr, "Usage: OculusWorldDemo [input XML]\n");
- MainFilePath = WORLDDEMO_ASSET_FILE;
+ // Configure Stereo settings. Default pixel density is 1.0f.
+ Sizei recommenedTex0Size = ovrHmd_GetFovTextureSize(Hmd, ovrEye_Left, eyes[0].Fov, DesiredPixelDensity);
+ Sizei recommenedTex1Size = ovrHmd_GetFovTextureSize(Hmd, ovrEye_Right, eyes[1].Fov, DesiredPixelDensity);
+
+ if (RendertargetIsSharedByBothEyes)
+ {
+ Sizei rtSize(recommenedTex0Size.w + recommenedTex1Size.w,
+ Alg::Max(recommenedTex0Size.h, recommenedTex1Size.h));
+
+ // Use returned size as the actual RT size may be different due to HW limits.
+ rtSize = EnsureRendertargetAtLeastThisBig(Rendertarget_BothEyes, rtSize);
+
+ // Don't draw more then recommended size; this also ensures that resolution reported
+ // in the overlay HUD size is updated correctly for FOV/pixel density change.
+ Sizei leftSize = Sizei::Min(Sizei(rtSize.w/2, rtSize.h), recommenedTex0Size);
+ Sizei rightSize = Sizei::Min(Sizei(rtSize.w/2, rtSize.h), recommenedTex1Size);
+
+ eyes[0].TextureSize = rtSize;
+ eyes[1].TextureSize = rtSize;
+ eyes[0].RenderViewport = Recti(Vector2i(0), leftSize);
+ eyes[1].RenderViewport = Recti(Vector2i((rtSize.w+1)/2, 0), rightSize);
+
+ // Store texture pointers that will be passed for rendering.
+ // Same texture is used, but with different viewports.
+ EyeTexture[0] = RenderTargets[Rendertarget_BothEyes].Tex;
+ EyeTexture[1] = RenderTargets[Rendertarget_BothEyes].Tex;
+ EyeTexture[0].Header.RenderViewport = eyes[0].RenderViewport;
+ EyeTexture[1].Header.RenderViewport = eyes[1].RenderViewport;
+ }
+
+ else
+ {
+ eyes[0].TextureSize = EnsureRendertargetAtLeastThisBig(Rendertarget_Left, recommenedTex0Size);
+ eyes[1].TextureSize = EnsureRendertargetAtLeastThisBig(Rendertarget_Right, recommenedTex1Size);
+ eyes[0].RenderViewport = Recti(Sizei::Min(eyes[0].TextureSize, recommenedTex0Size));
+ eyes[1].RenderViewport = Recti(Sizei::Min(eyes[1].TextureSize, recommenedTex1Size));
+
+ // Store texture pointers that will be passed for rendering.
+ EyeTexture[0] = RenderTargets[Rendertarget_Left].Tex;
+ EyeTexture[1] = RenderTargets[Rendertarget_Right].Tex;
+ }
}
- // Try to modify path for correctness in case specified file is not found.
- if (!SysFile(MainFilePath).IsValid())
+
+ unsigned hmdCaps = ovrHmdCap_Orientation | (VsyncEnabled ? 0 : ovrHmdCap_NoVSync);
+ unsigned distortionCaps = ovrDistortion_Chromatic;
+
+ ovrRenderAPIConfig config = pRender->Get_ovrRenderAPIConfig();
+
+ if (TimewarpEnabled)
+ distortionCaps |= ovrDistortion_TimeWarp;
+
+ if (!ovrHmd_ConfigureRendering( Hmd, &config, hmdCaps, distortionCaps,
+ eyes, EyeRenderDesc ))
{
- String prefixPath1(pPlatform->GetContentDirectory() + "/" + WORLDDEMO_ASSET_PATH1),
- prefixPath2(WORLDDEMO_ASSET_PATH2),
- prefixPath3(WORLDDEMO_ASSET_PATH3);
- if (SysFile(prefixPath1 + MainFilePath).IsValid())
- MainFilePath = prefixPath1 + MainFilePath;
- else if (SysFile(prefixPath2 + MainFilePath).IsValid())
- MainFilePath = prefixPath2 + MainFilePath;
- else if (SysFile(prefixPath3 + MainFilePath).IsValid())
- MainFilePath = prefixPath3 + MainFilePath;
+ // Fail exit? TBD
+ return;
}
- PopulatePreloadScene();
+ if (ForceZeroIpd)
+ {
+ // Remove IPD adjust
+ EyeRenderDesc[0].ViewAdjust = Vector3f(0);
+ EyeRenderDesc[1].ViewAdjust = Vector3f(0);
+ }
- LastUpdate = pPlatform->GetAppTime();
- //pPlatform->PlayMusicFile(L"Loop.wav");
+ // ovrHmdCap_LatencyTest - enables internal latency feedback
+ unsigned sensorCaps = ovrHmdCap_Orientation|ovrHmdCap_YawCorrection|ovrHmdCap_LatencyTest;
+ if (PositionTrackingEnabled)
+ sensorCaps |= ovrHmdCap_Position;
+ if (IsLowPersistence)
+ sensorCaps |= ovrHmdCap_LowPersistence;
+ if (DynamicPrediction)
+ sensorCaps |= ovrHmdCap_DynamicPrediction;
- return 0;
+ if (StartSensorCaps != sensorCaps)
+ {
+ ovrHmd_StartSensor(Hmd, sensorCaps, 0);
+ StartSensorCaps = sensorCaps;
+ }
+
+ // Calculate projections
+ Projection[0] = ovrMatrix4f_Projection(EyeRenderDesc[0].Desc.Fov, 0.01f, 10000.0f, true);
+ Projection[1] = ovrMatrix4f_Projection(EyeRenderDesc[1].Desc.Fov, 0.01f, 10000.0f, true);
+
+ float orthoDistance = 0.8f; // 2D is 0.8 meter from camera
+ Vector2f orthoScale0 = Vector2f(1.0f) / Vector2f(EyeRenderDesc[0].PixelsPerTanAngleAtCenter);
+ Vector2f orthoScale1 = Vector2f(1.0f) / Vector2f(EyeRenderDesc[1].PixelsPerTanAngleAtCenter);
+
+ OrthoProjection[0] = ovrMatrix4f_OrthoSubProjection(Projection[0], orthoScale0, orthoDistance,
+ EyeRenderDesc[0].ViewAdjust.x);
+ OrthoProjection[1] = ovrMatrix4f_OrthoSubProjection(Projection[1], orthoScale1, orthoDistance,
+ EyeRenderDesc[1].ViewAdjust.x);
}
-void OculusWorldDemoApp::OnMessage(const Message& msg)
+
+
+// Returns the actual size present.
+Sizei OculusWorldDemoApp::EnsureRendertargetAtLeastThisBig(int rtNum, Sizei requestedSize)
{
- if (msg.Type == Message_DeviceAdded || msg.Type == Message_DeviceRemoved)
+ OVR_ASSERT((rtNum >= 0) && (rtNum < Rendertarget_LAST));
+
+ // Texture size that we already have might be big enough.
+ Sizei newRTSize;
+
+ RenderTarget& rt = RenderTargets[rtNum];
+ if (!rt.pTex)
{
- if (msg.pDevice == pManager)
- {
- const MessageDeviceStatus& statusMsg =
- static_cast<const MessageDeviceStatus&>(msg);
+ // Hmmm... someone nuked my texture. Rez change or similar. Make sure we reallocate.
+ rt.Tex.Header.TextureSize = Sizei(0);
+ newRTSize = requestedSize;
+ }
+ else
+ {
+ newRTSize = rt.Tex.Header.TextureSize;
+ }
- { // limit the scope of the lock
- Lock::Locker lock(pManager->GetHandlerLock());
- DeviceStatusNotificationsQueue.PushBack(
- DeviceStatusNotificationDesc(statusMsg.Type, statusMsg.Handle));
- }
+ // %50 linear growth each time is a nice balance between being too greedy
+ // for a 2D surface and too slow to prevent fragmentation.
+ while ( newRTSize.w < requestedSize.w )
+ {
+ newRTSize.w += newRTSize.w/2;
+ }
+ while ( newRTSize.h < requestedSize.h )
+ {
+ newRTSize.h += newRTSize.h/2;
+ }
- switch (statusMsg.Type)
- {
- case OVR::Message_DeviceAdded:
- LogText("DeviceManager reported device added.\n");
- break;
-
- case OVR::Message_DeviceRemoved:
- LogText("DeviceManager reported device removed.\n");
- break;
-
- default: OVR_ASSERT(0); // unexpected type
- }
- }
+ // Put some sane limits on it. 4k x 4k is fine for most modern video cards.
+ // Nobody should be messing around with surfaces smaller than 4k pixels these days.
+ newRTSize = Sizei::Max(Sizei::Min(newRTSize, Sizei(4096)), Sizei(64));
+
+ // Does that require actual reallocation?
+ if (Sizei(rt.Tex.Header.TextureSize) != newRTSize)
+ {
+ rt.pTex = *pRender->CreateTexture(Texture_RGBA | Texture_RenderTarget | (MultisampleEnabled ? 4 : 1),
+ newRTSize.w, newRTSize.h, NULL);
+ rt.pTex->SetSampleMode(Sample_ClampBorder | Sample_Linear);
+
+
+ // Configure texture for SDK Rendering.
+ rt.Tex = rt.pTex->Get_ovrTexture();
}
+
+ return newRTSize;
}
+
+//-----------------------------------------------------------------------------
+// ***** Message Handlers
+
void OculusWorldDemoApp::OnResize(int width, int height)
{
- Width = width;
- Height = height;
- SConfig.SetFullViewport(Viewport(0, 0, Width, Height));
+ WindowSize = Sizei(width, height);
+ // Re-calculate?
}
void OculusWorldDemoApp::OnMouseMove(int x, int y, int modifiers)
{
+ OVR_UNUSED(y);
if(modifiers & Mod_MouseRelative)
{
// Get Delta
- int dx = x, dy = y;
-
- const float maxPitch = ((3.1415f / 2) * 0.98f);
+ int dx = x;
// Apply to rotation. Subtract for right body frame rotation,
// since yaw rotation is positive CCW when looking down on XZ plane.
- ThePlayer.EyeYaw -= (Sensitivity * dx) / 360.0f;
-
- if(!pSensor)
- {
- ThePlayer.EyePitch -= (Sensitivity * dy) / 360.0f;
-
- if(ThePlayer.EyePitch > maxPitch)
- {
- ThePlayer.EyePitch = maxPitch;
- }
- if(ThePlayer.EyePitch < -maxPitch)
- {
- ThePlayer.EyePitch = -maxPitch;
- }
- }
+ ThePlayer.BodyYaw -= (Sensitivity * dx) / 360.0f;
}
}
void OculusWorldDemoApp::OnKey(OVR::KeyCode key, int chr, bool down, int modifiers)
{
- OVR_UNUSED(chr);
+ if (Menu.OnKey(key, chr, down, modifiers))
+ return;
+
+ // Handle player movement keys.
+ if (ThePlayer.HandleMoveKey(key, down))
+ return;
switch(key)
{
case Key_Q:
if (down && (modifiers & Mod_Control))
- {
pPlatform->Exit(0);
- }
- break;
-
- // Handle player movement keys.
- // We just update movement state here, while the actual translation is done in OnIdle()
- // based on time.
- case Key_W:
- ThePlayer.MoveForward = down ? (ThePlayer.MoveForward | 1) : (ThePlayer.MoveForward & ~1);
- break;
- case Key_S:
- ThePlayer.MoveBack = down ? (ThePlayer.MoveBack | 1) : (ThePlayer.MoveBack & ~1);
- break;
- case Key_A:
- ThePlayer.MoveLeft = down ? (ThePlayer.MoveLeft | 1) : (ThePlayer.MoveLeft & ~1);
- break;
- case Key_D:
- ThePlayer.MoveRight = down ? (ThePlayer.MoveRight | 1) : (ThePlayer.MoveRight & ~1);
- break;
- case Key_Up:
- ThePlayer.MoveForward = down ? (ThePlayer.MoveForward | 2) : (ThePlayer.MoveForward & ~2);
- break;
- case Key_Down:
- ThePlayer.MoveBack = down ? (ThePlayer.MoveBack | 2) : (ThePlayer.MoveBack & ~2);
- break;
- case Key_Left:
- ThePlayer.MoveLeft = down ? (ThePlayer.MoveLeft | 2) : (ThePlayer.MoveLeft & ~2);
break;
- case Key_Right:
- ThePlayer.MoveRight = down ? (ThePlayer.MoveRight | 2) : (ThePlayer.MoveRight & ~2);
- break;
-
- case Key_Minus:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustEyeHeight : 0;
- AdjustDirection = -1;
- break;
- case Key_Equal:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustEyeHeight : 0;
- AdjustDirection = 1;
- break;
-
- case Key_B:
- if (down)
- {
- if(SConfig.GetDistortionScale() == 1.0f)
- {
- if(SConfig.GetHMDInfo().HScreenSize > 0.140f) // 7"
- {
- SConfig.SetDistortionFitPointVP(-1.0f, 0.0f);
- }
- else
- {
- SConfig.SetDistortionFitPointVP(0.0f, 1.0f);
- }
- }
- else
- {
- // No fitting; scale == 1.0.
- SConfig.SetDistortionFitPointVP(0, 0);
- }
- }
- break;
-
- // Support toggling background color for distortion so that we can see
- // the effect on the periphery.
- case Key_V:
- if (down)
- {
- if(DistortionClearColor.B == 0)
- {
- DistortionClearColor = Color(0, 128, 255);
- }
- else
- {
- DistortionClearColor = Color(0, 0, 0);
- }
-
- pRender->SetDistortionClearColor(DistortionClearColor);
- }
- break;
-
-
- case Key_F1:
- SConfig.SetStereoMode(Stereo_None);
- PostProcess = PostProcess_None;
- SetAdjustMessage("StereoMode: None");
- break;
- case Key_F2:
- SConfig.SetStereoMode(Stereo_LeftRight_Multipass);
- PostProcess = PostProcess_None;
- SetAdjustMessage("StereoMode: Stereo + No Distortion");
- break;
- case Key_F3:
- SConfig.SetStereoMode(Stereo_LeftRight_Multipass);
- PostProcess = PostProcess_Distortion;
- SetAdjustMessage("StereoMode: Stereo + Distortion");
- break;
-
- case Key_R:
- SFusion.Reset();
- SetAdjustMessage("Sensor Fusion Reset");
- break;
-
- case Key_Space:
- if (!down)
- {
- TextScreen = (enum TextScreen)((TextScreen + 1) % Text_Count);
- }
+
+ case Key_Escape:
+ // Back to primary windowed
+ if (!down) ChangeDisplay ( true, false, false );
break;
- case Key_F4:
- if (!down)
- {
- RenderParams = pRender->GetParams();
- RenderParams.Multisample = RenderParams.Multisample > 1 ? 1 : 4;
- pRender->SetParams(RenderParams);
- if(RenderParams.Multisample > 1)
- {
- SetAdjustMessage("Multisampling On");
- }
- else
- {
- SetAdjustMessage("Multisampling Off");
- }
- }
- break;
case Key_F9:
-#ifndef OVR_OS_LINUX // On Linux F9 does the same as F11.
- if (!down)
- {
- CycleDisplay();
- }
+#ifndef OVR_OS_LINUX
+ // Cycle through displays, going fullscreen on each one.
+ if (!down) ChangeDisplay ( false, true, false );
break;
+#else
+ // On Linux, fallthrough to F10/F11
#endif
+
#ifdef OVR_OS_MAC
- case Key_F10: // F11 is reserved on Mac
+ // F11 is reserved on Mac, F10 doesn't work on Windows
+ case Key_F10:
#else
case Key_F11:
#endif
+ if (!down) ChangeDisplay ( false, false, true );
+ break;
+
+ case Key_R:
if (!down)
{
- RenderParams = pRender->GetParams();
- RenderParams.Display = DisplayId(SConfig.GetHMDInfo().DisplayDeviceName,SConfig.GetHMDInfo().DisplayId);
- pRender->SetParams(RenderParams);
-
- pPlatform->SetMouseMode(Mouse_Normal);
- pPlatform->SetFullscreen(RenderParams, pRender->IsFullscreen() ? Display_Window : Display_FakeFullscreen);
- pPlatform->SetMouseMode(Mouse_Relative); // Avoid mode world rotation jump.
- // If using an HMD, enable post-process (for distortion) and stereo.
- if(RenderParams.IsDisplaySet() && pRender->IsFullscreen())
- {
- SConfig.SetStereoMode(Stereo_LeftRight_Multipass);
- PostProcess = PostProcess_Distortion;
- }
+ ovrHmd_ResetSensor(Hmd);
+ Menu.SetPopupMessage("Sensor Fusion Reset");
}
break;
- case Key_Escape:
- if(!down)
+ case Key_Space:
+ if (!down)
{
- // switch to primary screen windowed mode
- pPlatform->SetFullscreen(RenderParams, Display_Window);
- RenderParams.Display = pPlatform->GetDisplay(0);
- pRender->SetParams(RenderParams);
- Screen = 0;
+ TextScreen = (enum TextScreen)((TextScreen + 1) % Text_Count);
}
break;
- // Stereo adjustments.
- case Key_BracketLeft:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustFov : 0;
- AdjustDirection = 1;
- break;
- case Key_BracketRight:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustFov : 0;
- AdjustDirection = -1;
- break;
-
- case Key_Insert:
- case Key_Num0:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustIPD : 0;
- AdjustDirection = 1;
+ // Distortion correction adjustments
+ case Key_Backslash:
break;
- case Key_Delete:
- case Key_Num9:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustIPD : 0;
- AdjustDirection = -1;
- break;
-
- case Key_PageUp:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustAspect : 0;
- AdjustDirection = 1;
- break;
- case Key_PageDown:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustAspect : 0;
- AdjustDirection = -1;
- break;
-
- // Distortion correction adjustments
- case Key_H:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK0 : NULL;
- AdjustDirection = -1;
- break;
- case Key_Y:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK0 : NULL;
- AdjustDirection = 1;
- break;
- case Key_J:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK1 : NULL;
- AdjustDirection = -1;
- break;
- case Key_U:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK1 : NULL;
- AdjustDirection = 1;
- break;
- case Key_K:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK2 : NULL;
- AdjustDirection = -1;
- break;
- case Key_I:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK2 : NULL;
- AdjustDirection = 1;
- break;
- case Key_L:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK3 : NULL;
- AdjustDirection = -1;
- break;
- case Key_O:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustDistortionK3 : NULL;
- AdjustDirection = 1;
- break;
-
- case Key_Tab:
- if (down)
- {
- float t0 = SConfig.GetDistortionK(0),
- t1 = SConfig.GetDistortionK(1),
- t2 = SConfig.GetDistortionK(2),
- t3 = SConfig.GetDistortionK(3);
- float tESD = SConfig.GetEyeToScreenDistance(),
- taspect = SConfig.GetAspectMultiplier(),
- tipd = SConfig.GetIPD();
-
- if(SavedK0 > 0.0f)
- {
- SConfig.SetDistortionK(0, SavedK0);
- SConfig.SetDistortionK(1, SavedK1);
- SConfig.SetDistortionK(2, SavedK2);
- SConfig.SetDistortionK(3, SavedK3);
- SConfig.SetEyeToScreenDistance(SavedESD);
- SConfig.SetAspectMultiplier(SavedAspect);
- SConfig.SetIPD(SavedEyeDistance);
-
- if ( ShiftDown )
- {
- // Swap saved and current values. Good for doing direct comparisons.
- SetAdjustMessage("Swapped current and saved. New settings:\n"
- "ESD:\t120 %.3f\t350 Eye:\t490 %.3f\n"
- "K0: \t120 %.4f\t350 K2: \t490 %.4f\n"
- "K1: \t120 %.4f\t350 K3: \t490 %.4f\n",
- SavedESD, SavedEyeDistance,
- SavedK0, SavedK2,
- SavedK1, SavedK3);
- SavedK0 = t0;
- SavedK1 = t1;
- SavedK2 = t2;
- SavedK3 = t3;
- SavedESD = tESD;
- SavedAspect = taspect;
- SavedEyeDistance = tipd;
- }
- else
- {
- SetAdjustMessage("Restored:\n"
- "ESD:\t120 %.3f\t350 Eye:\t490 %.3f\n"
- "K0: \t120 %.4f\t350 K2: \t490 %.4f\n"
- "K1: \t120 %.4f\t350 K3: \t490 %.4f\n",
- SavedESD, SavedEyeDistance,
- SavedK0, SavedK2,
- SavedK1, SavedK3);
- }
- }
- else
- {
- SetAdjustMessage("Setting Saved");
- SavedK0 = t0;
- SavedK1 = t1;
- SavedK2 = t2;
- SavedK3 = t3;
- SavedESD = tESD;
- SavedAspect = taspect;
- SavedEyeDistance = tipd;
- }
-
- }
- break;
-
- case Key_G:
- if (down)
- {
- if(SceneMode == Scene_World)
- {
- SceneMode = Scene_Grid;
- SetAdjustMessage("Grid Only");
- }
- else if(SceneMode == Scene_Grid)
- {
- SceneMode = Scene_Both;
- SetAdjustMessage("Grid Overlay");
- }
- else if(SceneMode == Scene_Both)
- {
- SceneMode = Scene_World;
- SetAdjustMessage("Grid Off");
- }
- }
- break;
-
// Holding down Shift key accelerates adjustment velocity.
case Key_Shift:
ShiftDown = down;
break;
-
- // Reset the camera position in case we get stuck
- case Key_T:
- ThePlayer.EyePos = Vector3f(10.0f, ThePlayer.UserEyeHeight, 10.0f);
+ case Key_Control:
+ CtrlDown = down;
break;
- case Key_F5:
- if (!down)
+ // Reset the camera position in case we get stuck
+ case Key_T:
+ if (down)
{
- UPInt numNodes = MainScene.Models.GetSize();
- for(UPInt i = 0; i < numNodes; i++)
+ struct {
+ float x, z;
+ float YawDegrees;
+ } Positions[] =
{
- Ptr<OVR::Render::Model> nodePtr = MainScene.Models[i];
- Render::Model* pNode = nodePtr.GetPtr();
- if(pNode->IsCollisionModel)
- {
- pNode->Visible = !pNode->Visible;
- }
- }
+ // x z Yaw
+ { 7.7f, -1.0f, 180.0f }, // The starting position.
+ { 10.0f, 10.0f, 90.0f }, // Outside, looking at some trees.
+ { 19.26f, 5.43f, 22.0f }, // Outside, looking at the fountain.
+ };
+
+ static int nextPosition = 0;
+ nextPosition = (nextPosition + 1) % (sizeof(Positions)/sizeof(Positions[0]));
+
+ ThePlayer.BodyPos = Vector3f(Positions[nextPosition].x,
+ ThePlayer.UserEyeHeight, Positions[nextPosition].z);
+ ThePlayer.BodyYaw = DegreeToRad( Positions[nextPosition].YawDegrees );
}
break;
- case Key_N:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustMotionPrediction : NULL;
- AdjustDirection = -1;
+ case Key_Num1:
+ ThePlayer.BodyPos = Vector3f(-1.85f, 6.0f, -0.52f);
+ ThePlayer.BodyPos.y += ThePlayer.UserEyeHeight;
+ ThePlayer.BodyYaw = 3.1415f / 2;
+ ThePlayer.HandleMovement(0, &CollisionModels, &GroundCollisionModels, ShiftDown);
break;
- case Key_M:
- pAdjustFunc = down ? &OculusWorldDemoApp::AdjustMotionPrediction : NULL;
- AdjustDirection = 1;
+ default:
break;
+ }
+}
-/*
- case Key_N:
- RaiseLOD();
- break;
- case Key_M:
- DropLOD();
- break;
-*/
+//-----------------------------------------------------------------------------
- // Cycle through drift correction options
- case Key_Z:
- if (down)
- {
- if (SFusion.IsYawCorrectionEnabled())
- {
- SFusion.SetGravityEnabled(false);
- SFusion.SetYawCorrectionEnabled(false);
- }
- else if (SFusion.IsGravityEnabled())
- {
- SFusion.SetYawCorrectionEnabled(true);
- }
- else
- {
- SFusion.SetGravityEnabled(true);
- }
- SetAdjustMessage("Tilt Correction %s\nYaw Correction %s",
- SFusion.IsGravityEnabled() ? "On" : "Off",
- SFusion.IsYawCorrectionEnabled() ? "On" : "Off");
- }
- break;
- // Show view of yaw angles (for mag calibration/analysis)
- case Key_F6:
- if (down)
- {
- if (SceneMode != Scene_YawView)
- {
- SceneMode = Scene_YawView;
- SetAdjustMessage("Magnetometer Yaw Angle Marks");
- }
- else
- {
- SceneMode = Scene_World;
- SetAdjustMessage("Magnetometer Marks Off");
- }
- }
- break;
+Matrix4f OculusWorldDemoApp::CalculateViewFromPose(const Posef& pose)
+{
+ Posef worldPose = ThePlayer.VirtualWorldPoseFromRealPose(pose);
- case Key_C:
- if (down)
- {
- // Toggle chromatic aberration correction on/off.
- RenderDevice::PostProcessShader shader = pRender->GetPostProcessShader();
+ // Rotate and position View Camera
+ Vector3f up = worldPose.Orientation.Rotate(UpVector);
+ Vector3f forward = worldPose.Orientation.Rotate(ForwardVector);
- if (shader == RenderDevice::PostProcessShader_Distortion)
- {
- pRender->SetPostProcessShader(RenderDevice::PostProcessShader_DistortionAndChromAb);
- SetAdjustMessage("Chromatic Aberration Correction On");
- }
- else if (shader == RenderDevice::PostProcessShader_DistortionAndChromAb)
- {
- pRender->SetPostProcessShader(RenderDevice::PostProcessShader_Distortion);
- SetAdjustMessage("Chromatic Aberration Correction Off");
- }
- else
- OVR_ASSERT(false);
- }
- break;
+ // Transform the position of the center eye in the real world (i.e. sitting in your chair)
+ // into the frame of the player's virtual body.
- case Key_P:
- if (down)
- {
- // Toggle motion prediction.
- if (SFusion.IsPredictionEnabled())
- {
- SFusion.SetPredictionEnabled(false);
- SetAdjustMessage("Motion Prediction Off");
- }
- else
- {
- SFusion.SetPredictionEnabled(true);
- SetAdjustMessage("Motion Prediction On");
- }
- }
- break;
- default:
- break;
- }
+ // It is important to have head movement in scale with IPD.
+ // If you shrink one, you should also shrink the other.
+ // So with zero IPD (i.e. everything at infinity),
+ // head movement should also be zero.
+ Vector3f viewPos = ForceZeroHeadMovement ? ThePlayer.BodyPos : worldPose.Position;
+
+ Matrix4f view = Matrix4f::LookAtRH(viewPos, viewPos + forward, up);
+ return view;
}
+
+
void OculusWorldDemoApp::OnIdle()
{
+ double curtime = ovr_GetTimeInSeconds();
+ // If running slower than 10fps, clamp. Helps when debugging, because then dt can be minutes!
+ float dt = Alg::Min<float>(float(curtime - LastUpdate), 0.1f);
+ LastUpdate = curtime;
- double curtime = pPlatform->GetAppTime();
- float dt = float(curtime - LastUpdate);
- LastUpdate = curtime;
-
- // Update gamepad.
- GamepadState gamepadState;
- if (GetPlatformCore()->GetGamepadManager()->GetGamepadState(0, &gamepadState))
- {
- GamepadStateChanged(gamepadState);
- }
+ Profiler.RecordSample(RenderProfiler::Sample_FrameStart);
if (LoadingState == LoadingState_DoLoad)
{
PopulateScene(MainFilePath.ToCStr());
LoadingState = LoadingState_Finished;
return;
- }
-
- // Check if any new devices were connected.
- {
- bool queueIsEmpty = false;
- while (!queueIsEmpty)
- {
- DeviceStatusNotificationDesc desc;
-
- {
- Lock::Locker lock(pManager->GetHandlerLock());
- if (DeviceStatusNotificationsQueue.GetSize() == 0)
- break;
- desc = DeviceStatusNotificationsQueue.Front();
-
- // We can't call Clear under the lock since this may introduce a dead lock:
- // this thread is locked by HandlerLock and the Clear might cause
- // call of Device->Release, which will use Manager->DeviceLock. The bkg
- // thread is most likely locked by opposite way:
- // Manager->DeviceLock ==> HandlerLock, therefore - a dead lock.
- // So, just grab the first element, save a copy of it and remove
- // the element (Device->Release won't be called since we made a copy).
-
- DeviceStatusNotificationsQueue.RemoveAt(0);
- queueIsEmpty = (DeviceStatusNotificationsQueue.GetSize() == 0);
- }
-
- bool wasAlreadyCreated = desc.Handle.IsCreated();
-
- if (desc.Action == Message_DeviceAdded)
- {
- switch(desc.Handle.GetType())
- {
- case Device_Sensor:
- if (desc.Handle.IsAvailable() && !desc.Handle.IsCreated())
- {
- if (!pSensor)
- {
- pSensor = *desc.Handle.CreateDeviceTyped<SensorDevice>();
- if (pSensor)
- {
- SFusion.AttachToSensor(pSensor);
-
- SetAdjustMessage("---------------------------\n"
- "SENSOR connected\n"
- "---------------------------");
- }
- else
- {
- SetAdjustMessage("----------------------------\n"
- "SENSOR connect failed\n"
- "Unplug and reconnect it.\n"
- "----------------------------");
- }
- }
- else if (!wasAlreadyCreated)
- {
- LogText("A new SENSOR has been detected, but it is not currently used.");
- }
- }
- break;
- case Device_LatencyTester:
- if (desc.Handle.IsAvailable() && !desc.Handle.IsCreated())
- {
- if (!pLatencyTester)
- {
- pLatencyTester = *desc.Handle.CreateDeviceTyped<LatencyTestDevice>();
- LatencyUtil.SetDevice(pLatencyTester);
- if (!wasAlreadyCreated)
- SetAdjustMessage("----------------------------------------\n"
- "LATENCY TESTER connected\n"
- "----------------------------------------");
- }
- }
- break;
- case Device_HMD:
- {
- OVR::HMDInfo info;
- desc.Handle.GetDeviceInfo(&info);
- // if strlen(info.DisplayDeviceName) == 0 then
- // this HMD is 'fake' (created using sensor).
- if (strlen(info.DisplayDeviceName) > 0 && (!pHMD || !info.IsSameDisplay(TheHMDInfo)))
- {
- SetAdjustMessage("------------------------\n"
- "HMD connected\n"
- "------------------------");
- if (!pHMD || !desc.Handle.IsDevice(pHMD))
- pHMD = *desc.Handle.CreateDeviceTyped<HMDDevice>();
- // update stereo config with new HMDInfo
- if (pHMD && pHMD->GetDeviceInfo(&TheHMDInfo))
- {
- //RenderParams.MonitorName = hmd.DisplayDeviceName;
- SConfig.SetHMDInfo(TheHMDInfo);
- }
- LogText("HMD device added.\n");
- }
- break;
- }
- default:;
- }
- }
- else if (desc.Action == Message_DeviceRemoved)
- {
- if (desc.Handle.IsDevice(pSensor))
- {
- LogText("Sensor reported device removed.\n");
- SFusion.AttachToSensor(NULL);
- pSensor.Clear();
- SetAdjustMessage("-------------------------------\n"
- "SENSOR disconnected.\n"
- "-------------------------------");
- }
- else if (desc.Handle.IsDevice(pLatencyTester))
- {
- LogText("Latency Tester reported device removed.\n");
- LatencyUtil.SetDevice(NULL);
- pLatencyTester.Clear();
- SetAdjustMessage("---------------------------------------------\n"
- "LATENCY SENSOR disconnected.\n"
- "---------------------------------------------");
- }
- else if (desc.Handle.IsDevice(pHMD))
- {
- if (pHMD && !pHMD->IsDisconnected())
- {
- SetAdjustMessage("---------------------------\n"
- "HMD disconnected\n"
- "---------------------------");
- // Disconnect HMD. pSensor is used to restore 'fake' HMD device
- // (can be NULL).
- pHMD = pHMD->Disconnect(pSensor);
-
- // This will initialize TheHMDInfo with information about configured IPD,
- // screen size and other variables needed for correct projection.
- // We pass HMD DisplayDeviceName into the renderer to select the
- // correct monitor in full-screen mode.
- if (pHMD && pHMD->GetDeviceInfo(&TheHMDInfo))
- {
- //RenderParams.MonitorName = hmd.DisplayDeviceName;
- SConfig.SetHMDInfo(TheHMDInfo);
- }
- LogText("HMD device removed.\n");
- }
- }
- }
- else
- OVR_ASSERT(0); // unexpected action
- }
- }
+ }
- // If one of Stereo setting adjustment keys is pressed, adjust related state.
- if (pAdjustFunc)
+ if (HmdSettingsChanged)
{
- (this->*pAdjustFunc)(dt * AdjustDirection * (ShiftDown ? 5.0f : 1.0f));
+ CalculateHmdValues();
+ HmdSettingsChanged = false;
}
- // Process latency tester results.
- const char* results = LatencyUtil.GetResultsString();
- if (results != NULL)
- {
- LogText("LATENCY TESTER: %s\n", results);
- }
+ HmdFrameTiming = ovrHmd_BeginFrame(Hmd, 0);
- // >>> THIS MUST BE PLACED AS CLOSE AS POSSIBLE TO WHERE THE HMD ORIENTATION IS READ <<<
- LatencyUtil.ProcessInputs();
- // Handle Sensor motion.
- // We extract Yaw, Pitch, Roll instead of directly using the orientation
- // to allow "additional" yaw manipulation with mouse/controller.
- if(pSensor)
+ // Update gamepad.
+ GamepadState gamepadState;
+ if (GetPlatformCore()->GetGamepadManager()->GetGamepadState(0, &gamepadState))
{
- Quatf hmdOrient = SFusion.GetPredictedOrientation();
+ GamepadStateChanged(gamepadState);
+ }
- float yaw = 0.0f;
- hmdOrient.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &ThePlayer.EyePitch, &ThePlayer.EyeRoll);
+ SensorState ss = ovrHmd_GetSensorState(Hmd, HmdFrameTiming.ScanoutMidpointSeconds);
+ HmdStatus = ss.StatusFlags;
- ThePlayer.EyeYaw += (yaw - ThePlayer.LastSensorYaw);
- ThePlayer.LastSensorYaw = yaw;
+ // Change message status around positional tracking.
+ bool hadVisionTracking = HaveVisionTracking;
+ HaveVisionTracking = (ss.StatusFlags & Status_PositionTracked) != 0;
+ if (HaveVisionTracking && !hadVisionTracking)
+ Menu.SetPopupMessage("Vision Tracking Acquired");
+ if (!HaveVisionTracking && hadVisionTracking)
+ Menu.SetPopupMessage("Lost Vision Tracking");
+
+ // Check if any new devices were connected.
+ ProcessDeviceNotificationQueue();
+ // FPS count and timing.
+ UpdateFrameRateCounter(curtime);
- // NOTE: We can get a matrix from orientation as follows:
- // Matrix4f hmdMat(hmdOrient);
+
+ // Update pose based on frame!
+ ThePlayer.HeadPose = ss.Predicted.Transform;
+ // Movement/rotation with the gamepad.
+ ThePlayer.BodyYaw -= ThePlayer.GamepadRotate.x * dt;
+ ThePlayer.HandleMovement(dt, &CollisionModels, &GroundCollisionModels, ShiftDown);
- // Test logic - assign quaternion result directly to view:
- // Quatf hmdOrient = SFusion.GetOrientation();
- // View = Matrix4f(hmdOrient.Inverted()) * Matrix4f::Translation(-EyePos);
- }
+ // Record after processing time.
+ Profiler.RecordSample(RenderProfiler::Sample_AfterGameProcessing);
- if(curtime >= NextFPSUpdate)
- {
- NextFPSUpdate = curtime + 1.0;
- FPS = FrameCounter;
- FrameCounter = 0;
- }
- FrameCounter++;
- if(FPS < 40)
- {
- ConsecutiveLowFPSFrames++;
- }
- else
+ // Determine if we are rendering this frame. Frame rendering may be
+ // skipped based on FreezeEyeUpdate and Time-warp timing state.
+ bool bupdateRenderedView = FrameNeedsRendering(curtime);
+
+ if (bupdateRenderedView)
{
- ConsecutiveLowFPSFrames = 0;
- }
+ // If render texture size is changing, apply dynamic changes to viewport.
+ ApplyDynamicResolutionScaling();
- if(ConsecutiveLowFPSFrames > 200)
- {
- DropLOD();
- ConsecutiveLowFPSFrames = 0;
- }
+ pRender->BeginScene(PostProcess_None);
- ThePlayer.EyeYaw -= ThePlayer.GamepadRotate.x * dt;
- ThePlayer.HandleCollision(dt, &CollisionModels, &GroundCollisionModels, ShiftDown);
+ if (ForceZeroIpd)
+ {
+ // Zero IPD eye rendering: draw into left eye only,
+ // re-use texture for right eye.
+ pRender->SetRenderTarget(RenderTargets[Rendertarget_Left].pTex);
+ pRender->Clear();
+
+ ovrPosef eyeRenderPose = ovrHmd_BeginEyeRender(Hmd, ovrEye_Left);
+
+ View = CalculateViewFromPose(eyeRenderPose);
+ RenderEyeView(ovrEye_Left);
+ ovrHmd_EndEyeRender(Hmd, ovrEye_Left, eyeRenderPose, &EyeTexture[ovrEye_Left]);
- if(!pSensor)
- {
- ThePlayer.EyePitch -= ThePlayer.GamepadRotate.y * dt;
+ // Second eye gets the same texture (initialized to same value above).
+ ovrHmd_BeginEyeRender(Hmd, ovrEye_Right);
+ ovrHmd_EndEyeRender(Hmd, ovrEye_Right, eyeRenderPose, &EyeTexture[ovrEye_Right]);
+ }
- const float maxPitch = ((3.1415f / 2) * 0.98f);
- if(ThePlayer.EyePitch > maxPitch)
+ else if (RendertargetIsSharedByBothEyes)
{
- ThePlayer.EyePitch = maxPitch;
+ // Shared render target eye rendering; set up RT once for both eyes.
+ pRender->SetRenderTarget(RenderTargets[Rendertarget_BothEyes].pTex);
+ pRender->Clear();
+
+ for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++)
+ {
+ ovrEyeType eye = HmdDesc.EyeRenderOrder[eyeIndex];
+ ovrPosef eyeRenderPose = ovrHmd_BeginEyeRender(Hmd, eye);
+
+ View = CalculateViewFromPose(eyeRenderPose);
+ RenderEyeView(eye);
+ ovrHmd_EndEyeRender(Hmd, eye, eyeRenderPose, &EyeTexture[eye]);
+ }
}
- if(ThePlayer.EyePitch < -maxPitch)
+
+ else
{
- ThePlayer.EyePitch = -maxPitch;
- }
- }
+ // Separate eye rendering - each eye gets its own render target.
+ for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++)
+ {
+ ovrEyeType eye = HmdDesc.EyeRenderOrder[eyeIndex];
+ pRender->SetRenderTarget(
+ RenderTargets[(eye == 0) ? Rendertarget_Left : Rendertarget_Right].pTex);
+ pRender->Clear();
+
+ ovrPosef eyeRenderPose = ovrHmd_BeginEyeRender(Hmd, eye);
- // Rotate and position View Camera, using YawPitchRoll in BodyFrame coordinates.
- //
- Matrix4f rollPitchYaw = Matrix4f::RotationY(ThePlayer.EyeYaw) * Matrix4f::RotationX(ThePlayer.EyePitch) *
- Matrix4f::RotationZ(ThePlayer.EyeRoll);
- Vector3f up = rollPitchYaw.Transform(UpVector);
- Vector3f forward = rollPitchYaw.Transform(ForwardVector);
+ View = CalculateViewFromPose(eyeRenderPose);
+ RenderEyeView(eye);
+ ovrHmd_EndEyeRender(Hmd, eye, eyeRenderPose, &EyeTexture[eye]);
+ }
+ }
+ pRender->SetRenderTarget(0);
+ pRender->FinishScene();
+ }
- // Minimal head modeling; should be moved as an option to SensorFusion.
- float headBaseToEyeHeight = 0.15f; // Vertical height of eye from base of head
- float headBaseToEyeProtrusion = 0.09f; // Distance forward of eye from base of head
+ Profiler.RecordSample(RenderProfiler::Sample_AfterEyeRender);
- Vector3f eyeCenterInHeadFrame(0.0f, headBaseToEyeHeight, -headBaseToEyeProtrusion);
- Vector3f shiftedEyePos = ThePlayer.EyePos + rollPitchYaw.Transform(eyeCenterInHeadFrame);
- shiftedEyePos.y -= eyeCenterInHeadFrame.y; // Bring the head back down to original height
- View = Matrix4f::LookAtRH(shiftedEyePos, shiftedEyePos + forward, up);
+ // TODO: These happen inside ovrHmd_EndFrame; need to hook into it.
+ //Profiler.RecordSample(RenderProfiler::Sample_BeforeDistortion);
+ ovrHmd_EndFrame(Hmd);
+ Profiler.RecordSample(RenderProfiler::Sample_AfterPresent);
+}
- // Transformation without head modeling.
- // View = Matrix4f::LookAtRH(EyePos, EyePos + forward, up);
- // This is an alternative to LookAtRH:
- // Here we transpose the rotation matrix to get its inverse.
- // View = (Matrix4f::RotationY(EyeYaw) * Matrix4f::RotationX(EyePitch) *
- // Matrix4f::RotationZ(EyeRoll)).Transposed() *
- // Matrix4f::Translation(-EyePos);
+// Determine whether this frame needs rendering based on time-warp timing and flags.
+bool OculusWorldDemoApp::FrameNeedsRendering(double curtime)
+{
+ static double lastUpdate = 0.0;
+ double renderInterval = TimewarpRenderIntervalInSeconds;
+ double timeSinceLast = curtime - lastUpdate;
+ bool updateRenderedView = true;
- switch(SConfig.GetStereoMode())
+ if (TimewarpEnabled)
{
- case Stereo_None:
- Render(SConfig.GetEyeRenderParams(StereoEye_Center));
- break;
+ if (FreezeEyeUpdate)
+ {
+ // Draw one frame after (FreezeEyeUpdate = true) to update message text.
+ if (FreezeEyeOneFrameRendered)
+ updateRenderedView = false;
+ else
+ FreezeEyeOneFrameRendered = true;
+ }
+ else
+ {
+ FreezeEyeOneFrameRendered = false;
- case Stereo_LeftRight_Multipass:
- //case Stereo_LeftDouble_Multipass:
- Render(SConfig.GetEyeRenderParams(StereoEye_Left));
- Render(SConfig.GetEyeRenderParams(StereoEye_Right));
- break;
+ if ( (timeSinceLast < 0.0) || ((float)timeSinceLast > renderInterval) )
+ {
+ // This allows us to do "fractional" speeds, e.g. 45fps rendering on a 60fps display.
+ lastUpdate += renderInterval;
+ if ( timeSinceLast > 5.0 )
+ {
+ // renderInterval is probably tiny (i.e. "as fast as possible")
+ lastUpdate = curtime;
+ }
+ updateRenderedView = true;
+ }
+ else
+ {
+ updateRenderedView = false;
+ }
+ }
}
-
- pRender->Present();
- // Force GPU to flush the scene, resulting in the lowest possible latency.
- pRender->ForceFlushGPU();
+
+ return updateRenderedView;
}
-static const char* HelpText =
- "F1 \t100 NoStereo\n"
- "F2 \t100 Stereo \t420 Z \t520 Drift Correction\n"
- "F3 \t100 StereoHMD \t420 F6 \t520 Yaw Drift Info\n"
- "F4 \t100 MSAA \t420 R \t520 Reset SensorFusion\n"
- "F9 \t100 FullScreen \t420\n"
- "F11 \t100 Fast FullScreen \t500 - + \t660 Adj EyeHeight\n"
- "C \t100 Chromatic Ab \t500 [ ] \t660 Adj FOV\n"
- "P \t100 Motion Pred \t500 Shift \t660 Adj Faster\n"
- "N/M \t180 Adj Motion Pred\n"
- "( / ) \t180 Adj EyeDistance"
- ;
-
-
-enum DrawTextCenterType
-{
- DrawText_NoCenter= 0,
- DrawText_VCenter = 0x1,
- DrawText_HCenter = 0x2,
- DrawText_Center = DrawText_VCenter | DrawText_HCenter
-};
-
-static void DrawTextBox(RenderDevice* prender, float x, float y,
- float textSize, const char* text,
- DrawTextCenterType centerType = DrawText_NoCenter)
+void OculusWorldDemoApp::ApplyDynamicResolutionScaling()
{
- float ssize[2] = {0.0f, 0.0f};
-
- prender->MeasureText(&DejaVu, text, textSize, ssize);
-
- // Treat 0 a VCenter.
- if (centerType & DrawText_HCenter)
+ if (!DynamicRezScalingEnabled)
{
- x = -ssize[0]/2;
+ // Restore viewport rectangle in case dynamic res scaling was enabled before.
+ EyeTexture[0].Header.RenderViewport = EyeRenderDesc[0].Desc.RenderViewport;
+ EyeTexture[1].Header.RenderViewport = EyeRenderDesc[1].Desc.RenderViewport;
+ return;
}
- if (centerType & DrawText_VCenter)
+
+ // Demonstrate dynamic-resolution rendering.
+ // This demo is too simple to actually have a framerate that varies that much, so we'll
+ // just pretend this is trying to cope with highly dynamic rendering load.
+ float dynamicRezScale = 1.0f;
+
{
- y = -ssize[1]/2;
+ // Hacky stuff to make up a scaling...
+ // This produces value oscillating as follows: 0 -> 1 -> 0.
+ static double dynamicRezStartTime = ovr_GetTimeInSeconds();
+ float dynamicRezPhase = float ( ovr_GetTimeInSeconds() - dynamicRezStartTime );
+ const float dynamicRezTimeScale = 4.0f;
+
+ dynamicRezPhase /= dynamicRezTimeScale;
+ if ( dynamicRezPhase < 1.0f )
+ {
+ dynamicRezScale = dynamicRezPhase;
+ }
+ else if ( dynamicRezPhase < 2.0f )
+ {
+ dynamicRezScale = 2.0f - dynamicRezPhase;
+ }
+ else
+ {
+ // Reset it to prevent creep.
+ dynamicRezStartTime = ovr_GetTimeInSeconds();
+ dynamicRezScale = 0.0f;
+ }
+
+ // Map oscillation: 0.5 -> 1.0 -> 0.5
+ dynamicRezScale = dynamicRezScale * 0.5f + 0.5f;
}
- prender->FillRect(x-0.02f, y-0.02f, x+ssize[0]+0.02f, y+ssize[1]+0.02f, Color(40,40,100,210));
- prender->RenderText(&DejaVu, text, x, y, textSize, Color(255,255,0,210));
+ Sizei sizeLeft = EyeRenderDesc[0].Desc.RenderViewport.Size;
+ Sizei sizeRight = EyeRenderDesc[1].Desc.RenderViewport.Size;
+
+ // This viewport is used for rendering and passed into ovrHmd_EndEyeRender.
+ EyeTexture[0].Header.RenderViewport.Size = Sizei(int(sizeLeft.w * dynamicRezScale),
+ int(sizeLeft.h * dynamicRezScale));
+ EyeTexture[1].Header.RenderViewport.Size = Sizei(int(sizeRight.w * dynamicRezScale),
+ int(sizeRight.h * dynamicRezScale));
}
-void OculusWorldDemoApp::Render(const StereoEyeParams& stereo)
+
+void OculusWorldDemoApp::UpdateFrameRateCounter(double curtime)
{
- pRender->BeginScene(PostProcess);
+ FrameCounter++;
+ float secondsSinceLastMeasurement = (float)( curtime - LastFpsUpdate );
+
+ if (secondsSinceLastMeasurement >= SecondsOfFpsMeasurement)
+ {
+ SecondsPerFrame = (float)( curtime - LastFpsUpdate ) / (float)FrameCounter;
+ FPS = 1.0f / SecondsPerFrame;
+ LastFpsUpdate = curtime;
+ FrameCounter = 0;
+ }
+}
- // *** 3D - Configures Viewport/Projection and Render
- pRender->ApplyStereoParams(stereo);
- pRender->Clear();
+void OculusWorldDemoApp::RenderEyeView(ovrEyeType eye)
+{
+ Recti renderViewport = EyeTexture[eye].Header.RenderViewport;
+ Matrix4f viewAdjust = Matrix4f::Translation(Vector3f(EyeRenderDesc[eye].ViewAdjust));
+
+
+ // *** 3D - Configures Viewport/Projection and Render
+
+ pRender->ApplyStereoParams(renderViewport, Projection[eye]);
pRender->SetDepthMode(true, true);
- if (SceneMode != Scene_Grid)
+
+ Matrix4f baseTranslate = Matrix4f::Translation(ThePlayer.BodyPos);
+ Matrix4f baseYaw = Matrix4f::RotationY(ThePlayer.BodyYaw.Get());
+
+
+ if (GridDisplayMode != GridDisplay_GridOnly)
{
- MainScene.Render(pRender, stereo.ViewAdjust * View);
- }
+ if (SceneMode != Scene_OculusCubes)
+ {
+ MainScene.Render(pRender, viewAdjust * View);
+ RenderAnimatedBlocks(eye, ovr_GetTimeInSeconds());
+ }
+
+ if (SceneMode == Scene_Cubes)
+ {
+ // Draw scene cubes overlay. Red if position tracked, blue otherwise.
+ Scene sceneCubes = (HmdStatus & ovrStatus_PositionTracked) ?
+ RedCubesScene : BlueCubesScene;
+ sceneCubes.Render(pRender, viewAdjust * View * baseTranslate * baseYaw);
+ }
- if (SceneMode == Scene_YawView)
+ else if (SceneMode == Scene_OculusCubes)
+ {
+ OculusCubesScene.Render(pRender, viewAdjust * View * baseTranslate * baseYaw);
+ }
+ }
+
+ if (GridDisplayMode != GridDisplay_None)
{
- Matrix4f trackerOnlyOrient = Matrix4f::RotationY(ThePlayer.LastSensorYaw)
- * Matrix4f::RotationX(ThePlayer.EyePitch)
- * Matrix4f::RotationZ(ThePlayer.EyeRoll);
- YawLinesScene.Render(pRender, stereo.ViewAdjust * trackerOnlyOrient.Inverted());
- //YawMarkRedScene.Render(pRender, stereo.ViewAdjust);
+ RenderGrid(eye);
}
- // *** 2D Text & Grid - Configure Orthographic rendering.
+
+ // *** 2D Text - Configure Orthographic rendering.
// Render UI in 2D orthographic coordinate system that maps [-1,1] range
// to a readable FOV area centered at your eye and properly adjusted.
- pRender->ApplyStereoParams2D(stereo);
+ pRender->ApplyStereoParams(renderViewport, OrthoProjection[eye]);
pRender->SetDepthMode(false, false);
- float unitPixel = SConfig.Get2DUnitPixel();
- float textHeight= unitPixel * 22;
-
- if ((SceneMode == Scene_Grid)||(SceneMode == Scene_Both))
- { // Draw grid two pixels thick.
- GridScene.Render(pRender, Matrix4f());
- GridScene.Render(pRender, Matrix4f::Translation(unitPixel,unitPixel,0));
- }
+ // We set this scale up in CreateOrthoSubProjection().
+ float textHeight = 22.0f;
// Display Loading screen-shot in frame 0.
if (LoadingState != LoadingState_Finished)
{
- LoadingScene.Render(pRender, Matrix4f());
+ const float scale = textHeight * 25.0f;
+ Matrix4f view ( scale, 0.0f, 0.0f, 0.0f, scale, 0.0f, 0.0f, 0.0f, scale );
+ LoadingScene.Render(pRender, view);
String loadMessage = String("Loading ") + MainFilePath;
- DrawTextBox(pRender, 0.0f, 0.0f, textHeight, loadMessage.ToCStr(), DrawText_HCenter);
+ DrawTextBox(pRender, 0.0f, -textHeight, textHeight, loadMessage.ToCStr(), DrawText_HCenter);
LoadingState = LoadingState_DoLoad;
}
- if(!AdjustMessage.IsEmpty() && AdjustMessageTimeout > pPlatform->GetAppTime())
- {
- DrawTextBox(pRender,0.0f,0.4f, textHeight, AdjustMessage.ToCStr(), DrawText_HCenter);
- }
+ // HUD overlay brought up by spacebar.
+ RenderTextInfoHud(textHeight);
+ // Menu brought up by
+ Menu.Render(pRender);
+}
+
+
+
+// NOTE - try to keep these in sync with the PDF docs!
+static const char* HelpText1 =
+ "Spacebar \t500 Toggle debug info overlay\n"
+ "W, S \t500 Move forward, back\n"
+ "A, D \t500 Strafe left, right\n"
+ "Mouse move \t500 Look left, right\n"
+ "Left gamepad stick \t500 Move\n"
+ "Right gamepad stick \t500 Turn\n"
+ "T \t500 Reset player position";
+
+static const char* HelpText2 =
+ "R \t250 Reset sensor orientation\n"
+ "G \t250 Cycle grid overlay mode\n"
+ "-, + \t250 Adjust eye height\n"
+ "Esc \t250 Cancel full-screen\n"
+ "F4 \t250 Multisampling toggle\n"
+ "F9 \t250 Hardware full-screen (low latency)\n"
+ "F11 \t250 Faked full-screen (easier debugging)\n"
+ "Ctrl+Q \t250 Quit";
+
+
+void FormatLatencyReading(char* buff, UPInt size, float val)
+{
+ if (val < 0.000001f)
+ OVR_strcpy(buff, size, "N/A ");
+ else
+ OVR_sprintf(buff, size, "%4.2fms", val * 1000.0f);
+}
+
+
+void OculusWorldDemoApp::RenderTextInfoHud(float textHeight)
+{
+ // View port & 2D ortho projection must be set before call.
+
+ float hmdYaw, hmdPitch, hmdRoll;
switch(TextScreen)
{
- case Text_Orientation:
+ case Text_Info:
{
- char buf[256], gpustat[256];
+ char buf[512], gpustat[256];
+
+ // Average FOVs.
+ FovPort leftFov = EyeRenderDesc[0].Desc.Fov;
+ FovPort rightFov = EyeRenderDesc[1].Desc.Fov;
+
+ // Rendered size changes based on selected options & dynamic rendering.
+ int pixelSizeWidth = EyeTexture[0].Header.RenderViewport.Size.w +
+ ((!ForceZeroIpd) ?
+ EyeTexture[1].Header.RenderViewport.Size.w : 0);
+ int pixelSizeHeight = ( EyeTexture[0].Header.RenderViewport.Size.h +
+ EyeTexture[1].Header.RenderViewport.Size.h ) / 2;
+
+ // No DK2, no message.
+ char latency2Text[128] = "";
+ {
+ //float latency2 = ovrHmd_GetMeasuredLatencyTest2(Hmd) * 1000.0f; // show it in ms
+ //if (latency2 > 0)
+ // OVR_sprintf(latency2Text, sizeof(latency2Text), "%.2fms", latency2);
+
+ float latencies[3] = { 0.0f, 0.0f, 0.0f };
+ if (ovrHmd_GetFloatArray(Hmd, "DK2Latency", latencies, 3) == 3)
+ {
+ char latencyText0[32], latencyText1[32], latencyText2[32];
+ FormatLatencyReading(latencyText0, sizeof(latencyText0), latencies[0]);
+ FormatLatencyReading(latencyText1, sizeof(latencyText1), latencies[1]);
+ FormatLatencyReading(latencyText2, sizeof(latencyText2), latencies[2]);
+
+ OVR_sprintf(latency2Text, sizeof(latency2Text),
+ " DK2 Latency Ren: %s TWrp: %s\n"
+ " PostPresent: %s ",
+ latencyText0, latencyText1, latencyText2);
+ }
+ }
+
+ ThePlayer.HeadPose.Orientation.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&hmdYaw, &hmdPitch, &hmdRoll);
OVR_sprintf(buf, sizeof(buf),
- " Yaw:%4.0f Pitch:%4.0f Roll:%4.0f \n"
- " FPS: %d Frame: %d \n Pos: %3.2f, %3.2f, %3.2f \n"
- " EyeHeight: %3.2f",
- RadToDegree(ThePlayer.EyeYaw), RadToDegree(ThePlayer.EyePitch), RadToDegree(ThePlayer.EyeRoll),
- FPS, FrameCounter, ThePlayer.EyePos.x, ThePlayer.EyePos.y, ThePlayer.EyePos.z, ThePlayer.UserEyeHeight);
+ " HMD YPR:%4.0f %4.0f %4.0f Player Yaw: %4.0f\n"
+ " FPS: %.1f ms/frame: %.1f Frame: %d\n"
+ " Pos: %3.2f, %3.2f, %3.2f HMD: %s\n"
+ " EyeHeight: %3.2f, IPD: %3.1fmm\n" //", Lens: %s\n"
+ " FOV %3.1fx%3.1f, Resolution: %ix%i\n"
+ "%s",
+ RadToDegree(hmdYaw), RadToDegree(hmdPitch), RadToDegree(hmdRoll),
+ RadToDegree(ThePlayer.BodyYaw.Get()),
+ FPS, SecondsPerFrame * 1000.0f, FrameCounter,
+ ThePlayer.BodyPos.x, ThePlayer.BodyPos.y, ThePlayer.BodyPos.z,
+ //GetDebugNameHmdType ( TheHmdRenderInfo.HmdType ),
+ HmdDesc.ProductName,
+ ThePlayer.UserEyeHeight,
+ ovrHmd_GetFloat(Hmd, OVR_KEY_IPD, 0) * 1000.0f,
+ //( EyeOffsetFromNoseLeft + EyeOffsetFromNoseRight ) * 1000.0f,
+ //GetDebugNameEyeCupType ( TheHmdRenderInfo.EyeCups ), // Lens/EyeCup not exposed
+
+ (leftFov.GetHorizontalFovDegrees() + rightFov.GetHorizontalFovDegrees()) * 0.5f,
+ (leftFov.GetVerticalFovDegrees() + rightFov.GetVerticalFovDegrees()) * 0.5f,
+
+ pixelSizeWidth, pixelSizeHeight,
+
+ latency2Text
+ );
+
size_t texMemInMB = pRender->GetTotalTextureMemoryUsage() / 1058576;
if (texMemInMB)
{
- OVR_sprintf(gpustat, sizeof(gpustat), "\n GPU Tex: %u MB", texMemInMB);
+ OVR_sprintf(gpustat, sizeof(gpustat), " GPU Tex: %u MB", texMemInMB);
OVR_strcat(buf, sizeof(buf), gpustat);
}
- DrawTextBox(pRender, 0.0f, -0.15f, textHeight, buf, DrawText_HCenter);
+ DrawTextBox(pRender, 0.0f, 0.0f, textHeight, buf, DrawText_Center);
}
break;
-
- case Text_Config:
- {
- char textBuff[2048];
-
- OVR_sprintf(textBuff, sizeof(textBuff),
- "Fov\t300 %9.4f\n"
- "EyeDistance\t300 %9.4f\n"
- "DistortionK0\t300 %9.4f\n"
- "DistortionK1\t300 %9.4f\n"
- "DistortionK2\t300 %9.4f\n"
- "DistortionK3\t300 %9.4f\n"
- "TexScale\t300 %9.4f",
- SConfig.GetYFOVDegrees(),
- SConfig.GetIPD(),
- SConfig.GetDistortionK(0),
- SConfig.GetDistortionK(1),
- SConfig.GetDistortionK(2),
- SConfig.GetDistortionK(3),
- SConfig.GetDistortionScale());
-
- DrawTextBox(pRender, 0.0f, 0.0f, textHeight, textBuff, DrawText_Center);
- }
+
+ case Text_Timing:
+ Profiler.DrawOverlay(pRender);
break;
-
- case Text_Help:
- DrawTextBox(pRender, 0.0f, -0.1f, textHeight, HelpText, DrawText_Center);
-
- default:
+
+ case Text_Help1:
+ DrawTextBox(pRender, 0.0f, 0.0f, textHeight, HelpText1, DrawText_Center);
+ break;
+ case Text_Help2:
+ DrawTextBox(pRender, 0.0f, 0.0f, textHeight, HelpText2, DrawText_Center);
+ break;
+
+ case Text_None:
break;
- }
-
- // Display colored quad if we're doing a latency test.
- Color colorToDisplay;
- if (LatencyUtil.DisplayScreenColor(colorToDisplay))
- {
- pRender->FillRect(-0.4f, -0.4f, 0.4f, 0.4f, colorToDisplay);
+ default:
+ OVR_ASSERT ( !"Missing text screen" );
+ break;
}
-
- pRender->FinishScene();
}
-// Sets temporarily displayed message for adjustments
-void OculusWorldDemoApp::SetAdjustMessage(const char* format, ...)
-{
- Lock::Locker lock(pManager->GetHandlerLock());
- char textBuff[2048];
- va_list argList;
- va_start(argList, format);
- OVR_vsprintf(textBuff, sizeof(textBuff), format, argList);
- va_end(argList);
-
- // Message will time out in 4 seconds.
- AdjustMessage = textBuff;
- AdjustMessageTimeout = pPlatform->GetAppTime() + 4.0f;
-}
-
-void OculusWorldDemoApp::SetAdjustMessageTimeout(float timeout)
-{
- AdjustMessageTimeout = pPlatform->GetAppTime() + timeout;
-}
+//-----------------------------------------------------------------------------
+// ***** Callbacks For Menu changes
-// ***** View Control Adjustments
+// Non-trivial callback go here.
-void OculusWorldDemoApp::AdjustFov(float dt)
+void OculusWorldDemoApp::HmdSettingChangeFreeRTs(OptionVar*)
{
- float esd = SConfig.GetEyeToScreenDistance() + 0.01f * dt;
- SConfig.SetEyeToScreenDistance(esd);
- SetAdjustMessage("ESD:%6.3f FOV: %6.3f", esd, SConfig.GetYFOVDegrees());
+ HmdSettingsChanged = true;
+ // Cause the RTs to be recreated with the new mode.
+ for ( int rtNum = 0; rtNum < Rendertarget_LAST; rtNum++ )
+ RenderTargets[rtNum].pTex = NULL;
}
-void OculusWorldDemoApp::AdjustAspect(float dt)
+void OculusWorldDemoApp::MultisampleChange(OptionVar*)
{
- float rawAspect = SConfig.GetAspect() / SConfig.GetAspectMultiplier();
- float newAspect = SConfig.GetAspect() + 0.01f * dt;
- SConfig.SetAspectMultiplier(newAspect / rawAspect);
- SetAdjustMessage("Aspect: %6.3f", newAspect);
+ HmdSettingChangeFreeRTs();
}
-void OculusWorldDemoApp::AdjustDistortion(float dt, int kIndex, const char* label)
+void OculusWorldDemoApp::CenterPupilDepthChange(OptionVar*)
{
- SConfig.SetDistortionK(kIndex, SConfig.GetDistortionK(kIndex) + 0.03f * dt);
- SetAdjustMessage("%s: %6.4f", label, SConfig.GetDistortionK(kIndex));
+ ovrHmd_SetFloat(Hmd, "CenterPupilDepth", CenterPupilDepthMeters);
}
-void OculusWorldDemoApp::AdjustIPD(float dt)
+void OculusWorldDemoApp::DistortionClearColorChange(OptionVar*)
{
- SConfig.SetIPD(SConfig.GetIPD() + 0.025f * dt);
- SetAdjustMessage("EyeDistance: %6.4f", SConfig.GetIPD());
+ float clearColor[2][4] = { { 0.0f, 0.0f, 0.0f, 0.0f },
+ { 0.0f, 0.5f, 1.0f, 0.0f } };
+ ovrHmd_SetFloatArray(Hmd, "DistortionClearColor",
+ clearColor[(int)DistortionClearBlue], 4);
}
-void OculusWorldDemoApp::AdjustEyeHeight(float dt)
-{
- float dist = 0.5f * dt;
-
- ThePlayer.UserEyeHeight += dist;
- ThePlayer.EyePos.y += dist;
- SetAdjustMessage("UserEyeHeight: %4.2f", ThePlayer.UserEyeHeight);
-}
+//-----------------------------------------------------------------------------
-void OculusWorldDemoApp::AdjustMotionPrediction(float dt)
+void OculusWorldDemoApp::ProcessDeviceNotificationQueue()
{
- float motionPred = SFusion.GetPredictionDelta() + 0.01f * dt;
-
- if (motionPred < 0.0f)
- {
- motionPred = 0.0f;
- }
-
- SFusion.SetPrediction(motionPred);
-
- SetAdjustMessage("MotionPrediction: %6.3fs", motionPred);
+ // TBD: Process device plug & Unplug
}
-void OculusWorldDemoApp::AdjustDistortion(float val, int kIndex)
-{
- SConfig.SetDistortionK(kIndex, val);
- SetAdjustMessage("K%d: %6.4f", kIndex, SConfig.GetDistortionK(kIndex));
-}
-void OculusWorldDemoApp::AdjustEsd(float val)
+//-----------------------------------------------------------------------------
+void OculusWorldDemoApp::ChangeDisplay ( bool bBackToWindowed, bool bNextFullscreen,
+ bool bFullWindowDebugging )
{
- SConfig.SetEyeToScreenDistance(val);
- float esd = SConfig.GetEyeToScreenDistance();
- SetAdjustMessage("ESD:%6.3f FOV: %6.3f", esd, SConfig.GetYFOVDegrees());
-}
+ // Exactly one should be set...
+ OVR_ASSERT ( ( bBackToWindowed ? 1 : 0 ) + ( bNextFullscreen ? 1 : 0 ) +
+ ( bFullWindowDebugging ? 1 : 0 ) == 1 );
+ OVR_UNUSED ( bNextFullscreen );
-// Loads the scene data
-void OculusWorldDemoApp::PopulateScene(const char *fileName)
-{
- XmlHandler xmlHandler;
- if(!xmlHandler.ReadFile(fileName, pRender, &MainScene, &CollisionModels, &GroundCollisionModels))
+ if ( bFullWindowDebugging )
{
- SetAdjustMessage("---------------------------------\nFILE LOAD FAILED\n---------------------------------");
- SetAdjustMessageTimeout(10.0f);
- }
-
- MainScene.SetAmbient(Vector4f(1.0f, 1.0f, 1.0f, 1.0f));
-
- // Distortion debug grid (brought up by 'G' key).
- Ptr<Model> gridModel = *Model::CreateGrid(Vector3f(0,0,0), Vector3f(1.0f/10, 0,0), Vector3f(0,1.0f/10,0),
- 10, 10, 5,
- Color(0, 255, 0, 255), Color(255, 50, 50, 255) );
- GridScene.World.Add(gridModel);
-
- // Yaw angle marker and lines (brought up by ';' key).
- float shifty = -0.5f;
- Ptr<Model> yawMarkGreenModel = *Model::CreateBox(Color(0, 255, 0, 255), Vector3f(0.0f, shifty, -2.0f), Vector3f(0.05f, 0.05f, 0.05f));
- YawMarkGreenScene.World.Add(yawMarkGreenModel);
- Ptr<Model> yawMarkRedModel = *Model::CreateBox(Color(255, 0, 0, 255), Vector3f(0.0f, shifty, -2.0f), Vector3f(0.05f, 0.05f, 0.05f));
- YawMarkRedScene.World.Add(yawMarkRedModel);
-
- Ptr<Model> yawLinesModel = *new Model();
- Color c = Color(255, 200, 200, 255);
- float r = 1.5f;
- yawLinesModel->AddTriangle(yawLinesModel->AddVertex(Vector3f(-0.1f, 0, -r), c),
- yawLinesModel->AddVertex(Vector3f(0, 0, -r-0.2f), c),
- yawLinesModel->AddVertex(Vector3f(0.1f, 0, -r), c));
- yawLinesModel->AddTriangle(yawLinesModel->AddVertex(Vector3f(-r-0.1f, 0, -r), c),
- yawLinesModel->AddVertex(Vector3f(-r, 0, -r-0.2f), c),
- yawLinesModel->AddVertex(Vector3f(-r+0.1f, 0, -r), c));
- yawLinesModel->AddTriangle(yawLinesModel->AddVertex(Vector3f(r-0.1f, 0, -r), c),
- yawLinesModel->AddVertex(Vector3f(r, 0, -r-0.2f), c),
- yawLinesModel->AddVertex(Vector3f(r+0.1f, 0, -r), c));
- yawLinesModel->SetPosition(Vector3f(0.0f,-1.2f,0.0f));
- YawLinesScene.World.Add(yawLinesModel);
-}
-
-
-void OculusWorldDemoApp::PopulatePreloadScene()
-{
- // Load-screen screen shot image
- String fileName = MainFilePath;
- fileName.StripExtension();
-
- Ptr<File> imageFile = *new SysFile(fileName + "_LoadScreen.tga");
- Ptr<Texture> imageTex;
- if (imageFile->IsValid())
- imageTex = *LoadTextureTga(pRender, imageFile);
+ // Slightly hacky. Doesn't actually go fullscreen, just makes a screen-sized wndow.
+ // This has higher latency than fullscreen, and is not intended for actual use,
+ // but makes for much nicer debugging on some systems.
+ RenderParams = pRender->GetParams();
+ RenderParams.Display = DisplayId(HmdDesc.DisplayDeviceName, HmdDesc.DisplayId);
+ pRender->SetParams(RenderParams);
- // Image is rendered as a single quad.
- if (imageTex)
- {
- imageTex->SetSampleMode(Sample_Anisotropic|Sample_Repeat);
- Ptr<Model> m = *new Model(Prim_Triangles);
- m->AddVertex(-0.5f, 0.5f, 0.0f, Color(255,255,255,255), 0.0f, 0.0f);
- m->AddVertex( 0.5f, 0.5f, 0.0f, Color(255,255,255,255), 1.0f, 0.0f);
- m->AddVertex( 0.5f, -0.5f, 0.0f, Color(255,255,255,255), 1.0f, 1.0f);
- m->AddVertex(-0.5f, -0.5f, 0.0f, Color(255,255,255,255), 0.0f, 1.0f);
- m->AddTriangle(2,1,0);
- m->AddTriangle(0,3,2);
-
- Ptr<ShaderFill> fill = *new ShaderFill(*pRender->CreateShaderSet());
- fill->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Vertex, VShader_MVP));
- fill->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_Texture));
- fill->SetTexture(0, imageTex);
- m->Fill = fill;
-
- LoadingScene.World.Add(m);
+ pPlatform->SetMouseMode(Mouse_Normal);
+ pPlatform->SetFullscreen(RenderParams, pRender->IsFullscreen() ? Display_Window : Display_FakeFullscreen);
+ pPlatform->SetMouseMode(Mouse_Relative); // Avoid mode world rotation jump.
+
+ // If using an HMD, enable post-process (for distortion) and stereo.
+ if (RenderParams.IsDisplaySet() && pRender->IsFullscreen())
+ {
+ //SetPostProcessingMode ( PostProcess );
+ }
}
-}
-
-void OculusWorldDemoApp::ClearScene()
-{
- MainScene.Clear();
- GridScene.Clear();
- YawMarkGreenScene.Clear();
- YawMarkRedScene.Clear();
- YawLinesScene.Clear();
-}
-
-void OculusWorldDemoApp::PopulateLODFileNames()
-{
- //OVR::String mainFilePath = MainFilePath;
- LODFilePaths.PushBack(MainFilePath);
- int LODIndex = 1;
- SPInt pos = strcspn(MainFilePath.ToCStr(), ".");
- SPInt len = strlen(MainFilePath.ToCStr());
- SPInt diff = len - pos;
-
- if (diff == 0)
- return;
-
- while(true)
+ else
{
- char pathWithoutExt[250];
- char buffer[250];
- for(SPInt i = 0; i < pos; ++i)
+ int screenCount = pPlatform->GetDisplayCount();
+
+ int screenNumberToSwitchTo;
+ if ( bBackToWindowed )
{
- pathWithoutExt[i] = MainFilePath[(int)i];
+ screenNumberToSwitchTo = -1;
}
- pathWithoutExt[pos] = '\0';
- OVR_sprintf(buffer, sizeof(buffer), "%s%i.xml", pathWithoutExt, LODIndex);
- FILE* fp = 0;
-#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
- errno_t err = fopen_s(&fp, buffer, "rb");
- if(!fp || err)
+ else
{
-#else
- fp = fopen(buffer, "rb");
- if(!fp)
- {
-#endif
- break;
+ if (!pRender->IsFullscreen())
+ {
+ // Currently windowed.
+ // Try to find HMD Screen, making it the first screen in the full-screen cycle.
+ FirstScreenInCycle = 0;
+ if (!UsingDebugHmd)
+ {
+ DisplayId HMD (HmdDesc.DisplayDeviceName, HmdDesc.DisplayId);
+ for (int i = 0; i< screenCount; i++)
+ {
+ if (pPlatform->GetDisplay(i) == HMD)
+ {
+ FirstScreenInCycle = i;
+ break;
+ }
+ }
+ }
+ ScreenNumber = FirstScreenInCycle;
+ screenNumberToSwitchTo = ScreenNumber;
+ }
+ else
+ {
+ // Currently fullscreen, so cycle to the next screen.
+ ScreenNumber++;
+ if (ScreenNumber == screenCount)
+ {
+ ScreenNumber = 0;
+ }
+ screenNumberToSwitchTo = ScreenNumber;
+ if (ScreenNumber == FirstScreenInCycle)
+ {
+ // We have cycled through all the fullscreen displays, so go back to windowed mode.
+ screenNumberToSwitchTo = -1;
+ }
+ }
}
- fclose(fp);
- OVR::String result = buffer;
- LODFilePaths.PushBack(result);
- LODIndex++;
- }
-}
-
-void OculusWorldDemoApp::DropLOD()
-{
- if(CurrentLODFileIndex < (int)(LODFilePaths.GetSize() - 1))
- {
- ClearScene();
- CurrentLODFileIndex++;
- PopulateScene(LODFilePaths[CurrentLODFileIndex].ToCStr());
- }
-}
-void OculusWorldDemoApp::RaiseLOD()
-{
- if(CurrentLODFileIndex > 0)
- {
- ClearScene();
- CurrentLODFileIndex--;
- PopulateScene(LODFilePaths[CurrentLODFileIndex].ToCStr());
- }
-}
-
-//-----------------------------------------------------------------------------
-void OculusWorldDemoApp::CycleDisplay()
-{
- int screenCount = pPlatform->GetDisplayCount();
-
- // If Windowed, switch to the HMD screen first in Full-Screen Mode.
- // If already Full-Screen, cycle to next screen until we reach FirstScreenInCycle.
-
- if (pRender->IsFullscreen())
- {
- // Right now, we always need to restore window before going to next screen.
+ // Always restore windowed mode before going to next screen, even if we were already fullscreen.
pPlatform->SetFullscreen(RenderParams, Display_Window);
-
- Screen++;
- if (Screen == screenCount)
- Screen = 0;
-
- RenderParams.Display = pPlatform->GetDisplay(Screen);
-
- if (Screen != FirstScreenInCycle)
+ if ( screenNumberToSwitchTo >= 0 )
{
+ // Go fullscreen.
+ RenderParams.Display = pPlatform->GetDisplay(screenNumberToSwitchTo);
pRender->SetParams(RenderParams);
- pPlatform->SetFullscreen(RenderParams, Display_Fullscreen);
+ pPlatform->SetFullscreen(RenderParams, Display_Fullscreen);
}
}
- else
- {
- // Try to find HMD Screen, making it the first screen in full-screen Cycle.
- FirstScreenInCycle = 0;
-
- if (pHMD)
- {
- DisplayId HMD (SConfig.GetHMDInfo().DisplayDeviceName, SConfig.GetHMDInfo().DisplayId);
- for (int i = 0; i< screenCount; i++)
- {
- if (pPlatform->GetDisplay(i) == HMD)
- {
- FirstScreenInCycle = i;
- break;
- }
- }
- }
- // Switch full-screen on the HMD.
- Screen = FirstScreenInCycle;
- RenderParams.Display = pPlatform->GetDisplay(Screen);
- pRender->SetParams(RenderParams);
- pPlatform->SetFullscreen(RenderParams, Display_Fullscreen);
- }
+
+ // Updates render target pointers & sizes.
+ HmdSettingChangeFreeRTs();
}
void OculusWorldDemoApp::GamepadStateChanged(const GamepadState& pad)
@@ -1764,6 +1271,15 @@ void OculusWorldDemoApp::GamepadStateChanged(const GamepadState& pad)
0,
pad.LY * pad.LY * (pad.LY > 0 ? -1 : 1));
ThePlayer.GamepadRotate = Vector3f(2 * pad.RX, -2 * pad.RY, 0);
+
+ UInt32 gamepadDeltas = (pad.Buttons ^ LastGamepadState.Buttons) & pad.Buttons;
+
+ if (gamepadDeltas)
+ {
+ Menu.OnGamepad(gamepadDeltas);
+ }
+
+ LastGamepadState = pad;
}
diff --git a/Samples/OculusWorldDemo/OculusWorldDemo.h b/Samples/OculusWorldDemo/OculusWorldDemo.h
new file mode 100644
index 0000000..54f0e9d
--- /dev/null
+++ b/Samples/OculusWorldDemo/OculusWorldDemo.h
@@ -0,0 +1,339 @@
+/************************************************************************************
+
+Filename : OculusWorldDemo.h
+Content : First-person view test application for Oculus Rift - Header file
+Created : October 4, 2012
+Authors : Michael Antonov, Andrew Reisse, Steve LaValle, Dov Katz
+ Peter Hoff, Dan Goodman, Bryan Croteau
+
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*************************************************************************************/
+
+#ifndef INC_OculusWorldDemo_h
+#define INC_OculusWorldDemo_h
+
+#include "OVR.h"
+
+#include "../CommonSrc/Platform/Platform_Default.h"
+#include "../CommonSrc/Render/Render_Device.h"
+#include "../CommonSrc/Render/Render_XmlSceneLoader.h"
+#include "../CommonSrc/Platform/Gamepad.h"
+
+#include "Util/Util_Render_Stereo.h"
+using namespace OVR::Util::Render;
+
+#include <Kernel/OVR_SysFile.h>
+#include <Kernel/OVR_Log.h>
+#include <Kernel/OVR_Timer.h>
+
+#include "Player.h"
+#include "OVR_DeviceConstants.h"
+
+#include "OptionMenu.h"
+#include "RenderProfiler.h"
+
+// Filename to be loaded by default, searching specified paths.
+#define WORLDDEMO_ASSET_FILE "Tuscany.xml"
+
+#define WORLDDEMO_ASSET_PATH1 "Assets/Tuscany/"
+#define WORLDDEMO_ASSET_PATH2 "../../../Assets/Tuscany/"
+// This path allows the shortcut to work.
+#define WORLDDEMO_ASSET_PATH3 "Samples/OculusWorldDemo/Assets/Tuscany/"
+
+using namespace OVR;
+using namespace OVR::Platform;
+using namespace OVR::Render;
+
+
+//-------------------------------------------------------------------------------------
+// ***** OculusWorldDemo Description
+
+// This app renders a loaded scene allowing the user to move along the
+// floor and look around with an HMD, mouse and keyboard. The following keys work:
+//
+// 'W', 'S', 'A', 'D' and Arrow Keys - Move forward, back; strafe left/right.
+//
+// Space - Bring up status and help display.
+// Tab - Bring up/hide menu with editable options.
+// F4 - Toggle MSAA.
+// F9 - Cycle through fullscreen and windowed modes.
+// Necessary for previewing content with Rift.
+//
+// Important Oculus-specific logic can be found at following locations:
+//
+// OculusWorldDemoApp::OnStartup - This function will initialize the SDK, creating the Hmd
+// and delegating to CalculateHmdValues to initialize it.
+//
+// OculusWorldDemoApp::OnIdle - Here we poll SensorFusion for orientation, apply it
+// to the scene and handle movement.
+// Stereo rendering is also done here, by delegating to
+// to the RenderEyeView() function for each eye.
+//
+
+//-------------------------------------------------------------------------------------
+// ***** OculusWorldDemo Application class
+
+// An instance of this class is created on application startup (main/WinMain).
+// It then works as follows:
+// - Graphics and HMD setup is done OculusWorldDemoApp::OnStartup(). Much of
+// HMD configuration here is moved to CalculateHmdValues.
+// OnStartup also creates the room model from Slab declarations.
+//
+// - Per-frame processing is done in OnIdle(). This function processes
+// sensor and movement input and then renders the frame.
+//
+// - Additional input processing is done in OnMouse, OnKey.
+
+class OculusWorldDemoApp : public Application
+{
+public:
+ OculusWorldDemoApp();
+ ~OculusWorldDemoApp();
+
+ virtual int OnStartup(int argc, const char** argv);
+ virtual void OnIdle();
+
+ virtual void OnMouseMove(int x, int y, int modifiers);
+ virtual void OnKey(OVR::KeyCode key, int chr, bool down, int modifiers);
+ virtual void OnResize(int width, int height);
+
+ bool SetupWindowAndRendering(int argc, const char** argv);
+
+ // Adds room model to scene.
+ void InitMainFilePath();
+ void PopulateScene(const char* fileName);
+ void PopulatePreloadScene();
+ void ClearScene();
+ void PopulateOptionMenu();
+
+
+ // Computes all of the Hmd values and configures render targets.
+ void CalculateHmdValues();
+ // Returns the actual size present.
+ Sizei EnsureRendertargetAtLeastThisBig (int rtNum, Sizei size);
+
+
+ // Renders full stereo scene for one eye.
+ void RenderEyeView(ovrEyeType eye);
+ // Renderes HUD overlay brough up by spacebar; 2D viewport must be set before call.
+ void RenderTextInfoHud(float textHeight);
+ void RenderAnimatedBlocks(ovrEyeType eye, double appTime);
+ void RenderGrid(ovrEyeType eye);
+
+ Matrix4f CalculateViewFromPose(const Posef& pose);
+
+ // Determine whether this frame needs rendering based on timewarp timing and flags.
+ bool FrameNeedsRendering(double curtime);
+ void ApplyDynamicResolutionScaling();
+ void UpdateFrameRateCounter(double curtime);
+
+
+ // Model creation and misc functions.
+ Model* CreateModel(Vector3f pos, struct SlabModel* sm);
+ Model* CreateBoundingModel(CollisionModel &cm);
+ void ChangeDisplay ( bool bBackToWindowed, bool bNextFullscreen, bool bFullWindowDebugging );
+ void GamepadStateChanged(const GamepadState& pad);
+
+ // Processes DeviceNotificationStatus queue to handles plug/unplug.
+ void ProcessDeviceNotificationQueue();
+
+
+ // ***** Callbacks for Menu option changes
+
+ // These contain extra actions to be taken in addition to switching the state.
+ void HmdSettingChange(OptionVar* = 0) { HmdSettingsChanged = true; }
+ void BlockShowChange(OptionVar* = 0) { BlocksCenter = ThePlayer.BodyPos; }
+ void EyeHeightChange(OptionVar* = 0) { ThePlayer.BodyPos.y = ThePlayer.UserEyeHeight; }
+
+ void HmdSettingChangeFreeRTs(OptionVar* = 0);
+ void MultisampleChange(OptionVar* = 0);
+ void CenterPupilDepthChange(OptionVar* = 0);
+ void DistortionClearColorChange(OptionVar* = 0);
+
+
+protected:
+ RenderDevice* pRender;
+ RendererParams RenderParams;
+ Sizei WindowSize;
+ int ScreenNumber;
+ int FirstScreenInCycle;
+
+ struct RenderTarget
+ {
+ Ptr<Texture> pTex;
+ ovrTexture Tex;
+ };
+ enum RendertargetsEnum
+ {
+ Rendertarget_Left,
+ Rendertarget_Right,
+ Rendertarget_BothEyes, // Used when both eyes are rendered to the same target.
+ Rendertarget_LAST
+ };
+ RenderTarget RenderTargets[Rendertarget_LAST];
+
+
+ // ***** Oculus HMD Variables
+
+ ovrHmd Hmd;
+ ovrHmdDesc HmdDesc;
+ ovrEyeRenderDesc EyeRenderDesc[2];
+ Matrix4f Projection[2]; // Projection matrix for eye.
+ Matrix4f OrthoProjection[2]; // Projection for 2D.
+ ovrTexture EyeTexture[2];
+ // Sensor caps applied.
+ unsigned StartSensorCaps;
+ bool UsingDebugHmd;
+
+ // Frame timing logic.
+ enum { SecondsOfFpsMeasurement = 1 };
+ int FrameCounter;
+ double NextFPSUpdate;
+ float SecondsPerFrame;
+ float FPS;
+ double LastFpsUpdate;
+
+ // Times a single frame.
+ double LastUpdate;
+
+ // Loaded data.
+ String MainFilePath;
+ Array<Ptr<CollisionModel> > CollisionModels;
+ Array<Ptr<CollisionModel> > GroundCollisionModels;
+
+ // Loading process displays screenshot in first frame
+ // and then proceeds to load until finished.
+ enum LoadingStateType
+ {
+ LoadingState_Frame0,
+ LoadingState_DoLoad,
+ LoadingState_Finished
+ } LoadingState;
+
+ // Set when vision tracking is detected.
+ bool HaveVisionTracking;
+
+ GamepadState LastGamepadState;
+
+ Player ThePlayer;
+ Matrix4f View;
+ Scene MainScene;
+ Scene LoadingScene;
+ Scene SmallGreenCube;
+
+ Scene OculusCubesScene;
+ Scene RedCubesScene;
+ Scene BlueCubesScene;
+
+ // Last frame asn sensor data reported by BeginFrame().
+ ovrFrameTiming HmdFrameTiming;
+ unsigned HmdStatus;
+
+
+ // ***** Modifiable Menu Options
+
+ // This flag is set when HMD settings change, causing HMD to be re-initialized.
+ bool HmdSettingsChanged;
+
+ // Render Target - affecting state.
+ bool RendertargetIsSharedByBothEyes;
+ bool DynamicRezScalingEnabled;
+ bool ForceZeroIpd;
+ float DesiredPixelDensity;
+ float FovSideTanMax;
+ float FovSideTanLimit; // Limit value for Fov.
+ // Time-warp.
+ bool TimewarpEnabled;
+ float TimewarpRenderIntervalInSeconds;
+ bool FreezeEyeUpdate;
+ bool FreezeEyeOneFrameRendered;
+
+ // Other global settings.
+ float CenterPupilDepthMeters;
+ // float IPD;
+ bool ForceZeroHeadMovement;
+ bool VsyncEnabled;
+ bool MultisampleEnabled;
+ // DK2 only
+ bool IsLowPersistence;
+ bool DynamicPrediction;
+ bool PositionTrackingEnabled;
+
+ // Support toggling background color for distortion so that we can see
+ // the effect on the periphery.
+ int DistortionClearBlue;
+
+ // Stereo settings adjustment state.
+ bool ShiftDown;
+ bool CtrlDown;
+
+
+ // ***** Scene Rendering Modes
+
+ enum SceneRenderMode
+ {
+ Scene_World,
+ Scene_Cubes,
+ Scene_OculusCubes
+ };
+ SceneRenderMode SceneMode;
+
+ enum GridDispayModeType
+ {
+ GridDisplay_None,
+ GridDisplay_GridOnly,
+ GridDisplay_GridAndScene
+ };
+ GridDispayModeType GridDisplayMode;
+
+ // What type of grid to display.
+ enum GridModeType
+ {
+ Grid_Rendertarget4,
+ Grid_Rendertarget16,
+ Grid_Lens,
+ Grid_Last
+ };
+ GridModeType GridMode;
+
+ // What help screen we display, brought up by 'Spacebar'.
+ enum TextScreen
+ {
+ Text_None,
+ Text_Info,
+ Text_Timing,
+ Text_Help1,
+ Text_Help2,
+ Text_Count
+ };
+ TextScreen TextScreen;
+
+ // Whether we are displaying animated blocks and what type.
+ int BlocksShowType;
+ Vector3f BlocksCenter;
+
+
+ // User configurable options, brought up by 'Tab' key.
+ // Also handles shortcuts and pop-up overlay messages.
+ OptionSelectionMenu Menu;
+
+ // Profiler for rendering - displays timing stats.
+ RenderProfiler Profiler;
+};
+
+
+
+#endif // INC_OculusWorldDemo_h
diff --git a/Samples/OculusWorldDemo/OculusWorldDemo_Msvc2010.vcxproj.filters b/Samples/OculusWorldDemo/OculusWorldDemo_Msvc2010.vcxproj.filters
deleted file mode 100644
index e96dc9e..0000000
--- a/Samples/OculusWorldDemo/OculusWorldDemo_Msvc2010.vcxproj.filters
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="CommonSrc">
- <UniqueIdentifier>{ba6e9e50-0655-4f12-a136-6d2a06015925}</UniqueIdentifier>
- </Filter>
- <Filter Include="CommonSrc\Platform">
- <UniqueIdentifier>{16e20d8b-eff7-454c-be85-02037c399e97}</UniqueIdentifier>
- </Filter>
- <Filter Include="CommonSrc\Render">
- <UniqueIdentifier>{1b6d51ae-a405-4f3d-be93-41a50db4f328}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="..\CommonSrc\Platform\Platform.cpp">
- <Filter>CommonSrc\Platform</Filter>
- </ClCompile>
- <ClCompile Include="..\CommonSrc\Platform\Win32_Platform.cpp">
- <Filter>CommonSrc\Platform</Filter>
- </ClCompile>
- <ClCompile Include="..\CommonSrc\Render\Render_Device.cpp">
- <Filter>CommonSrc\Render</Filter>
- </ClCompile>
- <ClCompile Include="..\CommonSrc\Render\Render_D3D1X_Device.cpp">
- <Filter>CommonSrc\Render</Filter>
- </ClCompile>
- <ClCompile Include="..\CommonSrc\Render\Render_D3D10_Device.cpp">
- <Filter>CommonSrc\Render</Filter>
- </ClCompile>
- <ClCompile Include="OculusWorldDemo.cpp" />
- <ClCompile Include="..\CommonSrc\Render\Render_D3D11_Device.cpp">
- <Filter>CommonSrc\Render</Filter>
- </ClCompile>
- <ClCompile Include="..\CommonSrc\Render\Render_LoadTextureTGA.cpp">
- <Filter>CommonSrc\Render</Filter>
- </ClCompile>
- <ClCompile Include="Player.cpp" />
- <ClCompile Include="..\..\3rdParty\TinyXml\tinyxml2.cpp" />
- <ClCompile Include="..\CommonSrc\Render\Render_LoadTextureDDS.cpp">
- <Filter>CommonSrc\Render</Filter>
- </ClCompile>
- <ClCompile Include="..\CommonSrc\Render\Render_XmlSceneLoader.cpp">
- <Filter>CommonSrc\Render</Filter>
- </ClCompile>
- <ClCompile Include="..\CommonSrc\Platform\Win32_Gamepad.cpp">
- <Filter>CommonSrc\Platform</Filter>
- </ClCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\CommonSrc\Platform\Win32_Platform.h">
- <Filter>CommonSrc\Platform</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Platform\Platform.h">
- <Filter>CommonSrc\Platform</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Platform\Platform_Default.h">
- <Filter>CommonSrc\Platform</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Render\Render_Font.h">
- <Filter>CommonSrc\Render</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Render\Render_Device.h">
- <Filter>CommonSrc\Render</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Render\Render_D3D1X_Device.h">
- <Filter>CommonSrc\Render</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Render\Render_D3D10_Device.h">
- <Filter>CommonSrc\Render</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Render\Render_D3D11_Device.h">
- <Filter>CommonSrc\Render</Filter>
- </ClInclude>
- <ClInclude Include="Player.h" />
- <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" />
- <ClInclude Include="..\CommonSrc\Render\Render_XmlSceneLoader.h">
- <Filter>CommonSrc\Render</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Platform\Gamepad.h">
- <Filter>CommonSrc\Platform</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Platform\Win32_Gamepad.h">
- <Filter>CommonSrc\Platform</Filter>
- </ClInclude>
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="OculusWorldDemo.rc" />
- </ItemGroup>
-</Project> \ No newline at end of file
diff --git a/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp b/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp
new file mode 100644
index 0000000..5dfe2d2
--- /dev/null
+++ b/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp
@@ -0,0 +1,399 @@
+/************************************************************************************
+
+Filename : OculusWorldDemo_Scene.cpp
+Content : Logic for loading, and creating rendered scene components,
+ cube and grid overlays, etc.
+Created : October 4, 2012
+Authors : Michael Antonov, Andrew Reisse, Steve LaValle, Dov Katz
+ Peter Hoff, Dan Goodman, Bryan Croteau
+
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*************************************************************************************/
+
+#include "OculusWorldDemo.h"
+
+
+//-------------------------------------------------------------------------------------
+// ***** Scene Creation / Loading
+
+void OculusWorldDemoApp::InitMainFilePath()
+{
+
+ MainFilePath = WORLDDEMO_ASSET_FILE;
+
+ // Try to modify path for correctness in case specified file is not found.
+ if (!SysFile(MainFilePath).IsValid())
+ {
+ String prefixPath1(pPlatform->GetContentDirectory() + "/" + WORLDDEMO_ASSET_PATH1),
+ prefixPath2(WORLDDEMO_ASSET_PATH2),
+ prefixPath3(WORLDDEMO_ASSET_PATH3);
+ if (SysFile(prefixPath1 + MainFilePath).IsValid())
+ MainFilePath = prefixPath1 + MainFilePath;
+ else if (SysFile(prefixPath2 + MainFilePath).IsValid())
+ MainFilePath = prefixPath2 + MainFilePath;
+ else if (SysFile(prefixPath3 + MainFilePath).IsValid())
+ MainFilePath = prefixPath3 + MainFilePath;
+ }
+}
+
+// Creates a grid of cubes.
+void PopulateCubeFieldScene(Scene* scene, Fill* fill,
+ int cubeCountX, int cubeCountY, int cubeCountZ, Vector3f offset,
+ float cubeSpacing = 0.5f, float cubeSize = 0.1f)
+{
+
+ Vector3f corner(-(((cubeCountX-1) * cubeSpacing) + cubeSize) * 0.5f,
+ -(((cubeCountY-1) * cubeSpacing) + cubeSize) * 0.5f,
+ -(((cubeCountZ-1) * cubeSpacing) + cubeSize) * 0.5f);
+ corner += offset;
+
+ Vector3f pos = corner;
+
+ for (int i = 0; i < cubeCountX; i++)
+ {
+ // Create a new model for each 'plane' of cubes so we don't exceed
+ // the vert size limit.
+ Ptr<Model> model = *new Model();
+ scene->World.Add(model);
+
+ if (fill)
+ model->Fill = fill;
+
+ for (int j = 0; j < cubeCountY; j++)
+ {
+ for (int k = 0; k < cubeCountZ; k++)
+ {
+ model->AddBox(0xFFFFFFFF, pos, Vector3f(cubeSize, cubeSize, cubeSize));
+ pos.z += cubeSpacing;
+ }
+
+ pos.z = corner.z;
+ pos.y += cubeSpacing;
+ }
+
+ pos.y = corner.y;
+ pos.x += cubeSpacing;
+ }
+}
+
+Fill* CreateTexureFill(RenderDevice* prender, const String& filename)
+{
+ Ptr<File> imageFile = *new SysFile(filename);
+ Ptr<Texture> imageTex;
+ if (imageFile->IsValid())
+ imageTex = *LoadTextureTga(prender, imageFile);
+
+ // Image is rendered as a single quad.
+ ShaderFill* fill = 0;
+ if (imageTex)
+ {
+ imageTex->SetSampleMode(Sample_Anisotropic|Sample_Repeat);
+ fill = new ShaderFill(*prender->CreateShaderSet());
+ fill->GetShaders()->SetShader(prender->LoadBuiltinShader(Shader_Vertex, VShader_MVP));
+ fill->GetShaders()->SetShader(prender->LoadBuiltinShader(Shader_Fragment, FShader_Texture));
+ fill->SetTexture(0, imageTex);
+ }
+
+ return fill;
+}
+
+
+// Loads the scene data
+void OculusWorldDemoApp::PopulateScene(const char *fileName)
+{
+ XmlHandler xmlHandler;
+ if(!xmlHandler.ReadFile(fileName, pRender, &MainScene, &CollisionModels, &GroundCollisionModels))
+ {
+ Menu.SetPopupMessage("FILE LOAD FAILED");
+ Menu.SetPopupTimeout(10.0f, true);
+ }
+
+ MainScene.SetAmbient(Color4f(1.0f, 1.0f, 1.0f, 1.0f));
+
+ // Handy cube.
+ Ptr<Model> smallGreenCubeModel = *Model::CreateBox(Color(0, 255, 0, 255), Vector3f(0.0f, 0.0f, 0.0f), Vector3f(0.004f, 0.004f, 0.004f));
+ SmallGreenCube.World.Add(smallGreenCubeModel);
+
+ String mainFilePathNoExtension = MainFilePath;
+ mainFilePathNoExtension.StripExtension();
+
+
+ // 10x10x10 cubes.
+ Ptr<Fill> fillR = *CreateTexureFill(pRender, mainFilePathNoExtension + "_redCube.tga");
+ PopulateCubeFieldScene(&RedCubesScene, fillR.GetPtr(), 10, 10, 10, Vector3f(0.0f, 0.0f, 0.0f), 0.4f);
+
+ // 10x10x10 cubes.
+ Ptr<Fill> fillB = *CreateTexureFill(pRender, mainFilePathNoExtension + "_blueCube.tga");
+ PopulateCubeFieldScene(&BlueCubesScene, fillB.GetPtr(), 10, 10, 10, Vector3f(0.0f, 0.0f, 0.0f), 0.4f);
+
+ // Anna: OculusWorldDemo/Assets/Tuscany/Tuscany_OculusCube.tga file needs to be added
+ Ptr<Fill> imageFill = *CreateTexureFill(pRender, mainFilePathNoExtension + "_OculusCube.tga");
+ PopulateCubeFieldScene(&OculusCubesScene, imageFill.GetPtr(), 11, 4, 35, Vector3f(0.0f, 0.0f, -6.0f), 0.5f);
+
+
+ float r = 0.01f;
+ Ptr<Model> purpleCubesModel = *new Model(Prim_Triangles);
+ for (int i = 0; i < 10; i++)
+ for (int j = 0; j < 10; j++)
+ for (int k = 0; k < 10; k++)
+ purpleCubesModel->AddSolidColorBox(i*0.25f-1.25f-r,j*0.25f-1.25f-r,k*0.25f-1.25f-r,
+ i*0.25f-1.25f+r,j*0.25f-1.25f+r,k*0.25f-1.25f+r,0xFF9F009F);
+}
+
+
+void OculusWorldDemoApp::PopulatePreloadScene()
+{
+ // Load-screen screen shot image
+ String fileName = MainFilePath;
+ fileName.StripExtension();
+
+ Ptr<File> imageFile = *new SysFile(fileName + "_LoadScreen.tga");
+ Ptr<Texture> imageTex;
+ if (imageFile->IsValid())
+ imageTex = *LoadTextureTga(pRender, imageFile);
+
+ // Image is rendered as a single quad.
+ if (imageTex)
+ {
+ imageTex->SetSampleMode(Sample_Anisotropic|Sample_Repeat);
+ Ptr<Model> m = *new Model(Prim_Triangles);
+ m->AddVertex(-0.5f, 0.5f, 0.0f, Color(255,255,255,255), 0.0f, 0.0f);
+ m->AddVertex( 0.5f, 0.5f, 0.0f, Color(255,255,255,255), 1.0f, 0.0f);
+ m->AddVertex( 0.5f, -0.5f, 0.0f, Color(255,255,255,255), 1.0f, 1.0f);
+ m->AddVertex(-0.5f, -0.5f, 0.0f, Color(255,255,255,255), 0.0f, 1.0f);
+ m->AddTriangle(2,1,0);
+ m->AddTriangle(0,3,2);
+
+ Ptr<ShaderFill> fill = *new ShaderFill(*pRender->CreateShaderSet());
+ fill->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Vertex, VShader_MVP));
+ fill->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_Texture));
+ fill->SetTexture(0, imageTex);
+ m->Fill = fill;
+
+ LoadingScene.World.Add(m);
+ }
+}
+
+void OculusWorldDemoApp::ClearScene()
+{
+ MainScene.Clear();
+ SmallGreenCube.Clear();
+}
+
+
+//-------------------------------------------------------------------------------------
+// ***** Rendering Content
+
+
+void OculusWorldDemoApp::RenderAnimatedBlocks(ovrEyeType eye, double appTime)
+{
+ Matrix4f viewAdjust = Matrix4f::Translation(Vector3f(EyeRenderDesc[eye].ViewAdjust));
+
+ switch ( BlocksShowType )
+ {
+ case 0:
+ // No blocks;
+ break;
+ case 1: {
+ // Horizontal circle around your head.
+ int const numBlocks = 10;
+ float const radius = 1.0f;
+ Matrix4f scaleUp = Matrix4f::Scaling ( 20.0f );
+ double scaledTime = appTime * 0.1;
+ float fracTime = (float)( scaledTime - floor ( scaledTime ) );
+
+ for ( int j = 0; j < 2; j++ )
+ {
+ for ( int i = 0; i < numBlocks; i++ )
+ {
+ float angle = ( ( (float)i / numBlocks ) + fracTime ) * ( Math<float>::Pi * 2.0f );
+ Vector3f pos;
+ pos.x = BlocksCenter.x + radius * cosf ( angle );
+ pos.y = BlocksCenter.y;
+ pos.z = BlocksCenter.z + radius * sinf ( angle );
+ if ( j == 0 )
+ {
+ pos.x = BlocksCenter.x - radius * cosf ( angle );
+ pos.y = BlocksCenter.y - 0.5f;
+ }
+ Matrix4f mat = Matrix4f::Translation ( pos );
+ SmallGreenCube.Render(pRender, viewAdjust * View * mat * scaleUp);
+ }
+ }
+ }break;
+
+ case 2: {
+ // Vertical circle around your head.
+ int const numBlocks = 10;
+ float const radius = 1.0f;
+ Matrix4f scaleUp = Matrix4f::Scaling ( 20.0f );
+ double scaledTime = appTime * 0.1;
+ float fracTime = (float)( scaledTime - floor ( scaledTime ) );
+
+ for ( int j = 0; j < 2; j++ )
+ {
+ for ( int i = 0; i < numBlocks; i++ )
+ {
+ float angle = ( ( (float)i / numBlocks ) + fracTime ) * ( Math<float>::Pi * 2.0f );
+ Vector3f pos;
+ pos.x = BlocksCenter.x;
+ pos.y = BlocksCenter.y + radius * cosf ( angle );
+ pos.z = BlocksCenter.z + radius * sinf ( angle );
+ if ( j == 0 )
+ {
+ pos.x = BlocksCenter.x - 0.5f;
+ pos.y = BlocksCenter.y - radius * cosf ( angle );
+ }
+ Matrix4f mat = Matrix4f::Translation ( pos );
+ SmallGreenCube.Render(pRender, viewAdjust * View * mat * scaleUp);
+ }
+ }
+ }break;
+
+ case 3:{
+ // Bouncing.
+ int const numBlocks = 10;
+ Matrix4f scaleUp = Matrix4f::Scaling ( 20.0f );
+
+ for ( int i = 0; i < numBlocks; i++ )
+ {
+ double scaledTime = 4.0f * appTime / (double)i;
+ float fracTime = (float)( scaledTime - floor ( scaledTime ) );
+
+ Vector3f pos = BlocksCenter;
+ pos.z += (float)i;
+ pos.y += -1.5f + 4.0f * ( 2.0f * fracTime * ( 1.0f - fracTime ) );
+ Matrix4f mat = Matrix4f::Translation ( pos );
+ SmallGreenCube.Render(pRender, viewAdjust * View * mat * scaleUp);
+ }
+ }break;
+
+ default:
+ BlocksShowType = 0;
+ break;
+ }
+}
+
+void OculusWorldDemoApp::RenderGrid(ovrEyeType eye)
+{
+ Recti renderViewport = EyeTexture[eye].Header.RenderViewport;
+
+ // Draw actual pixel grid on the RT.
+ // 1:1 mapping to screen pixels, origin in top-left.
+ Matrix4f ortho;
+ ortho.SetIdentity();
+ ortho.M[0][0] = 2.0f / (renderViewport.w); // X scale
+ ortho.M[0][3] = -1.0f; // X offset
+ ortho.M[1][1] = -2.0f / (renderViewport.h); // Y scale (for Y=down)
+ ortho.M[1][3] = 1.0f; // Y offset (Y=down)
+ ortho.M[2][2] = 0;
+ pRender->SetProjection(ortho);
+
+ pRender->SetDepthMode(false, false);
+ Color cNormal ( 255, 0, 0 );
+ Color cSpacer ( 255, 255, 0 );
+ Color cMid ( 0, 128, 255 );
+
+ int lineStep = 1;
+ int midX = 0;
+ int midY = 0;
+ int limitX = 0;
+ int limitY = 0;
+
+ switch ( GridMode )
+ {
+ case Grid_Rendertarget4:
+ lineStep = 4;
+ midX = renderViewport.w / 2;
+ midY = renderViewport.h / 2;
+ limitX = renderViewport.w / 2;
+ limitY = renderViewport.h / 2;
+ break;
+ case Grid_Rendertarget16:
+ lineStep = 16;
+ midX = renderViewport.w / 2;
+ midY = renderViewport.h / 2;
+ limitX = renderViewport.w / 2;
+ limitY = renderViewport.h / 2;
+ break;
+ case Grid_Lens:
+ {
+ lineStep = 48;
+ Vector2f rendertargetNDC = FovPort(EyeRenderDesc[eye].Desc.Fov).TanAngleToRendertargetNDC(Vector2f(0.0f));
+ midX = (int)( ( rendertargetNDC.x * 0.5f + 0.5f ) * (float)renderViewport.w + 0.5f );
+ midY = (int)( ( rendertargetNDC.y * 0.5f + 0.5f ) * (float)renderViewport.h + 0.5f );
+ limitX = Alg::Max ( renderViewport.w - midX, midX );
+ limitY = Alg::Max ( renderViewport.h - midY, midY );
+ }
+ break;
+ default: OVR_ASSERT ( false ); break;
+ }
+
+ int spacerMask = (lineStep<<2)-1;
+
+
+ for ( int xp = 0; xp < limitX; xp += lineStep )
+ {
+ float x[4];
+ float y[4];
+ x[0] = (float)( midX + xp );
+ y[0] = (float)0;
+ x[1] = (float)( midX + xp );
+ y[1] = (float)renderViewport.h;
+ x[2] = (float)( midX - xp );
+ y[2] = (float)0;
+ x[3] = (float)( midX - xp );
+ y[3] = (float)renderViewport.h;
+ if ( xp == 0 )
+ {
+ pRender->RenderLines ( 1, cMid, x, y );
+ }
+ else if ( ( xp & spacerMask ) == 0 )
+ {
+ pRender->RenderLines ( 2, cSpacer, x, y );
+ }
+ else
+ {
+ pRender->RenderLines ( 2, cNormal, x, y );
+ }
+ }
+ for ( int yp = 0; yp < limitY; yp += lineStep )
+ {
+ float x[4];
+ float y[4];
+ x[0] = (float)0;
+ y[0] = (float)( midY + yp );
+ x[1] = (float)renderViewport.w;
+ y[1] = (float)( midY + yp );
+ x[2] = (float)0;
+ y[2] = (float)( midY - yp );
+ x[3] = (float)renderViewport.w;
+ y[3] = (float)( midY - yp );
+ if ( yp == 0 )
+ {
+ pRender->RenderLines ( 1, cMid, x, y );
+ }
+ else if ( ( yp & spacerMask ) == 0 )
+ {
+ pRender->RenderLines ( 2, cSpacer, x, y );
+ }
+ else
+ {
+ pRender->RenderLines ( 2, cNormal, x, y );
+ }
+ }
+}
+
diff --git a/Samples/OculusWorldDemo/OptionMenu.cpp b/Samples/OculusWorldDemo/OptionMenu.cpp
new file mode 100644
index 0000000..283136d
--- /dev/null
+++ b/Samples/OculusWorldDemo/OptionMenu.cpp
@@ -0,0 +1,896 @@
+/************************************************************************************
+
+Filename : OptionMenu.h
+Content : Option selection and editing for OculusWorldDemo
+Created : March 7, 2014
+Authors : Michael Antonov, Caleb Leak
+
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*************************************************************************************/
+
+#include "OptionMenu.h"
+
+// Embed the font.
+#include "../CommonSrc/Render/Render_FontEmbed_DejaVu48.h"
+
+
+//-------------------------------------------------------------------------------------
+bool OptionShortcut::MatchKey(KeyCode key, bool shift) const
+{
+ for (UInt32 i = 0; i < Keys.GetSize(); i++)
+ {
+ if (Keys[i].Key != key)
+ continue;
+
+ if (!shift && Keys[i].ShiftUsage == ShortcutKey::Shift_RequireOn)
+ continue;
+
+ if (shift && Keys[i].ShiftUsage == ShortcutKey::Shift_RequireOff)
+ continue;
+
+ if(Keys[i].ShiftUsage == ShortcutKey::Shift_Modify)
+ {
+ pNotify->CallNotify(&shift);
+ }
+ else
+ {
+ pNotify->CallNotify();
+ }
+ return true;
+ }
+ return false;
+}
+
+bool OptionShortcut::MatchGamepadButton(UInt32 gamepadButtonMask) const
+{
+ for (UInt32 i = 0; i < GamepadButtons.GetSize(); i++)
+ {
+ if (GamepadButtons[i] & gamepadButtonMask)
+ {
+ if (pNotify != NULL)
+ {
+ pNotify->CallNotify();
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+
+//-------------------------------------------------------------------------------------
+String OptionMenuItem::PopNamespaceFrom(OptionMenuItem* menuItem)
+{
+ String label = menuItem->Label;
+ for (UInt32 i = 0; i < label.GetLength(); i++)
+ {
+ if (label.GetCharAt(i) == '.')
+ {
+ String ns = label.Substring(0, i);
+ menuItem->Label = label.Substring(i + 1, label.GetLength());
+ return ns;
+ }
+ }
+ return "";
+}
+
+//-------------------------------------------------------------------------------------
+
+String OptionVar::FormatEnum(OptionVar* var)
+{
+ UInt32 index = var->GetEnumIndex();
+ if (index < var->EnumValues.GetSize())
+ return var->EnumValues[index].Name;
+ return String("<Bad enum index>");
+}
+
+String OptionVar::FormatInt(OptionVar* var)
+{
+ char buff[64];
+ OVR_sprintf(buff, sizeof(buff), var->FormatString, *var->AsInt());
+ return String(buff);
+}
+
+String OptionVar::FormatFloat(OptionVar* var)
+{
+ char buff[64];
+ OVR_sprintf(buff, sizeof(buff), var->FormatString, *var->AsFloat() * var->FormatScale);
+ return String(buff);
+}
+
+String OptionVar::FormatBool(OptionVar* var)
+{
+ return *var->AsBool() ? "On" : "Off";
+}
+
+
+OptionVar::OptionVar(const char* name, void* pvar, VarType type,
+ FormatFunction formatFunction,
+ UpdateFunction updateFunction)
+{
+ Label = name;
+ Type = type;
+ this->pVar = pvar;
+ fFormat = formatFunction;
+ fUpdate = updateFunction;
+ pNotify = 0;
+ FormatString= 0;
+
+ MaxFloat = Math<float>::MaxValue;
+ MinFloat = -Math<float>::MaxValue;
+ StepFloat = 1.0f;
+ FormatScale = 1.0f;
+
+ MaxInt = 0x7FFFFFFF;
+ MinInt = -(MaxInt) - 1;
+ StepInt = 1;
+
+ ShortcutUp.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::NextValue);
+ ShortcutDown.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::PrevValue);
+}
+
+OptionVar::OptionVar(const char* name, SInt32* pvar,
+ SInt32 min, SInt32 max, SInt32 stepSize,
+ const char* formatString,
+ FormatFunction formatFunction,
+ UpdateFunction updateFunction)
+{
+ Label = name;
+ Type = Type_Int;
+ this->pVar = pvar;
+ fFormat = formatFunction ? formatFunction : FormatInt;
+ fUpdate = updateFunction;
+ pNotify = 0;
+ FormatString= formatString;
+
+ MinInt = min;
+ MaxInt = max;
+ StepInt = stepSize;
+
+ ShortcutUp.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::NextValue);
+ ShortcutDown.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::PrevValue);
+}
+
+// Float with range and step size.
+OptionVar::OptionVar(const char* name, float* pvar,
+ float minf, float maxf, float stepSize,
+ const char* formatString, float formatScale,
+ FormatFunction formatFunction,
+ UpdateFunction updateFunction)
+{
+ Label = name;
+ Type = Type_Float;
+ this->pVar = pvar;
+ fFormat = formatFunction ? formatFunction : FormatFloat;
+ fUpdate = updateFunction;
+ pNotify = 0;
+ FormatString= formatString ? formatString : "%.3f";
+
+ MinFloat = minf;
+ MaxFloat = maxf;
+ StepFloat = stepSize;
+ FormatScale = formatScale;
+
+ ShortcutUp.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::NextValue);
+ ShortcutDown.pNotify = new FunctionNotifyContext<OptionVar, bool>(this, &OptionVar::PrevValue);
+}
+
+OptionVar::~OptionVar()
+{
+ if (pNotify)
+ delete pNotify;
+}
+
+void OptionVar::NextValue(bool* pFastStep)
+{
+ bool fastStep = (pFastStep != NULL && *pFastStep);
+ switch (Type)
+ {
+ case Type_Enum:
+ *AsInt() = ((GetEnumIndex() + 1) % EnumValues.GetSize());
+ break;
+
+ case Type_Int:
+ *AsInt() = Alg::Min<SInt32>(*AsInt() + StepInt * (fastStep ? 5 : 1), MaxInt);
+ break;
+
+ case Type_Float:
+ // TODO: Will behave strange with NaN values.
+ *AsFloat() = Alg::Min<float>(*AsFloat() + StepFloat * (fastStep ? 5.0f : 1.0f), MaxFloat);
+ break;
+
+ case Type_Bool:
+ *AsBool() = !*AsBool();
+ break;
+ }
+
+ SignalUpdate();
+}
+
+void OptionVar::PrevValue(bool* pFastStep)
+{
+ bool fastStep = (pFastStep != NULL && *pFastStep);
+ switch (Type)
+ {
+ case Type_Enum:
+ *AsInt() = ((GetEnumIndex() + (UInt32)EnumValues.GetSize() - 1) % EnumValues.GetSize());
+ break;
+
+ case Type_Int:
+ *AsInt() = Alg::Max<SInt32>(*AsInt() - StepInt * (fastStep ? 5 : 1), MinInt);
+ break;
+
+ case Type_Float:
+ // TODO: Will behave strange with NaN values.
+ *AsFloat() = Alg::Max<float>(*AsFloat() - StepFloat * (fastStep ? 5.0f : 1.0f), MinFloat);
+ break;
+
+ case Type_Bool:
+ *AsBool() = !*AsBool();
+ break;
+ }
+
+ SignalUpdate();
+}
+
+String OptionVar::HandleShortcutUpdate()
+{
+ SignalUpdate();
+ return Label + " - " + GetValue();
+}
+
+String OptionVar::ProcessShortcutKey(KeyCode key, bool shift)
+{
+ if (ShortcutUp.MatchKey(key, shift) || ShortcutDown.MatchKey(key, shift))
+ {
+ return HandleShortcutUpdate();
+ }
+
+ return String();
+}
+
+String OptionVar::ProcessShortcutButton(UInt32 buttonMask)
+{
+ if (ShortcutUp.MatchGamepadButton(buttonMask) || ShortcutDown.MatchGamepadButton(buttonMask))
+ {
+ return HandleShortcutUpdate();
+ }
+ return String();
+}
+
+
+OptionVar& OptionVar::AddEnumValue(const char* displayName, SInt32 value)
+{
+ EnumEntry entry;
+ entry.Name = displayName;
+ entry.Value = value;
+ EnumValues.PushBack(entry);
+ return *this;
+}
+
+String OptionVar::GetValue()
+{
+ return fFormat(this);
+}
+
+UInt32 OptionVar::GetEnumIndex()
+{
+ OVR_ASSERT(Type == Type_Enum);
+ OVR_ASSERT(EnumValues.GetSize() > 0);
+
+ // TODO: Change this from a linear search to binary or a hash.
+ for (UInt32 i = 0; i < EnumValues.GetSize(); i++)
+ {
+ if (EnumValues[i].Value == *AsInt())
+ return i;
+ }
+
+ // Enum values should always be found.
+ OVR_ASSERT(false);
+ return 0;
+}
+
+
+//-------------------------------------------------------------------------------------
+
+OptionSelectionMenu::OptionSelectionMenu(OptionSelectionMenu* parentMenu)
+{
+ DisplayState = Display_None;
+ SelectedIndex = 0;
+ SelectionActive = false;
+ ParentMenu = parentMenu;
+
+ PopupMessageTimeout = 0.0;
+ PopupMessageBorder = false;
+
+ // Setup handlers for menu navigation actions.
+ NavShortcuts[Nav_Up].pNotify = new FunctionNotifyContext<OptionSelectionMenu, bool>(this, &OptionSelectionMenu::HandleUp);
+ NavShortcuts[Nav_Down].pNotify = new FunctionNotifyContext<OptionSelectionMenu, bool>(this, &OptionSelectionMenu::HandleDown);
+ NavShortcuts[Nav_Left].pNotify = new FunctionNotifySimple<OptionSelectionMenu>(this, &OptionSelectionMenu::HandleLeft);
+ NavShortcuts[Nav_Right].pNotify = new FunctionNotifySimple<OptionSelectionMenu>(this, &OptionSelectionMenu::HandleRight);
+ NavShortcuts[Nav_Select].pNotify = new FunctionNotifySimple<OptionSelectionMenu>(this, &OptionSelectionMenu::HandleSelect);
+ NavShortcuts[Nav_Back].pNotify = new FunctionNotifySimple<OptionSelectionMenu>(this, &OptionSelectionMenu::HandleBack);
+ ToggleShortcut.pNotify = new FunctionNotifySimple<OptionSelectionMenu>(this, &OptionSelectionMenu::HandleMenuToggle);
+ ToggleSingleItemShortcut.pNotify = new FunctionNotifySimple<OptionSelectionMenu>(this, &OptionSelectionMenu::HandleSingleItemToggle);
+
+ // Bind keys and buttons to menu navigation actions.
+ NavShortcuts[Nav_Up].AddShortcut(ShortcutKey(Key_Up, ShortcutKey::Shift_Modify));
+ NavShortcuts[Nav_Up].AddShortcut(Gamepad_Up);
+
+ NavShortcuts[Nav_Down].AddShortcut(ShortcutKey(Key_Down, ShortcutKey::Shift_Modify));
+ NavShortcuts[Nav_Down].AddShortcut(Gamepad_Down);
+
+ NavShortcuts[Nav_Left].AddShortcut(ShortcutKey(Key_Left));
+ NavShortcuts[Nav_Left].AddShortcut(Gamepad_Left);
+
+ NavShortcuts[Nav_Right].AddShortcut(ShortcutKey(Key_Right));
+ NavShortcuts[Nav_Right].AddShortcut(Gamepad_Right);
+
+ NavShortcuts[Nav_Select].AddShortcut(ShortcutKey(Key_Return));
+ NavShortcuts[Nav_Select].AddShortcut(Gamepad_A);
+
+ NavShortcuts[Nav_Back].AddShortcut(ShortcutKey(Key_Escape));
+ NavShortcuts[Nav_Back].AddShortcut(Gamepad_B);
+
+ ToggleShortcut.AddShortcut(ShortcutKey(Key_Tab, ShortcutKey::Shift_Ignore));
+ ToggleShortcut.AddShortcut(Gamepad_Start);
+
+ ToggleSingleItemShortcut.AddShortcut(ShortcutKey(Key_Backspace, ShortcutKey::Shift_Ignore));
+}
+
+OptionSelectionMenu::~OptionSelectionMenu()
+{
+ for (UInt32 i = 0; i < Items.GetSize(); i++)
+ delete Items[i];
+}
+
+bool OptionSelectionMenu::OnKey(OVR::KeyCode key, int chr, bool down, int modifiers)
+{
+ bool shift = ((modifiers & Mod_Shift) != 0);
+
+ if (down)
+ {
+ String s = ProcessShortcutKey(key, shift);
+ if (!s.IsEmpty())
+ {
+ PopupMessage = s;
+ PopupMessageTimeout = ovr_GetTimeInSeconds() + 4.0f;
+ PopupMessageBorder = false;
+ return true;
+ }
+ }
+
+ if (GetSubmenu() != NULL)
+ {
+ return GetSubmenu()->OnKey(key, chr, down, modifiers);
+ }
+
+ if (down)
+ {
+ if (ToggleShortcut.MatchKey(key, shift))
+ return true;
+
+ if (ToggleSingleItemShortcut.MatchKey(key, shift))
+ return true;
+
+ if (DisplayState == Display_None)
+ return false;
+
+ for (int i = 0; i < Nav_LAST; i++)
+ {
+ if (NavShortcuts[i].MatchKey(key, shift))
+ return true;
+ }
+ }
+
+ // Let the caller process keystroke
+ return false;
+}
+
+bool OptionSelectionMenu::OnGamepad(UInt32 buttonMask)
+{
+ // Check global shortcuts first.
+ String s = ProcessShortcutButton(buttonMask);
+ if (!s.IsEmpty())
+ {
+ PopupMessage = s;
+ PopupMessageTimeout = ovr_GetTimeInSeconds() + 4.0f;
+ return true;
+ }
+
+ if (GetSubmenu() != NULL)
+ {
+ return GetSubmenu()->OnGamepad(buttonMask);
+ }
+
+ if (ToggleShortcut.MatchGamepadButton(buttonMask))
+ return true;
+
+ if (DisplayState == Display_None)
+ return false;
+
+ for (int i = 0; i < Nav_LAST; i++)
+ {
+ if (NavShortcuts[i].MatchGamepadButton(buttonMask))
+ return true;
+ }
+
+ // Let the caller process keystroke
+ return false;
+}
+
+String OptionSelectionMenu::ProcessShortcutKey(KeyCode key, bool shift)
+{
+ String s;
+
+ for (UPInt i = 0; (i < Items.GetSize()) && s.IsEmpty(); i++)
+ {
+ s = Items[i]->ProcessShortcutKey(key, shift);
+ }
+
+ return s;
+}
+
+String OptionSelectionMenu::ProcessShortcutButton(UInt32 buttonMask)
+{
+ String s;
+
+ for (UPInt i = 0; (i < Items.GetSize()) && s.IsEmpty(); i++)
+ {
+ s = Items[i]->ProcessShortcutButton(buttonMask);
+ }
+
+ return s;
+}
+
+// Fills in inclusive character range; returns false if line not found.
+bool FindLineCharRange(const char* text, int searchLine, UPInt charRange[2])
+{
+ UPInt i = 0;
+
+ for (int line = 0; line <= searchLine; line ++)
+ {
+ if (line == searchLine)
+ {
+ charRange[0] = i;
+ }
+
+ // Find end of line.
+ while (text[i] != '\n' && text[i] != 0)
+ {
+ i++;
+ }
+
+ if (line == searchLine)
+ {
+ charRange[1] = (charRange[0] == i) ? charRange[0] : i-1;
+ return true;
+ }
+
+ if (text[i] == 0)
+ break;
+ // Skip newline
+ i++;
+ }
+
+ return false;
+}
+
+
+void OptionSelectionMenu::Render(RenderDevice* prender, String title)
+{
+ // If we are invisible, render shortcut notifications.
+ // Both child and parent have visible == true even if only child is shown.
+ if (DisplayState == Display_None)
+ {
+ renderShortcutChangeMessage(prender);
+ return;
+ }
+
+ title += Label;
+
+ // Delegate to sub-menu if active.
+ if (GetSubmenu() != NULL)
+ {
+ if (title.GetSize() > 0)
+ title += " > ";
+
+ GetSubmenu()->Render(prender, title);
+ return;
+ }
+
+ Color focusColor(180, 80, 20, 210);
+ Color pickedColor(120, 55, 10, 140);
+ Color titleColor(0x18, 0x1A, 0x4D, 210);
+ Color titleOutlineColor(0x18, 0x18, 0x18, 240);
+
+ float labelsSize[2] = {0.0f, 0.0f};
+ float bufferSize[2] = {0.0f, 0.0f};
+ float valuesSize[2] = {0.0f, 0.0f};
+ float maxValueWidth = 0.0f;
+
+ UPInt selection[2] = { 0, 0 };
+ Vector2f labelSelectionRect[2];
+ Vector2f valueSelectionRect[2];
+ bool havelLabelSelection = false;
+ bool haveValueSelection = false;
+
+ float textSize = 22.0f;
+ prender->MeasureText(&DejaVu, " ", textSize, bufferSize);
+
+ String values;
+ String menuItems;
+
+ int highlightIndex = 0;
+ if (DisplayState == Display_Menu)
+ {
+ highlightIndex = SelectedIndex;
+ for (UInt32 i = 0; i < Items.GetSize(); i++)
+ {
+ if (i > 0)
+ values += "\n";
+ values += Items[i]->GetValue();
+ }
+
+ for (UInt32 i = 0; i < Items.GetSize(); i++)
+ {
+ if (i > 0)
+ menuItems += "\n";
+ menuItems += Items[i]->GetLabel();
+ }
+ }
+ else
+ {
+ values = Items[SelectedIndex]->GetValue();
+ menuItems = Items[SelectedIndex]->GetLabel();
+ }
+
+ // Measure labels
+ const char* menuItemsCStr = menuItems.ToCStr();
+ havelLabelSelection = FindLineCharRange(menuItemsCStr, highlightIndex, selection);
+ prender->MeasureText(&DejaVu, menuItemsCStr, textSize, labelsSize,
+ selection, labelSelectionRect);
+
+ // Measure label-to-value gap
+ const char* valuesCStr = values.ToCStr();
+ haveValueSelection = FindLineCharRange(valuesCStr, highlightIndex, selection);
+ prender->MeasureText(&DejaVu, valuesCStr, textSize, valuesSize, selection, valueSelectionRect);
+
+ // Measure max value size (absolute size varies, so just use a reasonable max)
+ maxValueWidth = prender->MeasureText(&DejaVu, "Max value width", textSize);
+ maxValueWidth = Alg::Max(maxValueWidth, valuesSize[0]);
+
+ Vector2f borderSize(4.0f, 4.0f);
+ Vector2f totalDimensions = borderSize * 2 + Vector2f(bufferSize[0], 0) + Vector2f(maxValueWidth, 0)
+ + Vector2f(labelsSize[0], labelsSize[1]);
+
+ Vector2f fudgeOffset= Vector2f(10.0f, 25.0f); // This offset looks better
+ Vector2f topLeft = (-totalDimensions / 2.0f) + fudgeOffset;
+ Vector2f bottomRight = topLeft + totalDimensions;
+
+ // If displaying a single item, shift it down.
+ if (DisplayState == Display_SingleItem)
+ {
+ topLeft.y += textSize * 7;
+ bottomRight.y += textSize * 7;
+ }
+
+ prender->FillRect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y, Color(40,40,100,210));
+
+ Vector2f labelsPos = topLeft + borderSize;
+ Vector2f valuesPos = labelsPos + Vector2f(labelsSize[0], 0) + Vector2f(bufferSize[0], 0);
+
+ // Highlight selected label
+ Vector2f selectionInset = Vector2f(0.3f, 2.0f);
+ if (DisplayState == Display_Menu)
+ {
+ Vector2f labelSelectionTopLeft = labelsPos + labelSelectionRect[0] - selectionInset;
+ Vector2f labelSelectionBottomRight = labelsPos + labelSelectionRect[1] + selectionInset;
+
+ prender->FillRect(labelSelectionTopLeft.x, labelSelectionTopLeft.y,
+ labelSelectionBottomRight.x, labelSelectionBottomRight.y,
+ SelectionActive ? pickedColor : focusColor);
+ }
+
+ // Highlight selected value if active
+ if (SelectionActive)
+ {
+ Vector2f valueSelectionTopLeft = valuesPos + valueSelectionRect[0] - selectionInset;
+ Vector2f valueSelectionBottomRight = valuesPos + valueSelectionRect[1] + selectionInset;
+ prender->FillRect(valueSelectionTopLeft.x, valueSelectionTopLeft.y,
+ valueSelectionBottomRight.x, valueSelectionBottomRight.y,
+ focusColor);
+ }
+
+ // Measure and draw title
+ if (DisplayState == Display_Menu && title.GetLength() > 0)
+ {
+ Vector2f titleDimensions;
+ prender->MeasureText(&DejaVu, title.ToCStr(), textSize, &titleDimensions.x);
+ Vector2f titleTopLeft = topLeft - Vector2f(0, borderSize.y) * 2 - Vector2f(0, titleDimensions.y);
+ titleDimensions.x = totalDimensions.x;
+
+ prender->FillRect(titleTopLeft.x, titleTopLeft.y,
+ titleTopLeft.x + totalDimensions.x,
+ titleTopLeft.y + titleDimensions.y + borderSize.y * 2,
+ titleOutlineColor);
+
+ prender->FillRect(titleTopLeft.x + borderSize.x / 2, titleTopLeft.y + borderSize.y / 2,
+ titleTopLeft.x + totalDimensions.x - borderSize.x / 2,
+ titleTopLeft.y + borderSize.y / 2 + titleDimensions.y,
+ titleColor);
+
+ prender->RenderText(&DejaVu, title.ToCStr(), titleTopLeft.x + borderSize.x,
+ titleTopLeft.y + borderSize.y, textSize, Color(255,255,0,210));
+ }
+
+ prender->RenderText(&DejaVu, menuItemsCStr, labelsPos.x, labelsPos.y, textSize, Color(255,255,0,210));
+
+ prender->RenderText(&DejaVu, valuesCStr, valuesPos.x, valuesPos.y, textSize, Color(255,255,0,210));
+}
+
+
+void OptionSelectionMenu::renderShortcutChangeMessage(RenderDevice* prender)
+{
+ if (ovr_GetTimeInSeconds() < PopupMessageTimeout)
+ {
+ DrawTextBox(prender, 0, 120, 22.0f, PopupMessage.ToCStr(),
+ DrawText_Center | (PopupMessageBorder ? DrawText_Border : 0));
+ }
+}
+
+
+void OptionSelectionMenu::SetPopupMessage(const char* format, ...)
+{
+ //Lock::Locker lock(pManager->GetHandlerLock());
+ char textBuff[2048];
+ va_list argList;
+ va_start(argList, format);
+ OVR_vsprintf(textBuff, sizeof(textBuff), format, argList);
+ va_end(argList);
+
+ // Message will time out in 4 seconds.
+ PopupMessage = textBuff;
+ PopupMessageTimeout = ovr_GetTimeInSeconds() + 4.0f;
+ PopupMessageBorder = false;
+}
+
+void OptionSelectionMenu::SetPopupTimeout(double timeoutSeconds, bool border)
+{
+ PopupMessageTimeout = ovr_GetTimeInSeconds() + timeoutSeconds;
+ PopupMessageBorder = border;
+}
+
+
+
+void OptionSelectionMenu::AddItem(OptionMenuItem* menuItem)
+{
+ String ns = PopNamespaceFrom(menuItem);
+
+ if (ns.GetLength() == 0)
+ {
+ Items.PushBack(menuItem);
+ }
+ else
+ {
+ // Item is part of a submenu, add it to that instead.
+ GetOrCreateSubmenu(ns)->AddItem(menuItem);
+ }
+}
+
+//virtual
+void OptionSelectionMenu::Select()
+{
+ SelectedIndex = 0;
+ SelectionActive = false;
+ DisplayState = Display_Menu;
+}
+
+
+OptionSelectionMenu* OptionSelectionMenu::GetSubmenu()
+{
+ if (!SelectionActive)
+ return NULL;
+
+ OptionSelectionMenu* submenu = dynamic_cast<OptionSelectionMenu*>(Items[SelectedIndex]);
+ return submenu;
+}
+
+
+OptionSelectionMenu* OptionSelectionMenu::GetOrCreateSubmenu(String submenuName)
+{
+ for (UInt32 i = 0; i < Items.GetSize(); i++)
+ {
+ OptionSelectionMenu* submenu = dynamic_cast<OptionSelectionMenu*>(Items[i]);
+
+ if (submenu != NULL && submenu->Label == submenuName)
+ {
+ return submenu;
+ }
+ }
+
+ // Submenu doesn't exist, create it.
+ OptionSelectionMenu* newSubmenu = new OptionSelectionMenu(this);
+ newSubmenu->Label = submenuName;
+ Items.PushBack(newSubmenu);
+ return newSubmenu;
+}
+
+void OptionSelectionMenu::HandleUp(bool* pFast)
+{
+ int numItems = (int)Items.GetSize();
+ if (SelectionActive)
+ Items[SelectedIndex]->NextValue(pFast);
+ else
+ SelectedIndex = ((SelectedIndex - 1 + numItems) % numItems);
+}
+
+void OptionSelectionMenu::HandleDown(bool* pFast)
+{
+ if (SelectionActive)
+ Items[SelectedIndex]->PrevValue(pFast);
+ else
+ SelectedIndex = ((SelectedIndex + 1) % Items.GetSize());
+}
+
+void OptionSelectionMenu::HandleLeft()
+{
+ if (DisplayState != Display_Menu)
+ return;
+
+ if (SelectionActive)
+ SelectionActive = false;
+ else if (ParentMenu)
+ {
+ // Escape to parent menu
+ ParentMenu->SelectionActive = false;
+ DisplayState = Display_Menu;
+ }
+}
+
+void OptionSelectionMenu::HandleRight()
+{
+ if (DisplayState != Display_Menu)
+ return;
+
+ if (!SelectionActive)
+ {
+ SelectionActive = true;
+ Items[SelectedIndex]->Select();
+ }
+}
+
+void OptionSelectionMenu::HandleSelect()
+{
+ if (!SelectionActive)
+ {
+ SelectionActive = true;
+ Items[SelectedIndex]->Select();
+ }
+ else
+ {
+ Items[SelectedIndex]->NextValue();
+ }
+}
+
+void OptionSelectionMenu::HandleBack()
+{
+ if (DisplayState != Display_Menu)
+ return;
+
+ if (!SelectionActive)
+ DisplayState = Display_None;
+ else
+ SelectionActive = false;
+}
+
+void OptionSelectionMenu::HandleMenuToggle()
+{
+ // Mark this & parent With correct visibility.
+ OptionSelectionMenu* menu = this;
+
+ if (DisplayState == Display_Menu)
+ DisplayState = Display_None;
+ else
+ DisplayState = Display_Menu;
+
+ while (menu)
+ {
+ menu->DisplayState = DisplayState;
+ menu = menu->ParentMenu;
+ }
+ // Hide message
+ PopupMessageTimeout = 0;
+}
+
+void OptionSelectionMenu::HandleSingleItemToggle()
+{
+ // Mark this & parent With correct visibility.
+ OptionSelectionMenu* menu = this;
+
+ if (DisplayState == Display_SingleItem)
+ DisplayState = Display_None;
+ else
+ {
+ DisplayState = Display_SingleItem;
+ SelectionActive = true;
+ }
+
+ while (menu)
+ {
+ menu->DisplayState = DisplayState;
+ menu = menu->ParentMenu;
+ }
+ // Hide message
+ PopupMessageTimeout = 0;
+}
+
+
+//-------------------------------------------------------------------------------------
+// **** Text Rendering / Management
+
+void DrawTextBox(RenderDevice* prender, float x, float y,
+ float textSize, const char* text, unsigned centerType)
+{
+ float ssize[2] = {0.0f, 0.0f};
+
+ prender->MeasureText(&DejaVu, text, textSize, ssize);
+
+ // Treat 0 a VCenter.
+ if (centerType & DrawText_HCenter)
+ {
+ x -= ssize[0]/2;
+ }
+ if (centerType & DrawText_VCenter)
+ {
+ y -= ssize[1]/2;
+ }
+
+ const float borderSize = 4.0f;
+ float linesHeight = 0.0f;
+
+ if (centerType & DrawText_Border)
+ linesHeight = 10.0f;
+
+ prender->FillRect(x-borderSize, y-borderSize - linesHeight,
+ x+ssize[0]+borderSize, y+ssize[1]+borderSize + linesHeight,
+ Color(40,40,100,210));
+
+ if (centerType & DrawText_Border)
+ {
+ // Add top & bottom lines
+ float topLineY = y-borderSize - linesHeight * 0.5f,
+ bottomLineY = y+ssize[1]+borderSize + linesHeight * 0.5f;
+
+ prender->FillRect(x-borderSize * 0.5f, topLineY,
+ x+ssize[0]+borderSize * 0.5f, topLineY + 2.0f,
+ Color(255,255,0,210));
+ prender->FillRect(x-borderSize * 0.5f, bottomLineY,
+ x+ssize[0]+borderSize * 0.5f, bottomLineY + 2.0f,
+ Color(255,255,0,210));
+ }
+
+ prender->RenderText(&DejaVu, text, x, y, textSize, Color(255,255,0,210));
+}
+
+void CleanupDrawTextFont()
+{
+ if (DejaVu.fill)
+ {
+ DejaVu.fill->Release();
+ DejaVu.fill = 0;
+ }
+}
diff --git a/Samples/OculusWorldDemo/OptionMenu.h b/Samples/OculusWorldDemo/OptionMenu.h
new file mode 100644
index 0000000..ba90b08
--- /dev/null
+++ b/Samples/OculusWorldDemo/OptionMenu.h
@@ -0,0 +1,442 @@
+/************************************************************************************
+
+Filename : OptionMenu.h
+Content : Option selection and editing for OculusWorldDemo
+Created : March 7, 2014
+Authors : Michael Antonov, Caleb Leak
+
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*************************************************************************************/
+
+#ifndef INC_OptionMenu_h
+#define INC_OptionMenu_h
+
+#include "OVR.h"
+
+#include "../CommonSrc/Platform/Platform_Default.h"
+#include "../CommonSrc/Render/Render_Device.h"
+#include "../CommonSrc/Platform/Gamepad.h"
+
+#include "Util/Util_Render_Stereo.h"
+using namespace OVR::Util::Render;
+
+#include <Kernel/OVR_SysFile.h>
+#include <Kernel/OVR_Log.h>
+#include <Kernel/OVR_Timer.h>
+
+#include "Player.h"
+#include "OVR_DeviceConstants.h"
+
+
+using namespace OVR;
+using namespace OVR::Platform;
+using namespace OVR::Render;
+
+
+//-------------------------------------------------------------------------------------
+struct FunctionNotifyBase : public NewOverrideBase
+{
+ virtual void CallNotify(void*) { }
+ virtual void CallNotify() { }
+};
+
+// Simple member pointer wrapper to support calling class members
+template<class C, class X>
+struct FunctionNotifyContext : public FunctionNotifyBase
+{
+ typedef void (C::*FnPtr)(X*);
+
+ FunctionNotifyContext(C* p, FnPtr fn) : pClass(p), pFn(fn), pContext(NULL) { }
+ FunctionNotifyContext(C* p, FnPtr fn, X* pContext) : pClass(p), pFn(fn), pContext(pContext) { }
+ virtual void CallNotify(void* var) { (void)(pClass->*pFn)(static_cast<X*>(var)); }
+ virtual void CallNotify() { (void)(pClass->*pFn)(pContext); }
+private:
+
+ X* pContext;
+ C* pClass;
+ FnPtr pFn;
+};
+
+template<class C>
+struct FunctionNotifySimple : public FunctionNotifyBase
+{
+ typedef void (C::*FnPtr)(void);
+
+ FunctionNotifySimple(C* p, FnPtr fn) : pClass(p), pFn(fn) { }
+ virtual void CallNotify(void*) { CallNotify(); }
+ virtual void CallNotify() { (void)(pClass->*pFn)(); }
+private:
+
+ C* pClass;
+ FnPtr pFn;
+};
+
+
+//-------------------------------------------------------------------------------------
+// Describes a shortcut key
+struct ShortcutKey
+{
+ enum ShiftUsageType
+ {
+ Shift_Ignore,
+ Shift_Modify,
+ Shift_RequireOn,
+ Shift_RequireOff
+ };
+
+ ShortcutKey(KeyCode key = Key_None, ShiftUsageType shiftUsage = Shift_RequireOff)
+ : Key(key), ShiftUsage(shiftUsage) { }
+
+ KeyCode Key;
+ ShiftUsageType ShiftUsage;
+};
+
+
+//-------------------------------------------------------------------------------------
+struct OptionShortcut
+{
+ Array<ShortcutKey> Keys;
+ Array<UInt32> GamepadButtons;
+ FunctionNotifyBase* pNotify;
+
+ OptionShortcut() : pNotify(NULL) {}
+ OptionShortcut(FunctionNotifyBase* pNotify) : pNotify(pNotify) {}
+ ~OptionShortcut() { if (pNotify) delete pNotify; }
+
+ void AddShortcut(ShortcutKey key) { Keys.PushBack(key); }
+ void AddShortcut(UInt32 gamepadButton) { GamepadButtons.PushBack(gamepadButton); }
+
+ bool MatchKey(KeyCode key, bool shift) const;
+ bool MatchGamepadButton(UInt32 gamepadButtonMask) const;
+};
+
+
+//-------------------------------------------------------------------------------------
+
+// Base class for a menu item. Internally, this can also be OptionSelectionMenu itself
+// to support nested menus. Users shouldn't need to use this class.
+class OptionMenuItem : public NewOverrideBase
+{
+public:
+ virtual ~OptionMenuItem() { }
+
+ virtual void Select() { }
+
+ virtual void NextValue(bool* pFastStep = NULL) { OVR_UNUSED1(pFastStep); }
+ virtual void PrevValue(bool* pFastStep = NULL) { OVR_UNUSED1(pFastStep); }
+
+ virtual String GetLabel() { return Label; }
+ virtual String GetValue() { return ""; }
+
+ // Returns empty string if shortcut not handled
+ virtual String ProcessShortcutKey(KeyCode key, bool shift) = 0;
+ virtual String ProcessShortcutButton(UInt32 buttonMask) = 0;
+
+protected:
+ String Label;
+ String PopNamespaceFrom(OptionMenuItem* menuItem);
+};
+
+
+//-------------------------------------------------------------------------------------
+
+// OptionVar implements a basic menu item, which binds to an external variable,
+// displaying and editing its state.
+class OptionVar : public OptionMenuItem
+{
+public:
+
+ enum VarType
+ {
+ Type_Enum,
+ Type_Int,
+ Type_Float,
+ Type_Bool
+ };
+
+ typedef String (*FormatFunction)(OptionVar*);
+ typedef void (*UpdateFunction)(OptionVar*);
+
+ static String FormatEnum(OptionVar* var);
+ static String FormatInt(OptionVar* var);
+ static String FormatFloat(OptionVar* var);
+ static String FormatTan(OptionVar* var);
+ static String FormatBool(OptionVar* var);
+
+ OptionVar(const char* name, void* pVar, VarType type,
+ FormatFunction formatFunction,
+ UpdateFunction updateFunction = NULL);
+
+ // Integer with range and step size.
+ OptionVar(const char* name, SInt32* pVar,
+ SInt32 min, SInt32 max, SInt32 stepSize=1,
+ const char* formatString = "%d",
+ FormatFunction formatFunction = 0, // Default int formatting.
+ UpdateFunction updateFunction = NULL);
+
+ // Float with range and step size.
+ OptionVar(const char* name, float* pvar,
+ float minf, float maxf, float stepSize = 1.0f,
+ const char* formatString = "%.3f", float formatScale = 1.0f,
+ FormatFunction formatFunction = 0, // Default float formatting.
+ UpdateFunction updateFunction = 0 );
+
+ virtual ~OptionVar();
+
+ SInt32* AsInt() { return reinterpret_cast<SInt32*>(pVar); }
+ bool* AsBool() { return reinterpret_cast<bool*>(pVar); }
+ float* AsFloat() { return reinterpret_cast<float*>(pVar); }
+ VarType GetType() { return Type; }
+
+ // Step through values (wrap for enums).
+ virtual void NextValue(bool* pFastStep);
+ virtual void PrevValue(bool* pFastStep);
+
+ // Executes shortcut message and returns notification string.
+ // Returns empty string for no action.
+ String HandleShortcutUpdate();
+ virtual String ProcessShortcutKey(KeyCode key, bool shift);
+ virtual String ProcessShortcutButton(UInt32 buttonMask);
+
+ OptionVar& AddEnumValue(const char* displayName, SInt32 value);
+
+ template<class C>
+ OptionVar& SetNotify(C* p, void (C::*fn)(OptionVar*))
+ {
+ OVR_ASSERT(pNotify == 0); // Can't set notifier twice.
+ pNotify = new FunctionNotifyContext<C, OptionVar>(p, fn, this);
+ return *this;
+ }
+
+
+ //String Format();
+ virtual String GetValue();
+
+ OptionVar& AddShortcutUpKey(const ShortcutKey& shortcut)
+ { ShortcutUp.AddShortcut(shortcut); return *this; }
+ OptionVar& AddShortcutUpKey(KeyCode key,
+ ShortcutKey::ShiftUsageType shiftUsage = ShortcutKey::Shift_Modify)
+ { ShortcutUp.AddShortcut(ShortcutKey(key, shiftUsage)); return *this; }
+ OptionVar& AddShortcutUpButton(UInt32 gamepadButton)
+ { ShortcutUp.AddShortcut(gamepadButton); return *this; }
+
+ OptionVar& AddShortcutDownKey(const ShortcutKey& shortcut)
+ { ShortcutDown.AddShortcut(shortcut); return *this; }
+ OptionVar& AddShortcutDownKey(KeyCode key,
+ ShortcutKey::ShiftUsageType shiftUsage = ShortcutKey::Shift_Modify)
+ { ShortcutDown.AddShortcut(ShortcutKey(key, shiftUsage)); return *this; }
+ OptionVar& AddShortcutDownButton(UInt32 gamepadButton)
+ { ShortcutDown.AddShortcut(gamepadButton); return *this; }
+
+ OptionVar& AddShortcutKey(const ShortcutKey& shortcut)
+ { return AddShortcutUpKey(shortcut); }
+ OptionVar& AddShortcutKey(KeyCode key,
+ ShortcutKey::ShiftUsageType shiftUsage = ShortcutKey::Shift_RequireOff)
+ { return AddShortcutUpKey(key, shiftUsage); }
+ OptionVar& AddShortcutButton(UInt32 gamepadButton)
+ { return AddShortcutUpButton(gamepadButton); }
+
+private:
+
+ void SignalUpdate()
+ {
+ if (fUpdate) fUpdate(this);
+ if (pNotify) pNotify->CallNotify(this);
+ }
+
+ struct EnumEntry
+ {
+ // Human readable name for enum.
+ String Name;
+ SInt32 Value;
+ };
+
+ // Array of possible enum values.
+ Array<EnumEntry> EnumValues;
+ // Gets the index of the current enum value.
+ UInt32 GetEnumIndex();
+
+ FormatFunction fFormat;
+ UpdateFunction fUpdate;
+ FunctionNotifyBase* pNotify;
+
+ VarType Type;
+ void* pVar;
+ const char* FormatString;
+
+ OptionShortcut ShortcutUp;
+ OptionShortcut ShortcutDown;
+
+ float MinFloat;
+ float MaxFloat;
+ float StepFloat;
+ float FormatScale; // Multiply float by this before rendering
+
+ SInt32 MinInt;
+ SInt32 MaxInt;
+ SInt32 StepInt;
+};
+
+
+//-------------------------------------------------------------------------------------
+// ***** OptionSelectionMenu
+
+// Implements an overlay option menu, brought up by the 'Tab' key.
+// Items are added to the menu with AddBool, AddEnum, AddFloat on startup,
+// and are editable by using arrow keys (underlying variable is modified).
+//
+// Call Render() to render the menu every frame.
+//
+// Menu also support displaying popup messages with a timeout, displayed
+// when menu body isn't up.
+
+class OptionSelectionMenu : public OptionMenuItem
+{
+public:
+ OptionSelectionMenu(OptionSelectionMenu* parentMenu = NULL);
+ ~OptionSelectionMenu();
+
+
+ bool OnKey(OVR::KeyCode key, int chr, bool down, int modifiers);
+ bool OnGamepad(UInt32 buttonMask);
+
+ void Render(RenderDevice* prender, String title = "");
+
+ void AddItem(OptionMenuItem* menuItem);
+
+ // Adds a boolean toggle. Returns added item to allow customization.
+ OptionVar& AddBool(const char* name, bool* pvar,
+ OptionVar::UpdateFunction updateFunction = 0,
+ OptionVar::FormatFunction formatFunction = OptionVar::FormatBool)
+ {
+ OptionVar* p = new OptionVar(name, pvar, OptionVar::Type_Bool,
+ formatFunction, updateFunction);
+ AddItem(p);
+ return *p;
+ }
+
+ // Adds a boolean toggle. Returns added item to allow customization.
+ OptionVar& AddEnum(const char* name, void* pvar,
+ OptionVar::UpdateFunction updateFunction = 0)
+ {
+ OptionVar* p = new OptionVar(name, pvar, OptionVar::Type_Enum,
+ OptionVar::FormatEnum, updateFunction);
+ AddItem(p);
+ return *p;
+ }
+
+
+ // Adds a Float variable. Returns added item to allow customization.
+ OptionVar& AddFloat( const char* name, float* pvar,
+ float minf, float maxf, float stepSize = 1.0f,
+ const char* formatString = "%.3f", float formatScale = 1.0f,
+ OptionVar::FormatFunction formatFunction = 0, // Default float formatting.
+ OptionVar::UpdateFunction updateFunction = 0 )
+ {
+ OptionVar* p = new OptionVar(name, pvar, minf, maxf, stepSize,
+ formatString, formatScale,
+ formatFunction, updateFunction);
+ AddItem(p);
+ return *p;
+ }
+
+ virtual void Select();
+ virtual String GetLabel() { return Label + " >"; }
+
+ virtual String ProcessShortcutKey(KeyCode key, bool shift);
+ virtual String ProcessShortcutButton(UInt32 buttonMask);
+
+ // Sets a message to display with a time-out. Default time-out is 4 seconds.
+ // This uses the same overlay approach as used for shortcut notifications.
+ void SetPopupMessage(const char* format, ...);
+ // Overrides current timeout, in seconds (not the future default value);
+ // intended to be called right after SetPopupMessage.
+ void SetPopupTimeout(double timeoutSeconds, bool border = false);
+
+protected:
+
+ void renderShortcutChangeMessage(RenderDevice* prender);
+
+public:
+ OptionSelectionMenu* GetSubmenu();
+ OptionSelectionMenu* GetOrCreateSubmenu(String submenuName);
+
+ enum DisplayStateType
+ {
+ Display_None,
+ Display_Menu,
+ Display_SingleItem
+ };
+
+ DisplayStateType DisplayState;
+ OptionSelectionMenu* ParentMenu;
+
+ ArrayPOD<OptionMenuItem*> Items;
+ int SelectedIndex;
+ bool SelectionActive;
+
+ String PopupMessage;
+ double PopupMessageTimeout;
+ bool PopupMessageBorder;
+
+ // Possible menu navigation actions.
+ enum NavigationActions
+ {
+ Nav_Up,
+ Nav_Down,
+ Nav_Left,
+ Nav_Right,
+ Nav_Select,
+ Nav_Back,
+ Nav_LAST
+ };
+
+ // Handlers for navigation actions.
+ void HandleUp(bool* pFast);
+ void HandleDown(bool* pFast);
+ void HandleLeft();
+ void HandleRight();
+ void HandleSelect();
+ void HandleBack();
+
+ void HandleMenuToggle();
+ void HandleSingleItemToggle();
+
+ OptionShortcut NavShortcuts[Nav_LAST];
+ OptionShortcut ToggleShortcut;
+ OptionShortcut ToggleSingleItemShortcut;
+};
+
+
+//-------------------------------------------------------------------------------------
+// Text Rendering Utility
+enum DrawTextCenterType
+{
+ DrawText_NoCenter= 0,
+ DrawText_VCenter = 0x01,
+ DrawText_HCenter = 0x02,
+ DrawText_Center = DrawText_VCenter | DrawText_HCenter,
+ DrawText_Border = 0x10,
+};
+
+void DrawTextBox(RenderDevice* prender, float x, float y,
+ float textSize, const char* text,
+ unsigned centerType = DrawText_NoCenter);
+
+void CleanupDrawTextFont();
+
+
+#endif // INC_OptionMenu_h
diff --git a/Samples/OculusWorldDemo/Player.cpp b/Samples/OculusWorldDemo/Player.cpp
index b910307..b2bf00e 100644
--- a/Samples/OculusWorldDemo/Player.cpp
+++ b/Samples/OculusWorldDemo/Player.cpp
@@ -23,135 +23,138 @@ limitations under the License.
#include "Player.h"
#include <Kernel/OVR_Alg.h>
-Player::Player(void)
- : UserEyeHeight(1.8f),
- EyePos(7.7f, 1.8f, -1.0f),
- EyeYaw(YawInitial), EyePitch(0), EyeRoll(0),
- LastSensorYaw(0)
+Player::Player()
+ : UserEyeHeight(1.76f - 0.15f), // 1.76 meters height (ave US male, Wikipedia), less 15 centimeters (TomF's top-of-head-to-eye distance).
+ BodyPos(7.7f, 1.76f - 0.15f, -1.0f),
+ BodyYaw(YawInitial)
{
MoveForward = MoveBack = MoveLeft = MoveRight = 0;
GamepadMove = Vector3f(0);
GamepadRotate = Vector3f(0);
}
+Player::~Player()
+{
+}
+
+Vector3f Player::GetPosition()
+{
+ return BodyPos + Quatf(Vector3f(0,1,0), BodyYaw.Get()).Rotate(HeadPose.Position);
+}
+
+Quatf Player::GetOrientation(bool baseOnly)
+{
+ Quatf baseQ = Quatf(Vector3f(0,1,0), BodyYaw.Get());
+ return baseOnly ? baseQ : baseQ * HeadPose.Orientation;
+}
-Player::~Player(void)
+Posef Player::VirtualWorldPoseFromRealPose(const Posef &sensorHeadPose)
{
+ Quatf baseQ = Quatf(Vector3f(0,1,0), BodyYaw.Get());
+
+ return Posef(baseQ * sensorHeadPose.Orientation,
+ BodyPos + baseQ.Rotate(sensorHeadPose.Position));
}
-void Player::HandleCollision(double dt, Array<Ptr<CollisionModel> >* collisionModels,
- Array<Ptr<CollisionModel> >* groundCollisionModels, bool shiftDown)
+
+void Player::HandleMovement(double dt, Array<Ptr<CollisionModel> >* collisionModels,
+ Array<Ptr<CollisionModel> >* groundCollisionModels, bool shiftDown)
{
- if(MoveForward || MoveBack || MoveLeft || MoveRight || GamepadMove.LengthSq() > 0)
+ // Handle keyboard movement.
+ // This translates BasePos based on the orientation and keys pressed.
+ // Note that Pitch and Roll do not affect movement (they only affect view).
+ Vector3f controllerMove;
+ if(MoveForward || MoveBack || MoveLeft || MoveRight)
{
- Vector3f orientationVector;
- // Handle keyboard movement.
- // This translates EyePos based on Yaw vector direction and keys pressed.
- // Note that Pitch and Roll do not affect movement (they only affect view).
- if(MoveForward || MoveBack || MoveLeft || MoveRight)
+ if (MoveForward)
{
- Vector3f localMoveVector(0, 0, 0);
- Matrix4f yawRotate = Matrix4f::RotationY(EyeYaw);
-
- if (MoveForward)
- {
- localMoveVector = ForwardVector;
- }
- else if (MoveBack)
- {
- localMoveVector = -ForwardVector;
- }
-
- if (MoveRight)
- {
- localMoveVector += RightVector;
- }
- else if (MoveLeft)
- {
- localMoveVector -= RightVector;
- }
+ controllerMove += ForwardVector;
+ }
+ else if (MoveBack)
+ {
+ controllerMove -= ForwardVector;
+ }
- // Normalize vector so we don't move faster diagonally.
- localMoveVector.Normalize();
- orientationVector = yawRotate.Transform(localMoveVector);
+ if (MoveRight)
+ {
+ controllerMove += RightVector;
}
- else if (GamepadMove.LengthSq() > 0)
+ else if (MoveLeft)
{
- Matrix4f yawRotate = Matrix4f::RotationY(EyeYaw);
- GamepadMove.Normalize();
- orientationVector = yawRotate.Transform(GamepadMove);
+ controllerMove -= RightVector;
}
+ }
+ else if (GamepadMove.LengthSq() > 0)
+ {
+ controllerMove = GamepadMove;
+ }
+ controllerMove = GetOrientation(bMotionRelativeToBody).Rotate(controllerMove);
+ controllerMove.y = 0; // Project to the horizontal plane
+ if (controllerMove.LengthSq() > 0)
+ {
+ // Normalize vector so we don't move faster diagonally.
+ controllerMove.Normalize();
+ controllerMove *= OVR::Alg::Min<float>(MoveSpeed * (float)dt * (shiftDown ? 3.0f : 1.0f), 1.0f);
+ }
- float moveLength = OVR::Alg::Min<float>(MoveSpeed * (float)dt * (shiftDown ? 3.0f : 1.0f), 1.0f);
+ // Compute total move direction vector and move length
+ Vector3f orientationVector = controllerMove;
+ float moveLength = orientationVector.Length();
+ if (moveLength > 0)
+ orientationVector.Normalize();
+
+ float checkLengthForward = moveLength;
+ Planef collisionPlaneForward;
+ bool gotCollision = false;
+
+ for(unsigned int i = 0; i < collisionModels->GetSize(); ++i)
+ {
+ // Checks for collisions at model base level, which should prevent us from
+ // slipping under walls
+ if (collisionModels->At(i)->TestRay(BodyPos, orientationVector, checkLengthForward,
+ &collisionPlaneForward))
+ {
+ gotCollision = true;
+ break;
+ }
+ }
- float checkLengthForward = moveLength;
- Planef collisionPlaneForward;
- float checkLengthLeft = moveLength;
- Planef collisionPlaneLeft;
- float checkLengthRight = moveLength;
- Planef collisionPlaneRight;
- bool gotCollision = false;
- bool gotCollisionLeft = false;
- bool gotCollisionRight = false;
+ if (gotCollision)
+ {
+ // Project orientationVector onto the plane
+ Vector3f slideVector = orientationVector - collisionPlaneForward.N
+ * (orientationVector.Dot(collisionPlaneForward.N));
- for(unsigned int i = 0; i < collisionModels->GetSize(); ++i)
+ // Make sure we aren't in a corner
+ for(unsigned int j = 0; j < collisionModels->GetSize(); ++j)
{
- // Checks for collisions at eye level, which should prevent us from
- // slipping under walls
- if (collisionModels->At(i)->TestRay(EyePos, orientationVector, checkLengthForward,
- &collisionPlaneForward))
- {
- gotCollision = true;
- }
-
- Matrix4f leftRotation = Matrix4f::RotationY(45 * (Math<float>::Pi / 180.0f));
- Vector3f leftVector = leftRotation.Transform(orientationVector);
- if (collisionModels->At(i)->TestRay(EyePos, leftVector, checkLengthLeft,
- &collisionPlaneLeft))
- {
- gotCollisionLeft = true;
- }
- Matrix4f rightRotation = Matrix4f::RotationY(-45 * (Math<float>::Pi / 180.0f));
- Vector3f rightVector = rightRotation.Transform(orientationVector);
- if (collisionModels->At(i)->TestRay(EyePos, rightVector, checkLengthRight,
- &collisionPlaneRight))
+ if (collisionModels->At(j)->TestPoint(BodyPos - Vector3f(0.0f, RailHeight, 0.0f) +
+ (slideVector * (moveLength))) )
{
- gotCollisionRight = true;
+ moveLength = 0;
+ break;
}
}
-
- if (gotCollision)
+ if (moveLength != 0)
{
- // Project orientationVector onto the plane
- Vector3f slideVector = orientationVector - collisionPlaneForward.N
- * (orientationVector.Dot(collisionPlaneForward.N));
-
- // Make sure we aren't in a corner
- for(unsigned int j = 0; j < collisionModels->GetSize(); ++j)
- {
- if (collisionModels->At(j)->TestPoint(EyePos - Vector3f(0.0f, RailHeight, 0.0f) +
- (slideVector * (moveLength))) )
- {
- moveLength = 0;
- }
- }
- if (moveLength != 0)
- {
- orientationVector = slideVector;
- }
+ orientationVector = slideVector;
}
- // Checks for collisions at foot level, which allows us to follow terrain
- orientationVector *= moveLength;
- EyePos += orientationVector;
+ }
+ // Checks for collisions at foot level, which allows us to follow terrain
+ orientationVector *= moveLength;
+ BodyPos += orientationVector;
- Planef collisionPlaneDown;
- float finalDistanceDown = 10;
+ Planef collisionPlaneDown;
+ float finalDistanceDown = 10;
+ // Only apply down if there is collision model (otherwise we get jitter).
+ if (groundCollisionModels->GetSize())
+ {
for(unsigned int i = 0; i < groundCollisionModels->GetSize(); ++i)
{
float checkLengthDown = 10;
- if (groundCollisionModels->At(i)->TestRay(EyePos, Vector3f(0.0f, -1.0f, 0.0f),
- checkLengthDown, &collisionPlaneDown))
+ if (groundCollisionModels->At(i)->TestRay(BodyPos, Vector3f(0.0f, -1.0f, 0.0f),
+ checkLengthDown, &collisionPlaneDown))
{
finalDistanceDown = Alg::Min(finalDistanceDown, checkLengthDown);
}
@@ -160,7 +163,32 @@ void Player::HandleCollision(double dt, Array<Ptr<CollisionModel> >* collisionMo
// Maintain the minimum camera height
if (UserEyeHeight - finalDistanceDown < 1.0f)
{
- EyePos.y += UserEyeHeight - finalDistanceDown;
+ BodyPos.y += UserEyeHeight - finalDistanceDown;
}
}
+
+}
+
+
+
+// Handle directional movement. Returns 'true' if movement was processed.
+bool Player::HandleMoveKey(OVR::KeyCode key, bool down)
+{
+ switch(key)
+ {
+ // Handle player movement keys.
+ // We just update movement state here, while the actual translation is done in OnIdle()
+ // based on time.
+ case OVR::Key_W: MoveForward = down ? (MoveForward | 1) : (MoveForward & ~1); return true;
+ case OVR::Key_S: MoveBack = down ? (MoveBack | 1) : (MoveBack & ~1); return true;
+ case OVR::Key_A: MoveLeft = down ? (MoveLeft | 1) : (MoveLeft & ~1); return true;
+ case OVR::Key_D: MoveRight = down ? (MoveRight | 1) : (MoveRight & ~1); return true;
+ case OVR::Key_Up: MoveForward = down ? (MoveForward | 2) : (MoveForward & ~2); return true;
+ case OVR::Key_Down: MoveBack = down ? (MoveBack | 2) : (MoveBack & ~2); return true;
+ case OVR::Key_Left: MoveLeft = down ? (MoveLeft | 2) : (MoveLeft & ~2); return true;
+ case OVR::Key_Right: MoveRight = down ? (MoveRight | 2) : (MoveRight & ~2); return true;
+ }
+ return false;
}
+
+
diff --git a/Samples/OculusWorldDemo/Player.h b/Samples/OculusWorldDemo/Player.h
index e57e67c..f8d29d5 100644
--- a/Samples/OculusWorldDemo/Player.h
+++ b/Samples/OculusWorldDemo/Player.h
@@ -1,7 +1,7 @@
/************************************************************************************
Filename : Player.h
-Content : Player location and hit-testing logic
+Content : Avatar movement and collision detection
Created : October 4, 2012
Copyright : Copyright 2012 Oculus, Inc. All Rights reserved.
@@ -25,23 +25,20 @@ limitations under the License.
#define OVR_WorldDemo_Player_h
#include "OVR.h"
+#include "Kernel/OVR_KeyCodes.h"
#include "../CommonSrc/Render/Render_Device.h"
using namespace OVR;
using namespace OVR::Render;
//-------------------------------------------------------------------------------------
-// The RHS coordinate system is defines as follows (as seen in perspective view):
-// Y - Up
-// Z - Back
-// X - Right
-const Vector3f UpVector(0.0f, 1.0f, 0.0f);
-const Vector3f ForwardVector(0.0f, 0.0f, -1.0f);
+// The RHS coordinate system is assumed.
const Vector3f RightVector(1.0f, 0.0f, 0.0f);
+const Vector3f UpVector(0.0f, 1.0f, 0.0f);
+const Vector3f ForwardVector(0.0f, 0.0f, -1.0f); // -1 because HMD looks along -Z at identity orientation
-// We start out looking in the positive Z (180 degree rotation).
-const float YawInitial = 3.141592f;
-const float Sensitivity = 1.0f;
+const float YawInitial = 0.0f;
+const float Sensitivity = 0.3f; // low sensitivity to ease people into it gently.
const float MoveSpeed = 3.0f; // m/s
// These are used for collision detection
@@ -58,24 +55,37 @@ public:
float UserEyeHeight;
- // Position and look. The following apply:
- Vector3f EyePos;
- float EyeYaw; // Rotation around Y, CCW positive when looking at RHS (X,Z) plane.
- float EyePitch; // Pitch. If sensor is plugged in, only read from sensor.
- float EyeRoll; // Roll, only accessible from Sensor.
- float LastSensorYaw; // Stores previous Yaw value from to support computing delta.
+ // Where the avatar coordinate system (and body) is positioned and oriented in the virtual world
+ // Modified by gamepad/mouse input
+ Vector3f BodyPos;
+ Anglef BodyYaw;
+
+ // Where the player head is positioned and oriented in the real world
+ Posef HeadPose;
+
+ // Where the avatar head is positioned and oriented in the virtual world
+ Vector3f GetPosition();
+ Quatf GetOrientation(bool baseOnly = false);
+
+ // Returns virtual world position based on a real world head pose.
+ // Allows predicting eyes separately based on scanout time.
+ Posef VirtualWorldPoseFromRealPose(const Posef &sensorHeadPose);
+
+ // Handle directional movement. Returns 'true' if movement was processed.
+ bool HandleMoveKey(OVR::KeyCode key, bool down);
- // Movement state; different bits may be set based on the state of keys.
+ // Movement state; different bits may be set based on the state of keys.
UByte MoveForward;
UByte MoveBack;
UByte MoveLeft;
UByte MoveRight;
Vector3f GamepadMove, GamepadRotate;
+ bool bMotionRelativeToBody;
Player();
~Player();
- void HandleCollision(double dt, Array<Ptr<CollisionModel> >* collisionModels,
- Array<Ptr<CollisionModel> >* groundCollisionModels, bool shiftDown);
+ void HandleMovement(double dt, Array<Ptr<CollisionModel> >* collisionModels,
+ Array<Ptr<CollisionModel> >* groundCollisionModels, bool shiftDown);
};
#endif
diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj b/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj
new file mode 100644
index 0000000..2167237
--- /dev/null
+++ b/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj
@@ -0,0 +1,227 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{456DA1F5-7D65-4B77-8336-277F3921639B}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>OculusWorldDemo</RootNamespace>
+ <ProjectName>OculusWorldDemo</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2010/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2010/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusWorldDemo</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2010/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2010/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusWorldDemo</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2010/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2010/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusWorldDemo</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2010/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2010/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusWorldDemo</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../3rdParty/glext;../../../../../LibOVR/Src;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2010/;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovrd.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;_WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../3rdParty/glext;../../../../../LibOVR/Src;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2010/;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovr64d.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../3rdParty/glext;../../../../../LibOVR/Src;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2010/;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovr.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>_WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../3rdParty/glext;../../../../../LibOVR/Src;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2010/;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovr64.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureDDS.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureTGA.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp" />
+ <ClCompile Include="..\..\..\OculusWorldDemo.cpp" />
+ <ClCompile Include="..\..\..\OculusWorldDemo_Scene.cpp" />
+ <ClCompile Include="..\..\..\OptionMenu.cpp" />
+ <ClCompile Include="..\..\..\Player.cpp" />
+ <ClCompile Include="..\..\..\RenderProfiler.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Gamepad.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform_Default.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Font.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.h" />
+ <ClInclude Include="..\..\..\OptionMenu.h" />
+ <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.h" />
+ <ClInclude Include="..\..\..\OculusWorldDemo.h" />
+ <ClInclude Include="..\..\..\Player.h" />
+ <ClInclude Include="..\..\..\RenderProfiler.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj.filters b/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj.filters
new file mode 100644
index 0000000..67678ea
--- /dev/null
+++ b/Samples/OculusWorldDemo/Projects/Win/VS2010/OculusWorldDemo.vcxproj.filters
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="CommonSrc">
+ <UniqueIdentifier>{ba6e9e50-0655-4f12-a136-6d2a06015925}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CommonSrc\Platform">
+ <UniqueIdentifier>{16e20d8b-eff7-454c-be85-02037c399e97}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CommonSrc\Render">
+ <UniqueIdentifier>{1b6d51ae-a405-4f3d-be93-41a50db4f328}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.cpp">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\OculusWorldDemo.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureTGA.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Player.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureDDS.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.cpp">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\OculusWorldDemo_Scene.cpp" />
+ <ClCompile Include="..\..\..\OptionMenu.cpp" />
+ <ClCompile Include="..\..\..\RenderProfiler.cpp" />
+ <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform_Default.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Font.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Gamepad.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\OculusWorldDemo.h" />
+ <ClInclude Include="..\..\..\RenderProfiler.h" />
+ <ClInclude Include="..\..\..\Player.h" />
+ <ClInclude Include="..\..\..\OptionMenu.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj b/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj
new file mode 100644
index 0000000..1dae2b3
--- /dev/null
+++ b/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4F8C2B89-7CF1-4763-8EEF-E969FB760E32}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>OculusWorldDemo</RootNamespace>
+ <ProjectName>OculusWorldDemo</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2012/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2012/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusWorldDemo</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2012/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2012/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusWorldDemo</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2012/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2012/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusWorldDemo</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2012/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2012/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusWorldDemo</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovrd.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;_WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovr64d.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovr.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>_WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2012/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovr64.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureDDS.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureTGA.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp" />
+ <ClCompile Include="..\..\..\OculusWorldDemo.cpp" />
+ <ClCompile Include="..\..\..\OculusWorldDemo_Scene.cpp" />
+ <ClCompile Include="..\..\..\OptionMenu.cpp" />
+ <ClCompile Include="..\..\..\Player.cpp" />
+ <ClCompile Include="..\..\..\RenderProfiler.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Gamepad.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform_Default.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Font.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.h" />
+ <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.h" />
+ <ClInclude Include="..\..\..\OculusWorldDemo.h" />
+ <ClInclude Include="..\..\..\Player.h" />
+ <ClInclude Include="..\..\..\RenderProfiler.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj.filters b/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj.filters
new file mode 100644
index 0000000..7246205
--- /dev/null
+++ b/Samples/OculusWorldDemo/Projects/Win/VS2012/OculusWorldDemo.vcxproj.filters
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="CommonSrc">
+ <UniqueIdentifier>{ba6e9e50-0655-4f12-a136-6d2a06015925}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CommonSrc\Platform">
+ <UniqueIdentifier>{16e20d8b-eff7-454c-be85-02037c399e97}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CommonSrc\Render">
+ <UniqueIdentifier>{1b6d51ae-a405-4f3d-be93-41a50db4f328}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.cpp">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\OculusWorldDemo.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureTGA.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Player.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureDDS.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.cpp">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\OculusWorldDemo_Scene.cpp" />
+ <ClCompile Include="..\..\..\OptionMenu.cpp" />
+ <ClCompile Include="..\..\..\RenderProfiler.cpp" />
+ <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform_Default.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Font.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Gamepad.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\OculusWorldDemo.h" />
+ <ClInclude Include="..\..\..\RenderProfiler.h" />
+ <ClInclude Include="..\..\..\Player.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj b/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj
new file mode 100644
index 0000000..b894075
--- /dev/null
+++ b/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{CA4E4127-1BAD-447C-BFF9-5AF940EEC376}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>OculusWorldDemo</RootNamespace>
+ <ProjectName>OculusWorldDemo</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2013/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2013/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusWorldDemo</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2013/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2013/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusWorldDemo</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2013/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2013/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusWorldDemo</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IntDir>$(ProjectDir)../../../Obj/Win/VS2013/$(Configuration)/$(PlatformName)/</IntDir>
+ <OutDir>$(ProjectDir)../../../Bin/Win/VS2013/$(Configuration)/$(PlatformName)/</OutDir>
+ <TargetName>OculusWorldDemo</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovrd.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>OVR_BUILD_DEBUG;_WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <MinimalRebuild>false</MinimalRebuild>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovr64d.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovr.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level4</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>_WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>../../../../../LibOVR/Include;../../../../../LibOVR/Src;../../../../../3rdParty/glext;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalLibraryDirectories>../../../../../LibOVR/Lib/$(Platform)/VS2013/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>opengl32.lib;libovr64.lib;dxgi.lib;d3d10_1.lib;d3d11.lib;d3dcompiler.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureDDS.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureTGA.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp" />
+ <ClCompile Include="..\..\..\OculusWorldDemo.cpp" />
+ <ClCompile Include="..\..\..\OculusWorldDemo_Scene.cpp" />
+ <ClCompile Include="..\..\..\OptionMenu.cpp" />
+ <ClCompile Include="..\..\..\Player.cpp" />
+ <ClCompile Include="..\..\..\RenderProfiler.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Gamepad.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform_Default.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Font.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.h" />
+ <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.h" />
+ <ClInclude Include="..\..\..\OculusWorldDemo.h" />
+ <ClInclude Include="..\..\..\Player.h" />
+ <ClInclude Include="..\..\..\RenderProfiler.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj.filters b/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj.filters
new file mode 100644
index 0000000..93fff72
--- /dev/null
+++ b/Samples/OculusWorldDemo/Projects/Win/VS2013/OculusWorldDemo.vcxproj.filters
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="CommonSrc">
+ <UniqueIdentifier>{ba6e9e50-0655-4f12-a136-6d2a06015925}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CommonSrc\Platform">
+ <UniqueIdentifier>{16e20d8b-eff7-454c-be85-02037c399e97}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="CommonSrc\Render">
+ <UniqueIdentifier>{1b6d51ae-a405-4f3d-be93-41a50db4f328}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Platform.cpp">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.cpp">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\OculusWorldDemo.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureTGA.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\Player.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_LoadTextureDDS.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.cpp">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\OculusWorldDemo_Scene.cpp" />
+ <ClCompile Include="..\..\..\OptionMenu.cpp" />
+ <ClCompile Include="..\..\..\RenderProfiler.cpp" />
+ <ClCompile Include="..\..\..\..\..\3rdParty\TinyXml\tinyxml2.cpp" />
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.cpp">
+ <Filter>CommonSrc\Render</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Platform.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Platform_Default.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Font.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D1X_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D10_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_D3D11_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\3rdParty\TinyXml\tinyxml2.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_XmlSceneLoader.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Gamepad.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Platform\Win32_Gamepad.h">
+ <Filter>CommonSrc\Platform</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\OculusWorldDemo.h" />
+ <ClInclude Include="..\..\..\RenderProfiler.h" />
+ <ClInclude Include="..\..\..\Player.h" />
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Win32_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\..\CommonSrc\Render\Render_GL_Device.h">
+ <Filter>CommonSrc\Render</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\..\..\OculusWorldDemo.rc" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Samples/OculusWorldDemo/Release/readme b/Samples/OculusWorldDemo/Release/readme
deleted file mode 100644
index c9d0bc0..0000000
--- a/Samples/OculusWorldDemo/Release/readme
+++ /dev/null
@@ -1,2 +0,0 @@
-This document exits to ensure that the required directory structure gets created correctly.
-
diff --git a/Samples/OculusWorldDemo/RenderProfiler.cpp b/Samples/OculusWorldDemo/RenderProfiler.cpp
new file mode 100644
index 0000000..00bbdd9
--- /dev/null
+++ b/Samples/OculusWorldDemo/RenderProfiler.cpp
@@ -0,0 +1,99 @@
+/************************************************************************************
+
+Filename : RenderProfiler.cpp
+Content : Profiling for render.
+Created : March 10, 2014
+Authors : Caleb Leak
+
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*************************************************************************************/
+
+#include "RenderProfiler.h"
+
+using namespace OVR;
+
+RenderProfiler::RenderProfiler()
+{
+ memset(SampleHistory, 0, sizeof(SampleHistory));
+ memset(SampleAverage, 0, sizeof(SampleAverage));
+ SampleCurrentFrame = 0;
+}
+
+void RenderProfiler::RecordSample(SampleType sampleType)
+{
+ if (sampleType == Sample_FrameStart)
+ {
+ // Recompute averages and subtract off frame start time.
+ for (int sample = 1; sample < Sample_LAST; sample++)
+ {
+ SampleHistory[SampleCurrentFrame][sample] -= SampleHistory[SampleCurrentFrame][0];
+
+ // Recompute the average for the current sample type.
+ SampleAverage[sample] = 0.0;
+ for (int frame = 0; frame < NumFramesOfTimerHistory; frame++)
+ {
+ SampleAverage[sample] += SampleHistory[frame][sample];
+ }
+ SampleAverage[sample] /= NumFramesOfTimerHistory;
+ }
+
+ SampleCurrentFrame = ((SampleCurrentFrame + 1) % NumFramesOfTimerHistory);
+ }
+
+ SampleHistory[SampleCurrentFrame][sampleType] = ovr_GetTimeInSeconds();
+}
+
+const double* RenderProfiler::GetLastSampleSet() const
+{
+ return SampleHistory[(SampleCurrentFrame - 1 + NumFramesOfTimerHistory) % NumFramesOfTimerHistory];
+}
+
+void RenderProfiler::DrawOverlay(RenderDevice* prender)
+{
+ char buf[256 * Sample_LAST];
+ OVR_strcpy ( buf, sizeof(buf), "Timing stats" ); // No trailing \n is deliberate.
+
+ /*int timerLastFrame = TimerCurrentFrame - 1;
+ if ( timerLastFrame < 0 )
+ {
+ timerLastFrame = NumFramesOfTimerHistory - 1;
+ }*/
+ // Timer 0 is always the time at the start of the frame.
+
+ const double* averages = GetAverages();
+ const double* lastSampleSet = GetLastSampleSet();
+
+ for ( int timerNum = 1; timerNum < Sample_LAST; timerNum++ )
+ {
+ char const *pName = "";
+ switch ( timerNum )
+ {
+ case Sample_AfterGameProcessing: pName = "AfterGameProcessing"; break;
+ case Sample_AfterEyeRender : pName = "AfterEyeRender "; break;
+// case Sample_BeforeDistortion : pName = "BeforeDistortion "; break;
+// case Sample_AfterDistortion : pName = "AfterDistortion "; break;
+ case Sample_AfterPresent : pName = "AfterPresent "; break;
+// case Sample_AfterFlush : pName = "AfterFlush "; break;
+ default: OVR_ASSERT ( false );
+ }
+ char bufTemp[256];
+ OVR_sprintf ( bufTemp, sizeof(bufTemp), "\nRaw: %.2lfms\t400Ave: %.2lfms\t800%s",
+ lastSampleSet[timerNum] * 1000.0, averages[timerNum] * 1000.0, pName );
+ OVR_strcat ( buf, sizeof(buf), bufTemp );
+ }
+
+ DrawTextBox(prender, 0.0f, 0.0f, 22.0f, buf, DrawText_Center);
+} \ No newline at end of file
diff --git a/Samples/OculusWorldDemo/RenderProfiler.h b/Samples/OculusWorldDemo/RenderProfiler.h
new file mode 100644
index 0000000..96ec50a
--- /dev/null
+++ b/Samples/OculusWorldDemo/RenderProfiler.h
@@ -0,0 +1,71 @@
+/************************************************************************************
+
+Filename : RenderProfiler.h
+Content : Profiling for render.
+Created : March 10, 2014
+Authors : Caleb Leak
+
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*************************************************************************************/
+
+#ifndef INC_RenderProfiler_h
+#define INC_RenderProfiler_h
+
+#include "OVR.h"
+
+// TODO: Refactor option menu so dependencies are in a separate file.
+#include "OptionMenu.h"
+
+//-------------------------------------------------------------------------------------
+// ***** RenderProfiler
+
+// Tracks reported timing sample in a frame and dislays them an overlay from DrawOverlay().
+class RenderProfiler
+{
+public:
+ enum { NumFramesOfTimerHistory = 10 };
+
+ enum SampleType
+ {
+ Sample_FrameStart ,
+ Sample_AfterGameProcessing ,
+ Sample_AfterEyeRender ,
+ // Sample_BeforeDistortion ,
+ // Sample_AfterDistortion ,
+ Sample_AfterPresent ,
+ // Sample_AfterFlush ,
+
+ Sample_LAST
+ };
+
+ RenderProfiler();
+
+ // Records the current time for the given sample type.
+ void RecordSample(SampleType sampleType);
+
+ const double* GetAverages() const { return SampleAverage; }
+ const double* GetLastSampleSet() const;
+
+ void DrawOverlay(RenderDevice* prender);
+
+private:
+
+ double SampleHistory[NumFramesOfTimerHistory][Sample_LAST];
+ double SampleAverage[Sample_LAST];
+ int SampleCurrentFrame;
+};
+
+#endif // INC_RenderProfiler_h
diff --git a/Samples/SensorBox/SensorBoxTest.cpp b/Samples/SensorBox/SensorBoxTest.cpp
deleted file mode 100644
index 7ca416f..0000000
--- a/Samples/SensorBox/SensorBoxTest.cpp
+++ /dev/null
@@ -1,506 +0,0 @@
-/************************************************************************************
-
-Filename : SensorBoxTest.h
-Content : Visual orientaion sensor test app; renders a rotating box over axes.
-Created : October 1, 2012
-Authors : Michael Antonov
-
-Copyright : Copyright 2012 Oculus, Inc. All Rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-*************************************************************************************/
-
-#include "OVR.h"
-#include "Kernel/OVR_String.h"
-
-#include "../CommonSrc/Platform/Platform_Default.h"
-#include "../CommonSrc/Render/Render_Device.h"
-#include "../CommonSrc/Platform/Gamepad.h"
-
-using namespace OVR;
-using namespace OVR::Platform;
-using namespace OVR::Render;
-
-//-------------------------------------------------------------------------------------
-// ***** SensorBoxTest Description
-
-// This application renders an axes-colored box that rotates with sensor input. App allows
-// user to toggle views for debugging purposes by pressing F1, F2, F3 keys.
-// Application further allows running multiple sensors at once to compare sensor quality.
-//
-// The Right-handed coordinate system is defines as follows (as seen in perspective view):
-// Y - Up (colored red)
-// Z - Back (Out from screen, colored blue)
-// X - Right (green)
-// All cameras are looking at the origin.
-
-// Camera view types.
-enum ViewType
-{
- View_Perspective,
- View_XZ_UpY,
- View_XY_DownZ,
- View_Count
-};
-
-
-//-------------------------------------------------------------------------------------
-
-class InputTestApp : public Application
-{
- RenderDevice* pRender;
-
- Ptr<DeviceManager> pManager;
- Ptr<HMDDevice> pHMD;
- Ptr<SensorDevice> pSensor;
- Ptr<SensorDevice> pSensor2;
-
- SensorFusion SFusion;
- SensorFusion SFusion2;
-
- double LastUpdate;
- ViewType CurrentView;
-
- double LastTitleUpdate;
-
- Matrix4f Proj;
- Matrix4f View;
- Scene Sc;
- Ptr<Model> pAxes; // Model of the coordinate system
- Ptr<Container> pBox; // Rendered box
- Ptr<Container> pBox2; // Second model (right now just lines)
-
- // Applies specified projection/lookAt direction to the scene.
- void SetView(ViewType view);
-
-public:
-
- InputTestApp();
- ~InputTestApp();
-
- virtual int OnStartup(int argc, const char** argv);
- virtual void OnIdle();
-
- virtual void OnMouseMove(int x, int y, int modifiers);
- virtual void OnKey(KeyCode key, int chr, bool down, int modifiers);
-};
-
-InputTestApp::InputTestApp()
- : pRender(0), CurrentView(View_Perspective),
- LastUpdate(0), LastTitleUpdate(0), pAxes(0), pBox(0)
-{
-
-}
-
-
-/*
-void UseCase()
-{
- using namespace OVR;
-
- OVR::System::Init();
-
- Ptr<DeviceManager> pManager = 0;
- Ptr<HMDDevice> pHMD = 0;
- Ptr<SensorDevice> pSensor = 0;
- SensorFusion FusionResult;
-
-
- // *** Initialization - Create the first available HMD Device
- pManager = *DeviceManager::Create();
- pHMD = *pManager->EnumerateDevices<HMDDevice>().CreateDevice();
- if (!pHMD)
- return;
- pSensor = *pHMD->GetSensor();
-
- // Get DisplayDeviceName, ScreenWidth/Height, etc..
- HMDInfo hmdInfo;
- pHMD->GetDeviceInfo(&hmdInfo);
-
- if (pSensor)
- FusionResult.AttachToSensor(pSensor);
-
- // *** Per Frame
- // Get orientation quaternion to control view
- Quatf q = FusionResult.GetOrientation();
-
- // Create a matrix from quaternion,
- // where elements [0][0] through [3][3] contain rotation.
- Matrix4f bodyFrameMatrix(q);
-
- // Get Euler angles from quaternion, in specified axis rotation order.
- float yaw, pitch, roll;
- q.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &pitch, &roll);
-
- // *** Shutdown
- pSensor.Clear();
- pHMD.Clear();
- pManager.Clear();
-
- OVR::System::Destroy();
-}
-*/
-
-InputTestApp::~InputTestApp()
-{
- pSensor.Clear();
- pManager.Clear();
-
-}
-
-
-int InputTestApp::OnStartup(int argc, const char** argv)
-{
- if (!pPlatform->SetupWindow(1200,800))
- return 1;
-
-
- pManager = *DeviceManager::Create();
-
- // This initialization logic supports running two sensors at the same time.
-
- DeviceEnumerator<SensorDevice> isensor = pManager->EnumerateDevices<SensorDevice>();
- DeviceEnumerator<SensorDevice> oculusSensor;
- DeviceEnumerator<SensorDevice> oculusSensor2;
-
- while(isensor)
- {
- DeviceInfo di;
- if (isensor.GetDeviceInfo(&di))
- {
- if (strstr(di.ProductName, "Tracker"))
- {
- if (!oculusSensor)
- oculusSensor = isensor;
- else if (!oculusSensor2)
- oculusSensor2 = isensor;
- }
- }
-
- isensor.Next();
- }
-
- if (oculusSensor)
- {
- pSensor = *oculusSensor.CreateDevice();
-
- if (pSensor)
- pSensor->SetRange(SensorRange(4 * 9.81f, 8 * Math<float>::Pi, 1.0f), true);
-
- if (oculusSensor2)
- {
- // Second Oculus sensor, useful for comparing firmware behavior & settings.
- pSensor2 = *oculusSensor2.CreateDevice();
-
- if (pSensor2)
- pSensor2->SetRange(SensorRange(4 * 9.81f, 8 * Math<float>::Pi, 1.0f), true);
- }
- }
-
- oculusSensor.Clear();
- oculusSensor2.Clear();
-
-
- /*
- DeviceHandle hHMD = pManager->EnumerateDevices<HMDDevice>();
- HMDInfo hmdInfo;
- if (hHMD)
- {
- hHMD.GetDeviceInfo(&hmdInfo);
- }
- */
-
- if (pSensor)
- SFusion.AttachToSensor(pSensor);
- if (pSensor2)
- SFusion2.AttachToSensor(pSensor2);
-
- /*
- // Test rotation: This give rotations clockwise (CW) while looking from
- // origin in the direction of the axis.
-
- Vector3f xV(1,0,0);
- Vector3f zV(0,0,1);
-
- Vector3f rxV = Matrix4f::RotationZ(DegreeToRad(10.0f)).Transform(xV);
- Vector3f ryV = Matrix4f::RotationY(DegreeToRad(10.0f)).Transform(xV);
- Vector3f rzV = Matrix4f::RotationX(DegreeToRad(10.0f)).Transform(zV);
- */
-
- // Report relative mouse motion (not absolute position)
- // pPlatform->SetMouseMode(Mouse_Relative);
-
- const char* graphics = "d3d10";
- for (int i = 1; i < argc; i++)
- if (!strcmp(argv[i], "-r") && i < argc-1)
- graphics = argv[i+1];
-
- pRender = pPlatform->SetupGraphics(OVR_DEFAULT_RENDER_DEVICE_SET, graphics,
- RendererParams());
-
- //WireframeFill = pRender->CreateSimpleFill(Fill::F_Wireframe);
-
-
-
- // *** Rotating Box
-
- pBox = *new Container;
- pBox->Add(Ptr<Model>(
- *Model::CreateAxisFaceColorBox(-2.0f, 2.0f, Color(0, 0xAA, 0), // x = green
- -1.0f, 1.0f, Color(0xAA,0, 0), // y = red
- -1.0f, 1.0f, Color(0, 0, 0xAA)) )); // z = blue
- // Drop-down line from box, to make it easier to see differences in angle.
- Ptr<Model> downLine = *new Model(Prim_Lines);
- downLine->AddLine(Vertex(0.0f,-4.5f, 0.0f, 0xFFE0B0B0),
- Vertex(0.0f, 0.0f, 0.0f, 0xFFE0B0B0));
- pBox->Add(downLine);
- Sc.World.Add(pBox);
-
-
- // Secondary rotating coordinate object, if we have two values.
- if (pSensor2)
- {
- pBox2 = *new Container;
-
- // Drop-down line from box, to make it easier to see differences in angle.
- Ptr<Model> lines = *new Model(Prim_Lines);
- lines->AddLine(Vertex( 0.0f,-4.0f, 0.0f, 0xFFA07070), // -Y
- Vertex( 0.0f, 0.0f, 0.0f, 0xFFA07070));
- lines->AddLine(Vertex(-4.0f, 0.0f, 0.0f, 0xFF70A070), // -X
- Vertex( 0.0f, 0.0f, 0.0f, 0xFF70A070));
- lines->AddLine(Vertex( 0.0f, 0.0f,-4.0f, 0xFF7070A0), // -Z
- Vertex( 0.0f, 0.0f, 0.0f, 0xFF7070A0));
- pBox2->Add(lines);
- Sc.World.Add(pBox2);
- }
-
-
- // *** World axis X,Y,Z rendering.
-
- pAxes = *new Model(Prim_Lines);
- pAxes->AddLine(Vertex(-8.0f, 0.0f, 0.0f, 0xFF40FF40),
- Vertex( 8.0f, 0.0f, 0.0f, 0xFF40FF40)); // X
- pAxes->AddLine(Vertex( 7.6f, 0.4f, 0.4f, 0xFF40FF40),
- Vertex( 8.0f, 0.0f, 0.0f, 0xFF40FF40)); // X - arrow
- pAxes->AddLine(Vertex( 7.6f,-0.4f,-0.4f, 0xFF40FF40),
- Vertex( 8.0f, 0.0f, 0.0f, 0xFF40FF40)); // X - arrow
-
- pAxes->AddLine(Vertex( 0.0f,-8.0f, 0.0f, 0xFFFF4040),
- Vertex( 0.0f, 8.0f, 0.0f, 0xFFFF4040)); // Y
- pAxes->AddLine(Vertex( 0.4f, 7.6f, 0.0f, 0xFFFF4040),
- Vertex( 0.0f, 8.0f, 0.0f, 0xFFFF4040)); // Y - arrow
- pAxes->AddLine(Vertex(-0.4f, 7.6f, 0.0f, 0xFFFF4040),
- Vertex( 0.0f, 8.0f, 0.0f, 0xFFFF4040)); // Y
-
- pAxes->AddLine(Vertex( 0.0f, 0.0f,-8.0f, 0xFF4040FF),
- Vertex( 0.0f, 0.0f, 8.0f, 0xFF4040FF)); // Z
- pAxes->AddLine(Vertex( 0.4f, 0.0f, 7.6f, 0xFF4040FF),
- Vertex( 0.0f, 0.0f, 8.0f, 0xFF4040FF)); // Z - arrow
- pAxes->AddLine(Vertex(-0.4f, 0.0f, 7.6f, 0xFF4040FF),
- Vertex( 0.0f, 0.0f, 8.0f, 0xFF4040FF)); // Z - arrow
- Sc.World.Add(pAxes);
-
-
- SetView(CurrentView);
-
-
- LastUpdate = pPlatform->GetAppTime();
- return 0;
-}
-
-void InputTestApp::SetView(ViewType type)
-{
- switch(type)
- {
- case View_Perspective:
- View = Matrix4f::LookAtRH(Vector3f(5.0f, 4.0f, 10.0f), // eye
- Vector3f(0.0f, 1.5f, 0.0f), // at
- Vector3f(0.0f, 1.0f, 0.0f));
- break;
-
- case View_XY_DownZ: // F2
- View = Matrix4f::LookAtRH(Vector3f(0.0f, 0.0f, 10.0f), // eye
- Vector3f(0.0f, 0.0f, 0.0f), // at
- Vector3f(0.0f, 1.0f, 0.0f));
- break;
-
- case View_XZ_UpY:
- View = Matrix4f::LookAtRH(Vector3f(0.0f,-10.0f, 0.0f), // eye
- Vector3f(0.0f, 0.0f, 0.0f), // at
- Vector3f(0.0f, 0.0f, 1.0f));
-
- break;
- default:
- break;
- }
-
- Proj = Matrix4f::PerspectiveRH(DegreeToRad(70.0f), 1280 / (float)800,
- 0.3f, 1000.0f); // LH
-}
-
-
-void InputTestApp::OnMouseMove(int x, int y, int modifiers)
-{
- OVR_UNUSED3(x, y, modifiers);
-}
-
-
-static float CalcDownAngleDegrees(Quatf q)
-{
- Vector3f downVector(0.0f, -1.0f, 0.0f);
- Vector3f val= q.Rotate(downVector);
- return RadToDegree(downVector.Angle(val));
-}
-
-void InputTestApp::OnKey(KeyCode key, int chr, bool down, int modifiers)
-{
- OVR_UNUSED2(chr, modifiers);
-
- switch (key)
- {
- case Key_Q:
- if (!down)
- pPlatform->Exit(0);
- break;
-
- case Key_F1:
- CurrentView = View_Perspective;
- SetView(CurrentView);
- //UpdateWindowTitle();
- break;
- case Key_F2:
- CurrentView = View_XY_DownZ;
- SetView(CurrentView);
- break;
- case Key_F3:
- CurrentView = View_XZ_UpY;
- SetView(CurrentView);
- break;
-
- case Key_R:
- if (down)
- {
- SFusion.Reset();
- SFusion2.Reset();
- }
- break;
-
- case Key_H:
- if (down && pSensor)
- {
- SensorDevice::CoordinateFrame coord = pSensor->GetCoordinateFrame();
- pSensor->SetCoordinateFrame(
- (coord == SensorDevice::Coord_Sensor) ?
- SensorDevice::Coord_HMD : SensorDevice::Coord_Sensor);
- SFusion.Reset();
- SFusion2.Reset();
- }
- break;
-
- case Key_G:
- if (down)
- {
- SFusion.SetGravityEnabled(!SFusion.IsGravityEnabled());
- SFusion2.SetGravityEnabled(SFusion.IsGravityEnabled());
- }
- break;
-
- case Key_A:
-
- if (down)
- {
- if (!pSensor2)
- {
- LogText("Angle: %2.3f\n", CalcDownAngleDegrees(SFusion.GetOrientation()));
- }
- else
- {
- LogText("Angle: %2.3f Secondary Sensor Angle: %2.3f\n",
- CalcDownAngleDegrees(SFusion.GetOrientation()),
- CalcDownAngleDegrees(SFusion2.GetOrientation()));
- }
- }
- break;
-
- /*
- case Key_End:
- if (!down)
- {
- OriAdjust = OriSensor.Conj();
- Sc.ViewPoint.SetOrientation(Quatf());
- }
- break; */
- default:
- break;
- }
-}
-
-void InputTestApp::OnIdle()
-{
- double curtime = pPlatform->GetAppTime();
- // float dt = float(LastUpdate - curtime);
- LastUpdate = curtime;
-
- if (pBox)
- {
- Quatf q = SFusion.GetOrientation();
- pBox->SetOrientation(q);
-
- // Test Euler conversion, alternative to the above:
- // Vector3f euler;
- // SFusion.GetOrientation().GetEulerABC<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(&euler.y, &euler.x, &euler.z);
- // Matrix4f mat = Matrix4f::RotationY(euler.y) * Matrix4f::RotationX(euler.x) * Matrix4f::RotationZ(euler.z);
- // pBox->SetMatrix(mat);
-
- // Update titlebar every 20th of a second.
- if ((curtime - LastTitleUpdate) > 0.05f)
- {
- char titleBuffer[512];
- SensorDevice::CoordinateFrame coord = SensorDevice::Coord_Sensor;
- if (pSensor)
- coord = pSensor->GetCoordinateFrame();
-
- OVR_sprintf(titleBuffer, 512, "OVR SensorBox %s %s Ang: %0.3f",
- (SFusion.IsGravityEnabled() ? "" : "[Grav Off]"),
- (coord == SensorDevice::Coord_HMD) ? "[HMD Coord]" : "",
- CalcDownAngleDegrees(q));
- pPlatform->SetWindowTitle(titleBuffer);
- LastTitleUpdate = curtime;
- }
- }
-
- if (pBox2)
- {
- pBox2->SetOrientation(SFusion2.GetOrientation());
- }
-
- // Render
- int w, h;
- pPlatform->GetWindowSize(&w, &h);
-
- pRender->SetViewport(0, 0, w, h);
-
- pRender->Clear();
- pRender->BeginScene();
-
- pRender->SetProjection(Proj);
- pRender->SetDepthMode(1,1);
-
- Sc.Render(pRender, View);
-
- pRender->Present();
-
-}
-
-OVR_PLATFORM_APP(InputTestApp);
diff --git a/Samples/SensorBox/SensorBoxTest.rc b/Samples/SensorBox/SensorBoxTest.rc
deleted file mode 100644
index 49a6a5a..0000000
--- a/Samples/SensorBox/SensorBoxTest.rc
+++ /dev/null
Binary files differ
diff --git a/Samples/SensorBox/SensorBoxTest_Msvc2010.vcxproj b/Samples/SensorBox/SensorBoxTest_Msvc2010.vcxproj
deleted file mode 100644
index a0c06af..0000000
--- a/Samples/SensorBox/SensorBoxTest_Msvc2010.vcxproj
+++ /dev/null
@@ -1,126 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{8051B837-2982-4F64-8C3B-FAF88B6D83AB}</ProjectGuid>
- <Keyword>Win32Proj</Keyword>
- <RootNamespace>SensorBoxTest</RootNamespace>
- <ProjectName>SensorBoxTest</ProjectName>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>true</UseDebugLibraries>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseDebugLibraries>false</UseDebugLibraries>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LinkIncremental>true</LinkIncremental>
- <IntDir>$(Configuration)\Obj\</IntDir>
- <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <LinkIncremental>false</LinkIncremental>
- <IntDir>$(Configuration)\Obj\</IntDir>
- <OutDir>$(ProjectDir)$(Configuration)\</OutDir>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <WarningLevel>Level4</WarningLevel>
- <Optimization>Disabled</Optimization>
- <PreprocessorDefinitions>OVR_BUILD_DEBUG;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>../../LibOVR/Include;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <DebugInformationFormat>OldStyle</DebugInformationFormat>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- <StringPooling>
- </StringPooling>
- <MinimalRebuild>false</MinimalRebuild>
- </ClCompile>
- <Link>
- <SubSystem>Windows</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <AdditionalDependencies>libovrd.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>../../LibOVR/Lib/Win32;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <WarningLevel>Level4</WarningLevel>
- <PrecompiledHeader>
- </PrecompiledHeader>
- <Optimization>MaxSpeed</Optimization>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <IntrinsicFunctions>true</IntrinsicFunctions>
- <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>../../LibOVR/Include;../../LibOVR/Src;../../3rdParty/glext;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <MultiProcessorCompilation>true</MultiProcessorCompilation>
- <DebugInformationFormat>OldStyle</DebugInformationFormat>
- </ClCompile>
- <Link>
- <SubSystem>Windows</SubSystem>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <OptimizeReferences>true</OptimizeReferences>
- <AdditionalLibraryDirectories>../../LibOVR/Lib/Win32;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
- <AdditionalDependencies>libovr.lib;dxgi.lib;d3d10.lib;d3d11.lib;d3dcompiler.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="..\CommonSrc\Platform\Platform.cpp" />
- <ClCompile Include="..\CommonSrc\Platform\Win32_Gamepad.cpp" />
- <ClCompile Include="..\CommonSrc\Platform\Win32_Platform.cpp" />
- <ClCompile Include="..\CommonSrc\Render\Render_Device.cpp" />
- <ClCompile Include="..\CommonSrc\Render\Render_D3D10_Device.cpp" />
- <ClCompile Include="..\CommonSrc\Render\Render_D3D11_Device.cpp" />
- <ClCompile Include="..\CommonSrc\Render\Render_D3D1X_Device.cpp">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- </ClCompile>
- <ClCompile Include="SensorBoxTest.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\CommonSrc\Platform\Gamepad.h" />
- <ClInclude Include="..\CommonSrc\Platform\Platform.h" />
- <ClInclude Include="..\CommonSrc\Platform\Platform_Default.h" />
- <ClInclude Include="..\CommonSrc\Platform\Win32_Gamepad.h" />
- <ClInclude Include="..\CommonSrc\Platform\Win32_Platform.h" />
- <ClInclude Include="..\CommonSrc\Render\Render_Font.h" />
- <ClInclude Include="..\CommonSrc\Render\Render.h" />
- <ClInclude Include="..\CommonSrc\Render\Render_D3D10_Device.h" />
- <ClInclude Include="..\CommonSrc\Render\Render_D3D11_Device.h" />
- <ClInclude Include="..\CommonSrc\Render\Render_D3D1X_Device.h" />
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="SensorBoxTest.rc" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/Samples/SensorBox/SensorBoxTest_Msvc2010.vcxproj.filters b/Samples/SensorBox/SensorBoxTest_Msvc2010.vcxproj.filters
deleted file mode 100644
index 5c2ee68..0000000
--- a/Samples/SensorBox/SensorBoxTest_Msvc2010.vcxproj.filters
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="CommonSrc">
- <UniqueIdentifier>{ba673e50-0655-4f12-a166-6d3ab6015925}</UniqueIdentifier>
- </Filter>
- <Filter Include="CommonSrc\Platform">
- <UniqueIdentifier>{16e20aab-eff7-45ff-be85-0203ad399e97}</UniqueIdentifier>
- </Filter>
- <Filter Include="CommonSrc\Render">
- <UniqueIdentifier>{1b6db3ae-a405-4f65-be93-41a62db4fa21}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="..\CommonSrc\Platform\Platform.cpp">
- <Filter>CommonSrc\Platform</Filter>
- </ClCompile>
- <ClCompile Include="..\CommonSrc\Platform\Win32_Platform.cpp">
- <Filter>CommonSrc\Platform</Filter>
- </ClCompile>
- <ClCompile Include="..\CommonSrc\Render\Render_Device.cpp">
- <Filter>CommonSrc\Render</Filter>
- </ClCompile>
- <ClCompile Include="..\CommonSrc\Render\Render_D3D1X_Device.cpp">
- <Filter>CommonSrc\Render</Filter>
- </ClCompile>
- <ClCompile Include="..\CommonSrc\Render\Render_D3D10_Device.cpp">
- <Filter>CommonSrc\Render</Filter>
- </ClCompile>
- <ClCompile Include="..\CommonSrc\Render\Render_D3D11_Device.cpp">
- <Filter>CommonSrc\Render</Filter>
- </ClCompile>
- <ClCompile Include="SensorBoxTest.cpp" />
- <ClCompile Include="..\CommonSrc\Platform\Win32_Gamepad.cpp">
- <Filter>CommonSrc\Platform</Filter>
- </ClCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\CommonSrc\Platform\Win32_Platform.h">
- <Filter>CommonSrc\Platform</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Platform\Platform.h">
- <Filter>CommonSrc\Platform</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Platform\Platform_Default.h">
- <Filter>CommonSrc\Platform</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Render\Render_Font.h">
- <Filter>CommonSrc\Render</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Render\Render.h">
- <Filter>CommonSrc\Render</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Render\Render_D3D1X_Device.h">
- <Filter>CommonSrc\Render</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Render\Render_D3D10_Device.h">
- <Filter>CommonSrc\Render</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Render\Render_D3D11_Device.h">
- <Filter>CommonSrc\Render</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Platform\Gamepad.h">
- <Filter>CommonSrc\Platform</Filter>
- </ClInclude>
- <ClInclude Include="..\CommonSrc\Platform\Win32_Gamepad.h">
- <Filter>CommonSrc\Platform</Filter>
- </ClInclude>
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="SensorBoxTest.rc" />
- </ItemGroup>
-</Project> \ No newline at end of file
diff --git a/Win_OculusWorldDemo.lnk b/Win_OculusWorldDemo.lnk
deleted file mode 100644
index d846ead..0000000
--- a/Win_OculusWorldDemo.lnk
+++ /dev/null
Binary files differ
diff --git a/readme.txt b/readme.txt
index cd53c94..5c584cf 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,5 +1,5 @@
Oculus SDK
-(C) Oculus VR, Inc. 2013. All Rights Reserved.
+(C) Oculus VR, Inc. 2014. All Rights Reserved.
The latest version of the Oculus SDK is available at http://developer.oculusvr.com.