mirror of
https://github.com/CrispyPin/sinpin-vr.git
synced 2024-11-25 19:40:26 +01:00
Compare commits
5 commits
06d9b171a0
...
3f1670809c
Author | SHA1 | Date | |
---|---|---|---|
3f1670809c | |||
6aef8f92d7 | |||
ef25392907 | |||
e7df6a2776 | |||
2242c2c824 |
1 changed files with 116 additions and 87 deletions
203
src/main.cpp
203
src/main.cpp
|
@ -1,113 +1,142 @@
|
|||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "openvr/openvr.h"
|
||||
|
||||
static vr::ETrackingUniverseOrigin TRACKING_UNIVERSE = vr::ETrackingUniverseOrigin::TrackingUniverseStanding;
|
||||
auto TRACKING_UNIVERSE = vr::ETrackingUniverseOrigin::TrackingUniverseStanding;
|
||||
|
||||
#define WIDTH 1024
|
||||
#define HEIGHT 1024
|
||||
#define FRAMERATE 30
|
||||
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
bool should_exit = false;
|
||||
|
||||
Display *xdisplay;
|
||||
Window root_window;
|
||||
|
||||
vr::IVRSystem *ovr_sys;
|
||||
vr::IVROverlay *ovr_overlay;
|
||||
vr::VROverlayHandle_t handle;
|
||||
vr::VROverlayHandle_t main_overlay;
|
||||
vr::Texture_t vr_texture;
|
||||
|
||||
GLuint overlaytexture;
|
||||
GLuint screen_texture;
|
||||
GLFWwindow *gl_window;
|
||||
|
||||
void cleanup(int _sig = 0);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
void init_x11()
|
||||
{
|
||||
signal(SIGINT, cleanup);
|
||||
{
|
||||
xdisplay = XOpenDisplay(nullptr);
|
||||
assert(xdisplay != nullptr);
|
||||
printf("Created X11 display\n");
|
||||
root_window = XRootWindow(xdisplay, 0);
|
||||
}
|
||||
|
||||
{
|
||||
assert(glfwInit() == true);
|
||||
glfwWindowHint(GLFW_VISIBLE, false);
|
||||
gl_window = glfwCreateWindow(WIDTH, HEIGHT, "Overlay", nullptr, nullptr);
|
||||
assert(gl_window != nullptr);
|
||||
glfwMakeContextCurrent(gl_window);
|
||||
printf("Created GLFW context\n");
|
||||
}
|
||||
|
||||
{
|
||||
vr::EVRInitError init_err;
|
||||
ovr_sys = vr::VR_Init(&init_err, vr::EVRApplicationType::VRApplication_Overlay);
|
||||
assert(init_err == 0);
|
||||
ovr_overlay = vr::VROverlay();
|
||||
printf("Initialized openvr overlay\n");
|
||||
}
|
||||
|
||||
{
|
||||
auto overlay_err = ovr_overlay->CreateOverlay("deskpot", "Desktop view", &handle);
|
||||
assert(overlay_err == 0);
|
||||
ovr_overlay->ShowOverlay(handle);
|
||||
ovr_overlay->SetOverlayTextureColorSpace(handle, vr::EColorSpace::ColorSpace_Gamma);
|
||||
ovr_overlay->SetOverlayWidthInMeters(handle, 0.5f);
|
||||
uint8_t col[4] = {20, 100, 100, 255};
|
||||
ovr_overlay->SetOverlayRaw(handle, &col, 1, 1, 4);
|
||||
printf("Created overlay instance\n");
|
||||
}
|
||||
|
||||
{
|
||||
vr::HmdMatrix34_t transform;
|
||||
auto err = ovr_overlay->GetOverlayTransformAbsolute(handle, &TRACKING_UNIVERSE, &transform);
|
||||
assert(err == 0);
|
||||
transform.m[1][1] = -1;
|
||||
err = ovr_overlay->SetOverlayTransformAbsolute(handle, TRACKING_UNIVERSE, &transform);
|
||||
assert(err == 0);
|
||||
}
|
||||
|
||||
{
|
||||
glGenTextures(1, &overlaytexture);
|
||||
glBindTexture(GL_TEXTURE_2D, overlaytexture);
|
||||
}
|
||||
|
||||
vr::Texture_t vr_texture;
|
||||
vr_texture.eColorSpace = vr::EColorSpace::ColorSpace_Auto;
|
||||
vr_texture.eType = vr::ETextureType::TextureType_OpenGL;
|
||||
|
||||
while (1)
|
||||
{
|
||||
auto frame = XGetImage(xdisplay, root_window, 0, 0, WIDTH, HEIGHT, AllPlanes, ZPixmap);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, frame->data);
|
||||
XDestroyImage(frame);
|
||||
|
||||
{
|
||||
vr_texture.handle = (void *)(uintptr_t)overlaytexture;
|
||||
auto set_err = ovr_overlay->SetOverlayTexture(handle, &vr_texture);
|
||||
if (set_err)
|
||||
{
|
||||
printf("error setting texture: %d\n", set_err);
|
||||
assert(set_err == 0);
|
||||
}
|
||||
}
|
||||
glfwSwapBuffers(gl_window);
|
||||
|
||||
ovr_overlay->WaitFrameSync(20);
|
||||
}
|
||||
cleanup();
|
||||
return 0;
|
||||
xdisplay = XOpenDisplay(nullptr);
|
||||
assert(xdisplay != nullptr);
|
||||
printf("Created X11 display\n");
|
||||
root_window = XRootWindow(xdisplay, 0);
|
||||
XWindowAttributes attributes;
|
||||
XGetWindowAttributes(xdisplay, root_window, &attributes);
|
||||
width = attributes.width;
|
||||
height = attributes.height;
|
||||
}
|
||||
|
||||
void cleanup(int _sig)
|
||||
void init_glfw()
|
||||
{
|
||||
assert(glfwInit() == true);
|
||||
glfwWindowHint(GLFW_VISIBLE, false);
|
||||
gl_window = glfwCreateWindow(width, height, "Overlay", nullptr, nullptr);
|
||||
assert(gl_window != nullptr);
|
||||
glfwMakeContextCurrent(gl_window);
|
||||
printf("Created GLFW context\n");
|
||||
|
||||
glGenTextures(1, &screen_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, screen_texture);
|
||||
|
||||
vr_texture.eColorSpace = vr::EColorSpace::ColorSpace_Auto;
|
||||
vr_texture.eType = vr::ETextureType::TextureType_OpenGL;
|
||||
vr_texture.handle = (void *)(uintptr_t)screen_texture;
|
||||
}
|
||||
|
||||
void init_vr()
|
||||
{
|
||||
vr::EVRInitError init_err;
|
||||
ovr_sys = vr::VR_Init(&init_err, vr::EVRApplicationType::VRApplication_Overlay);
|
||||
assert(init_err == 0);
|
||||
ovr_overlay = vr::VROverlay();
|
||||
printf("Initialized openvr overlay\n");
|
||||
}
|
||||
|
||||
void init_overlay()
|
||||
{
|
||||
auto overlay_err = ovr_overlay->CreateOverlay("deskpot", "Desktop view", &main_overlay);
|
||||
assert(overlay_err == 0);
|
||||
ovr_overlay->ShowOverlay(main_overlay);
|
||||
ovr_overlay->SetOverlayWidthInMeters(main_overlay, 2.5f);
|
||||
uint8_t col[4] = {20, 50, 50, 255};
|
||||
ovr_overlay->SetOverlayRaw(main_overlay, &col, 1, 1, 4);
|
||||
printf("Created overlay instance\n");
|
||||
|
||||
vr::HmdMatrix34_t transform;
|
||||
auto err = ovr_overlay->GetOverlayTransformAbsolute(main_overlay, &TRACKING_UNIVERSE, &transform);
|
||||
assert(err == 0);
|
||||
transform.m[1][1] = -1; // flip Y axis
|
||||
err = ovr_overlay->SetOverlayTransformAbsolute(main_overlay, TRACKING_UNIVERSE, &transform);
|
||||
assert(err == 0);
|
||||
}
|
||||
|
||||
void render_desktop()
|
||||
{
|
||||
auto frame = XGetImage(xdisplay, root_window, 0, 0, width, height, AllPlanes, ZPixmap);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, frame->data);
|
||||
XDestroyImage(frame);
|
||||
|
||||
auto set_err = ovr_overlay->SetOverlayTexture(main_overlay, &vr_texture);
|
||||
// if (set_err)
|
||||
// printf("error setting texture: %d\n", set_err);
|
||||
assert(set_err == 0);
|
||||
}
|
||||
|
||||
void update_cursor()
|
||||
{
|
||||
int pix_x, pix_y;
|
||||
{
|
||||
Window _t1;
|
||||
int _t2;
|
||||
unsigned int _t3;
|
||||
XQueryPointer(xdisplay, root_window, &_t1, &_t1, &pix_x, &pix_y, &_t2, &_t2, &_t3);
|
||||
}
|
||||
// TODO: make this work when aspect ratio is >1 (root window is taller than it is wide)
|
||||
float ratio = (float)height / (float)width;
|
||||
float top_edge = 0.5f - ratio / 2.0f;
|
||||
float x = pix_x / (float)width;
|
||||
float y = pix_y / (float)width + top_edge;
|
||||
auto pos = vr::HmdVector2_t{x, y};
|
||||
ovr_overlay->SetOverlayCursorPositionOverride(main_overlay, &pos);
|
||||
}
|
||||
|
||||
void interrupted(int _sig)
|
||||
{
|
||||
should_exit = true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
signal(SIGINT, interrupted);
|
||||
|
||||
init_x11();
|
||||
init_glfw();
|
||||
init_vr();
|
||||
init_overlay();
|
||||
|
||||
while (!should_exit)
|
||||
{
|
||||
render_desktop();
|
||||
update_cursor();
|
||||
|
||||
glfwSwapBuffers(gl_window);
|
||||
usleep(1000000 / FRAMERATE);
|
||||
}
|
||||
|
||||
printf("\nShutting down\n");
|
||||
vr::VR_Shutdown();
|
||||
glfwDestroyWindow(gl_window);
|
||||
glfwTerminate();
|
||||
exit(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue