mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-16 12:49:59 +01:00
Multi Window support in Rendering Manager and Display View
Important reshape of Rendering Manager to support creation of multiple output windows. The Display View is now designed to allow creating and manipulating output windows. Settings are incompatible with previous version.
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
#include "osc/OscOutboundPacketStream.h"
|
#include "osc/OscOutboundPacketStream.h"
|
||||||
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
@@ -36,10 +37,7 @@
|
|||||||
#include "ActionManager.h"
|
#include "ActionManager.h"
|
||||||
#include "TransitionView.h"
|
#include "TransitionView.h"
|
||||||
#include "NetworkToolkit.h"
|
#include "NetworkToolkit.h"
|
||||||
|
|
||||||
#include "UserInterfaceManager.h"
|
#include "UserInterfaceManager.h"
|
||||||
#include "RenderingManager.h"
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#include "ControlManager.h"
|
#include "ControlManager.h"
|
||||||
|
|
||||||
@@ -378,14 +376,6 @@ bool Control::init()
|
|||||||
//
|
//
|
||||||
terminate();
|
terminate();
|
||||||
|
|
||||||
//
|
|
||||||
// set keyboard callback
|
|
||||||
//
|
|
||||||
GLFWwindow *main = Rendering::manager().mainWindow().window();
|
|
||||||
GLFWwindow *output = Rendering::manager().outputWindow().window();
|
|
||||||
glfwSetKeyCallback( main, Control::keyboardCalback);
|
|
||||||
glfwSetKeyCallback( output, Control::keyboardCalback);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// load OSC Translator
|
// load OSC Translator
|
||||||
//
|
//
|
||||||
@@ -1181,7 +1171,7 @@ void Control::sendOutputStatus(const IpEndpointName &remoteEndpoint)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Control::keyboardCalback(GLFWwindow* window, int key, int, int action, int mods)
|
void Control::keyboardCalback(GLFWwindow* w, int key, int, int action, int mods)
|
||||||
{
|
{
|
||||||
if (UserInterface::manager().keyboardAvailable() && !mods )
|
if (UserInterface::manager().keyboardAvailable() && !mods )
|
||||||
{
|
{
|
||||||
@@ -1197,9 +1187,7 @@ void Control::keyboardCalback(GLFWwindow* window, int key, int, int action, int
|
|||||||
}
|
}
|
||||||
else if (_key == GLFW_KEY_ESCAPE && action == GLFW_PRESS )
|
else if (_key == GLFW_KEY_ESCAPE && action == GLFW_PRESS )
|
||||||
{
|
{
|
||||||
static GLFWwindow *output = Rendering::manager().outputWindow().window();
|
Rendering::manager().window(w)->exitFullscreen();
|
||||||
if (window==output)
|
|
||||||
Rendering::manager().outputWindow().exitFullscreen();
|
|
||||||
}
|
}
|
||||||
Control::manager().input_access_.unlock();
|
Control::manager().input_access_.unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ class GLFWwindow;
|
|||||||
|
|
||||||
class Control
|
class Control
|
||||||
{
|
{
|
||||||
|
friend class RenderingWindow;
|
||||||
|
|
||||||
// Private Constructor
|
// Private Constructor
|
||||||
Control();
|
Control();
|
||||||
Control(Control const& copy) = delete;
|
Control(Control const& copy) = delete;
|
||||||
@@ -151,6 +153,8 @@ protected:
|
|||||||
void sendBatchStatus(const IpEndpointName& remoteEndpoint);
|
void sendBatchStatus(const IpEndpointName& remoteEndpoint);
|
||||||
void sendOutputStatus(const IpEndpointName& remoteEndpoint);
|
void sendOutputStatus(const IpEndpointName& remoteEndpoint);
|
||||||
|
|
||||||
|
static void keyboardCalback(GLFWwindow*, int, int, int, int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static void listen();
|
static void listen();
|
||||||
@@ -169,7 +173,6 @@ private:
|
|||||||
int multitouch_active[INPUT_MULTITOUCH_COUNT];
|
int multitouch_active[INPUT_MULTITOUCH_COUNT];
|
||||||
glm::vec2 multitouch_values[INPUT_MULTITOUCH_COUNT];
|
glm::vec2 multitouch_values[INPUT_MULTITOUCH_COUNT];
|
||||||
|
|
||||||
static void keyboardCalback(GLFWwindow*, int, int, int, int);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
1142
src/DisplaysView.cpp
1142
src/DisplaysView.cpp
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,48 @@
|
|||||||
|
|
||||||
#include "View.h"
|
#include "View.h"
|
||||||
|
|
||||||
|
struct WindowPreview
|
||||||
|
{
|
||||||
|
Group *root_;
|
||||||
|
Group *status_;
|
||||||
|
Surface *surface_;
|
||||||
|
Surface *render_;
|
||||||
|
Switch *overlays_;
|
||||||
|
Switch *mode_;
|
||||||
|
Handles *handles_;
|
||||||
|
Handles *menu_;
|
||||||
|
Handles *icon_;
|
||||||
|
Surface *title_;
|
||||||
|
Symbol *fullscreen_;
|
||||||
|
std::string monitor_;
|
||||||
|
|
||||||
|
WindowPreview() {
|
||||||
|
root_ = nullptr;
|
||||||
|
status_ = nullptr;
|
||||||
|
surface_ = nullptr;
|
||||||
|
render_ = nullptr;
|
||||||
|
overlays_ = nullptr;
|
||||||
|
status_ = nullptr;
|
||||||
|
mode_ = nullptr;
|
||||||
|
handles_ = nullptr;
|
||||||
|
menu_ = nullptr;
|
||||||
|
icon_ = nullptr;
|
||||||
|
title_ = nullptr;
|
||||||
|
fullscreen_ = nullptr;
|
||||||
|
monitor_ = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hasNode
|
||||||
|
{
|
||||||
|
bool operator()(WindowPreview elem) const;
|
||||||
|
hasNode(Node *n) : _n(n) { }
|
||||||
|
private:
|
||||||
|
Node *_n;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class DisplaysView : public View
|
class DisplaysView : public View
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -23,31 +65,43 @@ public:
|
|||||||
void initiate () override;
|
void initiate () override;
|
||||||
void terminate (bool force = false) override;
|
void terminate (bool force = false) override;
|
||||||
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
|
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
|
||||||
|
Cursor over (glm::vec2) override;
|
||||||
void arrow (glm::vec2) override;
|
void arrow (glm::vec2) override;
|
||||||
bool doubleclic (glm::vec2) override;
|
bool doubleclic (glm::vec2) override;
|
||||||
|
|
||||||
glm::ivec4 outputCoordinates() const;
|
glm::ivec4 windowCoordinates(int index) const;
|
||||||
std::string outputFullscreenMonitor() const;
|
std::string fullscreenMonitor(int index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Group *output_;
|
|
||||||
Group *output_status_;
|
|
||||||
Surface *output_surface_;
|
|
||||||
Surface *output_render_;
|
|
||||||
Switch *output_overlays_;
|
|
||||||
Switch *output_mode_;
|
|
||||||
Handles *output_handles_;
|
|
||||||
Handles *output_menu_;
|
|
||||||
Handles *output_visible_;
|
|
||||||
Symbol *output_fullscreen_;
|
|
||||||
|
|
||||||
bool output_selected_;
|
|
||||||
bool show_output_menu_;
|
|
||||||
int display_action_;
|
|
||||||
bool draw_pending_;
|
bool draw_pending_;
|
||||||
|
float output_ar;
|
||||||
|
|
||||||
|
std::vector<WindowPreview> windows_;
|
||||||
|
int current_window_;
|
||||||
|
Group *current_window_status_;
|
||||||
|
bool show_window_menu_;
|
||||||
|
|
||||||
|
// Group *window_;
|
||||||
|
// Group *window_status_;
|
||||||
|
// Surface *window_surface_;
|
||||||
|
// Surface *window_render_;
|
||||||
|
// Switch *window_overlays_;
|
||||||
|
// Switch *window_mode_;
|
||||||
|
// Handles *window_handles_;
|
||||||
|
// Handles *window_menu_;
|
||||||
|
// Handles *window_icon_;
|
||||||
|
// Surface *window_title_;
|
||||||
|
// Symbol *window_fullscreen_;
|
||||||
|
//// Surface *preview_surface_;
|
||||||
|
// std::string window_monitor_;
|
||||||
|
|
||||||
|
// bool window_selected_;
|
||||||
|
int display_action_;
|
||||||
|
|
||||||
|
|
||||||
|
// bool get_UV_window_render_from_pick(const glm::vec3 &pos, glm::vec2 *uv);
|
||||||
|
|
||||||
std::string output_monitor_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@
|
|||||||
#include "SystemToolkit.h"
|
#include "SystemToolkit.h"
|
||||||
#include "GstToolkit.h"
|
#include "GstToolkit.h"
|
||||||
#include "UserInterfaceManager.h"
|
#include "UserInterfaceManager.h"
|
||||||
|
#include "ControlManager.h"
|
||||||
|
|
||||||
#include "RenderingManager.h"
|
#include "RenderingManager.h"
|
||||||
|
|
||||||
@@ -120,8 +121,6 @@ void Rendering::LinkPipeline( GstPipeline *pipeline )
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
std::map<GLFWwindow *, RenderingWindow*> GLFW_window_;
|
|
||||||
|
|
||||||
static void glfw_error_callback(int error, const char* description)
|
static void glfw_error_callback(int error, const char* description)
|
||||||
{
|
{
|
||||||
g_printerr("Glfw Error %d: %s\n", error, description);
|
g_printerr("Glfw Error %d: %s\n", error, description);
|
||||||
@@ -131,11 +130,11 @@ static void WindowResizeCallback( GLFWwindow *w, int width, int height)
|
|||||||
{
|
{
|
||||||
if (Rendering::manager().mainWindow().window() == w) {
|
if (Rendering::manager().mainWindow().window() == w) {
|
||||||
// UI manager tries to keep windows in the workspace
|
// UI manager tries to keep windows in the workspace
|
||||||
WorkspaceWindow::notifyWorkspaceSizeChanged(GLFW_window_[w]->previous_size.x, GLFW_window_[w]->previous_size.y, width, height);
|
WorkspaceWindow::notifyWorkspaceSizeChanged(Rendering::manager().mainWindow().previous_size.x, Rendering::manager().mainWindow().previous_size.y, width, height);
|
||||||
GLFW_window_[w]->previous_size = glm::vec2(width, height);
|
Rendering::manager().mainWindow().previous_size = glm::vec2(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
int id = GLFW_window_[w]->index();
|
int id = Rendering::manager().window(w)->index();
|
||||||
Settings::application.windows[id].fullscreen = glfwGetWindowMonitor(w) != nullptr;
|
Settings::application.windows[id].fullscreen = glfwGetWindowMonitor(w) != nullptr;
|
||||||
if (!Settings::application.windows[id].fullscreen) {
|
if (!Settings::application.windows[id].fullscreen) {
|
||||||
Settings::application.windows[id].w = width;
|
Settings::application.windows[id].w = width;
|
||||||
@@ -149,7 +148,7 @@ static void WindowResizeCallback( GLFWwindow *w, int width, int height)
|
|||||||
|
|
||||||
static void WindowMoveCallback( GLFWwindow *w, int x, int y)
|
static void WindowMoveCallback( GLFWwindow *w, int x, int y)
|
||||||
{
|
{
|
||||||
int id = GLFW_window_[w]->index();
|
int id = Rendering::manager().window(w)->index();
|
||||||
if (!Settings::application.windows[id].fullscreen) {
|
if (!Settings::application.windows[id].fullscreen) {
|
||||||
Settings::application.windows[id].x = x;
|
Settings::application.windows[id].x = x;
|
||||||
Settings::application.windows[id].y = y;
|
Settings::application.windows[id].y = y;
|
||||||
@@ -167,7 +166,7 @@ static void OutputWindowEvent( GLFWwindow *w, int button, int action, int)
|
|||||||
|
|
||||||
// exit fullscreen if its the case
|
// exit fullscreen if its the case
|
||||||
if (glfwGetWindowMonitor(w) != nullptr)
|
if (glfwGetWindowMonitor(w) != nullptr)
|
||||||
Rendering::manager().outputWindow().exitFullscreen();
|
Rendering::manager().window(w)->exitFullscreen();
|
||||||
|
|
||||||
// show main window in DISPLAYS view to
|
// show main window in DISPLAYS view to
|
||||||
// indicate how to manipulate output window
|
// indicate how to manipulate output window
|
||||||
@@ -203,9 +202,6 @@ void Rendering::MonitorConnect(GLFWmonitor* monitor, int event)
|
|||||||
std::string n = glfwGetMonitorName(monitors[i]);
|
std::string n = glfwGetMonitorName(monitors[i]);
|
||||||
// add
|
// add
|
||||||
Rendering::manager().monitors_geometry_[n] = glm::ivec4(x, y, vm->width, vm->height);
|
Rendering::manager().monitors_geometry_[n] = glm::ivec4(x, y, vm->width, vm->height);
|
||||||
|
|
||||||
g_printerr("Monitor %d : %s, %d Hz, %d x %d px\n", i, glfwGetMonitorName(monitors[i]),
|
|
||||||
vm->refreshRate, vm->width, vm->height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// inform Displays View that monitors changed
|
// inform Displays View that monitors changed
|
||||||
@@ -285,33 +281,15 @@ Rendering::Rendering()
|
|||||||
|
|
||||||
bool Rendering::init()
|
bool Rendering::init()
|
||||||
{
|
{
|
||||||
// Setup window
|
//
|
||||||
|
// Setup GLFW
|
||||||
|
//
|
||||||
glfwSetErrorCallback(glfw_error_callback);
|
glfwSetErrorCallback(glfw_error_callback);
|
||||||
if (!glfwInit()){
|
if (!glfwInit()){
|
||||||
g_printerr("Failed to Initialize GLFW.\n");
|
g_printerr("Failed to Initialize GLFW.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decide GL+GLSL versions GL 3.3 + GLSL 150
|
|
||||||
glsl_version = "#version 150";
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
|
|
||||||
#if __APPLE__
|
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// OpenGL Multisampling main window
|
|
||||||
//
|
|
||||||
glfwWindowHint(GLFW_SAMPLES, Settings::application.render.multisampling);
|
|
||||||
main_.init(0);
|
|
||||||
// set application icon
|
|
||||||
main_.setIcon("images/vimix_256x256.png");
|
|
||||||
// additional window callbacks for main window
|
|
||||||
glfwSetWindowCloseCallback( main_.window(), WindowCloseCallback );
|
|
||||||
glfwSetDropCallback( main_.window(), Rendering::FileDropped);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Gstreamer setup
|
// Gstreamer setup
|
||||||
//
|
//
|
||||||
@@ -349,7 +327,9 @@ bool Rendering::init()
|
|||||||
Log::Info("Found Frei0r plugins in %s", frei0r_path.c_str());
|
Log::Info("Found Frei0r plugins in %s", frei0r_path.c_str());
|
||||||
g_setenv ("FREI0R_PATH", frei0r_path.c_str(), TRUE);
|
g_setenv ("FREI0R_PATH", frei0r_path.c_str(), TRUE);
|
||||||
}
|
}
|
||||||
g_setenv ("GST_GL_API", "opengl3", TRUE);
|
|
||||||
|
// init gstreamer with opengl API
|
||||||
|
g_setenv ("GST_GL_API", VIMIX_GL_VERSION, TRUE);
|
||||||
gst_init (NULL, NULL);
|
gst_init (NULL, NULL);
|
||||||
|
|
||||||
// increase selection rank for GPU decoding plugins
|
// increase selection rank for GPU decoding plugins
|
||||||
@@ -368,6 +348,7 @@ bool Rendering::init()
|
|||||||
else {
|
else {
|
||||||
Log::Info("No hardware decoding plugin found.");
|
Log::Info("No hardware decoding plugin found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SYNC_GSTREAMER_OPENGL_CONTEXT
|
#ifdef SYNC_GSTREAMER_OPENGL_CONTEXT
|
||||||
#if GST_GL_HAVE_PLATFORM_WGL
|
#if GST_GL_HAVE_PLATFORM_WGL
|
||||||
global_gl_context = gst_gl_context_new_wrapped (display, (guintptr) wglGetCurrentContext (),
|
global_gl_context = gst_gl_context_new_wrapped (display, (guintptr) wglGetCurrentContext (),
|
||||||
@@ -388,29 +369,48 @@ bool Rendering::init()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// output window
|
// Monitors
|
||||||
//
|
|
||||||
glfwWindowHint(GLFW_SAMPLES, 0); // no need for multisampling in displaying output
|
|
||||||
output_.init(1, main_.window());
|
|
||||||
output_.setIcon("images/vimix_256x256.png");
|
|
||||||
// special callbacks for user input in output window
|
|
||||||
glfwSetMouseButtonCallback( output_.window(), OutputWindowEvent);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Monitors configuration
|
|
||||||
//
|
//
|
||||||
Rendering::MonitorConnect(nullptr, GLFW_DONT_CARE);
|
Rendering::MonitorConnect(nullptr, GLFW_DONT_CARE);
|
||||||
// automatic detection of monitor connect & disconnect
|
// automatic detection of monitor connect & disconnect
|
||||||
glfwSetMonitorCallback(Rendering::MonitorConnect);
|
glfwSetMonitorCallback(Rendering::MonitorConnect);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main window
|
||||||
|
//
|
||||||
|
if ( !main_.init(0) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Output windows will be initialized in draw
|
||||||
|
//
|
||||||
|
outputs_ = std::vector<RenderingWindow>(MAX_OUTPUT_WINDOW);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenderingWindow* Rendering::window(GLFWwindow *w)
|
||||||
|
{
|
||||||
|
if (windows_.count(w))
|
||||||
|
return windows_[w];
|
||||||
|
else
|
||||||
|
return &main_;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderingWindow* Rendering::window(int index)
|
||||||
|
{
|
||||||
|
if (index > 0 && index <= MAX_OUTPUT_WINDOW )
|
||||||
|
return &outputs_[index - 1];
|
||||||
|
else
|
||||||
|
return &main_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Rendering::show()
|
void Rendering::show()
|
||||||
{
|
{
|
||||||
// show output window
|
// show output windows
|
||||||
output_.show();
|
for (auto it = outputs_.begin(); it != outputs_.end(); ++it)
|
||||||
|
it->show();
|
||||||
|
|
||||||
// show main window
|
// show main window
|
||||||
main_.show();
|
main_.show();
|
||||||
@@ -440,7 +440,8 @@ void Rendering::draw()
|
|||||||
|
|
||||||
// change windows fullscreen mode if requested
|
// change windows fullscreen mode if requested
|
||||||
main_.changeFullscreen_();
|
main_.changeFullscreen_();
|
||||||
output_.changeFullscreen_();
|
for (auto it = outputs_.begin(); it != outputs_.end(); ++it)
|
||||||
|
it->changeFullscreen_();
|
||||||
|
|
||||||
// change main window title if requested
|
// change main window title if requested
|
||||||
if (!main_new_title_.empty()) {
|
if (!main_new_title_.empty()) {
|
||||||
@@ -464,6 +465,20 @@ void Rendering::draw()
|
|||||||
request_screenshot_ = false;
|
request_screenshot_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw output windows and count number of success
|
||||||
|
int count = 0;
|
||||||
|
for (auto it = outputs_.begin(); it != outputs_.end(); ++it) {
|
||||||
|
if ( it->draw( Mixer::manager().session()->frame() ) )
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
// terminate or initialize output windows to match number of output windows
|
||||||
|
if (count > Settings::application.num_output_windows)
|
||||||
|
outputs_[count-1].terminate();
|
||||||
|
else if (count < Settings::application.num_output_windows) {
|
||||||
|
outputs_[count].init( count+1, main_.window());
|
||||||
|
outputs_[count].show();
|
||||||
|
}
|
||||||
|
|
||||||
// software framerate limiter < 62 FPS
|
// software framerate limiter < 62 FPS
|
||||||
{
|
{
|
||||||
static GTimer *timer = g_timer_new ();
|
static GTimer *timer = g_timer_new ();
|
||||||
@@ -474,18 +489,19 @@ void Rendering::draw()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// swap GL buffers
|
// swap GL buffers
|
||||||
glfwSwapBuffers(main_.window());
|
main_.swap();
|
||||||
|
for (auto it = outputs_.begin(); it != outputs_.end(); ++it)
|
||||||
// draw output window (and swap buffer output)
|
it->swap();
|
||||||
output_.draw( Mixer::manager().session()->frame() );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rendering::terminate()
|
void Rendering::terminate()
|
||||||
{
|
{
|
||||||
// close window
|
// terminate all windows
|
||||||
glfwDestroyWindow(output_.window());
|
for (auto it = outputs_.begin(); it != outputs_.end(); ++it)
|
||||||
glfwDestroyWindow(main_.window());
|
it->terminate();
|
||||||
|
|
||||||
|
main_.terminate();
|
||||||
|
|
||||||
// glfwTerminate();
|
// glfwTerminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -674,17 +690,15 @@ WindowSurface::WindowSurface(Shader *s) : Primitive(s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RenderingWindow::RenderingWindow() : window_(nullptr), master_(nullptr),
|
RenderingWindow::RenderingWindow() : window_(NULL), master_(NULL),
|
||||||
index_(-1), dpi_scale_(1.f), textureid_(0), fbo_(0), surface_(nullptr), request_change_fullscreen_(false)
|
index_(-1), dpi_scale_(1.f), textureid_(0), fbo_(0), surface_(nullptr), request_change_fullscreen_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingWindow::~RenderingWindow()
|
RenderingWindow::~RenderingWindow()
|
||||||
{
|
{
|
||||||
if (surface_ != nullptr)
|
if (window_ != NULL)
|
||||||
delete surface_;
|
terminate();
|
||||||
if (fbo_ != 0)
|
|
||||||
glDeleteFramebuffers(1, &fbo_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderingWindow::setTitle(const std::string &title)
|
void RenderingWindow::setTitle(const std::string &title)
|
||||||
@@ -695,7 +709,7 @@ void RenderingWindow::setTitle(const std::string &title)
|
|||||||
else
|
else
|
||||||
fulltitle = title + std::string(" - " APP_NAME);
|
fulltitle = title + std::string(" - " APP_NAME);
|
||||||
|
|
||||||
if (window_ != nullptr)
|
if (window_ != NULL)
|
||||||
glfwSetWindowTitle(window_, fulltitle.c_str());
|
glfwSetWindowTitle(window_, fulltitle.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -703,7 +717,7 @@ void RenderingWindow::setIcon(const std::string &resource)
|
|||||||
{
|
{
|
||||||
size_t fpsize = 0;
|
size_t fpsize = 0;
|
||||||
const char *fp = Resource::getData(resource, &fpsize);
|
const char *fp = Resource::getData(resource, &fpsize);
|
||||||
if (fp != nullptr && window_ != nullptr) {
|
if (fp != nullptr && window_) {
|
||||||
GLFWimage icon;
|
GLFWimage icon;
|
||||||
icon.pixels = stbi_load_from_memory( (const stbi_uc*)fp, fpsize, &icon.width, &icon.height, nullptr, 4 );
|
icon.pixels = stbi_load_from_memory( (const stbi_uc*)fp, fpsize, &icon.width, &icon.height, nullptr, 4 );
|
||||||
glfwSetWindowIcon( window_, 1, &icon );
|
glfwSetWindowIcon( window_, 1, &icon );
|
||||||
@@ -715,7 +729,7 @@ GLFWmonitor *RenderingWindow::monitor()
|
|||||||
{
|
{
|
||||||
// get monitor at the center of the window
|
// get monitor at the center of the window
|
||||||
int x = 0, y = 0, w = 2, h = 2;
|
int x = 0, y = 0, w = 2, h = 2;
|
||||||
if (window_ != nullptr) {
|
if (window_) {
|
||||||
glfwGetWindowSize(window_, &w, &h);
|
glfwGetWindowSize(window_, &w, &h);
|
||||||
glfwGetWindowPos(window_, &x, &y);
|
glfwGetWindowPos(window_, &x, &y);
|
||||||
}
|
}
|
||||||
@@ -724,7 +738,7 @@ GLFWmonitor *RenderingWindow::monitor()
|
|||||||
|
|
||||||
void RenderingWindow::setFullscreen_(GLFWmonitor *mo)
|
void RenderingWindow::setFullscreen_(GLFWmonitor *mo)
|
||||||
{
|
{
|
||||||
if (window_ == nullptr)
|
if (!window_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// disable fullscreen mode
|
// disable fullscreen mode
|
||||||
@@ -734,7 +748,7 @@ void RenderingWindow::setFullscreen_(GLFWmonitor *mo)
|
|||||||
|
|
||||||
// set to window mode
|
// set to window mode
|
||||||
glfwSetInputMode( window_, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
glfwSetInputMode( window_, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
glfwSetWindowMonitor( window_, nullptr, Settings::application.windows[index_].x,
|
glfwSetWindowMonitor( window_, NULL, Settings::application.windows[index_].x,
|
||||||
Settings::application.windows[index_].y,
|
Settings::application.windows[index_].y,
|
||||||
Settings::application.windows[index_].w,
|
Settings::application.windows[index_].w,
|
||||||
Settings::application.windows[index_].h, 0 );
|
Settings::application.windows[index_].h, 0 );
|
||||||
@@ -809,9 +823,26 @@ void RenderingWindow::changeFullscreen_()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingWindow::setDecoration (bool on)
|
||||||
|
{
|
||||||
|
if (window_ == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Settings::application.windows[index_].decorated = on;
|
||||||
|
glfwSetWindowAttrib( window_, GLFW_RESIZABLE, on ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
glfwSetWindowAttrib( window_, GLFW_DECORATED, on ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
void RenderingWindow::setCoordinates(glm::ivec4 rect)
|
void RenderingWindow::setCoordinates(glm::ivec4 rect)
|
||||||
{
|
{
|
||||||
glfwSetWindowSize( window_, rect.p, rect.q);
|
if (window_ == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// restore maximized window to be able to change its coordinates
|
||||||
|
if (glfwGetWindowAttrib(window_, GLFW_MAXIMIZED))
|
||||||
|
glfwRestoreWindow(window_);
|
||||||
|
|
||||||
|
glfwSetWindowSize( window_, glm::max(50, rect.p), glm::max(50, rect.q));
|
||||||
glfwSetWindowPos( window_, rect.x, rect.y);
|
glfwSetWindowPos( window_, rect.x, rect.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -849,19 +880,38 @@ float RenderingWindow::aspectRatio()
|
|||||||
|
|
||||||
bool RenderingWindow::init(int index, GLFWwindow *share)
|
bool RenderingWindow::init(int index, GLFWwindow *share)
|
||||||
{
|
{
|
||||||
|
if (window_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
glfwMakeContextCurrent(NULL);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Settings
|
||||||
|
///
|
||||||
index_ = index;
|
index_ = index;
|
||||||
master_ = share;
|
master_ = share;
|
||||||
|
|
||||||
// access Settings
|
|
||||||
Settings::WindowConfig winset = Settings::application.windows[index_];
|
Settings::WindowConfig winset = Settings::application.windows[index_];
|
||||||
|
|
||||||
|
///
|
||||||
|
/// GLFW window creation parameters
|
||||||
|
///
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
|
||||||
|
#if __APPLE__
|
||||||
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// multisampling in main window
|
||||||
|
glfwWindowHint(GLFW_SAMPLES, master_ == NULL ? Settings::application.render.multisampling : 0);
|
||||||
|
|
||||||
// do not show at creation
|
// do not show at creation
|
||||||
glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE);
|
glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE);
|
||||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||||
glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
|
glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
|
||||||
|
|
||||||
if (master_ != nullptr) {
|
// restore decoration state
|
||||||
// special window type for output
|
if (master_ != NULL && !winset.decorated) {
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
||||||
glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
|
glfwWindowHint(GLFW_DECORATED, GLFW_FALSE);
|
||||||
}
|
}
|
||||||
@@ -875,25 +925,49 @@ bool RenderingWindow::init(int index, GLFWwindow *share)
|
|||||||
|
|
||||||
// ensure minimal window size
|
// ensure minimal window size
|
||||||
glfwSetWindowSizeLimits(window_, 500, 500, GLFW_DONT_CARE, GLFW_DONT_CARE);
|
glfwSetWindowSizeLimits(window_, 500, 500, GLFW_DONT_CARE, GLFW_DONT_CARE);
|
||||||
|
|
||||||
previous_size = glm::vec2(winset.w, winset.h);
|
previous_size = glm::vec2(winset.w, winset.h);
|
||||||
|
|
||||||
// set initial position
|
// set initial position
|
||||||
glfwSetWindowPos(window_, winset.x, winset.y);
|
glfwSetWindowPos(window_, winset.x, winset.y);
|
||||||
|
|
||||||
|
// set icon
|
||||||
|
setIcon("images/vimix_256x256.png");
|
||||||
|
|
||||||
|
///
|
||||||
/// CALLBACKS
|
/// CALLBACKS
|
||||||
|
///
|
||||||
// store global ref to pointers (used by callbacks)
|
// store global ref to pointers (used by callbacks)
|
||||||
GLFW_window_[window_] = this;
|
Rendering::manager().windows_[window_] = this;
|
||||||
|
|
||||||
|
//
|
||||||
// window position and resize callbacks
|
// window position and resize callbacks
|
||||||
|
//
|
||||||
glfwSetWindowPosCallback( window_, WindowMoveCallback );
|
glfwSetWindowPosCallback( window_, WindowMoveCallback );
|
||||||
glfwSetWindowSizeCallback( window_, WindowResizeCallback );
|
glfwSetWindowSizeCallback( window_, WindowResizeCallback );
|
||||||
|
|
||||||
|
//
|
||||||
|
// set keyboard callback
|
||||||
|
//
|
||||||
|
// all windows capture keys
|
||||||
|
glfwSetKeyCallback( window_, Control::keyboardCalback);
|
||||||
|
|
||||||
|
if (master_ != NULL) {
|
||||||
|
// additional window callbacks for user input in output windows
|
||||||
|
glfwSetMouseButtonCallback( window_, OutputWindowEvent);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// additional window callbacks for main window
|
||||||
|
glfwSetWindowCloseCallback( window_, WindowCloseCallback );
|
||||||
|
glfwSetDropCallback( window_, Rendering::FileDropped);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize OpenGL
|
||||||
|
//
|
||||||
// take opengl context ownership
|
// take opengl context ownership
|
||||||
glfwMakeContextCurrent(window_);
|
glfwMakeContextCurrent(window_);
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize OpenGL loader on first call
|
// Initialize OpenGL loader on first call
|
||||||
//
|
|
||||||
static bool glad_initialized = false;
|
static bool glad_initialized = false;
|
||||||
if ( !glad_initialized ) {
|
if ( !glad_initialized ) {
|
||||||
bool err = gladLoadGLLoader((GLADloadproc) glfwGetProcAddress) == 0;
|
bool err = gladLoadGLLoader((GLADloadproc) glfwGetProcAddress) == 0;
|
||||||
@@ -920,19 +994,17 @@ bool RenderingWindow::init(int index, GLFWwindow *share)
|
|||||||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||||
|
|
||||||
// if not main window
|
// if not main window
|
||||||
if ( master_ != nullptr ) {
|
if ( master_ != NULL ) {
|
||||||
// Enable vsync on output window
|
// NO vsync on output windows
|
||||||
glfwSwapInterval(Settings::application.render.vsync);
|
glfwSwapInterval(0);
|
||||||
// no need for multisampling
|
// no need for multisampling
|
||||||
glDisable(GL_MULTISAMPLE);
|
glDisable(GL_MULTISAMPLE);
|
||||||
// clear to black
|
// clear to black
|
||||||
window_attributes_.clear_color = glm::vec4(0.f, 0.f, 0.f, 1.f);
|
window_attributes_.clear_color = glm::vec4(0.f, 0.f, 0.f, 1.f);
|
||||||
// give back context ownership
|
|
||||||
glfwMakeContextCurrent(master_);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Disable vsync on main window
|
// vsync on main window
|
||||||
glfwSwapInterval(0);
|
glfwSwapInterval(Settings::application.render.vsync);
|
||||||
// Enable Antialiasing multisampling
|
// Enable Antialiasing multisampling
|
||||||
if (Settings::application.render.multisampling > 0) {
|
if (Settings::application.render.multisampling > 0) {
|
||||||
glEnable(GL_MULTISAMPLE);
|
glEnable(GL_MULTISAMPLE);
|
||||||
@@ -945,20 +1017,46 @@ bool RenderingWindow::init(int index, GLFWwindow *share)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingWindow::terminate()
|
||||||
|
{
|
||||||
|
// cleanup
|
||||||
|
if (surface_ != nullptr)
|
||||||
|
delete surface_;
|
||||||
|
if (fbo_ != 0)
|
||||||
|
glDeleteFramebuffers(1, &fbo_);
|
||||||
|
if (window_ != NULL) {
|
||||||
|
// remove global ref to pointers
|
||||||
|
Rendering::manager().windows_.erase(window_);
|
||||||
|
// delete window
|
||||||
|
glfwDestroyWindow(window_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// invalidate
|
||||||
|
window_ = NULL;
|
||||||
|
surface_ = nullptr;
|
||||||
|
fbo_ = 0;
|
||||||
|
index_ = -1;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderingWindow::show()
|
void RenderingWindow::show()
|
||||||
{
|
{
|
||||||
|
if (!window_)
|
||||||
|
return;
|
||||||
|
|
||||||
glfwShowWindow(window_);
|
glfwShowWindow(window_);
|
||||||
|
|
||||||
if ( Settings::application.windows[index_].fullscreen ) {
|
if ( Settings::application.windows[index_].fullscreen ) {
|
||||||
GLFWmonitor *mo = Rendering::manager().monitorNamed(Settings::application.windows[index_].monitor);
|
GLFWmonitor *mo = Rendering::manager().monitorNamed(Settings::application.windows[index_].monitor);
|
||||||
setFullscreen_(mo);
|
setFullscreen_(mo);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RenderingWindow::makeCurrent()
|
void RenderingWindow::makeCurrent()
|
||||||
{
|
{
|
||||||
|
if (!window_)
|
||||||
|
return;
|
||||||
|
|
||||||
// handle window resize
|
// handle window resize
|
||||||
glfwGetFramebufferSize(window_, &(window_attributes_.viewport.x), &(window_attributes_.viewport.y));
|
glfwGetFramebufferSize(window_, &(window_attributes_.viewport.x), &(window_attributes_.viewport.y));
|
||||||
|
|
||||||
@@ -972,12 +1070,18 @@ void RenderingWindow::makeCurrent()
|
|||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO update parameters for draw on resize event (not every frame)
|
void RenderingWindow::swap()
|
||||||
|
{
|
||||||
|
if (window_)
|
||||||
|
// swap buffer
|
||||||
|
glfwSwapBuffers(window_);
|
||||||
|
|
||||||
void RenderingWindow::draw(FrameBuffer *fb)
|
}
|
||||||
|
|
||||||
|
bool RenderingWindow::draw(FrameBuffer *fb)
|
||||||
{
|
{
|
||||||
if (!window_ || !fb)
|
if (!window_ || !fb)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
// only draw if window is not iconified
|
// only draw if window is not iconified
|
||||||
if( !glfwGetWindowAttrib(window_, GLFW_ICONIFIED ) ) {
|
if( !glfwGetWindowAttrib(window_, GLFW_ICONIFIED ) ) {
|
||||||
@@ -1058,7 +1162,7 @@ void RenderingWindow::draw(FrameBuffer *fb)
|
|||||||
{
|
{
|
||||||
// VAO is not shared between multiple contexts of different windows
|
// VAO is not shared between multiple contexts of different windows
|
||||||
// so we have to create a new VAO for rendering the surface in this window
|
// so we have to create a new VAO for rendering the surface in this window
|
||||||
if (surface_ == 0)
|
if (surface_ == nullptr)
|
||||||
surface_ = new WindowSurface;
|
surface_ = new WindowSurface;
|
||||||
|
|
||||||
// calculate scaling factor of frame buffer inside window
|
// calculate scaling factor of frame buffer inside window
|
||||||
@@ -1089,12 +1193,8 @@ void RenderingWindow::draw(FrameBuffer *fb)
|
|||||||
|
|
||||||
// restore attribs
|
// restore attribs
|
||||||
Rendering::manager().popAttrib();
|
Rendering::manager().popAttrib();
|
||||||
|
|
||||||
// swap buffer
|
|
||||||
glfwSwapBuffers(window_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// give back context ownership
|
return true;
|
||||||
glfwMakeContextCurrent(master_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <gst/gl/gl.h>
|
#include <gst/gl/gl.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
@@ -38,6 +39,9 @@ class RenderingWindow
|
|||||||
uint fbo_;
|
uint fbo_;
|
||||||
class WindowSurface *surface_;
|
class WindowSurface *surface_;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setTitle(const std::string &title = "");
|
||||||
|
void setIcon(const std::string &resource);
|
||||||
bool request_change_fullscreen_;
|
bool request_change_fullscreen_;
|
||||||
void changeFullscreen_ ();
|
void changeFullscreen_ ();
|
||||||
void setFullscreen_(GLFWmonitor *mo);
|
void setFullscreen_(GLFWmonitor *mo);
|
||||||
@@ -51,8 +55,7 @@ public:
|
|||||||
inline GLFWwindow *window() const { return window_; }
|
inline GLFWwindow *window() const { return window_; }
|
||||||
|
|
||||||
bool init(int index, GLFWwindow *share = NULL);
|
bool init(int index, GLFWwindow *share = NULL);
|
||||||
void setIcon(const std::string &resource);
|
void terminate();
|
||||||
void setTitle(const std::string &title = "");
|
|
||||||
|
|
||||||
// show window (fullscreen if needed)
|
// show window (fullscreen if needed)
|
||||||
void show();
|
void show();
|
||||||
@@ -61,16 +64,20 @@ public:
|
|||||||
void makeCurrent();
|
void makeCurrent();
|
||||||
|
|
||||||
// draw a framebuffer
|
// draw a framebuffer
|
||||||
void draw(FrameBuffer *fb);
|
bool draw(FrameBuffer *fb);
|
||||||
|
void swap();
|
||||||
|
|
||||||
// fullscreen
|
// fullscreen
|
||||||
bool isFullscreen ();
|
bool isFullscreen ();
|
||||||
void exitFullscreen ();
|
void exitFullscreen ();
|
||||||
void setFullscreen (std::string monitorname);
|
void setFullscreen (std::string monitorname);
|
||||||
void toggleFullscreen ();
|
void toggleFullscreen ();
|
||||||
|
// get monitor in which the window is
|
||||||
|
GLFWmonitor *monitor();
|
||||||
|
|
||||||
// set geometry
|
// set geometry and decoration
|
||||||
void setCoordinates(glm::ivec4 rect);
|
void setCoordinates(glm::ivec4 rect);
|
||||||
|
void setDecoration (bool on);
|
||||||
|
|
||||||
// get width of rendering area
|
// get width of rendering area
|
||||||
int width();
|
int width();
|
||||||
@@ -78,20 +85,18 @@ public:
|
|||||||
int height();
|
int height();
|
||||||
// get aspect ratio of rendering area
|
// get aspect ratio of rendering area
|
||||||
float aspectRatio();
|
float aspectRatio();
|
||||||
|
// high dpi monitor scaling
|
||||||
|
inline float dpiScale() const { return dpi_scale_; }
|
||||||
// get number of pixels to render X milimeters in height
|
// get number of pixels to render X milimeters in height
|
||||||
int pixelsforRealHeight(float milimeters);
|
int pixelsforRealHeight(float milimeters);
|
||||||
|
|
||||||
inline float dpiScale() const { return dpi_scale_; }
|
|
||||||
|
|
||||||
// get monitor in which the window is
|
|
||||||
GLFWmonitor *monitor();
|
|
||||||
|
|
||||||
glm::vec2 previous_size;
|
glm::vec2 previous_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Rendering
|
class Rendering
|
||||||
{
|
{
|
||||||
friend class UserInterface;
|
friend class UserInterface;
|
||||||
|
friend class RenderingWindow;
|
||||||
|
|
||||||
// Private Constructor
|
// Private Constructor
|
||||||
Rendering();
|
Rendering();
|
||||||
@@ -120,7 +125,7 @@ public:
|
|||||||
// Post-loop termination
|
// Post-loop termination
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
// add function to call during Draw
|
// add function to call during draw
|
||||||
typedef void (* RenderingCallback)(void);
|
typedef void (* RenderingCallback)(void);
|
||||||
void pushBackDrawCallback(RenderingCallback function);
|
void pushBackDrawCallback(RenderingCallback function);
|
||||||
|
|
||||||
@@ -129,16 +134,6 @@ public:
|
|||||||
void popAttrib();
|
void popAttrib();
|
||||||
RenderingAttrib currentAttrib();
|
RenderingAttrib currentAttrib();
|
||||||
|
|
||||||
// get hold on the windows
|
|
||||||
inline RenderingWindow& mainWindow() { return main_; }
|
|
||||||
inline RenderingWindow& outputWindow() { return output_; }
|
|
||||||
inline void setMainWindowTitle(const std::string t) { main_new_title_ = t; }
|
|
||||||
|
|
||||||
// request screenshot
|
|
||||||
void requestScreenshot();
|
|
||||||
// get Screenshot
|
|
||||||
class Screenshot *currentScreenshot();
|
|
||||||
|
|
||||||
// get projection matrix (for sharers) => Views
|
// get projection matrix (for sharers) => Views
|
||||||
glm::mat4 Projection();
|
glm::mat4 Projection();
|
||||||
// unproject from window coordinate to scene
|
// unproject from window coordinate to scene
|
||||||
@@ -146,6 +141,21 @@ public:
|
|||||||
// project from scene coordinate to window
|
// project from scene coordinate to window
|
||||||
glm::vec2 project(glm::vec3 scene_coordinate, glm::mat4 modelview = glm::mat4(1.f), bool to_framebuffer = true);
|
glm::vec2 project(glm::vec3 scene_coordinate, glm::mat4 modelview = glm::mat4(1.f), bool to_framebuffer = true);
|
||||||
|
|
||||||
|
// Application main window management
|
||||||
|
inline RenderingWindow& mainWindow() { return main_; }
|
||||||
|
inline void setMainWindowTitle(const std::string t) { main_new_title_ = t; }
|
||||||
|
// request screenshot
|
||||||
|
void requestScreenshot();
|
||||||
|
// get Screenshot
|
||||||
|
class Screenshot *currentScreenshot();
|
||||||
|
|
||||||
|
// Rendering output windows management
|
||||||
|
inline RenderingWindow& outputWindow(size_t i) { return outputs_[i]; }
|
||||||
|
|
||||||
|
// windows access (cannot fail; defaults to main window on invalid argument)
|
||||||
|
RenderingWindow* window(GLFWwindow *w);
|
||||||
|
RenderingWindow* window(int index);
|
||||||
|
|
||||||
// get hold on the monitors
|
// get hold on the monitors
|
||||||
inline std::map<std::string, glm::ivec4> monitors() { return monitors_geometry_; }
|
inline std::map<std::string, glm::ivec4> monitors() { return monitors_geometry_; }
|
||||||
// get which monitor contains this point
|
// get which monitor contains this point
|
||||||
@@ -162,9 +172,14 @@ public:
|
|||||||
static void LinkPipeline( GstPipeline *pipeline );
|
static void LinkPipeline( GstPipeline *pipeline );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
// GLFW windows management
|
||||||
|
std::map<GLFWwindow *, RenderingWindow*> windows_;
|
||||||
|
|
||||||
std::string glsl_version;
|
// file drop callback
|
||||||
|
static void FileDropped(GLFWwindow* main_window_, int path_count, const char* paths[]);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
// list of rendering attributes
|
// list of rendering attributes
|
||||||
std::list<RenderingAttrib> draw_attributes_;
|
std::list<RenderingAttrib> draw_attributes_;
|
||||||
@@ -172,20 +187,17 @@ private:
|
|||||||
// list of functions to call at each Draw
|
// list of functions to call at each Draw
|
||||||
std::list<RenderingCallback> draw_callbacks_;
|
std::list<RenderingCallback> draw_callbacks_;
|
||||||
|
|
||||||
|
// windows
|
||||||
RenderingWindow main_;
|
RenderingWindow main_;
|
||||||
std::string main_new_title_;
|
std::string main_new_title_;
|
||||||
RenderingWindow output_;
|
std::vector<RenderingWindow> outputs_;
|
||||||
|
|
||||||
// monitors
|
// monitors
|
||||||
std::map<std::string, glm::ivec4> monitors_geometry_;
|
std::map<std::string, glm::ivec4> monitors_geometry_;
|
||||||
static void MonitorConnect(GLFWmonitor* monitor, int event);
|
static void MonitorConnect(GLFWmonitor* monitor, int event);
|
||||||
|
|
||||||
// file drop callback
|
|
||||||
static void FileDropped(GLFWwindow* main_window_, int path_count, const char* paths[]);
|
|
||||||
|
|
||||||
Screenshot screenshot_;
|
Screenshot screenshot_;
|
||||||
bool request_screenshot_;
|
bool request_screenshot_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ void Settings::Save(uint64_t runtime)
|
|||||||
// Windows
|
// Windows
|
||||||
{
|
{
|
||||||
XMLElement *windowsNode = xmlDoc.NewElement( "Windows" );
|
XMLElement *windowsNode = xmlDoc.NewElement( "Windows" );
|
||||||
|
windowsNode->SetAttribute("num_output_windows", application.num_output_windows);
|
||||||
|
|
||||||
for (int i = 0; i < (int) application.windows.size(); ++i)
|
for (int i = 0; i < (int) application.windows.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -108,6 +109,7 @@ void Settings::Save(uint64_t runtime)
|
|||||||
window->SetAttribute("h", w.h);
|
window->SetAttribute("h", w.h);
|
||||||
window->SetAttribute("f", w.fullscreen);
|
window->SetAttribute("f", w.fullscreen);
|
||||||
window->SetAttribute("s", w.scaled);
|
window->SetAttribute("s", w.scaled);
|
||||||
|
window->SetAttribute("d", w.decorated);
|
||||||
window->SetAttribute("m", w.monitor.c_str());
|
window->SetAttribute("m", w.monitor.c_str());
|
||||||
windowsNode->InsertEndChild(window);
|
windowsNode->InsertEndChild(window);
|
||||||
}
|
}
|
||||||
@@ -494,6 +496,8 @@ void Settings::Load()
|
|||||||
XMLElement * pElement = pRoot->FirstChildElement("Windows");
|
XMLElement * pElement = pRoot->FirstChildElement("Windows");
|
||||||
if (pElement)
|
if (pElement)
|
||||||
{
|
{
|
||||||
|
pElement->QueryIntAttribute("num_output_windows", &application.num_output_windows);
|
||||||
|
|
||||||
XMLElement* windowNode = pElement->FirstChildElement("Window");
|
XMLElement* windowNode = pElement->FirstChildElement("Window");
|
||||||
for( ; windowNode ; windowNode=windowNode->NextSiblingElement())
|
for( ; windowNode ; windowNode=windowNode->NextSiblingElement())
|
||||||
{
|
{
|
||||||
@@ -504,13 +508,17 @@ void Settings::Load()
|
|||||||
windowNode->QueryIntAttribute("h", &w.h);
|
windowNode->QueryIntAttribute("h", &w.h);
|
||||||
windowNode->QueryBoolAttribute("f", &w.fullscreen);
|
windowNode->QueryBoolAttribute("f", &w.fullscreen);
|
||||||
windowNode->QueryBoolAttribute("s", &w.scaled);
|
windowNode->QueryBoolAttribute("s", &w.scaled);
|
||||||
|
windowNode->QueryBoolAttribute("d", &w.decorated);
|
||||||
const char *text = windowNode->Attribute("m");
|
const char *text = windowNode->Attribute("m");
|
||||||
if (text)
|
if (text)
|
||||||
w.monitor = std::string(text);
|
w.monitor = std::string(text);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
windowNode->QueryIntAttribute("id", &i);
|
windowNode->QueryIntAttribute("id", &i);
|
||||||
w.name = application.windows[i].name; // keep only original name
|
if (i > 0)
|
||||||
|
w.name = APP_NAME " output " + std::to_string(i);
|
||||||
|
else
|
||||||
|
w.name = APP_TITLE;
|
||||||
application.windows[i] = w;
|
application.windows[i] = w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,9 +61,11 @@ struct WindowConfig
|
|||||||
int x,y,w,h;
|
int x,y,w,h;
|
||||||
bool fullscreen;
|
bool fullscreen;
|
||||||
bool scaled;
|
bool scaled;
|
||||||
|
bool decorated;
|
||||||
std::string monitor;
|
std::string monitor;
|
||||||
|
|
||||||
WindowConfig() : name(""), x(15), y(15), w(1280), h(720), fullscreen(false), scaled(false), monitor("") { }
|
WindowConfig() : name(APP_TITLE), x(15), y(15), w(1280), h(720),
|
||||||
|
fullscreen(false), scaled(false), decorated(true), monitor("") { }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -299,6 +301,7 @@ struct Application
|
|||||||
ControllerConfig control;
|
ControllerConfig control;
|
||||||
|
|
||||||
// multiple windows handling
|
// multiple windows handling
|
||||||
|
int num_output_windows;
|
||||||
std::vector<WindowConfig> windows;
|
std::vector<WindowConfig> windows;
|
||||||
|
|
||||||
// recent files histories
|
// recent files histories
|
||||||
@@ -334,12 +337,16 @@ struct Application
|
|||||||
current_view = 1;
|
current_view = 1;
|
||||||
current_workspace= 1;
|
current_workspace= 1;
|
||||||
brush = glm::vec3(0.5f, 0.1f, 0.f);
|
brush = glm::vec3(0.5f, 0.1f, 0.f);
|
||||||
windows = std::vector<WindowConfig>(3);
|
num_output_windows = 1;
|
||||||
windows[0].name = APP_TITLE;
|
windows = std::vector<WindowConfig>(1+MAX_OUTPUT_WINDOW);
|
||||||
windows[0].w = 1600;
|
windows[0].w = 1600;
|
||||||
windows[0].h = 900;
|
windows[0].h = 900;
|
||||||
windows[1].name = "Output " APP_TITLE;
|
windows[1].w = 1270;
|
||||||
windows[2].name = "Fullscreen " APP_TITLE;
|
windows[1].h = 720;
|
||||||
|
windows[2].w = 1270;
|
||||||
|
windows[2].h = 720;
|
||||||
|
windows[3].w = 1270;
|
||||||
|
windows[3].h = 720;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ bool UserInterface::Init()
|
|||||||
|
|
||||||
// Setup Platform/Renderer bindings
|
// Setup Platform/Renderer bindings
|
||||||
ImGui_ImplGlfw_InitForOpenGL(Rendering::manager().mainWindow().window(), true);
|
ImGui_ImplGlfw_InitForOpenGL(Rendering::manager().mainWindow().window(), true);
|
||||||
ImGui_ImplOpenGL3_Init(Rendering::manager().glsl_version.c_str());
|
ImGui_ImplOpenGL3_Init(VIMIX_GLSL_VERSION);
|
||||||
|
|
||||||
// hack to change keys according to keyboard layout
|
// hack to change keys according to keyboard layout
|
||||||
io.KeyMap[ImGuiKey_A] = Control::layoutKey(GLFW_KEY_A);
|
io.KeyMap[ImGuiKey_A] = Control::layoutKey(GLFW_KEY_A);
|
||||||
@@ -1497,7 +1497,7 @@ void ToolBox::Render()
|
|||||||
// init
|
// init
|
||||||
if (refresh_rate < 0.f) {
|
if (refresh_rate < 0.f) {
|
||||||
|
|
||||||
const GLFWvidmode* mode = glfwGetVideoMode(Rendering::manager().outputWindow().monitor());
|
const GLFWvidmode* mode = glfwGetVideoMode(Rendering::manager().mainWindow().monitor());
|
||||||
refresh_rate = float(mode->refreshRate);
|
refresh_rate = float(mode->refreshRate);
|
||||||
if (Settings::application.render.vsync > 0)
|
if (Settings::application.render.vsync > 0)
|
||||||
refresh_rate /= Settings::application.render.vsync;
|
refresh_rate /= Settings::application.render.vsync;
|
||||||
@@ -4137,8 +4137,9 @@ void OutputPreview::Render()
|
|||||||
if (ImGui::BeginMenu(IMGUI_TITLE_PREVIEW))
|
if (ImGui::BeginMenu(IMGUI_TITLE_PREVIEW))
|
||||||
{
|
{
|
||||||
// Output window menu
|
// Output window menu
|
||||||
if ( ImGui::MenuItem( ICON_FA_WINDOW_RESTORE " Show window") )
|
// TODO Menu options for output windows creation / show ?
|
||||||
Rendering::manager().outputWindow().show();
|
// if ( ImGui::MenuItem( ICON_FA_WINDOW_RESTORE " Show window") )
|
||||||
|
// Rendering::manager().outputWindow().show();
|
||||||
|
|
||||||
ImGui::MenuItem( MENU_OUTPUTDISABLE, SHORTCUT_OUTPUTDISABLE, &Settings::application.render.disabled);
|
ImGui::MenuItem( MENU_OUTPUTDISABLE, SHORTCUT_OUTPUTDISABLE, &Settings::application.render.disabled);
|
||||||
|
|
||||||
@@ -4368,9 +4369,6 @@ void OutputPreview::Render()
|
|||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
// mouse over the image
|
// mouse over the image
|
||||||
if ( ImGui::IsItemHovered() ) {
|
if ( ImGui::IsItemHovered() ) {
|
||||||
// raise window on double clic
|
|
||||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) )
|
|
||||||
Rendering::manager().outputWindow().show();
|
|
||||||
// show magnifying glass if active
|
// show magnifying glass if active
|
||||||
if (magnifying_glass)
|
if (magnifying_glass)
|
||||||
DrawInspector(output->texture(), imagesize, imagesize, draw_pos);
|
DrawInspector(output->texture(), imagesize, imagesize, draw_pos);
|
||||||
@@ -4467,7 +4465,7 @@ void OutputPreview::Render()
|
|||||||
if (Settings::application.render.disabled)
|
if (Settings::application.render.disabled)
|
||||||
{
|
{
|
||||||
ImGui::SetCursorScreenPos(ImVec2(draw_pos.x + r, draw_pos.y + imagesize.y - 2.f*r));
|
ImGui::SetCursorScreenPos(ImVec2(draw_pos.x + r, draw_pos.y + imagesize.y - 2.f*r));
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(COLOR_FRAME, 0.8f));
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(COLOR_WINDOW, 0.8f));
|
||||||
ImGui::Text(ICON_FA_EYE_SLASH);
|
ImGui::Text(ICON_FA_EYE_SLASH);
|
||||||
ImGui::PopStyleColor(1);
|
ImGui::PopStyleColor(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,10 @@
|
|||||||
#define XML_VERSION_MINOR 3
|
#define XML_VERSION_MINOR 3
|
||||||
#define MAX_RECENT_HISTORY 20
|
#define MAX_RECENT_HISTORY 20
|
||||||
#define MAX_SESSION_LEVEL 3
|
#define MAX_SESSION_LEVEL 3
|
||||||
|
#define MAX_OUTPUT_WINDOW 3
|
||||||
|
|
||||||
|
#define VIMIX_GL_VERSION "opengl3"
|
||||||
|
#define VIMIX_GLSL_VERSION "#version 150"
|
||||||
|
|
||||||
#define VIMIX_FILE_EXT "mix"
|
#define VIMIX_FILE_EXT "mix"
|
||||||
#define VIMIX_FILE_PATTERN "*.mix"
|
#define VIMIX_FILE_PATTERN "*.mix"
|
||||||
@@ -110,7 +114,8 @@
|
|||||||
#define COLOR_LIMBO_CIRCLE 0.173f, 0.173f, 0.173f
|
#define COLOR_LIMBO_CIRCLE 0.173f, 0.173f, 0.173f
|
||||||
#define COLOR_SLIDER_CIRCLE 0.11f, 0.11f, 0.11f
|
#define COLOR_SLIDER_CIRCLE 0.11f, 0.11f, 0.11f
|
||||||
#define COLOR_STASH_CIRCLE 0.06f, 0.06f, 0.06f
|
#define COLOR_STASH_CIRCLE 0.06f, 0.06f, 0.06f
|
||||||
#define COLOR_MONITOR 0.2f, 0.85f, 0.85f
|
#define COLOR_MONITOR 0.90f, 0.90f, 0.90f
|
||||||
|
#define COLOR_WINDOW 0.2f, 0.85f, 0.85f
|
||||||
#define COLOR_MENU_HOVERED 0.3f, 0.3f, 0.3f
|
#define COLOR_MENU_HOVERED 0.3f, 0.3f, 0.3f
|
||||||
|
|
||||||
#define OSC_PORT_RECV_DEFAULT 7000
|
#define OSC_PORT_RECV_DEFAULT 7000
|
||||||
|
|||||||
Reference in New Issue
Block a user