From c68283042ce14580820573bf9ffe6d8b8932c252 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Sat, 4 Apr 2015 00:37:02 -0700 Subject: [PATCH] UI: Add fullscreen projector class This allows viewing a source, scene, or the main preview in a fullscreen window. --- obs/CMakeLists.txt | 2 + obs/window-projector.cpp | 103 +++++++++++++++++++++++++++++++++++++++ obs/window-projector.hpp | 25 ++++++++++ 3 files changed, 130 insertions(+) create mode 100644 obs/window-projector.cpp create mode 100644 obs/window-projector.hpp diff --git a/obs/CMakeLists.txt b/obs/CMakeLists.txt index 189d5cb44..79dd35b0e 100644 --- a/obs/CMakeLists.txt +++ b/obs/CMakeLists.txt @@ -103,6 +103,7 @@ set(obs_SOURCES window-basic-preview.cpp window-namedialog.cpp window-log-reply.cpp + window-projector.cpp window-remux.cpp properties-view.cpp focus-list.cpp @@ -134,6 +135,7 @@ set(obs_HEADERS window-basic-preview.hpp window-namedialog.hpp window-log-reply.hpp + window-projector.hpp window-remux.hpp properties-view.hpp display-helpers.hpp diff --git a/obs/window-projector.cpp b/obs/window-projector.cpp new file mode 100644 index 000000000..3ff741bb7 --- /dev/null +++ b/obs/window-projector.cpp @@ -0,0 +1,103 @@ +#include +#include "window-projector.hpp" +#include "display-helpers.hpp" +#include "qt-wrappers.hpp" +#include "platform.hpp" + +OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_) + : OBSQTDisplay (widget, + Qt::Window | Qt::FramelessWindowHint), + source (source_), + removedSignal (obs_source_get_signal_handler(source), + "removed", OBSSourceRemoved, this) +{ + setAttribute(Qt::WA_DeleteOnClose, true); +} + +OBSProjector::~OBSProjector() +{ + if (source) + obs_source_dec_showing(source); +} + +void OBSProjector::Init(int monitor) +{ + std::vector monitors; + GetMonitors(monitors); + MonitorInfo &mi = monitors[monitor]; + + setGeometry(mi.x, mi.y, mi.cx, mi.cy); + + show(); + + if (source) + obs_source_inc_showing(source); + + struct gs_init_data gid = {}; + gid.cx = mi.cx; + gid.cy = mi.cy; + gid.format = GS_RGBA; + QTToGSWindow(winId(), gid.window); + + display = obs_display_create(&gid); + obs_display_set_background_color(display, 0x000000); + obs_display_add_draw_callback(display, OBSRender, this); + + QAction *action = new QAction(this); + action->setShortcut(Qt::Key_Escape); + addAction(action); + + connect(action, SIGNAL(triggered()), this, SLOT(EscapeTriggered())); +} + +void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy) +{ + OBSProjector *window = reinterpret_cast(data); + + uint32_t targetCX; + uint32_t targetCY; + int x, y; + int newCX, newCY; + float scale; + + if (window->source) { + targetCX = std::max(obs_source_get_width(window->source), 1u); + targetCY = std::max(obs_source_get_height(window->source), 1u); + } else { + struct obs_video_info ovi; + obs_get_video_info(&ovi); + targetCX = ovi.base_width; + targetCY = ovi.base_height; + } + + GetScaleAndCenterPos(targetCX, targetCY, cx, cy, x, y, scale); + + newCX = int(scale * float(targetCX)); + newCY = int(scale * float(targetCY)); + + gs_viewport_push(); + gs_projection_push(); + gs_ortho(0.0f, float(targetCX), 0.0f, float(targetCY), -100.0f, 100.0f); + gs_set_viewport(x, y, newCX, newCY); + + if (window->source) + obs_source_video_render(window->source); + else + obs_render_main_view(); + + gs_projection_pop(); + gs_viewport_pop(); +} + +void OBSProjector::OBSSourceRemoved(void *data, calldata_t *params) +{ + OBSProjector *window = reinterpret_cast(data); + window->deleteLater(); + + UNUSED_PARAMETER(params); +} + +void OBSProjector::EscapeTriggered() +{ + deleteLater(); +} diff --git a/obs/window-projector.hpp b/obs/window-projector.hpp new file mode 100644 index 000000000..377114dd6 --- /dev/null +++ b/obs/window-projector.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include "qt-display.hpp" + +class OBSProjector : public OBSQTDisplay { + Q_OBJECT + +private: + OBSDisplay display; + OBSSource source; + OBSSignal removedSignal; + + static void OBSRender(void *data, uint32_t cx, uint32_t cy); + static void OBSSourceRemoved(void *data, calldata_t *params); + +private slots: + void EscapeTriggered(); + +public: + OBSProjector(QWidget *parent, obs_source_t *source); + ~OBSProjector(); + + void Init(int monitor); +};