sinpin-vr/src/panel.cpp

90 lines
2.3 KiB
C++
Raw Normal View History

#include "panel.h"
2023-04-13 21:45:21 +02:00
#include "app.h"
#include "overlay.h"
2023-04-13 23:01:26 +02:00
Panel::Panel(App *app, int index, int x, int y, int width, int height)
: _app(app),
_index(index),
_x(x),
_y(y),
_width(width),
2023-04-11 19:26:26 +02:00
_height(height),
2023-04-13 21:45:21 +02:00
_overlay(app, "screen_view_" + std::to_string(index))
{
glGenTextures(1, &_gl_texture);
glBindTexture(GL_TEXTURE_2D, _gl_texture);
2023-04-07 19:13:52 +02:00
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB,
_width, _height, 0,
GL_BGRA, GL_UNSIGNED_BYTE, 0);
2023-04-07 13:26:42 +02:00
_texture.eColorSpace = vr::ColorSpace_Auto;
_texture.eType = vr::TextureType_OpenGL;
_texture.handle = (void *)(uintptr_t)_gl_texture;
2023-04-15 11:58:22 +02:00
_overlay.SetRatio(height / (float)width);
2023-04-16 18:40:44 +02:00
_overlay.SetTextureToColor(50, 20, 50);
2023-04-24 20:22:09 +02:00
ResetTransform();
}
void Panel::ResetTransform()
{
float width = _width / _app->_pixels_per_meter;
float pos_x = _x / _app->_pixels_per_meter + width / 2.0f - _app->_total_width_meters / 2.0f;
float height = _height / _app->_pixels_per_meter;
float pos_y = 1.2f + _y / _app->_pixels_per_meter - height / 2.0f + _app->_total_height_meters / 2.0f;
VRMat pose = {{{1, 0, 0, pos_x}, {0, 1, 0, pos_y}, {0, 0, 1, 0}}};
_overlay.SetTransformWorld(&pose);
_overlay.SetWidth(width);
}
void Panel::Update()
{
Render();
UpdateCursor();
2023-04-13 21:45:21 +02:00
_overlay.Update();
}
Overlay *Panel::GetOverlay()
{
return &_overlay;
}
void Panel::Render()
{
2023-04-07 19:13:52 +02:00
glCopyImageSubData(
_app->_gl_frame, GL_TEXTURE_2D, 0,
_x, _y, 0,
_gl_texture, GL_TEXTURE_2D, 0,
0, 0, 0,
_width, _height, 1);
2023-04-13 21:45:21 +02:00
_overlay.SetTexture(&_texture);
}
void Panel::SetHidden(bool state)
{
2023-04-13 21:45:21 +02:00
_overlay.SetHidden(state);
}
void Panel::UpdateCursor()
{
auto global_pos = _app->GetCursorPosition();
if (global_pos.x < _x || global_pos.x >= _x + _width || global_pos.y < _y || global_pos.y >= _y + _height)
{
2023-04-13 21:45:21 +02:00
_app->vr_overlay->ClearOverlayCursorPositionOverride(_overlay.Id());
return;
}
int local_x = global_pos.x - _x;
int local_y = global_pos.y - _y;
// 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 = local_x / (float)_width;
float y = 1.0f - (local_y / (float)_width + top_edge);
auto pos = vr::HmdVector2_t{x, y};
2023-04-13 21:45:21 +02:00
_app->vr_overlay->SetOverlayCursorPositionOverride(_overlay.Id(), &pos);
}