1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-02-25 07:52:43 +01:00

#23 VR support for Vive and Oculus (WIP)

This commit is contained in:
XProger 2018-02-11 03:32:33 +03:00
parent 7b61ceb638
commit 9cccafcd32
9 changed files with 4086 additions and 46 deletions

View File

@ -593,13 +593,9 @@ struct Camera : ICamera {
} else } else
updateFirstPerson(); updateFirstPerson();
if (Core::settings.detail.vr) {
/* mViewInv = mViewInv * Input::hmd.eye[0];
if (Core::settings.detail.VR) {
mat4 head = Input::head.getMatrix();
mViewInv = mViewInv * head;
} }
*/
} }
updateListener(); updateListener();
@ -608,11 +604,15 @@ struct Camera : ICamera {
virtual void setup(bool calcMatrices) { virtual void setup(bool calcMatrices) {
if (calcMatrices) { if (calcMatrices) {
Core::mViewInv = mViewInv;
if (Core::settings.detail.vr)
Core::mViewInv = Core::mViewInv * Input::hmd.eye[Core::eye == -1.0f ? 0 : 1];
if (reflectPlane) { if (reflectPlane) {
Core::mViewInv = mat4(*reflectPlane) * mViewInv; Core::mViewInv = mat4(*reflectPlane) * Core::mViewInv;
Core::mViewInv.scale(vec3(1.0f, -1.0f, 1.0f)); Core::mViewInv.scale(vec3(1.0f, -1.0f, 1.0f));
} else }
Core::mViewInv = mViewInv;
Core::mView = Core::mViewInv.inverse(); Core::mView = Core::mViewInv.inverse();
if (shake > 0.0f) if (shake > 0.0f)
@ -621,7 +621,10 @@ struct Camera : ICamera {
if (Core::settings.detail.stereo) if (Core::settings.detail.stereo)
Core::mView.translate(Core::mViewInv.right().xyz() * (-Core::eye * (firstPerson ? 8.0f : 32.0f) )); Core::mView.translate(Core::mViewInv.right().xyz() * (-Core::eye * (firstPerson ? 8.0f : 32.0f) ));
Core::mProj = mat4(fov, aspect, znear, zfar); if (Core::settings.detail.vr)
Core::mProj = Input::hmd.proj[Core::eye == -1.0f ? 0 : 1];
else
Core::mProj = mat4(fov, aspect, znear, zfar);
} }
Core::setViewProj(Core::mView, Core::mProj); Core::setViewProj(Core::mView, Core::mProj);

View File

@ -292,6 +292,7 @@ namespace Core {
}; };
bool vsync; bool vsync;
bool stereo; bool stereo;
bool vr;
SplitScreen splitscreen; SplitScreen splitscreen;
void setFilter(Quality value) { void setFilter(Quality value) {
@ -723,6 +724,8 @@ namespace Core {
namespace Core { namespace Core {
Texture *eyeTex[2];
bool extSupport(const char *str, const char *ext) { bool extSupport(const char *str, const char *ext) {
return strstr(str, ext) != NULL; return strstr(str, ext) != NULL;
} }
@ -1014,6 +1017,7 @@ namespace Core {
settings.detail.setWater (Core::Settings::HIGH); settings.detail.setWater (Core::Settings::HIGH);
settings.detail.vsync = true; settings.detail.vsync = true;
settings.detail.stereo = false; settings.detail.stereo = false;
settings.detail.vr = false;
settings.detail.splitscreen = Settings::SPLIT_NONE; settings.detail.splitscreen = Settings::SPLIT_NONE;
settings.audio.music = 0.7f; settings.audio.music = 0.7f;
@ -1054,10 +1058,14 @@ namespace Core {
settings.audio.reverb = false; settings.audio.reverb = false;
#endif #endif
eyeTex[0] = eyeTex[1] = NULL;
resetTime(); resetTime();
} }
void deinit() { void deinit() {
delete eyeTex[0];
delete eyeTex[1];
delete whiteTex; delete whiteTex;
#ifdef _PSP #ifdef _PSP
delete[] cmdBuf; delete[] cmdBuf;
@ -1073,6 +1081,13 @@ namespace Core {
Sound::deinit(); Sound::deinit();
} }
#ifdef VR_SUPPORT
void initVR(int width, int height) {
eyeTex[0] = new Texture(width, height, Texture::RGBA);
eyeTex[1] = new Texture(width, height, Texture::RGBA);
}
#endif
#ifndef _PSP #ifndef _PSP
int cacheRenderTarget(bool depth, int width, int height) { int cacheRenderTarget(bool depth, int width, int height) {
RenderTargetCache &cache = rtCache[depth]; RenderTargetCache &cache = rtCache[depth];

View File

@ -29,32 +29,23 @@ namespace Input {
} touch[6]; } touch[6];
struct HMD { struct HMD {
Basis pivot; mat4 eye[2];
Basis basis; mat4 proj[2];
bool ready; mat4 controllers[2];
vec3 zero;
bool ready;
void set() { void setView(const mat4 &pL, const mat4 &pR, const mat4 &vL, const mat4 &vR) {
if (!ready) { proj[0] = pL;
pivot = basis; proj[1] = pR;
ready = true; eye[0] = vL;
} eye[1] = vR;
} }
void reset() { void reset() {
pivot.identity(); //
basis.identity();
ready = false;
} }
} hmd;
mat4 getMatrix() {
Basis b = pivot.inverse() * basis;
mat4 m;
m.identity();
m.setRot(b.rot);
m.setPos(b.pos);
return m;
}
} head;
enum TouchButton { bNone, bWeapon, bWalk, bAction, bJump, bInventory, bMAX }; enum TouchButton { bNone, bWeapon, bWalk, bAction, bJump, bInventory, bMAX };
enum TouchZone { zMove, zLook, zButton, zMAX }; enum TouchZone { zMove, zLook, zButton, zMAX };
@ -126,11 +117,13 @@ namespace Input {
memset(&mouse, 0, sizeof(mouse)); memset(&mouse, 0, sizeof(mouse));
memset(&joy, 0, sizeof(joy)); memset(&joy, 0, sizeof(joy));
memset(&touch, 0, sizeof(touch)); memset(&touch, 0, sizeof(touch));
head.reset(); hmd.reset();
} }
void init() { void init() {
reset(); reset();
hmd.ready = false;
hmd.zero = vec3(INF, INF, INF);
touchTimerVis = 0.0f; touchTimerVis = 0.0f;
touchTimerTap = 0.0f; touchTimerTap = 0.0f;
doubleTap = false; doubleTap = false;

View File

@ -1142,7 +1142,7 @@ struct Lara : Character {
} }
vec3 getAngle(const vec3 &dir) { vec3 getAngle(const vec3 &dir) {
return vec3(atan2(dir.y, sqrtf(dir.x * dir.x + dir.z * dir.z)) - angle.x, atan2(dir.x, dir.z) - angle.y + PI, 0.0f); return vec3(atan2f(dir.y, sqrtf(dir.x * dir.x + dir.z * dir.z)) - angle.x, atan2f(dir.x, dir.z) - angle.y + PI, 0.0f);
} }
virtual void lookAt(Controller *target) { virtual void lookAt(Controller *target) {

View File

@ -1977,6 +1977,34 @@ struct Level : IGame {
if (shadow) shadow->bind(sShadow); if (shadow) shadow->bind(sShadow);
Core::pass = Core::passCompose; Core::pass = Core::passCompose;
if (view == 0 && Input::hmd.ready) {
Core::settings.detail.vr = true;
mat4 oldView = camera->mViewInv;
Texture *oldTarget = Core::defaultTarget;
vec4 vp = Core::viewportDef;
Core::defaultTarget = Core::eyeTex[0];
Core::viewportDef = vec4(0, 0, float(Core::defaultTarget->width), float(Core::defaultTarget->height));
Core::setTarget(NULL, true);
Core::eye = -1.0f;
setup();
renderView(camera->getRoomIndex(), true);
Core::defaultTarget = Core::eyeTex[1];
Core::viewportDef = vec4(0, 0, float(Core::defaultTarget->width), float(Core::defaultTarget->height));
Core::setTarget(NULL, true);
Core::eye = 1.0f;
setup();
renderView(camera->getRoomIndex(), true);
Core::settings.detail.vr = false;
Core::defaultTarget = oldTarget;
Core::setTarget(NULL, true);
Core::viewportDef = vp;
}
if (Core::settings.detail.stereo) { // left/right SBS stereo if (Core::settings.detail.stereo) { // left/right SBS stereo
vec4 vp = Core::viewportDef; vec4 vp = Core::viewportDef;
Core::viewportDef = vec4(vp.x - vp.x * 0.5f, vp.y, vp.z * 0.5f, vp.w); Core::viewportDef = vec4(vp.x - vp.x * 0.5f, vp.y, vp.z * 0.5f, vp.w);

3857
src/libs/openvr/openvr.h Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
@ -27,26 +27,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset> <PlatformToolset>v140_xp</PlatformToolset>
<CharacterSet>NotSet</CharacterSet> <CharacterSet>NotSet</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Editor|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Editor|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset> <PlatformToolset>v140_xp</PlatformToolset>
<CharacterSet>NotSet</CharacterSet> <CharacterSet>NotSet</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset> <PlatformToolset>v140_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet> <CharacterSet>NotSet</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset> <PlatformToolset>v140_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet> <CharacterSet>NotSet</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -70,6 +70,7 @@
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<OutDir>..\..\..\bin\</OutDir> <OutDir>..\..\..\bin\</OutDir>
<IncludePath>..\..\;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath> <IncludePath>..\..\;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
<LibraryPath>..\..\libs\openvr;$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Editor|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Editor|Win32'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
@ -81,6 +82,7 @@
<OutDir>..\..\..\bin\</OutDir> <OutDir>..\..\..\bin\</OutDir>
<GenerateManifest>false</GenerateManifest> <GenerateManifest>false</GenerateManifest>
<IncludePath>..\..\;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath> <IncludePath>..\..\;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
<LibraryPath>..\..\libs\openvr;$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
@ -102,7 +104,7 @@
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>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> <AdditionalDependencies>openvr_api.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> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Editor|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Editor|Win32'">
@ -145,7 +147,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>wcrt.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> <AdditionalDependencies>openvr_api.lib;wcrt.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>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<RandomizedBaseAddress>false</RandomizedBaseAddress> <RandomizedBaseAddress>false</RandomizedBaseAddress>

View File

@ -7,13 +7,25 @@
#ifdef MINIMAL #ifdef MINIMAL
#if _MSC_VER >= 1900 // VS2015 (1900) VS2017 (1910) #if _MSC_VER >= 1900 // VS2015 (1900) VS2017 (1910)
#define _NO_CRT_STDIO_INLINE
#include <malloc.h> #include <malloc.h>
void __cdecl operator delete(void *ptr, unsigned int size) { free(ptr); } void __cdecl operator delete(void *ptr, unsigned int size) { free(ptr); }
// add "/d2noftol3" to compiler additional options // add "/d2noftol3" to compiler additional options
// add define _NO_CRT_STDIO_INLINE
#endif #endif
#endif #endif
//#define VR_SUPPORT
// TODO: fix depth precision
// TODO: fix water surface rendering
// TODO: fix clipping
// TODO: add MSAA support for render targets
// TODO: add IK for arms
// TODO: controls
#ifdef VR_SUPPORT
#include "libs/openvr/openvr.h"
#endif
#include "game.h" #include "game.h"
@ -372,7 +384,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
return 0; return 0;
} }
HGLRC initGL(HDC hDC) { HGLRC glInit(HDC hDC) {
PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd)); memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd); pfd.nSize = sizeof(pfd);
@ -393,11 +405,119 @@ HGLRC initGL(HDC hDC) {
return hRC; return hRC;
} }
void freeGL(HGLRC hRC) { void glFree(HGLRC hRC) {
wglMakeCurrent(0, 0); wglMakeCurrent(0, 0);
wglDeleteContext(hRC); wglDeleteContext(hRC);
} }
#ifdef VR_SUPPORT
vr::IVRSystem *hmd;
vr::TrackedDevicePose_t tPose[vr::k_unMaxTrackedDeviceCount];
void vrInit() {
vr::EVRInitError eError = vr::VRInitError_None;
hmd = vr::VR_Init(&eError, vr::VRApplication_Scene);
if (eError != vr::VRInitError_None) {
hmd = NULL;
LOG("! unable to init VR runtime: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(eError));
return;
}
if (!vr::VRCompositor()) {
vr::VR_Shutdown();
LOG("! compositor initialization failed\n");
return;
}
}
void vrInitTargets() {
uint32_t width, height;
hmd->GetRecommendedRenderTargetSize( &width, &height);
Core::initVR(width, height);
}
void vrFree() {
if (!hmd) return;
vr::VR_Shutdown();
}
mat4 convToMat4(const vr::HmdMatrix44_t &m) {
return mat4(m.m[0][0], m.m[1][0], m.m[2][0], m.m[3][0],
m.m[0][1], m.m[1][1], m.m[2][1], m.m[3][1],
m.m[0][2], m.m[1][2], m.m[2][2], m.m[3][2],
m.m[0][3], m.m[1][3], m.m[2][3], m.m[3][3]);
}
mat4 convToMat4(const vr::HmdMatrix34_t &m) {
return mat4(m.m[0][0], m.m[1][0], m.m[2][0], 0.0f,
m.m[0][1], m.m[1][1], m.m[2][1], 0.0f,
m.m[0][2], m.m[1][2], m.m[2][2], 0.0f,
m.m[0][3], m.m[1][3], m.m[2][3], 1.0f);
}
void vrUpdateInput() {
if (!hmd) return;
vr::VREvent_t event;
while (hmd->PollNextEvent(&event, sizeof(event))) {
//ProcessVREvent( event );
switch (event.eventType) {
case vr::VREvent_TrackedDeviceActivated:
//SetupRenderModelForTrackedDevice( event.trackedDeviceIndex );
LOG( "Device %u attached. Setting up render model\n", event.trackedDeviceIndex);
break;
case vr::VREvent_TrackedDeviceDeactivated:
LOG("Device %u detached.\n", event.trackedDeviceIndex);
break;
case vr::VREvent_TrackedDeviceUpdated:
LOG("Device %u updated.\n", event.trackedDeviceIndex);
break;
}
}
for (vr::TrackedDeviceIndex_t unDevice = 0; unDevice < vr::k_unMaxTrackedDeviceCount; unDevice++) {
vr::VRControllerState_t state;
if (hmd->GetControllerState(unDevice, &state, sizeof(state))) {
//m_rbShowTrackedDevice[ unDevice ] = state.ulButtonPressed == 0;
}
}
}
void vrUpdateView() {
if (!hmd) return;
vr::VRCompositor()->WaitGetPoses(tPose, vr::k_unMaxTrackedDeviceCount, NULL, 0);
if (!tPose[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid)
return;
mat4 pL = convToMat4(hmd->GetProjectionMatrix(vr::Eye_Left, 8.0f, 45.0f * 1024.0f));
mat4 pR = convToMat4(hmd->GetProjectionMatrix(vr::Eye_Right, 8.0f, 45.0f * 1024.0f));
mat4 head = convToMat4(tPose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking);
if (Input::hmd.zero.x == INF)
Input::hmd.zero = head.getPos();
head.setPos(head.getPos() - Input::hmd.zero);
mat4 vL = head * convToMat4(hmd->GetEyeToHeadTransform(vr::Eye_Left));
mat4 vR = head * convToMat4(hmd->GetEyeToHeadTransform(vr::Eye_Right));
const float ONE_METER = 768.0f / 1.8f; // Lara's height in units / height in meters
vL.setPos(vL.getPos() * ONE_METER);
vR.setPos(vR.getPos() * ONE_METER);
Input::hmd.setView(pL, pR, vL, vR);
}
void vrCompose() {
if (!hmd) return;
vr::Texture_t LTex = {(void*)(uintptr_t)Core::eyeTex[0]->ID, vr::TextureType_OpenGL, vr::ColorSpace_Gamma};
vr::VRCompositor()->Submit(vr::Eye_Left, &LTex);
vr::Texture_t RTex = {(void*)(uintptr_t)Core::eyeTex[1]->ID, vr::TextureType_OpenGL, vr::ColorSpace_Gamma};
vr::VRCompositor()->Submit(vr::Eye_Right, &RTex);
}
#endif // #ifdef VR_SUPPORT
char Stream::cacheDir[255]; char Stream::cacheDir[255];
char Stream::contentDir[255]; char Stream::contentDir[255];
@ -425,8 +545,12 @@ int main(int argc, char** argv) {
HWND hWnd = CreateWindow("static", "OpenLara", WS_OVERLAPPEDWINDOW, 0, 0, r.right - r.left, r.bottom - r.top, 0, 0, 0, 0); HWND hWnd = CreateWindow("static", "OpenLara", WS_OVERLAPPEDWINDOW, 0, 0, r.right - r.left, r.bottom - r.top, 0, 0, 0, 0);
HDC hDC = GetDC(hWnd); HDC hDC = GetDC(hWnd);
HGLRC hRC = initGL(hDC); HGLRC hRC = glInit(hDC);
#ifdef VR_SUPPORT
vrInit();
#endif
Sound::channelsCount = 0; Sound::channelsCount = 0;
osStartTime = osGetTime(); osStartTime = osGetTime();
@ -437,6 +561,11 @@ int main(int argc, char** argv) {
Game::init(argc > 1 ? argv[1] : NULL); Game::init(argc > 1 ? argv[1] : NULL);
#ifdef VR_SUPPORT
Input::hmd.ready = hmd != NULL;
vrInitTargets();
#endif
SetWindowLong(hWnd, GWL_WNDPROC, (LONG)&WndProc); SetWindowLong(hWnd, GWL_WNDPROC, (LONG)&WndProc);
ShowWindow(hWnd, SW_SHOWDEFAULT); ShowWindow(hWnd, SW_SHOWDEFAULT);
@ -450,8 +579,17 @@ int main(int argc, char** argv) {
Core::quit(); Core::quit();
} else { } else {
joyUpdate(); joyUpdate();
#ifdef VR_SUPPORT
vrUpdateInput();
#endif
if (Game::update()) { if (Game::update()) {
#ifdef VR_SUPPORT
vrUpdateView();
#endif
Game::render(); Game::render();
#ifdef VR_SUPPORT
vrCompose();
#endif
Core::waitVBlank(); Core::waitVBlank();
SwapBuffers(hDC); SwapBuffers(hDC);
} }
@ -464,7 +602,11 @@ int main(int argc, char** argv) {
sndFree(); sndFree();
Game::deinit(); Game::deinit();
freeGL(hRC); #ifdef VR_SUPPORT
vrFree();
#endif
glFree(hRC);
ReleaseDC(hWnd, hDC); ReleaseDC(hWnd, hDC);
DestroyWindow(hWnd); DestroyWindow(hWnd);