aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-10-22 14:17:03 +0200
committerdec05eba <dec05eba@protonmail.com>2022-10-22 14:38:10 +0200
commit7ff679769bf6bc49619b19da00772a88758827e5 (patch)
tree110d465d375b531df5271cded9b54b723093bd00
parent40c62b43a29732bc795a7b7b990b5bec4688802f (diff)
Add a config file to store position/rotation/zoom and use those the next time vr-video-player starts
-rw-r--r--README.md2
-rwxr-xr-xbuild.sh6
-rw-r--r--include/config.hpp299
-rw-r--r--include/mpv.hpp2
-rw-r--r--src/main.cpp230
-rw-r--r--src/mpv.cpp9
6 files changed, 446 insertions, 102 deletions
diff --git a/README.md b/README.md
index 20d2839..c75d463 100644
--- a/README.md
+++ b/README.md
@@ -70,7 +70,7 @@ The video might not be in front of you, so to move the video in front of you, yo
* Press the select/back button on an xbox controller while the application is focused
* Send a SIGUSR1 signal to the application, using the following command: `killall -USR1 vr-video-player`
-You can zoom the view with alt + Q/E.
+You can zoom the view with Alt + Q/E.
When using the built-in video player and the vr window is focused you can then use left/right arrow keys to move back/forward in the video and space to pause. In the future vr-video-player will show a graphical interface inside vr to manipulate the video.
diff --git a/build.sh b/build.sh
index 1f2d44b..132f12d 100755
--- a/build.sh
+++ b/build.sh
@@ -3,7 +3,7 @@
dependencies="glm glew sdl2 openvr x11 xcomposite xfixes mpv"
includes=$(pkg-config --cflags $dependencies)
libs=$(pkg-config --libs $dependencies)
-gcc -c src/window_texture.c -O2 $includes
-g++ -c src/mpv.cpp -O2 $includes
-g++ -c src/main.cpp -O2 $includes
+gcc -c src/window_texture.c -O2 -DNDEBUG $includes
+g++ -c src/mpv.cpp -O2 -DNDEBUG $includes
+g++ -c src/main.cpp -O2 -DNDEBUG $includes
g++ -o vr-video-player -O2 window_texture.o mpv.o main.o -s $libs
diff --git a/include/config.hpp b/include/config.hpp
new file mode 100644
index 0000000..fcf69bf
--- /dev/null
+++ b/include/config.hpp
@@ -0,0 +1,299 @@
+#pragma once
+
+#include <string>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <pwd.h>
+#include <sys/stat.h>
+#include <functional>
+#include <glm/glm.hpp>
+#include <glm/ext/quaternion_float.hpp>
+
+struct SphereConfig {
+ glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f);
+ glm::quat rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
+ float zoom = 0.0f;
+};
+
+struct Sphere360Config {
+ glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f);
+ glm::quat rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
+ float zoom = 0.0f;
+};
+
+struct FlatConfig {
+ glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f);
+ glm::quat rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
+ float zoom = 0.0f;
+};
+
+struct PlaneConfig {
+ glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f);
+ glm::quat rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
+ float zoom = 0.0f;
+};
+
+struct Config {
+ SphereConfig sphere;
+ Sphere360Config sphere360;
+ FlatConfig flat;
+ PlaneConfig plane;
+};
+
+static std::string get_home_dir() {
+ const char *home_dir = getenv("HOME");
+ if(!home_dir) {
+ passwd *pw = getpwuid(getuid());
+ home_dir = pw->pw_dir;
+ }
+
+ if(!home_dir) {
+ fprintf(stderr, "Error: Failed to get home directory of user, using /tmp directory\n");
+ home_dir = "/tmp";
+ }
+
+ return home_dir;
+}
+
+static std::string get_config_dir() {
+ std::string config_dir;
+ const char *xdg_config_home = getenv("XDG_CONFIG_HOME");
+ if(xdg_config_home) {
+ config_dir = xdg_config_home;
+ } else {
+ config_dir = get_home_dir() + "/.config";
+ }
+ config_dir += "/vr-video-player";
+ return config_dir;
+}
+
+static int create_directory_recursive(char *path) {
+ int path_len = strlen(path);
+ char *p = path;
+ char *end = path + path_len;
+ for(;;) {
+ char *slash_p = strchr(p, '/');
+
+ // Skips first '/', we don't want to try and create the root directory
+ if(slash_p == path) {
+ ++p;
+ continue;
+ }
+
+ if(!slash_p)
+ slash_p = end;
+
+ char prev_char = *slash_p;
+ *slash_p = '\0';
+ int err = mkdir(path, S_IRWXU);
+ *slash_p = prev_char;
+
+ if(err == -1 && errno != EEXIST)
+ return err;
+
+ if(slash_p == end)
+ break;
+ else
+ p = slash_p + 1;
+ }
+ return 0;
+}
+
+static bool file_get_content(const char *filepath, std::string &file_content) {
+ file_content.clear();
+ bool success = false;
+
+ FILE *file = fopen(filepath, "rb");
+ if(!file)
+ return success;
+
+ fseek(file, 0, SEEK_END);
+ long file_size = ftell(file);
+ if(file_size != -1) {
+ file_content.resize(file_size);
+ fseek(file, 0, SEEK_SET);
+ if((long)fread(&file_content[0], 1, file_size, file) == file_size)
+ success = true;
+ }
+
+ fclose(file);
+ return success;
+}
+
+struct StringView {
+ const char *str;
+ size_t size;
+
+ bool operator == (const char *other) const {
+ int len = strlen(other);
+ return (size_t)len == size && memcmp(str, other, size) == 0;
+ }
+
+ size_t find(char c) const {
+ const void *p = memchr(str, c, size);
+ if(!p)
+ return std::string::npos;
+ return (const char*)p - str;
+ }
+};
+
+using StringSplitCallback = std::function<bool(StringView line)>;
+
+static void string_split_char(const std::string &str, char delimiter, StringSplitCallback callback_func) {
+ size_t index = 0;
+ while(index < str.size()) {
+ size_t new_index = str.find(delimiter, index);
+ if(new_index == std::string::npos)
+ new_index = str.size();
+
+ if(!callback_func({str.data() + index, new_index - index}))
+ break;
+
+ index = new_index + 1;
+ }
+}
+
+static bool config_split_key_value(const StringView str, StringView &key, StringView &value) {
+ key.str = nullptr;
+ key.size = 0;
+
+ value.str = nullptr;
+ value.size = 0;
+
+ size_t index = str.find(' ');
+ if(index == std::string::npos)
+ return std::string::npos;
+
+ key.str = str.str;
+ key.size = index;
+
+ value.str = str.str + index + 1;
+ value.size = str.size - (index + 1);
+
+ return true;
+}
+
+static bool string_to_float(std::string str, float &value, const StringView key) {
+ value = 0.0;
+ errno = 0;
+ char *endptr;
+ value = strtod(str.c_str(), &endptr);
+ if(endptr == str.c_str() || errno != 0) {
+ fprintf(stderr, "Warning: Invalid config option %.*s is not a float\n", (int)key.size, key.str);
+ return false;
+ }
+ return true;
+}
+
+static bool string_to_vec3(std::string str, glm::vec3 &value, const StringView key) {
+ if(sscanf(str.data(), "%f|%f|%f", &value.x, &value.y, &value.z) != 3) {
+ fprintf(stderr, "Warning: Invalid config option %.*s is not a glm::vec3\n", (int)key.size, key.str);
+ return false;
+ }
+ return true;
+}
+
+static bool string_to_quat(std::string str, glm::quat &value, const StringView key) {
+ if(sscanf(str.data(), "%f|%f|%f|%f", &value.x, &value.y, &value.z, &value.w) != 4) {
+ fprintf(stderr, "Warning: Invalid config option %.*s is not a glm::quat\n", (int)key.size, key.str);
+ return false;
+ }
+ return true;
+}
+
+static Config read_config(bool &exists) {
+ setlocale(LC_ALL, "C");
+
+ Config config;
+
+ const std::string config_path = get_config_dir() + "/config";
+ std::string file_content;
+ if(!file_get_content(config_path.c_str(), file_content)) {
+ fprintf(stderr, "Warning: Failed to read config file: %s\n", config_path.c_str());
+ exists = false;
+ return config;
+ }
+
+ string_split_char(file_content, '\n', [&](StringView line) {
+ StringView key, value;
+ if(!config_split_key_value(line, key, value)) {
+ fprintf(stderr, "Warning: Invalid config option format: %.*s\n", (int)line.size, line.str);
+ return true;
+ }
+
+ if(key == "sphere.position") {
+ string_to_vec3(std::string(value.str, value.size), config.sphere.position, key);
+ } else if(key == "sphere.rotation") {
+ string_to_quat(std::string(value.str, value.size), config.sphere.rotation, key);
+ } else if(key == "sphere.zoom") {
+ string_to_float(std::string(value.str, value.size), config.sphere.zoom, key);
+ } else if(key == "sphere360.position") {
+ string_to_vec3(std::string(value.str, value.size), config.sphere360.position, key);
+ } else if(key == "sphere360.rotation") {
+ string_to_quat(std::string(value.str, value.size), config.sphere360.rotation, key);
+ } else if(key == "sphere360.zoom") {
+ string_to_float(std::string(value.str, value.size), config.sphere360.zoom, key);
+ } else if(key == "flat.position") {
+ string_to_vec3(std::string(value.str, value.size), config.flat.position, key);
+ } else if(key == "flat.rotation") {
+ string_to_quat(std::string(value.str, value.size), config.flat.rotation, key);
+ } else if(key == "flat.zoom") {
+ string_to_float(std::string(value.str, value.size), config.flat.zoom, key);
+ } else if(key == "plane.position") {
+ string_to_vec3(std::string(value.str, value.size), config.plane.position, key);
+ } else if(key == "plane.rotation") {
+ string_to_quat(std::string(value.str, value.size), config.plane.rotation, key);
+ } else if(key == "plane.zoom") {
+ string_to_float(std::string(value.str, value.size), config.plane.zoom, key);
+ } else {
+ fprintf(stderr, "Warning: Invalid config option: %.*s\n", (int)line.size, line.str);
+ }
+
+ return true;
+ });
+
+ exists = true;
+ return config;
+}
+
+static void save_config(const Config &config) {
+ setlocale(LC_ALL, "C");
+
+ const std::string config_path = get_config_dir() + "/config";
+
+ char dir_tmp[PATH_MAX];
+ strcpy(dir_tmp, config_path.c_str());
+ char *dir = dirname(dir_tmp);
+
+ if(create_directory_recursive(dir) != 0) {
+ fprintf(stderr, "Warning: Failed to create config directory: %s\n", dir);
+ return;
+ }
+
+ FILE *file = fopen(config_path.c_str(), "wb");
+ if(!file) {
+ fprintf(stderr, "Warning: Failed to create config file: %s\n", config_path.c_str());
+ return;
+ }
+
+ fprintf(file, "sphere.position %f|%f|%f\n", config.sphere.position.x, config.sphere.position.y, config.sphere.position.z);
+ fprintf(file, "sphere.rotation %f|%f|%f|%f\n", config.sphere.rotation.x, config.sphere.rotation.y, config.sphere.rotation.z, config.sphere.rotation.w);
+ fprintf(file, "sphere.zoom %f\n", config.sphere.zoom);
+
+ fprintf(file, "sphere360.position %f|%f|%f\n", config.sphere360.position.x, config.sphere360.position.y, config.sphere360.position.z);
+ fprintf(file, "sphere360.rotation %f|%f|%f|%f\n", config.sphere360.rotation.x, config.sphere360.rotation.y, config.sphere360.rotation.z, config.sphere360.rotation.w);
+ fprintf(file, "sphere360.zoom %f\n", config.sphere360.zoom);
+
+ fprintf(file, "flat.position %f|%f|%f\n", config.flat.position.x, config.flat.position.y, config.flat.position.z);
+ fprintf(file, "flat.rotation %f|%f|%f|%f\n", config.flat.rotation.x, config.flat.rotation.y, config.flat.rotation.z, config.flat.rotation.w);
+ fprintf(file, "flat.zoom %f\n", config.flat.zoom);
+
+ fprintf(file, "plane.position %f|%f|%f\n", config.plane.position.x, config.plane.position.y, config.plane.position.z);
+ fprintf(file, "plane.rotation %f|%f|%f|%f\n", config.plane.rotation.x, config.plane.rotation.y, config.plane.rotation.z, config.plane.rotation.w);
+ fprintf(file, "plane.zoom %f\n", config.plane.zoom);
+
+ fclose(file);
+} \ No newline at end of file
diff --git a/include/mpv.hpp b/include/mpv.hpp
index b4e22b3..09ba2c1 100644
--- a/include/mpv.hpp
+++ b/include/mpv.hpp
@@ -16,7 +16,7 @@ public:
bool load_file(const char *path);
// |width| and |ħeight| are set to 0 unless there is an event to reconfigure video size
- void on_event(SDL_Event &event, bool *render_update, int64_t *width, int64_t *height, bool *quit);
+ void on_event(SDL_Event &event, bool *render_update, int64_t *width, int64_t *height, bool *quit, int *error);
void seek(double seconds);
void toggle_pause();
void draw(unsigned int framebuffer_id, int width, int height);
diff --git a/src/main.cpp b/src/main.cpp
index 016a392..8e74185 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -34,6 +34,7 @@
#include <GL/glew.h>
#include "../include/window_texture.h"
#include "../include/mpv.hpp"
+#include "../include/config.hpp"
#include <SDL.h>
#include <SDL_opengl.h>
@@ -70,6 +71,20 @@
static bool g_bPrintf = true;
+enum class ViewMode {
+ LEFT_RIGHT,
+ RIGHT_LEFT,
+ PLANE,
+ SPHERE360
+};
+
+enum class ProjectionMode {
+ SPHERE,
+ FLAT,
+ CYLINDER, /* aka plane */
+ SPHERE360
+};
+
//-----------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
@@ -121,10 +136,12 @@ public:
// Get focused window or None
Window get_focused_window();
+ void save_config();
+
+ int exit_code = 0;
+ bool bQuit = false;
private:
bool m_bDebugOpenGL;
- bool m_bVerbose;
- bool m_bPerf;
bool m_bVblank;
bool m_bGlFinishHack;
@@ -146,7 +163,6 @@ private: // OpenGL bookkeeping
int m_iValidPoseCount;
int m_iValidPoseCount_Last;
bool m_bResetRotation;
- glm::vec2 m_vAnalogValue;
std::string m_strPoseClasses; // what classes we saw poses for this frame
char m_rDevClassChar[ vr::k_unMaxTrackedDeviceCount ]; // for each device, a character representing its class
@@ -171,15 +187,10 @@ private: // OpenGL bookkeeping
GLuint m_glCompanionWindowIDIndexBuffer;
unsigned int m_uiCompanionWindowIndexSize;
- GLuint m_glControllerVertBuffer;
- GLuint m_unControllerVAO;
- unsigned int m_uiControllerVertcount;
-
glm::mat4 m_mat4HMDPose;
glm::mat4 m_mat4eyePosLeft;
glm::mat4 m_mat4eyePosRight;
- glm::mat4 m_mat4ProjectionCenter;
glm::mat4 m_mat4ProjectionLeft;
glm::mat4 m_mat4ProjectionRight;
@@ -188,6 +199,8 @@ private: // OpenGL bookkeeping
glm::quat hmd_rot = glm::quat(0.0f, 0.0f, 0.0f, 1.0f);
glm::quat m_reset_rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
+ Config config;
+
struct VertexDataScene
{
glm::vec3 position;
@@ -235,10 +248,6 @@ private: // OpenGL bookkeeping
uint32_t m_nRenderHeight;
vr::VRActionHandle_t m_actionHideCubes = vr::k_ulInvalidActionHandle;
- vr::VRActionHandle_t m_actionHideThisController = vr::k_ulInvalidActionHandle;
- vr::VRActionHandle_t m_actionTriggerHaptic = vr::k_ulInvalidActionHandle;
- vr::VRActionHandle_t m_actionAnalongInput = vr::k_ulInvalidActionHandle;
-
vr::VRActionSetHandle_t m_actionsetDemo = vr::k_ulInvalidActionSetHandle;
private: // X compositor
@@ -278,20 +287,6 @@ private: // X compositor
GLint pixmap_texture_width = 1;
GLint pixmap_texture_height = 1;
- enum class ViewMode {
- LEFT_RIGHT,
- RIGHT_LEFT,
- PLANE,
- SPHERE360
- };
-
- enum class ProjectionMode {
- SPHERE,
- FLAT,
- CYLINDER, /* aka plane */
- SPHERE360
- };
-
ProjectionMode projection_mode = ProjectionMode::SPHERE;
double zoom = 0.0;
float cursor_scale = 2.0f;
@@ -312,6 +307,8 @@ private: // X compositor
float cursor_scale_uniform[2];
double arrow_ratio;
bool cursor_image_set = false;
+
+ bool config_exists = false;
};
@@ -401,7 +398,7 @@ void dprintf( const char *fmt, ... )
}
static void usage() {
- fprintf(stderr, "usage: vr-video-player [--sphere|--sphere360|--flat|--plane] [--left-right|--right-left] [--stretch|--no-stretch] [--zoom zoom-level] [--cursor-scale scale] [--cursor-wrap|--no-cursor-wrap] [--follow-focused] [--video video] <window_id>\n");
+ fprintf(stderr, "usage: vr-video-player [--sphere|--sphere360|--flat|--plane] [--left-right|--right-left] [--stretch|--no-stretch] [--zoom zoom-level] [--cursor-scale scale] [--cursor-wrap|--no-cursor-wrap] [--follow-focused|--video video|<window_id>] [--use-system-mpv-config] [--free-camera] [--reduce-flicker]\n");
fprintf(stderr, "\n");
fprintf(stderr, "OPTIONS\n");
fprintf(stderr, " --sphere View the window as a stereoscopic 180 degrees screen (half sphere). The view will be attached to your head in vr. This is recommended for 180 degrees videos. This is the default value\n");
@@ -435,6 +432,35 @@ static void usage() {
exit(1);
}
+static void get_config_values(const Config &config, ProjectionMode projection_mode, glm::vec3 &pos, glm::quat &rot, float &zoom) {
+ switch(projection_mode) {
+ case ProjectionMode::SPHERE: {
+ pos = config.sphere.position;
+ rot = config.sphere.rotation;
+ zoom = config.sphere.zoom;
+ break;
+ }
+ case ProjectionMode::FLAT: {
+ pos = config.flat.position;
+ rot = config.flat.rotation;
+ zoom = config.flat.zoom;
+ break;
+ }
+ case ProjectionMode::CYLINDER: {
+ pos = config.plane.position;
+ rot = config.plane.rotation;
+ zoom = config.plane.zoom;
+ break;
+ }
+ case ProjectionMode::SPHERE360: {
+ pos = config.sphere360.position;
+ rot = config.sphere360.rotation;
+ zoom = config.sphere360.zoom;
+ break;
+ }
+ }
+}
+
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
@@ -448,12 +474,8 @@ CMainApplication::CMainApplication( int argc, char *argv[] )
, m_unCompanionWindowProgramID( 0 )
, m_pHMD( NULL )
, m_bDebugOpenGL( false )
- , m_bVerbose( false )
- , m_bPerf( false )
, m_bVblank( false )
, m_bGlFinishHack( false )
- , m_glControllerVertBuffer( 0 )
- , m_unControllerVAO( 0 )
, m_unSceneVAO( 0 )
, m_nSceneMatrixLocation( -1 )
, m_nSceneTextureOffsetXLocation( -1 )
@@ -623,6 +645,15 @@ CMainApplication::CMainApplication( int argc, char *argv[] )
#ifdef _DEBUG
m_bDebugOpenGL = true;
#endif
+
+ config = read_config(config_exists);
+ if(!config_exists)
+ return;
+
+ float saved_config = 0.0f;
+ get_config_values(config, projection_mode, hmd_pos, m_reset_rotation, saved_config);
+ if(!zoom_set)
+ zoom = saved_config;
};
@@ -748,7 +779,8 @@ bool CMainApplication::BInit()
}
auto standing_pos = m_pHMD->GetSeatedZeroPoseToStandingAbsoluteTrackingPose();
- hmd_pos += glm::vec3(standing_pos.m[0][3], standing_pos.m[1][3], standing_pos.m[2][3]);
+ if(!config_exists)
+ hmd_pos += glm::vec3(standing_pos.m[0][3], standing_pos.m[1][3], standing_pos.m[2][3]);
int nWindowPosX = 700;
int nWindowPosY = 100;
@@ -895,29 +927,20 @@ bool CMainApplication::BInit()
});
}
- //char cwd[4096];
- //getcwd(cwd, sizeof(cwd));
- //printf("cwd: %s\n", cwd);
- //dirname(cwd);
char action_manifest_path[PATH_MAX];
realpath("config/hellovr_actions.json", action_manifest_path);
if(access(action_manifest_path, F_OK) == -1) {
strcpy(action_manifest_path, "/usr/share/vr-video-player/hellovr_actions.json");
if(access(action_manifest_path, F_OK) == -1) {
fprintf(stderr, "Unable to find hellovr_action.json!\n");
- exit(1);
+ return false;
}
}
- fprintf(stderr, "Using config file: %s\n", action_manifest_path);
+ fprintf(stderr, "Using openvr config file: %s\n", action_manifest_path);
vr::VRInput()->SetActionManifestPath(action_manifest_path);
-
vr::VRInput()->GetActionHandle( "/actions/demo/in/HideCubes", &m_actionHideCubes );
- vr::VRInput()->GetActionHandle( "/actions/demo/in/HideThisController", &m_actionHideThisController);
- vr::VRInput()->GetActionHandle( "/actions/demo/in/TriggerHaptic", &m_actionTriggerHaptic );
- vr::VRInput()->GetActionHandle( "/actions/demo/in/AnalogInput", &m_actionAnalongInput );
-
vr::VRInput()->GetActionSetHandle( "/actions/demo", &m_actionsetDemo );
return true;
@@ -993,8 +1016,6 @@ bool CMainApplication::BInitGL()
//-----------------------------------------------------------------------------
bool CMainApplication::BInitCompositor()
{
- vr::EVRInitError peError = vr::VRInitError_None;
-
if ( !vr::VRCompositor() )
{
printf( "Compositor initialization failed. See log file for details\n" );
@@ -1068,10 +1089,6 @@ void CMainApplication::Shutdown()
{
glDeleteVertexArrays( 1, &m_unSceneVAO );
}
- if( m_unControllerVAO != 0 )
- {
- glDeleteVertexArrays( 1, &m_unControllerVAO );
- }
}
window_texture_deinit(&window_texture);
@@ -1171,8 +1188,12 @@ bool CMainApplication::HandleInput()
}
bool opdoot = false;
- if(mpv_file)
- mpv.on_event(sdlEvent, &opdoot, &video_width, &video_height, &mpv_quit);
+ if(mpv_file) {
+ int error = 0;
+ mpv.on_event(sdlEvent, &opdoot, &video_width, &video_height, &mpv_quit, &error);
+ if(mpv_quit && error != 0)
+ exit_code = 2;
+ }
if(opdoot)
set_render_update();
@@ -1180,7 +1201,7 @@ bool CMainApplication::HandleInput()
if(mpv_quit)
bRet = true;
- // TODO: Allow resize config
+ // TODO: Allow video resize to update texture size
if(video_width > 0 && video_height > 0 && video_width != mpv_video_width && video_height != mpv_video_height && !mpv_video_loaded && !mpv_loaded_in_thread) {
mpv_video_width = video_width;
mpv_video_height = video_height;
@@ -1326,13 +1347,6 @@ bool CMainApplication::HandleInput()
if(!free_camera)
hmd_pos = current_pos;
- vr::InputAnalogActionData_t analogData;
- if ( vr::VRInput()->GetAnalogActionData( m_actionAnalongInput, &analogData, sizeof( analogData ), vr::k_ulInvalidInputValueHandle ) == vr::VRInputError_None && analogData.bActive )
- {
- m_vAnalogValue[0] = analogData.x;
- m_vAnalogValue[1] = analogData.y;
- }
-
return bRet;
}
@@ -1341,8 +1355,6 @@ bool CMainApplication::HandleInput()
//-----------------------------------------------------------------------------
void CMainApplication::RunMainLoop()
{
- bool bQuit = false;
-
SDL_StartTextInput();
SDL_Joystick *controller = SDL_JoystickOpen(0);
@@ -1718,7 +1730,7 @@ bool CMainApplication::SetCursorFromX11CursorImage(XFixesCursorImage *x11_cursor
}
}
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, arrow_image_width, arrow_image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, cursor_data);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, arrow_image_width, arrow_image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, cursor_data);
delete []cursor_data;
glGenerateMipmap(GL_TEXTURE_2D);
@@ -1757,6 +1769,52 @@ Window CMainApplication::get_focused_window() {
return None;
}
+void CMainApplication::save_config() {
+ if(free_camera) {
+ switch(projection_mode) {
+ case ProjectionMode::SPHERE: {
+ config.sphere.position = hmd_pos;
+ break;
+ }
+ case ProjectionMode::FLAT: {
+ config.flat.position = hmd_pos;
+ break;
+ }
+ case ProjectionMode::CYLINDER: {
+ config.plane.position = hmd_pos;
+ break;
+ }
+ case ProjectionMode::SPHERE360: {
+ config.sphere360.position = hmd_pos;
+ break;
+ }
+ }
+ }
+ switch(projection_mode) {
+ case ProjectionMode::SPHERE: {
+ config.sphere.rotation = m_reset_rotation;
+ config.sphere.zoom = zoom;
+ break;
+ }
+ case ProjectionMode::FLAT: {
+ config.flat.rotation = m_reset_rotation;
+ config.flat.zoom = zoom;
+ break;
+ }
+ case ProjectionMode::CYLINDER: {
+ config.plane.rotation = m_reset_rotation;
+ config.plane.zoom = zoom;
+ break;
+ }
+ case ProjectionMode::SPHERE360: {
+ config.sphere360.rotation = m_reset_rotation;
+ config.sphere360.zoom = zoom;
+ break;
+ }
+ }
+ ::save_config(config);
+}
+
//-----------------------------------------------------------------------------
// Purpose: create a sea of cubes
@@ -2400,36 +2458,7 @@ void CMainApplication::RenderScene( vr::Hmd_Eye nEye )
glDrawArrays( GL_TRIANGLES, 0, m_uiVertcount );
glBindVertexArray( 0 );
-
glActiveTexture(GL_TEXTURE0);
-#if 0
- bool bIsInputAvailable = m_pHMD->IsInputAvailable();
-
- if( bIsInputAvailable )
- {
- // draw the controller axis lines
- glUseProgram( m_unControllerTransformProgramID );
- glUniformMatrix4fv( m_nControllerMatrixLocation, 1, GL_FALSE, glm::value_ptr(GetCurrentViewProjectionMatrix( nEye )));
- glBindVertexArray( m_unControllerVAO );
- glDrawArrays( GL_LINES, 0, m_uiControllerVertcount );
- glBindVertexArray( 0 );
- }
-
- // ----- Render Model rendering -----
- glUseProgram( m_unRenderModelProgramID );
-
- for ( EHand eHand = Left; eHand <= Right; ((int&)eHand)++ )
- {
- if ( !m_rHand[eHand].m_bShowController || !m_rHand[eHand].m_pRenderModel )
- continue;
-
- const glm::mat4 & matDeviceToTracking = m_rHand[eHand].m_rmat4Pose;
- glm::mat4 matMVP = GetCurrentViewProjectionMatrix( nEye ) * matDeviceToTracking;
- glUniformMatrix4fv( m_nRenderModelMatrixLocation, 1, GL_FALSE, glm::value_ptr(matMVP));
-
- m_rHand[eHand].m_pRenderModel->Draw();
- }
-#endif
glUseProgram( 0 );
}
@@ -2548,7 +2577,7 @@ void CMainApplication::UpdateHMDMatrixPose()
m_iValidPoseCount = 0;
m_strPoseClasses = "";
- for ( int nDevice = 0; nDevice < vr::k_unMaxTrackedDeviceCount; ++nDevice )
+ for ( int nDevice = 0; nDevice < (int)vr::k_unMaxTrackedDeviceCount; ++nDevice )
{
if ( m_rTrackedDevicePose[nDevice].bPoseIsValid )
{
@@ -2603,7 +2632,13 @@ CMainApplication *pMainApplication;
void reset_position(int signum)
{
printf("ok\n");
- pMainApplication->ResetRotation();
+ if(pMainApplication)
+ pMainApplication->ResetRotation();
+}
+
+void quit(int signum) {
+ if(pMainApplication)
+ pMainApplication->bQuit = true;
}
//-----------------------------------------------------------------------------
@@ -2616,6 +2651,9 @@ int main(int argc, char *argv[])
signal(SIGUSR1, reset_position);
signal(SIGUSR2, reset_position);
+ signal(SIGINT, quit);
+ signal(SIGTERM, quit);
+
if (!pMainApplication->BInit())
{
pMainApplication->Shutdown();
@@ -2623,8 +2661,10 @@ int main(int argc, char *argv[])
}
pMainApplication->RunMainLoop();
-
pMainApplication->Shutdown();
- return 0;
+ if(pMainApplication->exit_code == 0)
+ pMainApplication->save_config();
+
+ return pMainApplication->exit_code;
}
diff --git a/src/mpv.cpp b/src/mpv.cpp
index 164021e..0880049 100644
--- a/src/mpv.cpp
+++ b/src/mpv.cpp
@@ -159,7 +159,7 @@ bool Mpv::load_file(const char *path) {
return true;
}
-void Mpv::on_event(SDL_Event &event, bool *render_update, int64_t *width, int64_t *height, bool *quit) {
+void Mpv::on_event(SDL_Event &event, bool *render_update, int64_t *width, int64_t *height, bool *quit, int *error) {
if(render_update)
*render_update = false;
@@ -172,6 +172,9 @@ void Mpv::on_event(SDL_Event &event, bool *render_update, int64_t *width, int64_
if(quit)
*quit = false;
+ if(error)
+ *error = 0;
+
if(!created)
return;
@@ -200,8 +203,10 @@ void Mpv::on_event(SDL_Event &event, bool *render_update, int64_t *width, int64_
mpv_event_end_file *msg = (mpv_event_end_file*)mp_event->data;
if(msg->reason == MPV_END_FILE_REASON_ERROR) {
show_notification("vr video player mpv video error", mpv_error_string(msg->error), "critical");
- if(quit)
+ if(quit) {
*quit = true;
+ *error = -1;
+ }
}
if(msg->reason == MPV_END_FILE_REASON_EOF) {
show_notification("vr video player", "the video ended", "low");