mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-08 08:50:00 +01:00
Implementation of main RenderingWindow in the RenderingManager.
This commit is contained in:
@@ -168,7 +168,7 @@ void Mixer::update()
|
|||||||
// swap front and back sessions
|
// swap front and back sessions
|
||||||
swap();
|
swap();
|
||||||
// set session filename
|
// set session filename
|
||||||
Rendering::manager().setWindowTitle(session_->filename());
|
Rendering::manager().mainWindow().setTitle(session_->filename());
|
||||||
Settings::application.recentSessions.push(session_->filename());
|
Settings::application.recentSessions.push(session_->filename());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,19 +55,6 @@ static GstGLDisplay *global_display = NULL;
|
|||||||
|
|
||||||
static std::map<GLFWwindow *, RenderingWindow*> GLFW_window_;
|
static std::map<GLFWwindow *, RenderingWindow*> GLFW_window_;
|
||||||
|
|
||||||
void updateSettings(int id, GLFWwindow *w)
|
|
||||||
{
|
|
||||||
if ( !Settings::application.windows[id].fullscreen) {
|
|
||||||
int x, y;
|
|
||||||
glfwGetWindowPos(w, &x, &y);
|
|
||||||
Settings::application.windows[id].x = x;
|
|
||||||
Settings::application.windows[id].y = y;
|
|
||||||
glfwGetWindowSize(w, &x, &y);
|
|
||||||
Settings::application.windows[id].w = x;
|
|
||||||
Settings::application.windows[id].h = y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void glfw_error_callback(int error, const char* description)
|
static void glfw_error_callback(int error, const char* description)
|
||||||
{
|
{
|
||||||
Log::Error("Glfw Error %d: %s", error, description);
|
Log::Error("Glfw Error %d: %s", error, description);
|
||||||
@@ -96,7 +83,7 @@ static void WindowMoveCallback( GLFWwindow *w, int x, int y)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WindowKeyCallback( GLFWwindow *w, int key, int scancode, int action, int)
|
static void WindowEscapeFullscreen( GLFWwindow *w, int key, int scancode, int action, int)
|
||||||
{
|
{
|
||||||
if (action == GLFW_PRESS && key == GLFW_KEY_ESCAPE)
|
if (action == GLFW_PRESS && key == GLFW_KEY_ESCAPE)
|
||||||
{
|
{
|
||||||
@@ -105,7 +92,7 @@ static void WindowKeyCallback( GLFWwindow *w, int key, int scancode, int action,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WindowMouseCallback( GLFWwindow *w, int button, int action, int)
|
static void WindowToggleFullscreen( GLFWwindow *w, int button, int action, int)
|
||||||
{
|
{
|
||||||
static double seconds = 0.f;
|
static double seconds = 0.f;
|
||||||
|
|
||||||
@@ -123,9 +110,8 @@ static void WindowMouseCallback( GLFWwindow *w, int button, int action, int)
|
|||||||
|
|
||||||
Rendering::Rendering()
|
Rendering::Rendering()
|
||||||
{
|
{
|
||||||
main_window_ = nullptr;
|
// main_window_ = nullptr;
|
||||||
request_screenshot_ = false;
|
request_screenshot_ = false;
|
||||||
dpi_scale_ = 1.f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Rendering::init()
|
bool Rendering::init()
|
||||||
@@ -145,149 +131,65 @@ bool Rendering::init()
|
|||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
|
||||||
#endif
|
#endif
|
||||||
// GL Multisampling #3
|
|
||||||
|
//
|
||||||
|
// OpenGL Multisampling main window
|
||||||
|
//
|
||||||
glfwWindowHint(GLFW_SAMPLES, Settings::application.multisampling_level);
|
glfwWindowHint(GLFW_SAMPLES, Settings::application.multisampling_level);
|
||||||
|
main_.init(0);
|
||||||
|
// set application icon
|
||||||
|
main_.setIcon("images/vimix_256x256.png");
|
||||||
|
// additional window callbacks for main window
|
||||||
|
glfwSetWindowRefreshCallback( main_.window(), WindowRefreshCallback );
|
||||||
|
glfwSetDropCallback( main_.window(), Rendering::FileDropped);
|
||||||
|
|
||||||
// Create window with graphics context
|
//
|
||||||
Settings::WindowConfig winset = Settings::application.windows[0];
|
// Gstreamer setup for OpenGL
|
||||||
|
//
|
||||||
// do not show at creation
|
|
||||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
|
||||||
glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
|
|
||||||
main_window_ = glfwCreateWindow(winset.w, winset.h, winset.name.c_str(), NULL, NULL);
|
|
||||||
if (main_window_ == NULL){
|
|
||||||
Log::Error("Failed to Create GLFW Window.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add application icon
|
|
||||||
size_t fpsize = 0;
|
|
||||||
const char *fp = Resource::getData("images/vimix_256x256.png", &fpsize);
|
|
||||||
if (fp != nullptr) {
|
|
||||||
GLFWimage icon;
|
|
||||||
icon.pixels = stbi_load_from_memory( (const stbi_uc*)fp, fpsize, &icon.width, &icon.height, nullptr, 4 );
|
|
||||||
glfwSetWindowIcon( main_window_, 1, &icon );
|
|
||||||
free( icon.pixels );
|
|
||||||
}
|
|
||||||
|
|
||||||
// callbacks
|
|
||||||
glfwSetWindowRefreshCallback( main_window_, WindowRefreshCallback );
|
|
||||||
// glfwSetFramebufferSizeCallback( main_window_, WindowResizeCallback );
|
|
||||||
// glfwSetWindowPosCallback( main_window_, WindowMoveCallback );
|
|
||||||
|
|
||||||
glfwSetWindowPos(main_window_, winset.x, winset.y);
|
|
||||||
glfwMakeContextCurrent(main_window_);
|
|
||||||
glfwSwapInterval(1); // Enable vsync
|
|
||||||
|
|
||||||
// Initialize OpenGL loader
|
|
||||||
bool err = gladLoadGLLoader((GLADloadproc) glfwGetProcAddress) == 0;
|
|
||||||
if (err) {
|
|
||||||
Log::Error("Failed to initialize GLAD OpenGL loader.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// // show window
|
|
||||||
// glfwShowWindow(main_window_);
|
|
||||||
// // restore fullscreen
|
|
||||||
// if (winset.fullscreen)
|
|
||||||
// toggleFullscreen();
|
|
||||||
|
|
||||||
// Rendering area (here same as window)
|
|
||||||
glfwGetFramebufferSize(main_window_, &(main_window_attributes_.viewport.x), &(main_window_attributes_.viewport.y));
|
|
||||||
glViewport(0, 0, main_window_attributes_.viewport.x, main_window_attributes_.viewport.y);
|
|
||||||
main_window_attributes_.clear_color = glm::vec4(COLOR_BGROUND, 1.0);
|
|
||||||
|
|
||||||
// DPI scaling (retina)
|
|
||||||
dpi_scale_ = float(main_window_attributes_.viewport.y) / float(winset.h);
|
|
||||||
|
|
||||||
// Gstreamer link to context
|
|
||||||
g_setenv ("GST_GL_API", "opengl3", FALSE);
|
g_setenv ("GST_GL_API", "opengl3", FALSE);
|
||||||
gst_init (NULL, NULL);
|
gst_init (NULL, NULL);
|
||||||
|
|
||||||
// Antialiasing
|
|
||||||
if (Settings::application.multisampling_level > 0) {
|
|
||||||
glEnable(GL_MULTISAMPLE);
|
|
||||||
glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
|
|
||||||
}
|
|
||||||
// This hint can improve the speed of texturing when perspective-correct texture coordinate interpolation isn't needed
|
|
||||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
|
||||||
// This hint can improve the speed of shading when dFdx dFdy aren't needed in GLSL
|
|
||||||
glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_FASTEST);
|
|
||||||
|
|
||||||
|
|
||||||
#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 (),
|
||||||
GST_GL_PLATFORM_WGL, GST_GL_API_OPENGL);
|
GST_GL_PLATFORM_WGL, GST_GL_API_OPENGL);
|
||||||
|
|
||||||
#elif GST_GL_HAVE_PLATFORM_CGL
|
#elif GST_GL_HAVE_PLATFORM_CGL
|
||||||
|
// global_display = GST_GL_DISPLAY ( glfwGetCocoaMonitor(main_.window()) );
|
||||||
|
|
||||||
// global_display = GST_GL_DISPLAY ( glfwGetCocoaMonitor(main_window_) );
|
|
||||||
global_display = GST_GL_DISPLAY (gst_gl_display_cocoa_new ());
|
global_display = GST_GL_DISPLAY (gst_gl_display_cocoa_new ());
|
||||||
|
|
||||||
global_gl_context = gst_gl_context_new_wrapped (global_display,
|
global_gl_context = gst_gl_context_new_wrapped (global_display,
|
||||||
(guintptr) 0,
|
(guintptr) 0,
|
||||||
GST_GL_PLATFORM_CGL, GST_GL_API_OPENGL);
|
GST_GL_PLATFORM_CGL, GST_GL_API_OPENGL);
|
||||||
|
|
||||||
|
|
||||||
#elif GST_GL_HAVE_PLATFORM_GLX
|
#elif GST_GL_HAVE_PLATFORM_GLX
|
||||||
|
|
||||||
//
|
|
||||||
global_display = (GstGLDisplay*) gst_gl_display_x11_new_with_display( glfwGetX11Display() );
|
global_display = (GstGLDisplay*) gst_gl_display_x11_new_with_display( glfwGetX11Display() );
|
||||||
|
|
||||||
global_gl_context = gst_gl_context_new_wrapped (global_display,
|
global_gl_context = gst_gl_context_new_wrapped (global_display,
|
||||||
(guintptr) glfwGetGLXContext(main_window_),
|
(guintptr) glfwGetGLXContext(main_.window()),
|
||||||
GST_GL_PLATFORM_GLX, GST_GL_API_OPENGL);
|
GST_GL_PLATFORM_GLX, GST_GL_API_OPENGL);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO : force GPU decoding
|
//
|
||||||
|
|
||||||
// GstElementFactory *vdpauh264dec = gst_element_factory_find("vdpauh264dec");
|
|
||||||
// if (vdpauh264dec)
|
|
||||||
// gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE(vdpauh264dec), GST_RANK_PRIMARY); // or GST_RANK_MARGINAL
|
|
||||||
// GstElementFactory *vdpaumpeg4dec = gst_element_factory_find("vdpaumpeg4dec");
|
|
||||||
// if (vdpaumpeg4dec)
|
|
||||||
// gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE(vdpaumpeg4dec), GST_RANK_PRIMARY);
|
|
||||||
// GstElementFactory *vdpaumpegdec = gst_element_factory_find("vdpaumpegdec");
|
|
||||||
// if (vdpaumpegdec)
|
|
||||||
// gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE(vdpaumpegdec), GST_RANK_PRIMARY);
|
|
||||||
|
|
||||||
// file drop callback
|
|
||||||
glfwSetDropCallback(main_window_, Rendering::FileDropped);
|
|
||||||
|
|
||||||
// output window
|
// output window
|
||||||
output.init(1, main_window_);
|
//
|
||||||
output.setIcon("images/vimix_square_256x256.png");
|
glfwWindowHint(GLFW_SAMPLES, 0); // no need for multisampling in displaying output
|
||||||
|
output_.init(1, main_.window());
|
||||||
|
// set special icon
|
||||||
|
output_.setIcon("images/vimix_square_256x256.png");
|
||||||
|
// special callbacks for user input in output window
|
||||||
|
glfwSetKeyCallback( output_.window(), WindowEscapeFullscreen);
|
||||||
|
glfwSetMouseButtonCallback( output_.window(), WindowToggleFullscreen);
|
||||||
|
|
||||||
// show window
|
// show output window
|
||||||
glfwShowWindow(main_window_);
|
output_.show();
|
||||||
// restore fullscreen
|
|
||||||
if (winset.fullscreen)
|
// show main window
|
||||||
toggleFullscreen();
|
main_.show();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Rendering::isActive()
|
bool Rendering::isActive()
|
||||||
{
|
{
|
||||||
return !glfwWindowShouldClose(main_window_);
|
return !glfwWindowShouldClose(main_.window());
|
||||||
}
|
}
|
||||||
|
|
||||||
int Rendering::getWindowId(GLFWwindow *w)
|
|
||||||
{
|
|
||||||
if (w == main_window_)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
// TODO manage more than one output
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rendering::setWindowTitle(std::string title)
|
|
||||||
{
|
|
||||||
std::string window_title = std::string(APP_NAME " -- ") + title;
|
|
||||||
glfwSetWindowTitle(main_window_, window_title.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rendering::pushFrontDrawCallback(RenderingCallback function)
|
void Rendering::pushFrontDrawCallback(RenderingCallback function)
|
||||||
{
|
{
|
||||||
@@ -308,81 +210,48 @@ void Rendering::draw()
|
|||||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
if ( Begin() )
|
main_.makeCurrent();
|
||||||
|
|
||||||
|
UserInterface::manager().NewFrame();
|
||||||
|
|
||||||
|
std::list<Rendering::RenderingCallback>::iterator iter;
|
||||||
|
for (iter=draw_callbacks_.begin(); iter != draw_callbacks_.end(); iter++)
|
||||||
{
|
{
|
||||||
UserInterface::manager().NewFrame();
|
(*iter)();
|
||||||
|
|
||||||
std::list<Rendering::RenderingCallback>::iterator iter;
|
|
||||||
for (iter=draw_callbacks_.begin(); iter != draw_callbacks_.end(); iter++)
|
|
||||||
{
|
|
||||||
(*iter)();
|
|
||||||
}
|
|
||||||
|
|
||||||
UserInterface::manager().Render();
|
|
||||||
End();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UserInterface::manager().Render();
|
||||||
|
|
||||||
|
// perform screenshot if requested
|
||||||
|
if (request_screenshot_) {
|
||||||
|
// glfwMakeContextCurrent(main_window_);
|
||||||
|
screenshot_.CreateFromCaptureGL(0, 0, main_.width(), main_.height());
|
||||||
|
request_screenshot_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// swap GL buffers
|
||||||
|
glfwSwapBuffers(main_.window());
|
||||||
|
|
||||||
// no g_main_loop_run(loop) : update global GMainContext
|
// no g_main_loop_run(loop) : update global GMainContext
|
||||||
g_main_context_iteration(NULL, FALSE);
|
g_main_context_iteration(NULL, FALSE);
|
||||||
|
|
||||||
// draw output window
|
// draw output window
|
||||||
output.draw( Mixer::manager().session()->frame() );
|
output_.draw( Mixer::manager().session()->frame() );
|
||||||
}
|
|
||||||
|
|
||||||
bool Rendering::Begin()
|
|
||||||
{
|
|
||||||
|
|
||||||
// TODO : optimize if window is minimized? (i.e. render output only)
|
|
||||||
// if( glfwGetWindowAttrib( main_window_, GLFW_ICONIFIED ) )
|
|
||||||
// {
|
|
||||||
// std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) );
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// handle window resize
|
|
||||||
glfwGetFramebufferSize(main_window_, &(main_window_attributes_.viewport.x), &(main_window_attributes_.viewport.y));
|
|
||||||
|
|
||||||
// ensure main context is current
|
|
||||||
glfwMakeContextCurrent(main_window_);
|
|
||||||
|
|
||||||
// setup and clear
|
|
||||||
glViewport(0, 0, main_window_attributes_.viewport.x, main_window_attributes_.viewport.y);
|
|
||||||
glClearColor(main_window_attributes_.clear_color.r, main_window_attributes_.clear_color.g,
|
|
||||||
main_window_attributes_.clear_color.b, main_window_attributes_.clear_color.a);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rendering::End()
|
|
||||||
{
|
|
||||||
// glfwMakeContextCurrent(main_window_);
|
|
||||||
|
|
||||||
// perform screenshot if requested
|
|
||||||
if (request_screenshot_) {
|
|
||||||
screenshot_.CreateFromCaptureGL(0, 0, main_window_attributes_.viewport.x, main_window_attributes_.viewport.y);
|
|
||||||
request_screenshot_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// swap GL buffers
|
|
||||||
glfwSwapBuffers(main_window_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Rendering::terminate()
|
void Rendering::terminate()
|
||||||
{
|
{
|
||||||
// save pos
|
|
||||||
updateSettings(0, main_window_);
|
|
||||||
|
|
||||||
// close window
|
// close window
|
||||||
glfwDestroyWindow(main_window_);
|
glfwDestroyWindow(output_.window());
|
||||||
|
glfwDestroyWindow(main_.window());
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Rendering::close()
|
void Rendering::close()
|
||||||
{
|
{
|
||||||
glfwSetWindowShouldClose(main_window_, true);
|
glfwSetWindowShouldClose(main_.window(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -413,7 +282,8 @@ void Rendering::popAttrib()
|
|||||||
RenderingAttrib Rendering::currentAttrib()
|
RenderingAttrib Rendering::currentAttrib()
|
||||||
{
|
{
|
||||||
// default rendering attrib is the main window's
|
// default rendering attrib is the main window's
|
||||||
RenderingAttrib ra = main_window_attributes_;
|
RenderingAttrib ra = main_.attribs();
|
||||||
|
|
||||||
// but if there is an element at top, return it
|
// but if there is an element at top, return it
|
||||||
if (draw_attributes_.size() > 0)
|
if (draw_attributes_.size() > 0)
|
||||||
ra = draw_attributes_.front();
|
ra = draw_attributes_.front();
|
||||||
@@ -423,7 +293,7 @@ RenderingAttrib Rendering::currentAttrib()
|
|||||||
glm::mat4 Rendering::Projection()
|
glm::mat4 Rendering::Projection()
|
||||||
{
|
{
|
||||||
static glm::mat4 projection = glm::ortho(-SCENE_UNIT, SCENE_UNIT, -SCENE_UNIT, SCENE_UNIT, -SCENE_DEPTH, 1.f);
|
static glm::mat4 projection = glm::ortho(-SCENE_UNIT, SCENE_UNIT, -SCENE_UNIT, SCENE_UNIT, -SCENE_DEPTH, 1.f);
|
||||||
glm::mat4 scale = glm::scale(glm::identity<glm::mat4>(), glm::vec3(1.f, aspectRatio(), 1.f));
|
glm::mat4 scale = glm::scale(glm::identity<glm::mat4>(), glm::vec3(1.f, main_.aspectRatio(), 1.f));
|
||||||
|
|
||||||
return projection * scale;
|
return projection * scale;
|
||||||
}
|
}
|
||||||
@@ -431,8 +301,8 @@ glm::mat4 Rendering::Projection()
|
|||||||
|
|
||||||
glm::vec3 Rendering::unProject(glm::vec2 screen_coordinate, glm::mat4 modelview)
|
glm::vec3 Rendering::unProject(glm::vec2 screen_coordinate, glm::mat4 modelview)
|
||||||
{
|
{
|
||||||
glm::vec3 coordinates = glm::vec3( screen_coordinate.x, main_window_attributes_.viewport.y - screen_coordinate.y, 0.f);
|
glm::vec3 coordinates = glm::vec3( screen_coordinate.x, main_.height() - screen_coordinate.y, 0.f);
|
||||||
glm::vec4 viewport = glm::vec4( 0.f, 0.f, main_window_attributes_.viewport.x, main_window_attributes_.viewport.y);
|
glm::vec4 viewport = glm::vec4( 0.f, 0.f, main_.width(), main_.height());
|
||||||
|
|
||||||
// Log::Info("unproject %d x %d", main_window_attributes_.viewport.x, main_window_attributes_.viewport.y);
|
// Log::Info("unproject %d x %d", main_window_attributes_.viewport.x, main_window_attributes_.viewport.y);
|
||||||
|
|
||||||
@@ -441,69 +311,6 @@ glm::vec3 Rendering::unProject(glm::vec2 screen_coordinate, glm::mat4 modelview)
|
|||||||
return point;
|
return point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float Rendering::monitorWidth()
|
|
||||||
{
|
|
||||||
GLFWmonitor *monitor = glfwGetWindowMonitor (main_window_);
|
|
||||||
if (!monitor)
|
|
||||||
monitor = glfwGetPrimaryMonitor ();
|
|
||||||
int xpos, ypos, width, height;
|
|
||||||
glfwGetMonitorWorkarea(monitor, &xpos, &ypos, &width, &height);
|
|
||||||
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Rendering::monitorHeight()
|
|
||||||
{
|
|
||||||
GLFWmonitor *monitor = glfwGetWindowMonitor (main_window_);
|
|
||||||
if (!monitor)
|
|
||||||
monitor = glfwGetPrimaryMonitor ();
|
|
||||||
// TODO : detect in which monitor is the main window and return the height for that monitor
|
|
||||||
int xpos, ypos, width, height;
|
|
||||||
glfwGetMonitorWorkarea(monitor, &xpos, &ypos, &width, &height);
|
|
||||||
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Rendering::isFullscreen ()
|
|
||||||
{
|
|
||||||
return (glfwGetWindowMonitor(main_window_) != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rendering::toggleFullscreen()
|
|
||||||
{
|
|
||||||
// if in fullscreen mode
|
|
||||||
if (isFullscreen()) {
|
|
||||||
// set to window mode
|
|
||||||
glfwSetWindowMonitor( main_window_, nullptr, Settings::application.windows[0].x,
|
|
||||||
Settings::application.windows[0].y,
|
|
||||||
Settings::application.windows[0].w,
|
|
||||||
Settings::application.windows[0].h, 0 );
|
|
||||||
Settings::application.windows[0].fullscreen = false;
|
|
||||||
}
|
|
||||||
// not in fullscreen mode
|
|
||||||
else {
|
|
||||||
// remember window geometry
|
|
||||||
updateSettings(0, main_window_);
|
|
||||||
|
|
||||||
// select monitor
|
|
||||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
|
||||||
const GLFWvidmode * mode = glfwGetVideoMode(monitor);
|
|
||||||
|
|
||||||
// set to fullscreen mode
|
|
||||||
glfwSetWindowMonitor( main_window_, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
|
|
||||||
Settings::application.windows[0].fullscreen = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
float Rendering::aspectRatio()
|
|
||||||
{
|
|
||||||
return static_cast<float>(main_window_attributes_.viewport.x) / static_cast<float>(main_window_attributes_.viewport.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rendering::FileDropped(GLFWwindow *, int path_count, const char* paths[])
|
void Rendering::FileDropped(GLFWwindow *, int path_count, const char* paths[])
|
||||||
{
|
{
|
||||||
for (int i = 0; i < path_count; ++i) {
|
for (int i = 0; i < path_count; ++i) {
|
||||||
@@ -527,11 +334,8 @@ void Rendering::requestScreenshot()
|
|||||||
request_screenshot_ = true;
|
request_screenshot_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenderingWindow::RenderingWindow() : window_(nullptr), master_(nullptr), id_(-1), dpi_scale_(1.f)
|
||||||
|
|
||||||
RenderingWindow::RenderingWindow() : window_(nullptr), master_(nullptr), frame_buffer_(nullptr), id_(-1)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingWindow::~RenderingWindow()
|
RenderingWindow::~RenderingWindow()
|
||||||
@@ -539,6 +343,15 @@ RenderingWindow::~RenderingWindow()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingWindow::setTitle(const std::string &title)
|
||||||
|
{
|
||||||
|
std::string fulltitle = Settings::application.windows[id_].name;
|
||||||
|
if ( !title.empty() )
|
||||||
|
fulltitle += " -- " + title;
|
||||||
|
|
||||||
|
glfwSetWindowTitle(window_, fulltitle.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
void RenderingWindow::setIcon(const std::string &resource)
|
void RenderingWindow::setIcon(const std::string &resource)
|
||||||
{
|
{
|
||||||
size_t fpsize = 0;
|
size_t fpsize = 0;
|
||||||
@@ -619,7 +432,6 @@ GLFWmonitor *RenderingWindow::monitor()
|
|||||||
return monitorAt(x, y);
|
return monitorAt(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RenderingWindow::setFullscreen(GLFWmonitor *mo)
|
void RenderingWindow::setFullscreen(GLFWmonitor *mo)
|
||||||
{
|
{
|
||||||
// if in fullscreen mode
|
// if in fullscreen mode
|
||||||
@@ -668,6 +480,14 @@ int RenderingWindow::height()
|
|||||||
return window_attributes_.viewport.y;
|
return window_attributes_.viewport.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RenderingWindow::maxHeight()
|
||||||
|
{
|
||||||
|
int workarea_x, workarea_y, workarea_width, workarea_height;
|
||||||
|
glfwGetMonitorWorkarea(monitor(), &workarea_x, &workarea_y, &workarea_width, &workarea_height);
|
||||||
|
|
||||||
|
return workarea_height * dpi_scale_;
|
||||||
|
}
|
||||||
|
|
||||||
float RenderingWindow::aspectRatio()
|
float RenderingWindow::aspectRatio()
|
||||||
{
|
{
|
||||||
return static_cast<float>(window_attributes_.viewport.x) / static_cast<float>(window_attributes_.viewport.y);
|
return static_cast<float>(window_attributes_.viewport.x) / static_cast<float>(window_attributes_.viewport.y);
|
||||||
@@ -678,58 +498,90 @@ bool RenderingWindow::init(int id, GLFWwindow *share)
|
|||||||
id_ = id;
|
id_ = id;
|
||||||
master_ = share;
|
master_ = share;
|
||||||
|
|
||||||
|
// access Settings
|
||||||
Settings::WindowConfig winset = Settings::application.windows[id_];
|
Settings::WindowConfig winset = Settings::application.windows[id_];
|
||||||
|
|
||||||
// setup endering area
|
|
||||||
window_attributes_.viewport.x = winset.w;
|
|
||||||
window_attributes_.viewport.y = winset.h;
|
|
||||||
window_attributes_.clear_color = glm::vec4(0.f, 0.f, 0.f, 1.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);
|
||||||
|
|
||||||
// no need for multisampling in displaying output
|
|
||||||
glfwWindowHint(GLFW_SAMPLES, 0);
|
|
||||||
|
|
||||||
// create the window normal
|
// create the window normal
|
||||||
window_ = glfwCreateWindow(winset.w, winset.h, winset.name.c_str(), NULL, master_);
|
window_ = glfwCreateWindow(winset.w, winset.h, winset.name.c_str(), NULL, master_);
|
||||||
if (window_ == NULL){
|
if (window_ == NULL){
|
||||||
Log::Error("Failed to create GLFW Window %d", id_);
|
Log::Error("Failed to create GLFW Window %d", id_);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// set position
|
|
||||||
glfwSetWindowPos(window_, winset.x, winset.y);
|
|
||||||
|
|
||||||
// store global ref to pointers (used by callbacks)
|
// store global ref to pointers (used by callbacks)
|
||||||
GLFW_window_[window_] = this;
|
GLFW_window_[window_] = this;
|
||||||
|
|
||||||
// callbacks
|
// set position
|
||||||
|
glfwSetWindowPos(window_, winset.x, winset.y);
|
||||||
|
// window position and resize callbacks
|
||||||
glfwSetFramebufferSizeCallback( window_, WindowResizeCallback );
|
glfwSetFramebufferSizeCallback( window_, WindowResizeCallback );
|
||||||
glfwSetWindowPosCallback( window_, WindowMoveCallback );
|
glfwSetWindowPosCallback( window_, WindowMoveCallback );
|
||||||
glfwSetKeyCallback( window_, WindowKeyCallback);
|
|
||||||
glfwSetMouseButtonCallback( window_, WindowMouseCallback);
|
|
||||||
|
|
||||||
// take context ownership
|
// take opengl context ownership
|
||||||
glfwMakeContextCurrent(window_);
|
glfwMakeContextCurrent(window_);
|
||||||
|
|
||||||
// While objects are shared, the global context state is not and will
|
static bool glad_initialized = false;
|
||||||
// need to be set up for each context
|
if ( !glad_initialized ) {
|
||||||
glfwSwapInterval(0); // Disable vsync
|
//
|
||||||
glDisable(GL_MULTISAMPLE);
|
// Initialize OpenGL loader
|
||||||
|
//
|
||||||
|
bool err = gladLoadGLLoader((GLADloadproc) glfwGetProcAddress) == 0;
|
||||||
|
if (err) {
|
||||||
|
Log::Error("Failed to initialize GLAD OpenGL loader.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
glad_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get rendering area
|
||||||
|
glfwGetFramebufferSize(window_, &(window_attributes_.viewport.x), &(window_attributes_.viewport.y));
|
||||||
|
// DPI scaling (retina)
|
||||||
|
dpi_scale_ = float(window_attributes_.viewport.y) / float(winset.h);
|
||||||
|
|
||||||
|
// This hint can improve the speed of texturing when perspective-correct texture coordinate interpolation isn't needed
|
||||||
|
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||||
|
// This hint can improve the speed of shading when dFdx dFdy aren't needed in GLSL
|
||||||
|
glHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_FASTEST);
|
||||||
|
|
||||||
|
// if not main window
|
||||||
|
if ( master_ != NULL ) {
|
||||||
|
// Disable vsync
|
||||||
|
glfwSwapInterval(0);
|
||||||
|
// no need for multisampling
|
||||||
|
glDisable(GL_MULTISAMPLE);
|
||||||
|
// clear to black
|
||||||
|
window_attributes_.clear_color = glm::vec4(0.f, 0.f, 0.f, 1.0);
|
||||||
|
// give back context ownership
|
||||||
|
glfwMakeContextCurrent(master_);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Enable vsync on main window
|
||||||
|
glfwSwapInterval(1);
|
||||||
|
// enable Antialiasing multisampling
|
||||||
|
if (Settings::application.multisampling_level > 0) {
|
||||||
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
|
||||||
|
}
|
||||||
|
// clear to grey
|
||||||
|
window_attributes_.clear_color = glm::vec4(COLOR_BGROUND, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingWindow::show()
|
||||||
|
{
|
||||||
if ( Settings::application.windows[id_].fullscreen ) {
|
if ( Settings::application.windows[id_].fullscreen ) {
|
||||||
GLFWmonitor *mo = monitorNamed(Settings::application.windows[id_].monitor);
|
GLFWmonitor *mo = monitorNamed(Settings::application.windows[id_].monitor);
|
||||||
setFullscreen(mo);
|
setFullscreen(mo);
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwShowWindow(window_);
|
glfwShowWindow(window_);
|
||||||
|
|
||||||
// give back context ownership
|
|
||||||
glfwMakeContextCurrent(master_);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// custom surface with a new VAO
|
// custom surface with a new VAO
|
||||||
@@ -751,6 +603,22 @@ WindowSurface::WindowSurface(Shader *s) : Primitive(s)
|
|||||||
drawMode_ = GL_TRIANGLE_STRIP;
|
drawMode_ = GL_TRIANGLE_STRIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RenderingWindow::makeCurrent()
|
||||||
|
{
|
||||||
|
// handle window resize
|
||||||
|
glfwGetFramebufferSize(window_, &(window_attributes_.viewport.x), &(window_attributes_.viewport.y));
|
||||||
|
|
||||||
|
// ensure main context is current
|
||||||
|
glfwMakeContextCurrent(window_);
|
||||||
|
|
||||||
|
// set and clear
|
||||||
|
glViewport(0, 0, window_attributes_.viewport.x, window_attributes_.viewport.y);
|
||||||
|
glClearColor(window_attributes_.clear_color.r, window_attributes_.clear_color.g,
|
||||||
|
window_attributes_.clear_color.b, window_attributes_.clear_color.a);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
void RenderingWindow::draw(FrameBuffer *fb)
|
void RenderingWindow::draw(FrameBuffer *fb)
|
||||||
{
|
{
|
||||||
if (!window_)
|
if (!window_)
|
||||||
|
|||||||
@@ -25,18 +25,29 @@ class RenderingWindow
|
|||||||
{
|
{
|
||||||
GLFWwindow *window_, *master_;
|
GLFWwindow *window_, *master_;
|
||||||
RenderingAttrib window_attributes_;
|
RenderingAttrib window_attributes_;
|
||||||
FrameBuffer *frame_buffer_;
|
|
||||||
int id_;
|
int id_;
|
||||||
|
float dpi_scale_;
|
||||||
|
|
||||||
|
// get monitor in which the window is
|
||||||
|
GLFWmonitor *monitor();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RenderingWindow();
|
RenderingWindow();
|
||||||
~RenderingWindow();
|
~RenderingWindow();
|
||||||
|
|
||||||
inline int id() const { return id_; }
|
inline int id() const { return id_; }
|
||||||
|
inline RenderingAttrib& attribs() { return window_attributes_; }
|
||||||
|
inline GLFWwindow *window() const { return window_; }
|
||||||
|
|
||||||
bool init(int id, GLFWwindow *share = nullptr);
|
bool init(int id, GLFWwindow *share = NULL);
|
||||||
void setIcon(const std::string &resource);
|
void setIcon(const std::string &resource);
|
||||||
|
void setTitle(const std::string &title);
|
||||||
|
|
||||||
|
// show window (fullscreen if needed)
|
||||||
|
void show();
|
||||||
|
|
||||||
|
// make context current and set viewport
|
||||||
|
void makeCurrent();
|
||||||
|
|
||||||
// draw a framebuffer
|
// draw a framebuffer
|
||||||
void draw(FrameBuffer *fb);
|
void draw(FrameBuffer *fb);
|
||||||
@@ -52,15 +63,12 @@ public:
|
|||||||
int height();
|
int height();
|
||||||
// get aspect ratio of rendering area
|
// get aspect ratio of rendering area
|
||||||
float aspectRatio();
|
float aspectRatio();
|
||||||
|
// get total height available in monitor
|
||||||
// get GLFW window
|
int maxHeight();
|
||||||
GLFWwindow *window();
|
|
||||||
|
|
||||||
// get monitor in which the window is
|
|
||||||
GLFWmonitor *monitor();
|
|
||||||
|
|
||||||
// get which monitor contains this point
|
// get which monitor contains this point
|
||||||
static GLFWmonitor *monitorAt(int x, int y);
|
static GLFWmonitor *monitorAt(int x, int y);
|
||||||
|
// get which monitor has this name
|
||||||
static GLFWmonitor *monitorNamed(const std::string &name);
|
static GLFWmonitor *monitorNamed(const std::string &name);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -103,53 +111,32 @@ public:
|
|||||||
void popAttrib();
|
void popAttrib();
|
||||||
RenderingAttrib currentAttrib();
|
RenderingAttrib currentAttrib();
|
||||||
|
|
||||||
|
// get hold on the main window
|
||||||
|
inline RenderingWindow& mainWindow() { return main_; }
|
||||||
|
|
||||||
// request screenshot
|
// request screenshot
|
||||||
void requestScreenshot();
|
void requestScreenshot();
|
||||||
// get Screenshot
|
// get Screenshot
|
||||||
class Screenshot *currentScreenshot();
|
class Screenshot *currentScreenshot();
|
||||||
|
|
||||||
// window management
|
|
||||||
void setWindowTitle(std::string title);
|
|
||||||
// request fullscreen
|
|
||||||
bool isFullscreen ();
|
|
||||||
void toggleFullscreen ();
|
|
||||||
// get aspect ratio of rendering area
|
|
||||||
float aspectRatio();
|
|
||||||
|
|
||||||
// monitor management
|
|
||||||
float monitorWidth();
|
|
||||||
float monitorHeight();
|
|
||||||
|
|
||||||
// get projection matrix (for sharers) => Views
|
// get projection matrix (for sharers) => Views
|
||||||
glm::mat4 Projection();
|
glm::mat4 Projection();
|
||||||
// unproject from window coordinate
|
// unproject from window coordinate
|
||||||
glm::vec3 unProject(glm::vec2 screen_coordinate, glm::mat4 modelview = glm::mat4(1.f));
|
glm::vec3 unProject(glm::vec2 screen_coordinate, glm::mat4 modelview = glm::mat4(1.f));
|
||||||
|
|
||||||
// utility for settings
|
|
||||||
int getWindowId(GLFWwindow *w);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// GLFW integration in OS window management
|
|
||||||
GLFWwindow *main_window_;
|
|
||||||
std::string glsl_version;
|
std::string glsl_version;
|
||||||
float dpi_scale_;
|
|
||||||
|
|
||||||
// loop update to begin new frame
|
|
||||||
bool Begin();
|
|
||||||
// loop update end frame
|
|
||||||
void End();
|
|
||||||
|
|
||||||
// void GrabWindow(int dx, int dy);
|
|
||||||
|
|
||||||
// list of rendering attributes
|
// list of rendering attributes
|
||||||
std::list<RenderingAttrib> draw_attributes_;
|
std::list<RenderingAttrib> draw_attributes_;
|
||||||
RenderingAttrib main_window_attributes_;
|
|
||||||
|
|
||||||
// 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_;
|
||||||
|
|
||||||
RenderingWindow output;
|
RenderingWindow main_;
|
||||||
|
RenderingWindow output_;
|
||||||
|
|
||||||
// file drop callback
|
// file drop callback
|
||||||
static void FileDropped(GLFWwindow* main_window_, int path_count, const char* paths[]);
|
static void FileDropped(GLFWwindow* main_window_, int path_count, const char* paths[]);
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ UserInterface::UserInterface()
|
|||||||
|
|
||||||
bool UserInterface::Init()
|
bool UserInterface::Init()
|
||||||
{
|
{
|
||||||
if (Rendering::manager().main_window_ == nullptr)
|
if (Rendering::manager().mainWindow().window()== nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Setup Dear ImGui context
|
// Setup Dear ImGui context
|
||||||
@@ -152,14 +152,14 @@ bool UserInterface::Init()
|
|||||||
io.FontGlobalScale = Settings::application.scale;
|
io.FontGlobalScale = Settings::application.scale;
|
||||||
|
|
||||||
// Setup Platform/Renderer bindings
|
// Setup Platform/Renderer bindings
|
||||||
ImGui_ImplGlfw_InitForOpenGL(Rendering::manager().main_window_, true);
|
ImGui_ImplGlfw_InitForOpenGL(Rendering::manager().mainWindow().window(), true);
|
||||||
ImGui_ImplOpenGL3_Init(Rendering::manager().glsl_version.c_str());
|
ImGui_ImplOpenGL3_Init(Rendering::manager().glsl_version.c_str());
|
||||||
|
|
||||||
// Setup Dear ImGui style
|
// Setup Dear ImGui style
|
||||||
ImGuiToolkit::SetAccentColor(static_cast<ImGuiToolkit::accent_color>(Settings::application.accent_color));
|
ImGuiToolkit::SetAccentColor(static_cast<ImGuiToolkit::accent_color>(Settings::application.accent_color));
|
||||||
|
|
||||||
// Estalish the base size from the resolution of the monitor
|
// Estalish the base size from the resolution of the monitor
|
||||||
float base_font_size = (Rendering::manager().monitorHeight() * Rendering::manager().dpi_scale_) / 100.f ;
|
float base_font_size = float(Rendering::manager().mainWindow().maxHeight()) / 100.f ;
|
||||||
// Load Fonts (using resource manager, NB: a temporary copy of the raw data is necessary)
|
// Load Fonts (using resource manager, NB: a temporary copy of the raw data is necessary)
|
||||||
ImGuiToolkit::SetFont(ImGuiToolkit::FONT_DEFAULT, "Roboto-Regular", int(base_font_size) );
|
ImGuiToolkit::SetFont(ImGuiToolkit::FONT_DEFAULT, "Roboto-Regular", int(base_font_size) );
|
||||||
ImGuiToolkit::SetFont(ImGuiToolkit::FONT_BOLD, "Roboto-Bold", int(base_font_size) );
|
ImGuiToolkit::SetFont(ImGuiToolkit::FONT_BOLD, "Roboto-Bold", int(base_font_size) );
|
||||||
@@ -169,7 +169,7 @@ bool UserInterface::Init()
|
|||||||
ImGuiToolkit::SetFont(ImGuiToolkit::FONT_LARGE, "Hack-Regular", MIN(int(base_font_size * 1.5f), 50), 1 );
|
ImGuiToolkit::SetFont(ImGuiToolkit::FONT_LARGE, "Hack-Regular", MIN(int(base_font_size * 1.5f), 50), 1 );
|
||||||
|
|
||||||
// info
|
// info
|
||||||
Log::Info("Monitor (%.1f,%.1f)", Rendering::manager().monitorWidth(), Rendering::manager().monitorHeight());
|
// Log::Info("Monitor (%.1f,%.1f)", Rendering::manager().monitorWidth(), Rendering::manager().monitorHeight());
|
||||||
Log::Info("Font size %d", int(base_font_size) );
|
Log::Info("Font size %d", int(base_font_size) );
|
||||||
|
|
||||||
// Style
|
// Style
|
||||||
@@ -262,7 +262,7 @@ void UserInterface::handleKeyboard()
|
|||||||
else if (ImGui::IsKeyPressed( GLFW_KEY_F3 ))
|
else if (ImGui::IsKeyPressed( GLFW_KEY_F3 ))
|
||||||
Mixer::manager().setCurrentView(View::LAYER);
|
Mixer::manager().setCurrentView(View::LAYER);
|
||||||
else if (ImGui::IsKeyPressed( GLFW_KEY_F11 ))
|
else if (ImGui::IsKeyPressed( GLFW_KEY_F11 ))
|
||||||
Rendering::manager().toggleFullscreen();
|
Rendering::manager().mainWindow().toggleFullscreen();
|
||||||
else if (ImGui::IsKeyPressed( GLFW_KEY_F12 ))
|
else if (ImGui::IsKeyPressed( GLFW_KEY_F12 ))
|
||||||
StartScreenshot();
|
StartScreenshot();
|
||||||
// normal keys // make sure no entry / window box is active
|
// normal keys // make sure no entry / window box is active
|
||||||
@@ -700,81 +700,84 @@ void UserInterface::RenderMediaPlayer()
|
|||||||
ImGui::Text(" %s %d x %d\n Framerate %.2f / %.2f", mp->codec().c_str(), mp->width(), mp->height(), mp->updateFrameRate() , mp->frameRate() );
|
ImGui::Text(" %s %d x %d\n Framerate %.2f / %.2f", mp->codec().c_str(), mp->width(), mp->height(), mp->updateFrameRate() , mp->frameRate() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::Button(ICON_FA_FAST_BACKWARD))
|
if (mp->duration() != GST_CLOCK_TIME_NONE) {
|
||||||
mp->rewind();
|
|
||||||
ImGui::SameLine(0, spacing);
|
|
||||||
|
|
||||||
// remember playing mode of the GUI
|
if (ImGui::Button(ICON_FA_FAST_BACKWARD))
|
||||||
bool media_playing_mode = mp->isPlaying();
|
mp->rewind();
|
||||||
|
|
||||||
// display buttons Play/Stop depending on current playing mode
|
|
||||||
if (media_playing_mode) {
|
|
||||||
|
|
||||||
if (ImGui::Button(ICON_FA_STOP " Stop"))
|
|
||||||
media_playing_mode = false;
|
|
||||||
ImGui::SameLine(0, spacing);
|
ImGui::SameLine(0, spacing);
|
||||||
|
|
||||||
ImGui::PushButtonRepeat(true);
|
// remember playing mode of the GUI
|
||||||
if (ImGui::Button(ICON_FA_FORWARD))
|
bool media_playing_mode = mp->isPlaying();
|
||||||
mp->fastForward ();
|
|
||||||
ImGui::PopButtonRepeat();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
if (ImGui::Button(ICON_FA_PLAY " Play"))
|
// display buttons Play/Stop depending on current playing mode
|
||||||
media_playing_mode = true;
|
if (media_playing_mode) {
|
||||||
|
|
||||||
|
if (ImGui::Button(ICON_FA_STOP " Stop"))
|
||||||
|
media_playing_mode = false;
|
||||||
|
ImGui::SameLine(0, spacing);
|
||||||
|
|
||||||
|
ImGui::PushButtonRepeat(true);
|
||||||
|
if (ImGui::Button(ICON_FA_FORWARD))
|
||||||
|
mp->fastForward ();
|
||||||
|
ImGui::PopButtonRepeat();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
if (ImGui::Button(ICON_FA_PLAY " Play"))
|
||||||
|
media_playing_mode = true;
|
||||||
|
ImGui::SameLine(0, spacing);
|
||||||
|
|
||||||
|
ImGui::PushButtonRepeat(true);
|
||||||
|
if (ImGui::Button(ICON_FA_STEP_FORWARD))
|
||||||
|
mp->seekNextFrame();
|
||||||
|
ImGui::PopButtonRepeat();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine(0, spacing * 4.f);
|
||||||
|
|
||||||
|
static int current_loop = 0;
|
||||||
|
static std::vector< std::pair<int, int> > iconsloop = { {0,15}, {1,15}, {19,14} };
|
||||||
|
current_loop = (int) mp->loop();
|
||||||
|
if ( ImGuiToolkit::ButtonIconMultistate(iconsloop, ¤t_loop) )
|
||||||
|
mp->setLoop( (MediaPlayer::LoopMode) current_loop );
|
||||||
|
|
||||||
|
float speed = static_cast<float>(mp->playSpeed());
|
||||||
ImGui::SameLine(0, spacing);
|
ImGui::SameLine(0, spacing);
|
||||||
|
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 40.0);
|
||||||
|
// ImGui::SetNextItemWidth(width - 90.0);
|
||||||
|
if (ImGui::DragFloat( "##Speed", &speed, 0.01f, -10.f, 10.f, "Speed x %.1f", 2.f))
|
||||||
|
mp->setPlaySpeed( static_cast<double>(speed) );
|
||||||
|
ImGui::SameLine(0, spacing);
|
||||||
|
if (ImGuiToolkit::ButtonIcon(12, 14)) {
|
||||||
|
speed = 1.f;
|
||||||
|
mp->setPlaySpeed( static_cast<double>(speed) );
|
||||||
|
mp->setLoop( MediaPlayer::LOOP_REWIND );
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::PushButtonRepeat(true);
|
guint64 current_t = mp->position();
|
||||||
if (ImGui::Button(ICON_FA_STEP_FORWARD))
|
guint64 seek_t = current_t;
|
||||||
mp->seekNextFrame();
|
|
||||||
ImGui::PopButtonRepeat();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine(0, spacing * 4.f);
|
bool slider_pressed = ImGuiToolkit::TimelineSlider( "simpletimeline", &seek_t,
|
||||||
|
mp->duration(), mp->frameDuration());
|
||||||
|
|
||||||
static int current_loop = 0;
|
// if the seek target time is different from the current position time
|
||||||
static std::vector< std::pair<int, int> > iconsloop = { {0,15}, {1,15}, {19,14} };
|
// (i.e. the difference is less than one frame)
|
||||||
current_loop = (int) mp->loop();
|
if ( ABS_DIFF (current_t, seek_t) > mp->frameDuration() ) {
|
||||||
if ( ImGuiToolkit::ButtonIconMultistate(iconsloop, ¤t_loop) )
|
|
||||||
mp->setLoop( (MediaPlayer::LoopMode) current_loop );
|
|
||||||
|
|
||||||
float speed = static_cast<float>(mp->playSpeed());
|
// request seek (ASYNC)
|
||||||
ImGui::SameLine(0, spacing);
|
mp->seekTo(seek_t);
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 40.0);
|
}
|
||||||
// ImGui::SetNextItemWidth(width - 90.0);
|
|
||||||
if (ImGui::DragFloat( "##Speed", &speed, 0.01f, -10.f, 10.f, "Speed x %.1f", 2.f))
|
|
||||||
mp->setPlaySpeed( static_cast<double>(speed) );
|
|
||||||
ImGui::SameLine(0, spacing);
|
|
||||||
if (ImGuiToolkit::ButtonIcon(12, 14)) {
|
|
||||||
speed = 1.f;
|
|
||||||
mp->setPlaySpeed( static_cast<double>(speed) );
|
|
||||||
mp->setLoop( MediaPlayer::LOOP_REWIND );
|
|
||||||
}
|
|
||||||
|
|
||||||
guint64 current_t = mp->position();
|
// play/stop command should be following the playing mode (buttons)
|
||||||
guint64 seek_t = current_t;
|
// AND force to stop when the slider is pressed
|
||||||
|
bool media_play = media_playing_mode & (!slider_pressed);
|
||||||
|
|
||||||
bool slider_pressed = ImGuiToolkit::TimelineSlider( "simpletimeline", &seek_t,
|
// apply play action to media only if status should change
|
||||||
mp->duration(), mp->frameDuration());
|
// NB: The seek command performed an ASYNC state change, but
|
||||||
|
// gst_element_get_state called in isPlaying() will wait for the state change to complete.
|
||||||
// if the seek target time is different from the current position time
|
if ( mp->isPlaying(true) != media_play ) {
|
||||||
// (i.e. the difference is less than one frame)
|
mp->play( media_play );
|
||||||
if ( ABS_DIFF (current_t, seek_t) > mp->frameDuration() ) {
|
}
|
||||||
|
|
||||||
// request seek (ASYNC)
|
|
||||||
mp->seekTo(seek_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// play/stop command should be following the playing mode (buttons)
|
|
||||||
// AND force to stop when the slider is pressed
|
|
||||||
bool media_play = media_playing_mode & (!slider_pressed);
|
|
||||||
|
|
||||||
// apply play action to media only if status should change
|
|
||||||
// NB: The seek command performed an ASYNC state change, but
|
|
||||||
// gst_element_get_state called in isPlaying() will wait for the state change to complete.
|
|
||||||
if ( mp->isPlaying(true) != media_play ) {
|
|
||||||
mp->play( media_play );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|||||||
Reference in New Issue
Block a user