mirror of
https://github.com/XProger/OpenLara.git
synced 2025-03-13 23:59:41 +01:00
Merge with VR branch
This commit is contained in:
commit
c8c7dde46c
BIN
bin/OpenLara.exe
BIN
bin/OpenLara.exe
Binary file not shown.
23
src/camera.h
23
src/camera.h
@ -594,13 +594,9 @@ struct Camera : ICamera {
|
||||
} else
|
||||
updateFirstPerson();
|
||||
|
||||
|
||||
/*
|
||||
if (Core::settings.detail.VR) {
|
||||
mat4 head = Input::head.getMatrix();
|
||||
mViewInv = mViewInv * head;
|
||||
if (Core::settings.detail.vr) {
|
||||
mViewInv = mViewInv * Input::hmd.eye[0];
|
||||
}
|
||||
*/
|
||||
}
|
||||
updateListener();
|
||||
|
||||
@ -609,11 +605,15 @@ struct Camera : ICamera {
|
||||
|
||||
virtual void setup(bool 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) {
|
||||
Core::mViewInv = mat4(*reflectPlane) * mViewInv;
|
||||
Core::mViewInv = mat4(*reflectPlane) * Core::mViewInv;
|
||||
Core::mViewInv.scale(vec3(1.0f, -1.0f, 1.0f));
|
||||
} else
|
||||
Core::mViewInv = mViewInv;
|
||||
}
|
||||
|
||||
Core::mView = Core::mViewInv.inverse();
|
||||
if (shake > 0.0f)
|
||||
@ -622,7 +622,10 @@ struct Camera : ICamera {
|
||||
if (Core::settings.detail.stereo == Core::Settings::STEREO_ON)
|
||||
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);
|
||||
|
16
src/core.h
16
src/core.h
@ -298,7 +298,7 @@ namespace Core {
|
||||
};
|
||||
uint8 vsync;
|
||||
uint8 stereo;
|
||||
|
||||
uint8 vr;
|
||||
void setFilter(Quality value) {
|
||||
if (value > MEDIUM && !(support.maxAniso > 1))
|
||||
value = MEDIUM;
|
||||
@ -729,6 +729,8 @@ namespace Core {
|
||||
|
||||
namespace Core {
|
||||
|
||||
Texture *eyeTex[2];
|
||||
|
||||
bool extSupport(const char *str, const char *ext) {
|
||||
return strstr(str, ext) != NULL;
|
||||
}
|
||||
@ -1020,7 +1022,6 @@ namespace Core {
|
||||
settings.detail.setWater (Core::Settings::HIGH);
|
||||
settings.detail.vsync = true;
|
||||
settings.detail.stereo = Settings::STEREO_OFF;
|
||||
|
||||
settings.audio.music = 14;
|
||||
settings.audio.sound = 14;
|
||||
settings.audio.reverb = true;
|
||||
@ -1090,10 +1091,14 @@ namespace Core {
|
||||
settings.audio.reverb = false;
|
||||
#endif
|
||||
|
||||
eyeTex[0] = eyeTex[1] = NULL;
|
||||
|
||||
resetTime();
|
||||
}
|
||||
|
||||
void deinit() {
|
||||
delete eyeTex[0];
|
||||
delete eyeTex[1];
|
||||
delete whiteTex;
|
||||
#ifdef _PSP
|
||||
delete[] cmdBuf;
|
||||
@ -1109,6 +1114,13 @@ namespace Core {
|
||||
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
|
||||
int cacheRenderTarget(bool depth, int width, int height) {
|
||||
RenderTargetCache &cache = rtCache[depth];
|
||||
|
37
src/input.h
37
src/input.h
@ -30,32 +30,23 @@ namespace Input {
|
||||
} touch[6];
|
||||
|
||||
struct HMD {
|
||||
Basis pivot;
|
||||
Basis basis;
|
||||
bool ready;
|
||||
mat4 eye[2];
|
||||
mat4 proj[2];
|
||||
mat4 controllers[2];
|
||||
vec3 zero;
|
||||
bool ready;
|
||||
|
||||
void set() {
|
||||
if (!ready) {
|
||||
pivot = basis;
|
||||
ready = true;
|
||||
}
|
||||
void setView(const mat4 &pL, const mat4 &pR, const mat4 &vL, const mat4 &vR) {
|
||||
proj[0] = pL;
|
||||
proj[1] = pR;
|
||||
eye[0] = vL;
|
||||
eye[1] = vR;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
pivot.identity();
|
||||
basis.identity();
|
||||
ready = false;
|
||||
//
|
||||
}
|
||||
|
||||
mat4 getMatrix() {
|
||||
Basis b = pivot.inverse() * basis;
|
||||
mat4 m;
|
||||
m.identity();
|
||||
m.setRot(b.rot);
|
||||
m.setPos(b.pos);
|
||||
return m;
|
||||
}
|
||||
} head;
|
||||
} hmd;
|
||||
|
||||
enum TouchButton { bNone, bWeapon, bWalk, bAction, bJump, bInventory, bMAX };
|
||||
enum TouchZone { zMove, zLook, zButton, zMAX };
|
||||
@ -137,11 +128,13 @@ namespace Input {
|
||||
memset(&mouse, 0, sizeof(mouse));
|
||||
memset(&joy, 0, sizeof(joy));
|
||||
memset(&touch, 0, sizeof(touch));
|
||||
head.reset();
|
||||
hmd.reset();
|
||||
}
|
||||
|
||||
void init() {
|
||||
reset();
|
||||
hmd.ready = false;
|
||||
hmd.zero = vec3(INF, INF, INF);
|
||||
touchTimerVis = 0.0f;
|
||||
touchTimerTap = 0.0f;
|
||||
doubleTap = false;
|
||||
|
@ -657,7 +657,7 @@ struct Inventory {
|
||||
game->playSound(TR::SND_INV_PAGE);
|
||||
item->value = 1;
|
||||
|
||||
int passportSlotCount;
|
||||
int passportSlotCount = 0;
|
||||
TR::LevelID passportSlots[32];
|
||||
|
||||
switch (level->version & TR::VER_VERSION) {
|
||||
@ -1262,7 +1262,13 @@ struct Inventory {
|
||||
float dx = 32.0f - eye;
|
||||
UI::textOut(vec2(dx, 480 - 64), "Ctrl - Select", UI::aLeft, UI::width, UI::SHADE_NONE);
|
||||
if (chosen)
|
||||
UI::textOut(vec2(0, 480 - 64), "Alt - Go Back", UI::aRight, UI::width - dx, UI::SHADE_NONE);
|
||||
UI::textOut(vec2(0, 480 - 64),
|
||||
#ifdef __EMSCRIPTEN__
|
||||
"D"
|
||||
#else
|
||||
"Alt"
|
||||
#endif
|
||||
" - Go Back", UI::aRight, UI::width - dx, UI::SHADE_NONE);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1139,7 +1139,7 @@ struct Lara : Character {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
27
src/level.h
27
src/level.h
@ -2037,6 +2037,33 @@ struct Level : IGame {
|
||||
if (shadow) shadow->bind(sShadow);
|
||||
Core::pass = Core::passCompose;
|
||||
|
||||
if (view == 0 && Input::hmd.ready) {
|
||||
Core::settings.detail.vr = true;
|
||||
|
||||
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, false);
|
||||
|
||||
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, false);
|
||||
|
||||
Core::settings.detail.vr = false;
|
||||
|
||||
Core::defaultTarget = oldTarget;
|
||||
Core::setTarget(NULL, true);
|
||||
Core::viewportDef = vp;
|
||||
}
|
||||
|
||||
if (Core::settings.detail.stereo == Core::Settings::STEREO_ON) { // left/right SBS stereo
|
||||
setViewport(view, -1, false);
|
||||
setup();
|
||||
|
3857
src/libs/openvr/openvr.h
Normal file
3857
src/libs/openvr/openvr.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
src/libs/openvr/openvr_api.lib
Normal file
BIN
src/libs/openvr/openvr_api.lib
Normal file
Binary file not shown.
@ -7,13 +7,25 @@
|
||||
|
||||
#ifdef MINIMAL
|
||||
#if _MSC_VER >= 1900 // VS2015 (1900) VS2017 (1910)
|
||||
#define _NO_CRT_STDIO_INLINE
|
||||
#include <malloc.h>
|
||||
void __cdecl operator delete(void *ptr, unsigned int size) { free(ptr); }
|
||||
// add "/d2noftol3" to compiler additional options
|
||||
// add define _NO_CRT_STDIO_INLINE
|
||||
#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"
|
||||
|
||||
|
||||
@ -373,7 +385,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
|
||||
return 0;
|
||||
}
|
||||
|
||||
HGLRC initGL(HDC hDC) {
|
||||
HGLRC glInit(HDC hDC) {
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
memset(&pfd, 0, sizeof(pfd));
|
||||
pfd.nSize = sizeof(pfd);
|
||||
@ -394,11 +406,119 @@ HGLRC initGL(HDC hDC) {
|
||||
return hRC;
|
||||
}
|
||||
|
||||
void freeGL(HGLRC hRC) {
|
||||
void glFree(HGLRC hRC) {
|
||||
wglMakeCurrent(0, 0);
|
||||
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, <ex);
|
||||
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::contentDir[255];
|
||||
|
||||
@ -426,8 +546,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);
|
||||
|
||||
HDC hDC = GetDC(hWnd);
|
||||
HGLRC hRC = initGL(hDC);
|
||||
|
||||
HGLRC hRC = glInit(hDC);
|
||||
|
||||
#ifdef VR_SUPPORT
|
||||
vrInit();
|
||||
#endif
|
||||
|
||||
Sound::channelsCount = 0;
|
||||
|
||||
osStartTime = osGetTime();
|
||||
@ -439,6 +563,11 @@ int main(int argc, char** argv) {
|
||||
|
||||
Game::init(argc > 1 ? argv[1] : NULL);
|
||||
|
||||
#ifdef VR_SUPPORT
|
||||
Input::hmd.ready = hmd != NULL;
|
||||
vrInitTargets();
|
||||
#endif
|
||||
|
||||
SetWindowLong(hWnd, GWL_WNDPROC, (LONG)&WndProc);
|
||||
ShowWindow(hWnd, SW_SHOWDEFAULT);
|
||||
|
||||
@ -453,8 +582,17 @@ int main(int argc, char** argv) {
|
||||
} else {
|
||||
joyUpdate(0);
|
||||
joyUpdate(1);
|
||||
#ifdef VR_SUPPORT
|
||||
vrUpdateInput();
|
||||
#endif
|
||||
if (Game::update()) {
|
||||
#ifdef VR_SUPPORT
|
||||
vrUpdateView();
|
||||
#endif
|
||||
Game::render();
|
||||
#ifdef VR_SUPPORT
|
||||
vrCompose();
|
||||
#endif
|
||||
Core::waitVBlank();
|
||||
SwapBuffers(hDC);
|
||||
}
|
||||
@ -467,7 +605,11 @@ int main(int argc, char** argv) {
|
||||
sndFree();
|
||||
Game::deinit();
|
||||
|
||||
freeGL(hRC);
|
||||
#ifdef VR_SUPPORT
|
||||
vrFree();
|
||||
#endif
|
||||
|
||||
glFree(hRC);
|
||||
ReleaseDC(hWnd, hDC);
|
||||
|
||||
DestroyWindow(hWnd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user