Compare commits

...

1473 Commits
0.1 ... 0.8.0b

Author SHA1 Message Date
Bruno Herbelin
5db65b6e6e Update Flathub version 0.8.0 2023-04-01 18:05:19 +02:00
Bruno Herbelin
c71fc5575f Fixed typo filename 2023-04-01 18:01:33 +02:00
Bruno Herbelin
2ebf264feb Update screenshot webpage 2023-04-01 17:55:31 +02:00
Bruno Herbelin
aa20cf5138 Update webpage for 0.8.0 release 2023-04-01 17:41:09 +02:00
Bruno
5f96a8991a OSX info of Bundle integrating cmake version info
Attempt at linking vimix to MIME type .mix
2023-03-31 19:23:42 +02:00
Bruno
47e0d6ae19 BugFix UI Custom GST Source 2023-03-31 09:41:03 +02:00
Bruno Herbelin
e3e2d8d2f6 Fixe snap 0.8.0 2023-03-30 22:59:00 +02:00
Bruno Herbelin
f57e057f2a Update Snap Version 0.8.0
Using Core20 and Gnome 3-38 environment
2023-03-30 22:44:09 +02:00
Bruno Herbelin
dc0df8cc61 Merge remote-tracking branch 'origin/beta' 2023-03-29 23:27:01 +02:00
Bruno Herbelin
c30d7a2089 Add vaapi in Flatpak 2023-03-29 23:16:00 +02:00
Bruno
03bffb3319 OSX compilation 2023-03-28 22:29:56 +02:00
Bruno Herbelin
65dc93ed37 UI pedandic eye candies 2023-03-28 00:08:17 +02:00
Bruno Herbelin
8ed04b9c6e BugFix: capture frames
Correctly capture frames in RGB and RGBA from Player, and invert vertically only screenshots.
2023-03-27 23:37:08 +02:00
Bruno Herbelin
e6a9327bae Update vimix packages icons and Desktop entry 2023-03-27 17:08:10 +02:00
Bruno Herbelin
658c506653 BugFix: add failure management in SessionSource
As in update of Mixer manager, failed sources are managed in update of SessionSources. RenderSources that fail are re-created. Attach/Detach/Attached of sources functions is unified between Session and Mixer.
2023-03-27 15:59:59 +02:00
Bruno Herbelin
ad4a4281b4 BugFix: failed source detached from mixing group 2023-03-26 20:43:49 +02:00
Bruno Herbelin
6b0070ec56 Fixed Info panel Session File Source
and other UI minor details.
2023-03-26 20:05:35 +02:00
Bruno Herbelin
c9cf6baf4b Improved Device support for V4L2 streams
Allow to reload list of devices, avoid timestamp warning in Loopback, clear UI menu.
2023-03-26 17:36:18 +02:00
Bruno Herbelin
85a25a0a39 Improved report of Media Player error 2023-03-25 20:33:30 +01:00
Bruno Herbelin
e192d254f9 Improved package support of encoder selection (x265) 2023-03-25 00:05:16 +01:00
Bruno Herbelin
9e2b9d7cf4 fix missing include gl gst 2023-03-24 22:53:18 +01:00
Bruno Herbelin
cd545213e4 Extend support of gstreamer in Flatpak
Include plugins for shm, v4l2 and libav.
2023-03-24 16:19:57 +01:00
Bruno Herbelin
935d2ff02c Update Copyright date to 2023 2023-03-23 22:55:48 +01:00
Bruno Herbelin
b7d6218b89 New icon vimix 2023-03-23 22:50:43 +01:00
Bruno Herbelin
d86754b0e6 UI selection Workspace in Geometry View
Back to the combo box (smaller and unified with other views) but following the unified color accent.
2023-03-23 22:49:35 +01:00
Bruno Herbelin
b97674a404 Minor GUI fixes 2023-03-22 22:50:43 +01:00
Bruno Herbelin
f91522fc14 Introducing multiple levels of Source Failure
This allows Mixer manager to deal with failed sources with the appropriate action: try to repair, leave for user to recreate, or delete.
2023-03-22 22:50:08 +01:00
Bruno Herbelin
9b4ef00278 Copy&Paste source DUPLICATE content (not clone) 2023-03-19 06:19:52 +01:00
Bruno Herbelin
43270c7763 Improve MIXING view UX
Slight change of opacity of Mixing icon of source (stipple) when becoming non visible. Mouse over highlight on circular buttons in Mixing circle.
2023-03-18 11:18:56 +01:00
Bruno Herbelin
9a98fb399c OSC source target by ID with # prefix
Targetting source by id should be with '#' + the number (e.g. /vimix/#2/alpha). For backward compatibility the '#' is still optional.
2023-03-18 10:30:40 +01:00
Bruno Herbelin
c255b0249f Bugfix: support OSC source target by name with ID
fix a confusion between targetting source by ID (number) and targetting a source name starting with a number.
2023-03-17 11:58:28 +01:00
Bruno Herbelin
b0e71f6f18 Compilation fix - epx10 is not standard function 2023-03-14 20:50:19 +01:00
Bruno Herbelin
7e59377daf Unified Button and colors in Views, using accent color
Using standard UI colors and simplified buttons in all views.
2023-03-12 15:10:31 +01:00
Bruno Herbelin
73aa369e6d Slight visual effect on source entering mixing circle 2023-03-12 15:07:28 +01:00
Bruno Herbelin
731d7e5d6b Allow Aplpha channel for Bundle (Session Group Source) 2023-03-12 15:06:50 +01:00
Bruno Herbelin
bc5e1c7df9 Cleanup Displays view UI 2023-03-12 12:29:01 +01:00
Bruno Herbelin
1a15f9b581 Added timeout to show Session preview 2023-03-12 12:28:38 +01:00
Bruno Herbelin
136d6052d8 Slider Color correction with quadratic and logarithmic scale
Gamma (log10) and other color correction sliders (brightness, contrast, saturation) now range from [-1 to +1] with pow 2 scaling.
2023-03-12 11:19:43 +01:00
Bruno Herbelin
811b270bae Implementation of Custom Output area in Window Displays View
Changed the 'Scaled' mode of window draw to allow custom centering and scaling of the output framebuffer in the window. Use DisplaysView to grab handles of the output frame. Save all windows custom output scaling in Settings.
2023-03-12 00:31:41 +01:00
Bruno Herbelin
7870e3cfce Tooltips in Texture View
Unified UX for Views with menu; show tooltip in TextureView as it is in DisplaysView
2023-03-10 19:17:50 +01:00
Bruno Herbelin
4874af1d5a Fixed recentering of Displays View
Adjust to always ensure all monitors are shown in the view window, also for vertical alignments and window.
2023-03-10 17:37:39 +01:00
Bruno Herbelin
1b7ead0479 Full redraw on window resize
Necessary for OSX, better anyway
2023-03-10 17:03:42 +01:00
Bruno Herbelin
ac97984314 UX clarification: replace Button to open URL by icon 'Show in Finder' 2023-03-08 23:52:47 +01:00
Bruno Herbelin
8c778e8afb Larger IMGUI_RIGHT_ALIGN 2023-03-08 22:12:37 +01:00
Bruno Herbelin
2b6bbce1d9 Highly optimized pre-processed shader for white balance 2023-03-08 19:43:08 +01:00
Bruno Herbelin
b8e0a9c1dd Code compilation fix 2023-03-07 23:38:13 +01:00
Bruno Herbelin
4c3c3de065 Minor BugFix Transition View
Cancel transition if opening the session failed.
2023-03-07 23:03:15 +01:00
Bruno Herbelin
a74801a0af BugFix MediaPlayer terminate asynchronously to avoid hanging
Deleting a MediaPlayer requires stopping the pipeline and deleting it; the call to gst_element_set_state (pipeline_, GST_STATE_NULL); is however hanging. Running this in a separate thread seems to fix the problem. It is not 100% sure however if the gst_object_unref ( GST_OBJECT (pipeline_) ); will be thread safe and not crashing...
2023-03-07 22:35:22 +01:00
Bruno Herbelin
cbe8217790 UX improvements, highlight icon button, ComboIcon, reset value label
Major changes in ImGuiVisitor (all image filtering and ImageProcessingShader), new imGuiToolkit ComboIcon (replacing previous ComboIcon widget), new icons,
2023-03-05 23:35:06 +01:00
Bruno Herbelin
e1cdf34955 BugFix; replace or open after media file select 2023-03-05 00:33:17 +01:00
Bruno Herbelin
fefc20c52a Fix locked source selection and manipulation 2023-03-04 23:48:36 +01:00
Bruno Herbelin
ad1e574cfe Rendering Manager pattern improved
Use Phillips test pattern if available, and rescale to framebuffer resolution
2023-03-04 20:18:11 +01:00
Bruno Herbelin
c25d4b7dad BugFix Stream: ensure replacement of texture on re-open 2023-03-04 13:25:12 +01:00
Bruno Herbelin
207aa88daf UX improvement: do not ask user confirmation after file selection
Create a source from file; validate the file dialog is enough to create the source (without intermediate step of confirmation).
2023-03-03 20:46:34 +01:00
Bruno Herbelin
3be08a3e63 Prevent multiple color pickers and inform user 2023-03-03 20:23:05 +01:00
Bruno Herbelin
7d91ffbafa Minor UX improvement Display View 2023-03-03 19:52:12 +01:00
Bruno Herbelin
128ba084ad Change Settings of windows to 'OutputWindows' to avoid incompatibility 2023-03-03 19:51:29 +01:00
Bruno Herbelin
0defff8f7c BugFix WhiteBalance Display View and Rendering window
Use of Settings whitebalance parameters for rendering both window and display preview window. Not most optimal maybe, but efficient and clear.
2023-03-02 23:30:17 +01:00
Bruno Herbelin
6e3497e4c4 Store RenderingWindows whitebalance in Settings 2023-03-02 05:02:48 +01:00
Bruno Herbelin
1c309b2c89 Added WhiteBalance to RenderingWindow and Display View
Render output frame to output window using a Shader implementing white balance correction. Adjusting parameters of white balance from Display View with color picker (white) and slider (temperature). GLSL filter for white balance created from ShaderToy.
2023-03-01 23:24:26 +01:00
Bruno Herbelin
35507e7fbb Cleanup Rendering and Display view code to get texture of output 2023-02-28 19:12:51 +01:00
Bruno Herbelin
bc439829cf DRAFT feature for showing test pattern on output window 2023-02-28 00:24:19 +01:00
Bruno Herbelin
93f433f388 Disabling the framebuffer blit of output rendering
Blit of framebuffer is incompatible with the new features of Display View to adjust whitebalance and geometry of rendered frame on output windows.
2023-02-28 00:23:54 +01:00
Bruno Herbelin
f9e99e2a33 Minor corrections Displays view 2023-02-27 00:51:51 +01:00
Bruno Herbelin
94dcf7c3f3 Add TAB navigation to Displays View
And improve Metrics with GPU RAM information
2023-02-27 00:21:18 +01:00
Bruno Herbelin
c3bb29182e 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.
2023-02-26 23:04:38 +01:00
Bruno Herbelin
b11f6d5b3b BugFix Color selection Chromakey filter 2023-02-25 12:43:27 +01:00
Bruno Herbelin
d2b900f7c3 Compilation cleanup 2023-02-24 06:36:04 +01:00
Bruno Herbelin
bf2b5d8882 Improved UI and help 2023-02-22 22:22:12 +01:00
Bruno Herbelin
e7878bdb8f Changed grey accent color to green, make help icon more visible. 2023-02-22 12:47:13 +01:00
Bruno Herbelin
0670550521 Improved UI for Color Picker 2023-02-21 11:46:56 +01:00
Bruno
f5df923c51 BugFix: non-ImGui calls to accent color cause crash 2023-02-21 10:10:22 +01:00
Bruno
f1f62816b5 OSX implementation of color dialog (with tinyfiledialog) 2023-02-21 10:05:18 +01:00
Bruno Herbelin
db462690b3 New color dialog to enable system color picking (GTK only)
Use GTK ColorChooserDialog for color selection of chromakey under linux
2023-02-21 00:09:24 +01:00
Bruno Herbelin
c28685c700 Improved OSC control for Batch, with sync status 2023-02-19 22:06:58 +01:00
Bruno Herbelin
1f1780597c Finalized Source Callbacks for color correction
Action Input mapping for gamma and invert color corrections
2023-02-19 12:40:23 +01:00
Bruno Herbelin
1590251dad New Source Callbacks for Play control )fast forward, seek, etc.)
2 new callbacks (PlayFastForward, PlaySpeed), modified Seek callback to take target time in seconds (instead of ratio of duration). Integrating this in Input Mapping GUI and Session saving.
2023-02-19 01:05:52 +01:00
Bruno Herbelin
d25c17342b Improved logs and Settings for hardware gstreamer plugins 2023-02-17 18:53:54 +01:00
Bruno Herbelin
e105022185 BugFix: correctly approximate rendering output aspect ratio 2023-02-16 19:28:21 +01:00
Bruno Herbelin
16931917b7 BugFix: Clone source failed do not crash
Clone source that lost its origin can be replaced.
2023-02-16 19:15:25 +01:00
Bruno Herbelin
e2e316a079 Renaming Session Group to Session Bundles and Session Child
For the user interface, use the term 'Bundle' and 'Child' session instead of Group.
2023-02-15 22:27:14 +01:00
Bruno Herbelin
1dd2151a20 BugFix: OSC target Batch testing was preventing other targets
Restore normal use of target /current for OSC
2023-02-14 00:34:21 +01:00
Bruno Herbelin
c7367ad46a Enable negative Alpha in Source Callback for inactive source
setAlpha() to negative value allows to make the source inactive (outside mixing circle)
2023-02-13 23:51:16 +01:00
Bruno Herbelin
21045411e7 BugFix UI Input Mapping 2023-02-09 23:18:43 +01:00
Bruno Herbelin
128e8834e8 Changed mechanism of Source Callback and Input Mapping
Session stores list of all callback instances and reacts on input release by calling the reverse callback if it exists, or by finishing the ongoing callback. This means the behavior of Callbacks is different for those who are reversible (i.e. returns a non-null reverse) from those which do not have reverse. The reversible callbacks enforce to be exclusive while active (key pressed), others can be repeated and complementary (run in parallel).
2023-02-09 23:18:24 +01:00
Bruno Herbelin
7433772606 Improves readability Player and Output image
True color without window transparency, info icons with shadow for readability
2023-02-06 23:30:40 +01:00
Bruno
8967f5f090 Forced int64 type for Session batch argument 2023-02-06 15:25:10 +01:00
Bruno Herbelin
3b51a6e2a9 Added OSC interface for batch# 2023-02-06 08:21:37 +01:00
Bruno Herbelin
c5cb635b4e Input Mapping for Batch of Sources
Session contains a set of 'Batch' that are created in the Player (renamed from PlayGroups). Session InputCallback can now target either a Source or a Batch, using std::variant (new type Target). Input Mapping reacts to input to create callbacks to a target, either a single source (as before) or to a Batch (multiple sources).
2023-02-05 17:05:47 +01:00
Bruno Herbelin
1e9f8d707e Unified Menu for capture actions in Player and Output 2023-02-04 13:54:17 +01:00
Bruno Herbelin
69a0aa4bd8 Accept all types of sources in Player
The concept of 'Selection' evolves to accept sources of any type, not only sources that are 'playable'. This way user can create pools to reference in OSC and in Input Mapping.
2023-02-03 19:43:02 +01:00
Bruno Herbelin
581fa88055 More informative error message on missing pattern 2023-02-03 19:30:45 +01:00
Bruno Herbelin
f991ae5aed Pedantic imgui coding 2023-02-03 19:30:17 +01:00
Bruno Herbelin
44825ece04 BugFix: Update after Session Group creation 2023-02-03 19:28:33 +01:00
Bruno Herbelin
eac2c5c020 BugFix: prevent crash on embedded session update 2023-02-03 19:27:31 +01:00
Bruno Herbelin
a593e97227 BugFix: Show Shader editor as WorkspaceWindow 2023-02-03 19:26:41 +01:00
BHBN
ecad786f50 User-built flatpack compile the Beta branch
When building the flatpak package using the instructions at https://github.com/brunoherbelin/vimix/tree/master/flatpak, users have the preview of the Beta version of vimix.
2023-02-02 22:55:28 +01:00
Bruno Herbelin
9012d33c05 Logging improvement on delete / create source 2023-01-31 21:23:26 +01:00
Bruno Herbelin
268751815f BugFix New Source File Doubleclic
WTF did I think it would be a good idea to delete a source in a separate thread? This obviously causes a crash. To be investigated when a source tailes to delete... but should not happen...
2023-01-31 21:22:53 +01:00
Bruno Herbelin
6529b170e6 Cleanup Source Fail reporting
All Stream report failure with logs, read in InfoVisitor for Sources. ImGuiVisitor for Sources also detect failure of source and its stream.
Cleanup of unused includes and functions.
2023-01-30 00:07:52 +01:00
Bruno Herbelin
5ce465cb30 New Session and Mixer mechanism for Failed sources
When a source in a session fails, it is not anymore deleted after update; the Mixer keeps it in the session but detaches it from the scene. This way the user can access the failed source in the navigator (listed in RED), and Replace the source. The Replacement of source is available for any source. The source visitor does not skip a visit if the source failed.
2023-01-29 14:33:35 +01:00
Bruno Herbelin
48f1df2fd6 ImGuiToolkit to render a Disabled Button 2023-01-29 10:54:57 +01:00
Bruno Herbelin
3e6ddf560a Player UI improvement
Changing icons of Player selection to 'CIRCLE' icons because the icon of Player is the CIRCLE with triangle. Also allows to have an icon for User Selection.
2023-01-29 10:54:28 +01:00
Bruno Herbelin
0051533ac8 Improved management of failed sources
Clone is failed if its origin is failed, handle MediaPlayer visitor and error message when fail, get SourceList of non-failed sources of a list.
2023-01-29 10:50:15 +01:00
Bruno Herbelin
e69ac7ca28 Correction of invalid keyboard shortcut in documentation 2023-01-27 22:23:28 +01:00
Bruno Herbelin
9c8abb8edf Updated selection target for OSC
Adds ability to target a selection of sources stored in the Player
2023-01-27 20:43:29 +01:00
Bruno Herbelin
9ee434f275 Cleanup Player UI
Add play/pause button on source icon in selection (dynamic or stored selection). Display source icon in lower left corner, instead of play status. Fix alignment disabled timeline. Minor bugfix.
2023-01-27 19:25:05 +01:00
Bruno Herbelin
4826d9fbf0 Logging unknown OSC attribute
Users otherwise don't know what is wrong when sending incorrect OSC attribute
2023-01-27 17:33:44 +01:00
Bruno Herbelin
3fd7b8ed3c Magnifying glass for Player and Output windows
Replace the 'inspector' menu in favor of a magnifying glass button at top right corner of imgui window for Player and Output preview. Disable the magnifying glass upon window unfocus.
2023-01-16 00:18:17 +01:00
Bruno Herbelin
ebc8d483d9 BugFix display source button UV in muti-source Player 2023-01-14 23:42:59 +01:00
Bruno Herbelin
9821d3595a BugFix display inpector UV in Player of cropped sources 2023-01-14 23:06:34 +01:00
Bruno Herbelin
f21be9d10c Put beta in home-made flatpak 2023-01-01 22:25:10 +01:00
Bruno Herbelin
d221036cde Remove Window Refresh callback
Rendering draw should NOT be called twice
2023-01-01 22:15:38 +01:00
Bruno Herbelin
1dbff48ebb Cleanup views and bugfixes
Remove dependency to Imgui in View class. Cosmetic improvement UI in views.
2023-01-01 16:34:47 +01:00
Bruno Herbelin
43e56fc433 Polishing up DisplaysView
Options to fit output window on all screens. Added doubleclic function to View class (Transition view and Displays view have specific reaction to double clic.
2022-12-30 21:46:08 +01:00
Bruno Herbelin
b3b562f4bb Stabilized Displays View
Manipulation of output window from Displays View, fullscreen and window modes. Adapted preview window of display.
2022-12-29 20:50:40 +01:00
Bruno Herbelin
784ac996d3 First operational implementation of Displays View 2022-12-29 00:39:51 +01:00
Bruno Herbelin
fb6a95078d Creation and minimal integration of Displays View 2022-12-26 15:46:37 +01:00
Bruno Herbelin
189e7b8bc9 Cleanup monitor management in Rendering Manager 2022-12-26 15:45:42 +01:00
Bruno Herbelin
55967ad27c Changed icon of output window 2022-12-24 00:51:20 +01:00
Bruno Herbelin
e2c82af4d6 Implementation of custom session resolution
Moved presets of resolution to RenderView (framebuffer class is lower level). Changed logic of UI selection of session resolution change.
2022-12-23 20:23:39 +01:00
Bruno Herbelin
8712923bec Detecting monitors in Rendering Manager 2022-12-18 12:11:42 +01:00
Bruno Herbelin
416635179b Fix warning runtime invalid scancode 2022-12-18 12:03:29 +01:00
BHBN
c1b635e036 Create jekyll-gh-pages.yml 2022-12-13 23:38:05 +01:00
Bruno Herbelin
2860d8f1de Update doc and README to mention flatpak 2022-12-13 18:32:32 +01:00
Bruno Herbelin
c1fb07b4c7 Fixed flatpak according to flathub recommendations 2022-12-12 23:19:37 +01:00
BHBN
5036c2231c Update build instructions to reference flatpak 2022-12-11 20:51:06 +01:00
BHBN
c848666e17 Update instruction flatpak markdown layout 2022-12-11 20:40:19 +01:00
Bruno Herbelin
55aef98a30 markdown readme 2022-12-11 16:09:38 +01:00
Bruno Herbelin
7cbbf799dc Documenting how to make a flatpak of vimix 2022-12-11 16:06:51 +01:00
Bruno Herbelin
30a4e0297c Making flatpak usable by command line 2022-12-11 15:19:10 +01:00
Bruno Herbelin
5f68f51693 Support for non-US keyboard layout
Hack to translate key press index to matched letter as key. Should work on most Latin keyboard layout, but not tested otherwise...
2022-12-11 14:10:19 +01:00
Bruno Herbelin
8e6aaf29e0 BugFix WorkspaceWindow toggle 2022-12-11 13:26:28 +01:00
Bruno Herbelin
cde0e74a2e Fixup Flatpak for Flathub install
NB: the Vimix.json flatpak for Flathub is in the dedicated Flathub branch for submission to repo. The local flatpak/.Vimix.json is for testing locally building flatpak with latest code.
2022-12-10 14:38:30 +01:00
Bruno Herbelin
2a573cbab3 Prepare for version 0.7.3 2022-12-10 11:18:15 +01:00
Bruno Herbelin
941275a1b9 UI Integration of output to SRT, Shmdata and V4L2
Improved user interface and messages for the activation of Output streaming with SRT, shared memory, or loopback camera with V4L2 under linux.
2022-12-09 20:10:37 +01:00
Bruno Herbelin
c5884ec498 Fixed and unified implementation shmdata and video broadcast 2022-12-07 09:32:08 +01:00
Bruno Herbelin
da06cf52ec Integration of Shmdata in vimix
Unified menu in output window for streaming (for SRT, Shmdata and peer to peer). Cleanup SRT broadcaster and bugfix on FrameGrabber default frame timing.
2022-12-06 23:21:17 +01:00
Bruno Herbelin
07e8f489c1 Initial implementation of Shmdata broadcast
If gstshmdatasink is available (from shmdata https://gitlab.com/sat-mtl/tools/shmdata/), the shmdata broadcaster can capture output and share it to memory
2022-12-06 23:19:00 +01:00
Bruno Herbelin
baed2ac031 Tolerate unknown audio codec to play video media
The case of  MISSING_PLUGINS for audio in gst discoverer should not prevent from decoding video stream in media. The failure of discoverer should only be in absence of video stream.
2022-12-04 19:11:44 +01:00
Bruno Herbelin
cdab138b2f GUI Renaming Network sharing to Peer-to-Peer sharing 2022-12-04 18:29:07 +01:00
Bruno Herbelin
06524edfb3 Bugfix - repair problem caused by previous change 2022-12-04 18:22:47 +01:00
Bruno Herbelin
0e40550427 Bugfix Monitor detect devices even if monitor crashes
As gst_device_monitor_start can crash, the Device::manager should still fill in the list of devices at first run (fix problem on Flatpak).
2022-12-04 14:16:37 +01:00
Bruno Herbelin
e08b6ade9e Fix C++17 compilation warning 2022-12-04 13:17:51 +01:00
Bruno Herbelin
36bc4944f9 Exploring options for RIST protocol stream broadcasting 2022-12-04 12:14:32 +01:00
Bruno Herbelin
a0be95d634 Enabling SHM streaming in localhost
Adding a mechanism to revert to UDP when SHM fails; we can thus re-enable the SHP streaming for programs in localhost
2022-12-04 00:29:09 +01:00
Bruno Herbelin
faf8d4c4ad Add shmdata lib to flatpak, detect gstshmdata plugin at runtime 2022-12-03 18:29:56 +01:00
Bruno Herbelin
8af740caa8 Detecting shmdata library and gst plugin
Find shmdata library and add it to gstreamer plugin path. User is informed on how to build shmdata.
2022-12-03 18:00:58 +01:00
Bruno Herbelin
69fa3521f9 Removed submodule ext/shmdata 2022-12-03 17:45:07 +01:00
Bruno Herbelin
991a96d3dc Add shmdata submodule 2022-12-02 18:53:00 +01:00
Bruno Herbelin
b10bf06305 Minimize compilation gstreamer in flatpak 2022-11-25 22:39:10 +01:00
Bruno Herbelin
7f54b30fbe packaging x264 encoder in flatpak 2022-11-25 21:22:46 +01:00
Bruno Herbelin
ee79043536 Packaging frei0r plugins in flatpak 2022-11-22 00:15:58 +01:00
Bruno Herbelin
c9e6611b92 Packaging gstreamer and SRT in flatpak 2022-11-21 00:50:47 +01:00
Bruno Herbelin
73d128d89a Merge remote-tracking branch 'origin/master' 2022-11-20 00:06:39 +01:00
Bruno Herbelin
5a240acd86 Fix cmake vimix version 2022-11-20 00:06:30 +01:00
Bruno Herbelin
7dc4a5cf87 Fix cmake vimix version 2022-11-20 00:01:53 +01:00
Bruno Herbelin
6d835297b2 tag 0.7.2 2022-11-19 23:44:08 +01:00
Bruno Herbelin
b44c29e235 No build in flatpak 2022-11-19 22:25:36 +01:00
Bruno Herbelin
8da9a9cf27 flatpak repo preparation 2022-11-19 22:22:37 +01:00
Bruno Herbelin
a3617626f7 Merge remote-tracking branch 'origin/master' 2022-11-19 20:20:27 +01:00
Bruno Herbelin
e44832ea9e Packaging with flatpak
Successful flatpak-builder process. Not tested further.
2022-11-19 20:20:12 +01:00
Bruno
f841e78dcf Bundle fix (OSX) 2022-10-26 10:01:28 +02:00
Bruno
e7a8d48cca Packaging fix (Cpack OSX) 2022-10-26 09:44:10 +02:00
Bruno
69e8d0e32f Compilation fix (OSX) 2022-10-25 21:38:21 +02:00
Bruno
830d1a6bf9 OSX entitlements to include audio input
Used for gstreamer sources that generates visuals from audio
2022-10-25 00:32:18 +02:00
Bruno Herbelin
e9b72b442a Cleanup source tree
Move all C++ source files in the src subfolder. Adapted the cmake process accordingly and cleanup.
2022-10-25 00:29:22 +02:00
Bruno Herbelin
77ac7eca18 OSC message fror session open, close and save 2022-10-22 10:45:56 +02:00
BHBN
86d4198ffd Merge pull request #54 from felixgonsug/flatpak-build
adding a startpoint to flatpak building
2022-10-20 21:32:26 +02:00
felix
37dfe31ac2 adding a startpoint to flatpak building 2022-10-18 13:34:27 -03:00
Bruno Herbelin
584e1c48e6 oops 2022-10-15 21:40:13 +02:00
Bruno Herbelin
15766ceb97 Prevent bad window manipulation 2022-10-15 19:12:09 +02:00
Bruno Herbelin
6e79f28b69 Prevent Player Inspector conflict with info overlay 2022-10-15 19:11:53 +02:00
Bruno Herbelin
e9632d206b OOps, fixed debug testing 2022-10-15 19:10:55 +02:00
Bruno Herbelin
a0f55bfcb5 Added Fading target for OSC session 2022-10-15 19:06:52 +02:00
Bruno Herbelin
3c32f1da6e Bugfix generation image sequence
Fixed pb with non-power of two height of video, added more informative error messages, fixed UI issue.
2022-10-15 15:19:17 +02:00
Bruno Herbelin
7e13c1b22a Move Group/Ungroup actions to Edit menu 2022-10-15 11:51:16 +02:00
Bruno Herbelin
2fc52e673f Added Color Correction mapping input
Map image processing source callbacks to key inputs.
2022-10-15 00:26:16 +02:00
Bruno Herbelin
48001a660b Source callbacks for Image Processing color correction
Added SourceCallback classes for brightness, contrast, saturation, etc. Added OSC interface to modify color corrections
2022-10-14 19:05:14 +02:00
Bruno Herbelin
5a6daf79b6 Allow Nil Values in OSC messages
Allows providing only one argument value when two (e.g. x and y) are required by specifying the NIL type ('N') in the OSC message. E.g. /vimix/current/position Nf 0.5 sets the Y position.
2022-10-13 17:34:17 +02:00
Bruno Herbelin
ae4fd9f7df Disable Broardast and inform user if SRT not available 2022-10-13 16:24:01 +02:00
Bruno Herbelin
7dfa8776fd Minor improvement Tooltips Settings 2022-09-10 11:24:02 +02:00
Bruno Herbelin
a836796fcc Fix previous 2022-09-08 23:36:13 +02:00
Bruno Herbelin
fb131972d4 Non-blocking deletion of source in SourcePreview
Detach a thread to delete the source currently in SourcePreview in Source new panel; avoids freezing display.
2022-09-08 23:31:27 +02:00
Bruno Herbelin
140ce358fa Added history of recent SRT hosts
Saving known hosts in settings and validating ip and port in SRT connector for source
2022-09-08 20:36:58 +02:00
Bruno Herbelin
dd92f2dccb Improved OSC sync
Accept OSC request to sync source by name or id. Changed OSC seek request to be by percent target
2022-08-17 19:11:21 +02:00
Bruno Herbelin
d62004eadf Update screenshots documentation recording 2022-08-17 18:49:25 +02:00
Bruno Herbelin
abc21e9692 Send source name in Status bundle of all sources 2022-08-09 23:44:22 +02:00
Bruno Herbelin
a13b0d5d91 BugFix Shadertoy ImageFilter 2022-08-08 21:17:16 +02:00
Bruno Herbelin
12f8c75c2d Update screenshots documentation 2022-08-07 11:17:28 +02:00
Bruno Herbelin
bdc1920166 Clone with copy attributes
Two modes of cloning: from the source panel with 'Clone & filter' clones with copy of attributes (geometry, alpha, etc.), from the Insert source panel with 'Internal' source creates a fresh new copy.
2022-08-07 11:13:45 +02:00
Bruno Herbelin
8cb0d57ffe Documenting advances features 2022-08-05 23:22:34 +02:00
Bruno Herbelin
7344689263 Update screenshot Ubuntu snap 2022-08-04 00:23:06 +02:00
Bruno Herbelin
f521ca1118 Fix UI and doc of Share local network 2022-08-04 00:22:38 +02:00
Bruno Herbelin
6712f1383e Fun vimix crow in About dialog 2022-08-02 23:36:09 +02:00
Bruno Herbelin
d756fd4a29 New communication image
Crow drawing done by DALL-E (no human copyright)
2022-08-01 22:22:36 +02:00
Bruno Herbelin
e070ef1b7f adding screenshots documentation SRT 2022-08-01 13:02:05 +02:00
Bruno Herbelin
ea7786a002 Set SRT Latency to 200ms
TODO: make it configurable
2022-08-01 12:39:55 +02:00
Bruno Herbelin
3eec07fac1 BugFix Discoverer for Stream 2022-08-01 11:22:50 +02:00
Bruno Herbelin
46afa76af8 update SRT documentation 2022-07-30 22:09:09 +02:00
Bruno Herbelin
6cc1ba64d8 adding screenshots documentation SRT 2022-07-29 23:26:20 +02:00
Bruno Herbelin
225596481f no architecture snap 2022-07-29 14:44:28 +02:00
Bruno Herbelin
4ef3b3b332 snapping fix 2022-07-29 14:33:52 +02:00
Bruno Herbelin
e7ac768b5b Merge remote-tracking branch 'origin/master' 2022-07-29 00:45:13 +02:00
Bruno Herbelin
b1e8833daa Complement snapcraft info and archittectures 2022-07-29 00:45:07 +02:00
Bruno Herbelin
155d71dc80 Complement snapcraft info and archittectures 2022-07-28 23:27:41 +02:00
Bruno Herbelin
94ebf17134 Add link to Wiki Filters and ShaderToy in Help 2022-07-28 23:11:12 +02:00
Bruno Herbelin
d6fe2edf0d Update and new images for wiki
Preparing documentation for filters a,d group features
2022-07-28 00:00:59 +02:00
Bruno Herbelin
867cd7e583 BugFix test number string 2022-07-27 23:33:36 +02:00
Bruno Herbelin
1a2471a32d Implementation of OSC targets Position, Size, Angle and Seek
Creation of SourceCallback to seek in MediaSource
2022-07-27 17:55:51 +02:00
Bruno Herbelin
057dd9c01d New images for wiki on filters 2022-07-23 23:18:11 +02:00
Bruno Herbelin
5a2c0e15e9 Change Player menu and new Frame inspector
Frame menu is active when a single source is selected. The Frame menu include actions to capture frame and to enable Frame Inspector. Frame inspector zooms on the image at cursor coordinate. Previous Control menu actions are back to main menu.
2022-07-23 22:45:14 +02:00
Bruno Herbelin
ae5ae24f6f BugFix source editor if playable 2022-07-23 12:07:44 +02:00
Bruno Herbelin
7a2f3fe840 BugFix Quit action in menu 2022-07-23 12:07:07 +02:00
Bruno Herbelin
b46788c81a snap 0.7.1 2022-07-21 23:05:20 +02:00
Bruno Herbelin
3c1f37e5f9 BugFix GLSL shader array init 2022-07-21 22:42:32 +02:00
Bruno Herbelin
d8d4322b2e Added option Recorder file naming style
VideoRecorder and PNGRecorder now have setting to decide how to name the files, with date prefix or sequentially numbered.  A base name is given with session filename.
2022-07-20 23:47:22 +02:00
Bruno Herbelin
1613e9ce46 BugFix: session creator restore play status of all types of sources
moved 'play' attribute to source instead of mediaplayer and use source callback to set play state after initialization.
2022-07-19 23:52:51 +02:00
Bruno Herbelin
aee3c8db1b Added ShaderToy support for iMouse to ImageFilter 2022-07-19 22:43:49 +02:00
Bruno Herbelin
becaeedff1 New fun shader vimix logo 2022-07-19 00:09:17 +02:00
Bruno Herbelin
c9c6651368 BugFix load display faster 2022-07-08 22:14:39 +02:00
Bruno Herbelin
d77371912b Changed Group ALL sources action to Group ACTIVE sources
Manage mixing groups and clones on the way. This makes the action more flexible for the user, allowing to group only a selection.
2022-07-06 23:34:36 +02:00
Bruno Herbelin
93cb12be89 BugFix UI Sequence recorder 2022-07-05 23:03:45 +02:00
Bruno Herbelin
4ac2bd8e92 BugFix fisplay Shader Code 2022-07-05 22:18:12 +02:00
Bruno Herbelin
34d52c975e Compilation fix
not needed call of non standard gst call
2022-07-05 22:17:59 +02:00
Bruno Herbelin
85194c7f4f Integration of MultiFileRecorder in UI for sequence creation 2022-07-04 00:07:23 +02:00
Bruno Herbelin
af009e03a0 BugFix New source pannel
Clear status of new source pannel when changing type of input.
2022-07-02 11:34:43 +02:00
Bruno Herbelin
cef7379c07 Initial implementation of MultiFileRecorder
Generate a video from a sequence of images.
2022-07-02 11:34:04 +02:00
Bruno Herbelin
f1e75d8593 BugFix change texture input Stream Sources 2022-06-22 23:48:21 +02:00
Bruno Herbelin
c5a194e98c Frame capture settings and options 2022-06-22 23:01:01 +02:00
Bruno Herbelin
7858033628 Player Frame capture F10
New feature of Player: capture frame (F10 shortcut). Extending the Screenshot class for reading pixels and saving to PNG. Cleaup of screenshot (now associated to F9).
2022-06-22 01:40:47 +02:00
Bruno Herbelin
f2405e02f6 Player display of non-playable source
Show also non-playable sources to allow testing pre- post-display. Show post-processed image only if source made changes.
2022-06-21 01:37:30 +02:00
Bruno Herbelin
452221daa5 User input unified and fixed for clone source
Fixed slider in player, show filtered image when disabled (outside mixing circle), correct timing for clone source (different for filters).
2022-06-20 17:29:12 +02:00
Bruno Herbelin
91f551c2d8 BugFix ShaderEditor 2022-06-19 02:00:32 +02:00
Bruno Herbelin
2ca1763280 Cleanup headers and licenses shaders code 2022-06-18 19:35:52 +02:00
Bruno Herbelin
da4a8333f7 Bugfix and clean code image filters ui, save and load 2022-06-18 18:08:16 +02:00
Bruno Herbelin
c0b08f3219 F11 for screen capture 2022-06-18 17:26:05 +02:00
Bruno Herbelin
c273e9125c F12 for enable/disable output
replacing the 'END' key that is not available on many keyboards.
2022-06-18 11:30:40 +02:00
Bruno Herbelin
7244b95844 Documentation and icons for FrameBuffer filters
unified icons, new entry in help window.
2022-06-18 11:30:11 +02:00
Bruno Herbelin
a298b6587d Added header for GLSL code, GLP3+
Ref to original ShaderToy authors.
2022-06-11 23:35:01 +02:00
Bruno Herbelin
d87f6b74f3 Fixed Shader Editor menu and behavior
Only Clones with ImageFilter of custom type are linked to UI for ShaderEditor. New menu to try presets of shader code. Link to ShaderToy website.
2022-06-10 00:04:56 +02:00
Bruno Herbelin
1f0b145740 Original implementation of Smooth Image filters
Smoothing and noise reduction filters + noise generators.
2022-06-08 23:44:19 +02:00
Bruno Herbelin
f6d528d36d Finalizing implementation of chroma and luma key Transparency filters 2022-06-07 23:49:21 +02:00
Bruno Herbelin
ea6502a282 Removing chromakey and lumakey from standard color correction shader
These effects now should be performed with effect on clone (alpha image processing shaders).
2022-06-07 19:04:52 +02:00
Bruno
8a36a94e73 not all GL Shading compilers accept ## for comments... 2022-06-07 10:45:23 +02:00
Bruno Herbelin
1604eaa239 Original implementation of Alpha Image filters
Chromakey (to finish), lumakey and alpha fill.
2022-06-06 23:33:36 +02:00
Bruno Herbelin
fec2fb7ce6 Original implementation of Resampling Image filters
This involves also resizing the renderbuffer of the clone source. Upsampling is cubic (faster approximation) and Downsampling is bilinear.
2022-06-05 23:43:23 +02:00
Bruno Herbelin
d2e3b854aa Put sobel as default edge filter
Default should be archetypal and efficient filter
2022-06-05 10:19:56 +02:00
Bruno Herbelin
f8e8d33c61 Bugfix show editor of clone source 2022-06-05 10:18:36 +02:00
Bruno Herbelin
dd76135efd Polishing sharpen and edge Image filters 2022-06-02 23:57:43 +02:00
Bruno Herbelin
d7be7a69ab Original implementation of Edge Image filters 2022-06-01 23:49:12 +02:00
Bruno Herbelin
fd942b28c6 Finishing Sharpen Image filters 2022-05-31 23:14:53 +02:00
Bruno Herbelin
7c850b0405 Original implementation of Sharpen Image filters 2022-05-31 22:53:28 +02:00
Bruno Herbelin
e3bb95b3dd Original implementation of Blur Image Filters
With Gaussian, fast Gaussian, Hashed and morphological (opening and closing) methods. Remembering shader code for other fast methods.
2022-05-31 00:34:37 +02:00
Bruno Herbelin
662d8bcfda Minor UI and wording changes 2022-05-24 23:28:36 +02:00
Bruno Herbelin
3c0b2c64e1 Added opposite action of 'Group all sources'
Mixer action ungroupAll expands all SessionGroupSources.
2022-05-24 21:30:54 +02:00
Bruno Herbelin
ed7d42cf6d Improved Player view of pre- and post-filtered images 2022-05-23 19:31:36 +02:00
Bruno
8852914ceb BugFix FrameBuffer Filter init 2022-05-23 08:55:16 +02:00
Bruno Herbelin
944778175a Improved computation of framebuffer memory usage 2022-05-23 00:45:54 +02:00
Bruno Herbelin
81704c08c9 Show post-processed image in Player by default 2022-05-22 22:19:07 +02:00
Bruno Herbelin
810059e6da Bugfix attach source 2022-05-22 22:18:43 +02:00
Bruno Herbelin
8d95bd16fd BugFix: change Device of DeviceSource with different resolution 2022-05-22 22:04:45 +02:00
Bruno Herbelin
4600253d1e Cleanup alignment Source pannel 2022-05-22 18:02:59 +02:00
Bruno Herbelin
d695aa9f57 FrameBuffer creation flags replace booleans
Instead of many creation options (with alpha, with multisampling, etc) use a single flag with boolean operators. Creation of the new mipmap flag for FrameBuffer, rendering the current FBO into multiple sub-resolutions.
2022-05-22 15:14:10 +02:00
Bruno Herbelin
7867aac55f Cleanup use of new icons 2022-05-22 11:18:57 +02:00
Bruno Herbelin
e26563c3d6 Remove all reference and icons from iconmonstr
Icons were unused and license was incompatible with GPL
2022-05-21 22:39:30 +02:00
Bruno
07ad262857 Sofware limiter for OSX seems to need more margin 2022-05-19 09:08:53 +02:00
Bruno Herbelin
cb0abd51db RenderingManager: FPS software limiter even with VSYNC
V-sync on multiple windows is not always performing well. So limiting to 61 FPS works with both VSYNC at 60FPS or without VSYNC. This means the settings for VSYNC is useless (removed from Settings panel).
2022-05-18 23:46:27 +02:00
Bruno
cc69baf0dd Compilation fix 2022-05-18 12:50:07 +02:00
Bruno Herbelin
852a8d04c9 Fixup UI ImageFilter 2022-05-18 00:19:48 +02:00
Bruno Herbelin
ffdacb3850 Unified implementation of filters for CloneSources
All filters now derive from FrameBufferFilter, which is always used in a CloneSource. Default FrameBufferFilter is Passthrough filter. Others are Delay and Image filters. Implemented UI selection of filter type, XML session save and load. Linked ImageFilter to Code editor.
2022-05-18 00:10:14 +02:00
Bruno Herbelin
062e8357fa Fixing morphological shaders code 2022-05-15 23:34:09 +02:00
Bruno Herbelin
07dece9cd7 Adding Filters 2022-05-15 23:33:18 +02:00
Bruno Herbelin
d628a513d9 Place clone at same depth of origin
TODO: shift other sources to make room?
2022-05-11 21:27:10 +02:00
Bruno Herbelin
6012ad9b1e Unified edge ImageFilters to invert 2022-05-07 23:31:21 +02:00
Bruno Herbelin
c3e618de36 BugFix Show Player 2022-05-07 23:30:52 +02:00
Bruno Herbelin
6b9795fe96 Remove (obsolete) filters from ImageProcessingShader
This shader is now only for Color correction
2022-05-07 23:15:35 +02:00
Bruno Herbelin
f7da3a347d New morphological operators 2022-05-07 23:01:17 +02:00
Bruno Herbelin
cf020d06c6 Place clone next to origin upon cloning 2022-05-07 23:01:02 +02:00
Bruno Herbelin
137b5ca4f9 BugFix ImageFilter timing
new debuging shader
2022-05-07 18:24:38 +02:00
Bruno Herbelin
82be9326a8 Fixed ImageFilter timing 2022-05-07 15:39:06 +02:00
Bruno Herbelin
222282dced Populating CloneSource with many preset ImageFilters 2022-05-07 13:39:08 +02:00
Bruno Herbelin
c7a2086850 Change Source filter to Color Correction
Removed filter selection from UI
2022-05-03 23:31:08 +02:00
Bruno Herbelin
168ac5065d Performance improvement: disable render when No ImageFilter selected 2022-05-03 23:30:21 +02:00
Bruno Herbelin
158ea1984f BugFix: more stable use of FBOs for delay 2022-05-03 23:29:18 +02:00
Bruno Herbelin
f66d73e385 Improved and added settings for MediaPlayer split view slider 2022-05-03 20:04:02 +02:00
Bruno Herbelin
252ed1c6f2 Added slider to show source pre-post processed in Player 2022-05-03 00:39:10 +02:00
Bruno Herbelin
69e35167bc BugFix Support for GStreamer upgrade to 1.20 2022-05-02 19:50:30 +02:00
Bruno Herbelin
2140075133 bugfix equal operator 2022-05-01 22:25:20 +02:00
Bruno Herbelin
80469ead18 Initial commit of ImageFilter shader presets
Clone source can choose a filter
2022-05-01 22:24:59 +02:00
Bruno Herbelin
77dc563219 Minimally operational Shader editor
Can edit code in GLSL, syntax highlighted, and compile shader. Compatible with ShaderToy code.
2022-04-23 01:02:31 +02:00
Bruno Herbelin
9d7f0b22f7 BugFix ATI get memory GL_TEXTURE_FREE_MEMORY_ATI 2022-04-21 18:38:34 +02:00
Bruno Herbelin
56b17116e3 Preliminary implementation of Shader editor
Connect TextEditor with ImageFilter from current Clone Source.  GLSL Compilation seems to work....
2022-04-21 00:18:37 +02:00
Bruno Herbelin
c71791b649 Bugfix handle keyboard for TextEditor. Starting to create Shader Editor
New WorkspaceWindow for the shader editor.
2022-04-20 18:26:31 +02:00
Bruno Herbelin
c8f8fcf9d3 BugFix: prevent View Terminate if not previously Initiated
Ensures Action::Manager stores terminated actions only if previously initiated (caused iterative action storing on keyboard repeat).
2022-04-20 16:43:42 +02:00
Bruno Herbelin
d41a85f4a1 New ImageFilter applied to Clone Sources
Preliminary implementation, effective but without consequence on the rendering.
2022-04-19 01:23:50 +02:00
Bruno Herbelin
3c465f9a7a Improved Shader compilation 2022-04-19 01:23:04 +02:00
Bruno Herbelin
c25427cf4a Add possibility to define ShadingProgram with GLSL code 2022-04-18 14:02:51 +02:00
Bruno Herbelin
1c8575e40c Add test of resource availability 2022-04-18 14:01:50 +02:00
Bruno Herbelin
e512eab1e8 Move code of getGPUMemoryInformation to Rendering manager 2022-04-18 14:01:21 +02:00
Bruno Herbelin
4dd8ceb245 Clone Source connection with directional dot line
use arrows to draw dot line between clone and its origin
2022-04-17 21:46:48 +02:00
Bruno Herbelin
07e2bd4bcf Improvement: reuse FBO for Thumbnailing
Avoid create and delete a new FBO for each thumbnail, as they are often the same size.
2022-04-17 12:51:55 +02:00
Bruno Herbelin
05eb62bb35 Allow CTRL+move of Locked sources 2022-04-17 12:35:34 +02:00
Bruno Herbelin
0df3342757 Improve Source naming increment 2022-04-17 11:22:32 +02:00
Bruno Herbelin
0615f38a26 BugFix Thumbnail in 21:9 aspect ratio 2022-04-17 00:19:34 +02:00
Bruno Herbelin
1fe63b68ee Message improvement Warning Change XML version 2022-04-16 23:52:13 +02:00
Bruno Herbelin
1e7dbb5331 BugFix Source init with clones when inactive at creation 2022-04-16 23:25:20 +02:00
Bruno Herbelin
0ddc03b7c0 Fixed Clone Source Activation 2022-04-16 21:18:45 +02:00
Bruno Herbelin
becc3d0953 Clone Source loading fixed and simplified
Fixed loading order. Removed the option of origin selection for Clone: not meaningful anymore with chain of clones.
2022-04-16 19:52:52 +02:00
Bruno Herbelin
48b1bfaebd Graphics Card Memory check before allocating FBO
Improved warning when allocating FrameBuffer. Avoid allocating FrameBuffer when buffering delay in Clone Source if we risk to consume all RAM in graphics card.
2022-04-16 12:57:31 +02:00
Bruno Herbelin
c043026764 Clone Source; dynamic memory for delay, connection line to origin 2022-04-16 01:33:41 +02:00
Bruno Herbelin
0aed9fc306 Added dotted line rendering 2022-04-16 01:31:55 +02:00
Bruno Herbelin
739559783b GPU monitoring of RAM available when allocating FBO
Warning when allocation of FBO is critical.
2022-04-16 01:31:09 +02:00
Bruno Herbelin
0f4076acab Documenting SRT Broadcast 2022-04-11 22:41:22 +02:00
BHBN
9692ac3f4d Merge pull request #43 from prez/musl
Fix compilation on musl libc
2022-04-11 22:24:01 +02:00
prez
365a333b1d Fix compilation on musl libc 2022-04-11 17:09:36 +02:00
Bruno Herbelin
f039755bde Set Max Clone delay to 2.0s 2022-04-10 23:32:44 +02:00
Bruno Herbelin
d314f1bae2 Player empty message more meaningful 2022-04-10 00:50:56 +02:00
Bruno Herbelin
aae1915519 SessionFile source restore version snapshot from UI 2022-04-10 00:50:31 +02:00
Bruno Herbelin
220df8918c Lock behavior change: do not show lock icon on unlocked inactive sources
Show unlocked icon only when active, show locked icon always
2022-04-09 19:29:37 +02:00
Bruno Herbelin
3e41655902 Unified Logs for sources initialization 2022-04-09 15:20:48 +02:00
Bruno Herbelin
54a23f5ae7 BugFix CountVisitor 2022-04-09 15:07:55 +02:00
Bruno Herbelin
edffcf8902 Added Total count of source in Session mix info 2022-04-09 14:46:09 +02:00
Bruno Herbelin
dd55f41264 BugFix Session Group init and playable status.
Improved logs
2022-04-09 14:45:12 +02:00
Bruno Herbelin
8fef0052a3 New CountVisitor to count the number of sources in session
Session size is the number of elements, use CountVisitor to count the total number of sources inside (recursively through SessionSources).
2022-04-09 00:35:20 +02:00
Bruno Herbelin
f2db10d29a Added Double Frame on Session Source 2022-04-09 00:33:43 +02:00
Bruno Herbelin
33756c775c Fixed Session load recursion, allow higher level of imbrication
Recursive load of SessionFile in a Session is now detected by filename and prevented. Deeper level of integration of sessionfile inside session is thus possible (set to 3). Sessions now have an id, allowing to reference them by id in the logs. Terminology is clarified between level and recursion.
2022-04-08 17:44:39 +02:00
Bruno Herbelin
ef65dd8cc6 Source list UI with Initials of source and name 2022-04-03 23:29:12 +02:00
Bruno Herbelin
74d0d851ca Display list of sources in Session Group UI panel 2022-04-03 23:18:14 +02:00
Bruno Herbelin
49ebc17334 Source info() gives type, InfoVisitor gives instance info
Changed (back) to clean use of source->info() to return type dependent info string. The InfoVisitor gives unified detailed information about instance.
2022-04-03 00:02:20 +02:00
Bruno Herbelin
548aba5b7c BugFix wrong initialization time counter 2022-04-02 23:59:00 +02:00
Bruno Herbelin
dc1f1e02a1 Unifying icons for session and group sources UI 2022-04-02 17:45:57 +02:00
Bruno
d10b809687 Unified Information string on Group Source 2022-03-28 10:57:32 +02:00
Bruno
ad438ef339 BugFix Session Group creation
Duplicate Action history store can cause crash
2022-03-28 10:57:09 +02:00
Bruno Herbelin
8a7a6ed4f5 Improve group session (play, info) 2022-03-27 23:38:35 +02:00
Bruno Herbelin
c6097e0397 Bugfix and cleanup Group source insert
NB: default setAlpha now re-uses the source previous mixing coordinates (does not force default location)
2022-03-27 15:30:56 +02:00
Bruno Herbelin
0f3e856438 BugFix WorkspaceWindow clear on ESC and Transition view 2022-03-27 00:09:18 +01:00
Bruno Herbelin
5b6ec81cee Depth sort View all scene (background, workspace and foreground) 2022-03-26 15:08:47 +01:00
Bruno Herbelin
e888bfbc8d BugFix SessionFile source import 2022-03-26 15:02:28 +01:00
Bruno Herbelin
b04ab65258 Merge remote-tracking branch 'origin/master' 2022-03-24 23:55:04 +01:00
Bruno Herbelin
46b707f246 Unified & fixed implementation of Group of sources (formerly flatten)
Fixed MixingGroup keep&restore when making Session Group Sources. New global feature to Group all sources into one session source. Unused but potentially useful implementation of flatten of mixer session into one new session source.
2022-03-24 23:52:00 +01:00
Bruno Herbelin
f2a6073829 Unified & fixed implementation of Group of sources (formerly flatten)
Fixed MixingGroup keep&restore when making Session Group Sources. New global feature to Group all sources into one session source. Unused but potentially useful implementation of flatten of mixer session into one new session source.
2022-03-24 00:23:27 +01:00
Bruno Herbelin
e5926a5371 BugFix Load mixing groups for Session source and groups 2022-03-23 22:03:02 +01:00
Bruno Herbelin
86c4581a50 BugFix gstreamer HW decoding
Enforce low priority when disabling on launch.
2022-03-23 22:01:07 +01:00
Bruno Herbelin
a80074dc21 Mixer functions cleanup, new flatten 'Embed in new' session 2022-03-22 00:20:41 +01:00
Bruno Herbelin
3effdd1408 Spelling and fix README and doc 2022-03-22 00:19:53 +01:00
Bruno
b927c55216 Temporary fix for preventing horizontal scrolling in main pannel 2022-03-21 16:24:40 +01:00
Bruno
49c590a9b5 OSX compilation update 0.7.0 2022-03-21 16:19:52 +01:00
Bruno Herbelin
8df6a2dd83 Display more informative error message on XML load fail. 2022-03-20 12:06:32 +01:00
Bruno Herbelin
fe66c95a29 Load Settings even for different version.
Cleanup Settings implementation.
2022-03-20 12:06:09 +01:00
Bruno Herbelin
c080959f64 Avoid very-long-line-length-in-source-file warning for glad generated source code 2022-03-20 00:30:56 +01:00
Bruno Herbelin
f27a88787d Add linux manpage and update main accordingly 2022-03-19 21:24:42 +01:00
Bruno Herbelin
5853495125 IMGUI API change for Text display 2022-03-19 16:46:59 +01:00
Bruno Herbelin
f49d94948d Bugfix Duplicate input mapping 2022-03-19 14:58:27 +01:00
Bruno Herbelin
82dad0fad3 UI improvement, rescaling windows content with user font scale 2022-03-19 14:58:12 +01:00
Bruno Herbelin
fea99498af Show initials of source in combo selectors. 2022-03-19 01:27:14 +01:00
Bruno Herbelin
5582ee8ed8 Compilation warning fix 2022-03-18 21:46:22 +01:00
Bruno Herbelin
f4b6db9404 Remove uncessary font, find fonts in system if not available. 2022-03-18 21:46:08 +01:00
Bruno Herbelin
5c92362aae Fixing typos and spelling mistakes 2022-03-16 23:28:39 +01:00
Bruno Herbelin
667ea9fa64 Fix glfw dependency different version 2022-03-15 22:15:18 +01:00
Bruno Herbelin
b710750035 Merge remote-tracking branch 'origin/master' 2022-03-15 18:49:12 +01:00
Bruno Herbelin
491ff01c79 Optional library dependency CMake 2022-03-14 23:34:02 +01:00
Bruno Herbelin
4981145dd8 Fix version from git 2022-03-14 23:34:02 +01:00
Bruno Herbelin
e9497b03f4 Fix version from git 2022-03-14 23:31:50 +01:00
Bruno Herbelin
d76e518db1 Optional library dependency CMake 2022-03-14 22:52:50 +01:00
Bruno Herbelin
a2906c6aa5 Preparing 0.7 2022-03-14 01:10:45 +01:00
Bruno Herbelin
e0676c66a0 Metronome fix
do not call now() multiple times to avoid time difference between calls.
2022-03-13 23:13:32 +01:00
Bruno Herbelin
0b12c5a169 Bugfix and Help Input mapping.
Duplicate input mapping, drag'n drop, and various UI improvements.
2022-03-12 18:05:53 +01:00
Bruno Herbelin
39b61fe331 Reimplementation of SourceInputCallbacks into Session
Session should be the object holding the list of inputs parameters (e.g. synchrony) and the list of source callbacks. This also avoids mixing input when copying sources.  Code could be improved but is operational.
2022-03-07 00:23:24 +01:00
Bruno Herbelin
83e77681d9 Various BugFix and UI improvements
Prevent key repeat for commands, allow maintain ESC key, replaced timeline BPM display (innacurate and confusing) with a simplified icon indicator for Metronome synchronization of Media player, improved Media Player loop mode tooltip, improved Pattern source selector.
2022-02-26 22:35:27 +01:00
Bruno Herbelin
95a69937bd BugFix Mediaplayer loop and info mediaplayer 2022-02-26 22:32:37 +01:00
Bruno Herbelin
c355bd7569 Bugfix: update depth of sources from dropped media file
To be investigated further if problem persists: patch seems to work (increment twice View::need_deep_update_) but not fully sure why two frames are necessary...
2022-02-22 23:32:43 +01:00
Bruno Herbelin
559a186cd9 BugFix repeated toggle clear workspace 2022-02-22 22:43:58 +01:00
Bruno Herbelin
7e81ef37d7 Upper-case keyboard key info 2022-02-21 12:33:22 +01:00
Bruno Herbelin
2e167d260d New Geometry source callback
Set Geometry callback applies and interpolates position, scale and rotation of a source. Implemented UI and XML.
2022-02-21 12:32:48 +01:00
Bruno Herbelin
aa50d818ec Added directionality and speed selection in Input Callback
Unified implementation of constructor for SourceCallbacks. New icons and IconMultitouch for configuration GUI of input callback.
2022-02-20 21:03:39 +01:00
Bruno Herbelin
b9dd0a3877 Added icons in Output window menu bar
Unified appearance with other windows
2022-02-20 21:01:28 +01:00
Bruno Herbelin
e03ef7e214 BugFix Clone is playable if its origin is playable too 2022-02-19 12:42:42 +01:00
Bruno Herbelin
caa05d739f BugFix double clic output window 2022-02-19 03:24:25 +01:00
Bruno Herbelin
f580673dea Minor changes in SRT and generator sources to help user
Clearly state 'listener' and 'call' roles for SRT. Add a '>' indicator to indicate if a generator is playable.
2022-02-18 19:09:37 +01:00
Bruno Herbelin
297d271e63 Change direction Loom
more logical to set positive delta to increase visibility
2022-02-15 23:44:54 +01:00
Bruno Herbelin
a28e4be5a3 Bugfix play selection 2022-02-15 23:44:14 +01:00
Bruno Herbelin
6b672acdc7 Improved UI for Input Mapping 2022-02-14 23:40:26 +01:00
Bruno Herbelin
26f5368264 Implementation Control manager with singleton mechanism (not static) 2022-02-13 22:29:55 +01:00
Bruno Herbelin
fc5b967973 Imput Mapping support for Multitouch with TouchOSC
16 touch buttons in Multitouch tab of TouchOSC companion app for user customized callbacks.
2022-02-13 12:49:43 +01:00
Bruno
3cf497fa91 Change Multitouch TouchOSC
Akai MPC inspiration for 16 buttons with touch variability
2022-02-11 12:48:43 +01:00
Bruno Herbelin
f50411e9db Bugfix Callbacks
Added duration to SetAlpha callback. Saving and loading Play callback.
2022-02-11 00:28:25 +01:00
Bruno Herbelin
74eca2e527 Added UI actions to change key of source callbacks and copy-paste
Drag&drop input button keys to change key associated to a list of source callbacks (i.e. move). Copy Paste in context popup menu to remember the input model to copy at another input.
2022-02-10 00:24:38 +01:00
Bruno Herbelin
6200e78e93 Bugfix Guru plot 2022-02-07 23:51:43 +01:00
Bruno Herbelin
904c122ee0 Minor UI improvement Input Mapping 2022-02-07 23:34:45 +01:00
Bruno Herbelin
741afaea18 Improved Source Callback for multi-callbacks compatibility 2022-02-07 17:45:34 +01:00
Bruno Herbelin
6cf86d80e2 Input Mapping suport for Gamepad Axis (multiply SourceCallback)
Apply the ControlValue as a multiplyer to the Callback. UI with indication bars for gamepad axis.
2022-02-07 13:27:05 +01:00
Bruno Herbelin
886305ec13 Input Mapping support for Gamepad buttons
Cleanup UI defines.
2022-02-06 23:37:11 +01:00
Bruno Herbelin
ab040f5268 First working implementation of Inputs Mapping
Management of inputs in Control, Management of callbacks creator per input in Source, Saving and Loading in Session, Unified renaming of SourceCallbacks, User interface window for creating and editing input mapping from Keyboard and Numerical keypad, with appropriate Settings.
2022-02-06 00:36:05 +01:00
Bruno Herbelin
8404e0f670 Milestone in SourceCallbacks and Keyboard callback trigger
Updated SourceCallback class to accept cloning, reversing, and visitors for saving./loading. New mechanism in Source to listen to key triggers for launching SourceCallbacks. Saving and loading in SessionVisitor and SessionCreator.
2022-01-30 00:25:08 +01:00
Bruno Herbelin
3605ae14b5 Validate Port value in UI before changing 2022-01-28 18:44:32 +01:00
Bruno Herbelin
bce372bd79 Display Info of created source in Preview 2022-01-26 18:58:43 +01:00
Bruno
715c48b7eb Slight Font offset ajustment for FontAwesome glyphs 2022-01-25 13:11:23 +01:00
Bruno Herbelin
eb9a3c2ad1 Make Metrics semi-transparent when Workspace cleared 2022-01-24 23:53:53 +01:00
Bruno Herbelin
b261829aea BugFix interference output window rescale on Workspace UI windows 2022-01-24 23:53:27 +01:00
Bruno Herbelin
595be6b7b8 Change Shortcut for sources Restart to CTRL_SPACE
Updated Help UI accordingly, plus including SrtReceiverSource
2022-01-24 23:34:23 +01:00
Bruno Herbelin
9ed76ae4da Finalizing implementation of SrtReceiverSource
Added icons, unified UI, loading and saving in XML.
2022-01-24 23:06:47 +01:00
Bruno Herbelin
2ae0ef40d4 SrtReceiverSource for broadcasted stream
Implemented dedicated source, with UI for creation and saving appropriate settings.
Also updated info and imgui visitors accordingly
2022-01-24 20:18:33 +01:00
Bruno Herbelin
f5f7d3c154 Fixed nvidia hw encoding pipelines 2022-01-23 19:43:07 +01:00
Bruno Herbelin
a9ab4dbe38 More robust implementation of Video Broadcast
Testing GST features and using HW accelerated  encoding if available
2022-01-23 12:17:08 +01:00
Bruno Herbelin
5c3c26851c Implemented Broadcast
Initial implementation of SRT streaming as listener. Changed stream terminology to distinguish network broadcasting and network sharing in local network. Updated user settings accordingly.
2022-01-23 01:10:10 +01:00
Bruno Herbelin
2b3696aab1 Slight change in terminology to distinguish streaming from broadcasting
VideoStream is reserved for point-to-point video streaming (between vimix), while VideoBroadcast is for sending out to many potential clients.
2022-01-22 00:23:59 +01:00
Bruno Herbelin
35ec0c9bcf BugFix: prevent repeated initialization 2022-01-22 00:20:40 +01:00
Bruno Herbelin
4f915d6708 UI info procrastination 2022-01-20 23:27:43 +01:00
Bruno Herbelin
f4eb8b246b Minor improvements in InfoVisitor for source info 2022-01-20 22:46:47 +01:00
Bruno Herbelin
1a80e52241 Initiating implementation of VideoBroadcast 2022-01-20 22:46:24 +01:00
Bruno Herbelin
afa27a04fe BugFix: fail DeviceSource if not plugged 2022-01-20 18:01:07 +01:00
Bruno Herbelin
b82c83de5e BugFix DeviceSource: shared access to stream vis Device::manager
Creation of multiple DeviceSources is possible (also for multiple sessions and transitions) through centralized management of gst streams. Creation and deletion of a shared stream accross DeviceSources is handled.
2022-01-20 01:28:30 +01:00
Bruno Herbelin
625e2305ba Fix Quit call for Linux 2022-01-17 23:55:44 +01:00
Bruno
6b4781b7d5 BugFix Device manager initialization
Ensure initialization is complete before other calls to Device::manager can operate (e.g. setDevice in session Creator)
2022-01-17 23:47:07 +01:00
Bruno
7acffabdd8 restore commented line 2022-01-17 20:23:50 +01:00
Bruno
e6f2aa2399 Merge remote-tracking branch 'origin/master' 2022-01-17 20:21:04 +01:00
Bruno
ece7e04c7c BugFix: correctly wait for Mixer to save file on exit
On the way, also improved Connection Manager ending properly.
2022-01-17 20:20:44 +01:00
Bruno
0b4d273e08 BugFix: correctly wait for Mixer to save file on exit
On the way, also improved Connection Manager ending properly.
2022-01-17 19:45:58 +01:00
Bruno Herbelin
81e8d6d99c Refactoring Session saving
use Session::save static method to save a session from a thread (same mechanism as Session::load). It calls Action::takeSnapshot if saving version is required. Mixer is busy during saving, pops up info when done.
2022-01-17 00:38:48 +01:00
Bruno Herbelin
e96444671e BugFix: give time to Save on exit and stop recordings on Quit 2022-01-16 19:16:51 +01:00
Bruno Herbelin
e52785a8b4 Cleanup UI for source info, cleanup code 2022-01-16 17:47:43 +01:00
Bruno Herbelin
ddccc5ff6b Strengthen implementation of Clone and Render sources
Change of vocabulary, UI display of playtime
2022-01-16 15:27:22 +01:00
Bruno Herbelin
8bbcef585f Isolate implementation of RenderSource and new Non-Recursive mode
Separate files for RenderSource, make RenderSource playable, and implement two rendering mechanisms
2022-01-16 12:20:28 +01:00
Bruno Herbelin
e58041227b Added delay and image selection to CloneSource 2022-01-15 00:15:52 +01:00
Bruno Herbelin
3678e8fb27 Isolate implementation of CloneSource 2022-01-13 22:00:25 +01:00
Bruno Herbelin
1146a9125b Cleanup extension filename and bugfix session preview 2022-01-13 21:41:50 +01:00
Bruno Herbelin
aab0c055ed UI improvements
Make room for more icons in left bar if necessary. Also react to resizing of workspace for windows not visible.
2022-01-09 13:18:13 +01:00
Bruno Herbelin
685082e212 Improved UI main panel & control
bugfix; scrolling about and settings icons, clic outside buttonswitch. Updated default windows position.
2022-01-09 00:01:06 +01:00
Bruno Herbelin
1bb8b636b9 Bugfix pop font 2022-01-08 15:04:31 +01:00
Bruno Herbelin
43c51c3b82 Navigator lower-left corner icons for Fullscreen and Workspace mode
Added icons to toggle fullscreen & show/hide windows. Using View names instead of hardcoded string. Cleanup some UI variables.
2022-01-08 15:04:21 +01:00
Bruno Herbelin
b9ed64fba2 Make sure the name of the view is set correclty
even if there was a setting found
2022-01-08 15:01:12 +01:00
Bruno Herbelin
ceaac03adf Log Window - Display last log line in title when collapsed 2022-01-08 10:57:12 +01:00
Bruno Herbelin
3085a837c8 Nicer rendering of workspace windows with transparency 2022-01-08 01:05:10 +01:00
Bruno Herbelin
2e5e2c8430 On Save-as, open FileDialog in same directory of previous filename 2022-01-08 00:49:20 +01:00
Bruno Herbelin
48df5c0eb1 Cleanup UI - Filters menu, Save-as property
Cleanup code in ImGuiToolkit::IconButton
2022-01-08 00:35:02 +01:00
Bruno Herbelin
fcad6766c3 Update UI update and TransitionView to match WorkspaceWindows clear
Enter Workspace Clear mode when switching to Transition view (instead of specific hack). Do not render all windows when in Clear workspace mode.
2022-01-07 20:08:32 +01:00
Bruno Herbelin
c91a4670de Added Link status next to source preview in left pannel
Give quick access to select the linked group.
2022-01-07 18:31:25 +01:00
Bruno Herbelin
5e7c325874 BugFix: double-clic selection of mixing group crash
Improved CTRL+Clic for mixing group selection instead.
2022-01-07 17:57:16 +01:00
Bruno Herbelin
6b8a1428d7 Disabled Debug log Framebuffer 2022-01-07 17:56:26 +01:00
Bruno Herbelin
5bd81db37e Bugfix DeviceSource
API changed v4l2.
2022-01-07 16:10:58 +01:00
Bruno Herbelin
9834baedfa Passing main argument to open session 2022-01-07 11:10:28 +01:00
Bruno Herbelin
0b4c42859d Last minute entries into Help toolbox 2022-01-07 01:56:35 +01:00
Bruno Herbelin
a92b45ae26 Select Linked MixingGroup on double clic & a bug fix 2022-01-06 22:04:05 +01:00
Bruno Herbelin
1e2096e691 Bugfix restore Session Recent combo on start 2022-01-06 21:46:41 +01:00
Bruno Herbelin
3df6ffe280 Major BugFix: avoid default gst g_main_context
Do NOT update g_main_context at RenderingManager update. Do not use g_main_context for Dialogs. Do not rely on default g_main_context for Device discoverer (implemented a thread save g_main_loop dedicated).
2022-01-06 20:20:30 +01:00
Bruno Herbelin
d4f370c071 UI WorkspaceWindows follow window resize
Fixed bug in restore window position.
2022-01-06 14:58:35 +01:00
Bruno Herbelin
b894ea866a Make Timer a workspace window 2022-01-06 09:13:50 +01:00
Bruno Herbelin
3a300a4ca3 New UI windows behavior to clear workspace on ESC
Press ESC to toggle a 'clear workspace' mode. 
Cleanup of UserInterface rendering of output preview to enable this.
Move include to internal_imgui.h outside of ImGuiToolkit.h.
2022-01-06 01:21:18 +01:00
Bruno Herbelin
0ad844d10e Do not show source panel after source creation 2022-01-05 15:48:36 +01:00
Bruno
d310a45f72 Updated CMake comment to new tinyfiledialog git 2022-01-05 15:38:24 +01:00
Bruno
57c31804b4 Cleanup UI dialog save on exit
Also set save-on-exit by default
2022-01-05 15:37:47 +01:00
Bruno Herbelin
5fb70a9b9a Save on exit; test before closing
Detect window close or quit events to make sure a filename is given if save-on-exit is active.
2022-01-05 15:08:52 +01:00
Bruno Herbelin
d402143989 Cleanup icons and minor bugfix UI 2022-01-05 01:02:44 +01:00
Bruno Herbelin
ad8d799cf6 BugFix Session group 2022-01-04 22:13:41 +01:00
Bruno
cec705264d Replaced Tinyfiledialog repo
Updated code is at https://git.code.sf.net/p/tinyfiledialogs/code
2022-01-04 18:16:12 +01:00
Bruno
28a2e61361 Removed submodule ext/tfd 2022-01-04 18:04:32 +01:00
Bruno
6017215ada Get Tinyfiledialog from its original author 2022-01-04 17:48:14 +01:00
Bruno
8f3128e4b3 Merge remote-tracking branch 'origin/master' 2022-01-04 14:38:04 +01:00
Bruno Herbelin
109e6f590a Disabling vtenc streaming for OSX (could not make it work) 2022-01-04 14:37:56 +01:00
Bruno
ac86d75e10 Merge remote-tracking branch 'origin/master' 2022-01-04 12:33:59 +01:00
Bruno Herbelin
8f0491ea57 Video Streamer with H264 hardware acceleration
Simplified option in user menu; lower bandwidth with H264, otherwise use JPEG. Always use RAW for localhost.
2022-01-04 12:33:46 +01:00
Bruno
6403e51ba7 Merge remote-tracking branch 'origin/master' 2022-01-04 10:02:05 +01:00
Bruno Herbelin
e0522608a4 UI improvement; hovering icons indicate possible action
Source filters icons without button. Unified lock icon with view. Updated help.
2022-01-04 00:54:12 +01:00
Bruno Herbelin
4b9a230803 oops 2022-01-03 22:16:55 +01:00
Bruno Herbelin
fc5246efaa New & improved align and distribute in MixingView 2022-01-03 18:20:02 +01:00
Bruno Herbelin
4eebfbb89f Improved Glyph layout
Support for shape and placement of glyph
2022-01-03 17:16:55 +01:00
Bruno Herbelin
353d2c4744 New Glyph decoration to show initials of source 2022-01-03 15:41:08 +01:00
Bruno Herbelin
2718e83132 Happy new year 2022 2022-01-02 23:17:22 +01:00
Bruno Herbelin
7547d1179d Cleanup UI
Ensure icons are dedicated to one single thing.
2022-01-02 19:54:48 +01:00
Bruno Herbelin
61e89286bc Fixed Device manager: restore gmainloop
The gmainloop is used by gst to detect devices. Fixed bugs on detection of invalid devices.
2022-01-02 14:17:10 +01:00
Bruno Herbelin
53ae715816 Restart the source after insertion from New Source panel 2022-01-02 11:49:02 +01:00
Bruno Herbelin
8cb37dba36 ORDER change: add sources at the end when create
Inserting sources at front was changing their index every time, which broke OSC addressing
2022-01-02 11:41:47 +01:00
Bruno Herbelin
4426f70de7 Code editor for Custom pattern gstreamer
Bugfix in Streamsource and UI
2022-01-01 23:59:30 +01:00
Bruno Herbelin
f0ca13150f New Custom pattern entry for New Source 2022-01-01 10:14:51 +01:00
Bruno Herbelin
780a20689c Improved user message for stream discovery failure 2022-01-01 10:13:46 +01:00
Bruno Herbelin
28f9ed1d8d Cleanup & new unwrapped function 2022-01-01 10:12:50 +01:00
Bruno Herbelin
2b5b8ad02c Bugfix Stream timeout initialization test 2021-12-31 14:24:51 +01:00
Bruno Herbelin
d5092b1765 Save & load GenericStrreamSource 2021-12-31 13:30:51 +01:00
Bruno Herbelin
fda62314f9 UI integration of GenericStreamSource 2021-12-31 13:16:39 +01:00
Bruno Herbelin
17018c137f MultiLine text display 2021-12-31 13:16:16 +01:00
Bruno Herbelin
8838c19c39 String functions to wrap test or join lists 2021-12-31 13:16:00 +01:00
Bruno Herbelin
f02a99a4e2 Improved GenericStreamSource, with stream discoverer
Also timeout to fail if open does not works + new GST icon.
2021-12-31 13:15:23 +01:00
Bruno Herbelin
7b26b0f23e Unified IMGUI_SAME_LINE width 2021-12-31 13:13:29 +01:00
Bruno Herbelin
0e9984827a Cleanup gst_element_get_state 2021-12-31 13:12:12 +01:00
Bruno Herbelin
033d41863a Added Stream Discoverer to detect frame size from a gstreamer pipeline
Previous use of Stream are not affected (the discoverer is passively returning the given width and height). But if the Stream is created without dimensions, it will run a discoverer to try to get preroll frames and detect width and height from there.
2021-12-30 00:15:43 +01:00
Bruno Herbelin
bc540044ac Accept launch of vimix if OSC connection failed 2021-12-29 14:41:27 +01:00
Bruno Herbelin
76a2535da3 Fixed issue of low quality stream in JPEG: new default to RGB RAW RTP stream
Backward compatibility through menu un stream output view (allow selecting JPEG)
2021-12-29 14:37:56 +01:00
Bruno Herbelin
ff48877d16 Fixed OSC feedback after source change. Added OSC command to lock source. 2021-12-27 23:36:28 +01:00
Bruno Herbelin
4b8efabc5f Improve and cleanup OSC control and translation
Changed default send Port to 7001. Updated documentation.
2021-12-27 17:28:11 +01:00
Bruno Herbelin
c79be090df Implementation of OSC settings and translator
Translations are in a config xml file in settings directory, and can be directly edited in text by the user. Settings UI allows changing Ports for incoming and outgoing UDP.
2021-12-27 01:04:49 +01:00
Bruno Herbelin
626eab7e8f Update and advertising of TouchOSC layout 2021-12-27 01:02:43 +01:00
Bruno Herbelin
c103b7d883 Finalization of OSC API, Tutorial for TouchOSC 2021-12-26 14:44:07 +01:00
Bruno Herbelin
cde055e29b Implementation of Session control
With Session recall from OSC
2021-12-26 01:20:44 +01:00
Bruno Herbelin
1cb448c42e Output session fading fixed for OSC and animation.
Linear interpolation (instead of dichotomy converge) for fading at Session update. Mixing View update reads value of session fading to animate the cursor (which was preventing other manipulation of fading). Cleanup fading in OSC controller, with animation options and fade-in and fade-out controls.
2021-12-26 00:41:02 +01:00
Bruno Herbelin
3d05444f30 Improved OSC control with TouchOSC
Added Looming source callback, and cleanup sync of sources. New horizontal version of OSCTouch UI.
2021-12-25 16:05:43 +01:00
Bruno Herbelin
7a551189d9 Improved log of OSC message. 2021-12-25 00:41:51 +01:00
Bruno Herbelin
b885e70fed Remove spaces from Source name
Replace space by underscore
2021-12-25 00:41:24 +01:00
Bruno Herbelin
0a27c14041 Control manager and TouchOSC sync 2021-12-23 22:17:05 +01:00
Bruno Herbelin
eb8e33e311 Correct call to Source Activation (inheritance) 2021-12-23 22:16:16 +01:00
Bruno Herbelin
2d44a60b90 Bi-directional OSC communication for Control manager
Unified OSC message declaration with Communicator
2021-12-21 23:48:20 +01:00
Bruno Herbelin
135b6a5702 cleanup SourceCallbacks on source destructor 2021-12-21 00:19:55 +01:00
Bruno Herbelin
706c72fda8 More OSC control
Grab and resize dynamically, select source by index, etc.
2021-12-21 00:19:39 +01:00
Bruno Herbelin
fb7bdba388 Code cleanup 2021-12-20 00:30:59 +01:00
Bruno Herbelin
733d08638d Control manager thread save with SourceCallbacks 2021-12-20 00:30:50 +01:00
Bruno Herbelin
cb3cca8a64 catchup previous commits 2021-12-20 00:29:57 +01:00
Bruno Herbelin
a3a581794e Node update callbacks do not need to be disabled 2021-12-20 00:26:08 +01:00
Bruno Herbelin
f921e7610c New mechanism for source update with callbacks
Similarly to Node update callbacks, sources now have SourceCallbacks called at the start of each update. Several SourceCallback are implemented to ensure thread safe update of more complex properties (mixing alpha, depth, etc.).
2021-12-20 00:25:42 +01:00
Bruno Herbelin
8deb364025 Cleanup of main update calbacks
Clarify update and draw of rendering manager by using callbacks (instead of hidden calls in draw method).
2021-12-19 01:12:25 +01:00
Bruno Herbelin
3a9c6f56bf Work in progress OSC Control manager
Support for log, output and source targets. Now needs to be developed for all attributes.
2021-12-19 01:11:29 +01:00
Bruno Herbelin
a612154123 Initial implementation of Control manager
Control manager will handle control actions, recorded or from OSC. Here skeleton for receiving OSC messages is in place. Cleanup of includes for NetworkToolkit. Touched a bit the BaseToolkit.
2021-12-18 16:02:37 +01:00
Bruno Herbelin
bbc5e50491 bugfix show Player when clic source 2021-12-18 10:18:36 +01:00
Bruno
6e3dd8165e Merge remote-tracking branch 'origin/master' 2021-12-13 09:37:13 +01:00
Bruno Herbelin
a7689a8f54 Help window, setting to show/hide Tooltips
Menu and keyboard shortcut declaration centralized. List of all keyboard shortcuts. ImGuiToolkit unified tooltips.
2021-12-12 23:12:56 +01:00
Bruno Herbelin
731a1af1a6 Defines for ImGuiToolkit icons for source. 2021-12-12 23:10:07 +01:00
Bruno Herbelin
f53ebd4389 BugFix crash on close Player window 2021-12-11 21:35:23 +01:00
Bruno
a2d61cc30a Merge remote-tracking branch 'origin/master' 2021-12-09 12:36:21 +01:00
Bruno Herbelin
baa6ddb401 Implementation of user defined mixing deactivation limit
Mixing view handles to grab and scale limbo area. Saving of user defined limit in Session (and snapshot). Testing for source activation outside of update during session update loop.
2021-12-08 23:55:27 +01:00
Bruno
4455aa6709 Merge remote-tracking branch 'origin/master' 2021-12-06 14:04:06 +01:00
Bruno Herbelin
315a8534d5 Store output PNG capture in list of recent recordings 2021-12-06 12:35:09 +01:00
Bruno Herbelin
d77bd4034d Improved UI tooltips 2021-12-06 12:29:22 +01:00
Bruno Herbelin
fa71797ed2 Unified implementation saving and loading settings history files 2021-12-06 11:41:03 +01:00
Bruno Herbelin
8c63552573 Global settings for Save and continue auto-preload
Added configuration for recent recording list. Added tooltip for filename in list.
2021-12-06 11:16:47 +01:00
Bruno Herbelin
a18d53c637 Improved Save and continue recording
When triggered from menu, prepare the UI for next openning of the new source pannel
2021-12-06 00:16:53 +01:00
Bruno Herbelin
ffe05368e8 Update New Source panel for Media
Added list of recent files, recent recordings, and folders list of media files. All saved in settings. Connect list of recent recordings with recorder.
2021-12-05 18:41:58 +01:00
Bruno Herbelin
923d84f378 Unified SystemToolkit list directory with dialog file patterns 2021-12-05 18:39:58 +01:00
Bruno Herbelin
e5334aae0a Cleaner file patterns for dialogs 2021-12-05 18:33:53 +01:00
Bruno Herbelin
4675be7e2a Unified notification of source creation with Source info
New virtual function source::info used for notification after adding source
2021-12-05 18:32:23 +01:00
Bruno Herbelin
bf3fc61ef7 Bad idea: do not use nvidia hardware decoder for jpeg
just crashes without reason and not very useful
2021-12-04 23:05:12 +01:00
Bruno Herbelin
ebd9fab312 Improved ordering of hardware decoding and log info 2021-12-04 00:23:27 +01:00
Bruno Herbelin
d359cf33d1 Improved runtime check of hardware encoder
gstreamer toolkit has_feature now tests possible instanciation
2021-12-03 23:36:07 +01:00
Bruno Herbelin
14bab1e299 Runtime selection of hardware GPU encoder
temporary implementation
2021-12-03 01:05:32 +01:00
Bruno Herbelin
4c4ad144b9 Finish Frame grabber after return on failed initialization 2021-12-03 01:05:04 +01:00
Bruno Herbelin
1157c0b1c5 cleanup frame grabber gst timer 2021-12-03 01:03:21 +01:00
Bruno Herbelin
68b2c5e0c1 Frame grabber threaded initialization
Start gstreamer init of frame grabber in a thread and wait future return from initializer before switching to active recording mode.
2021-12-02 11:45:22 +01:00
Bruno Herbelin
b97fd06f2a Bugfix Resolution frame buffer
Set width to power of 2, needed for encoding (even if OpenGL accepts to display it)
2021-12-02 11:40:31 +01:00
Bruno Herbelin
51f0f5bd66 Fixed ending of recording on exit 2021-12-02 09:35:02 +01:00
Bruno Herbelin
66f445997d Preliminary implementation of recording 'save & continue' 2021-12-01 23:05:41 +01:00
Bruno
addd199407 Merge remote-tracking branch 'origin/master' 2021-11-29 11:16:22 +01:00
Bruno Herbelin
73d4f7c1ea Ensure swap interval 2021-11-28 23:58:01 +01:00
Bruno Herbelin
25fc5562db Unified layout of HelpMarkers 2021-11-28 23:57:33 +01:00
Bruno Herbelin
4d52bcb5b3 Fix glfw set window pos 2021-11-28 20:50:56 +01:00
Bruno Herbelin
3d2de560b0 Timelines of metro-synched media player 2021-11-28 11:36:56 +01:00
Bruno Herbelin
809e30d906 Timeline display in beat unit for synched to metronome 2021-11-27 19:26:33 +01:00
Bruno Herbelin
ef9e41f20d Fixed display of time in minimal string mode 2021-11-27 19:23:51 +01:00
Bruno Herbelin
1b4849f214 Media player synchronicity to beat or phase
Metronome synched play, rewind and step. saving in xml.
2021-11-26 12:22:39 +01:00
Bruno
26cc67cd41 Merge remote-tracking branch 'origin/master' 2021-11-25 09:56:24 +01:00
Bruno Herbelin
e123d139e4 Introducing modes of Metronome synchronicity 2021-11-24 21:48:51 +01:00
Bruno Herbelin
a8abd52afb Merge remote-tracking branch 'origin/add-code-of-conduct-1' 2021-11-24 20:32:49 +01:00
Bruno Herbelin
091e99f21b New export function for Version of a session 2021-11-24 20:32:29 +01:00
Bruno
7b7875e23f Merge remote-tracking branch 'origin/add-code-of-conduct-1' 2021-11-24 10:41:55 +01:00
Bruno Herbelin
b6593c2a83 Added date to snapshot
Allows showing date of version
2021-11-24 00:15:40 +01:00
Bruno Herbelin
5ac7887360 Convert Snapshots into Versions of session
Added auto-snapshot on save to have an Iterative Saving mode, and change terminology of 'snapshots' to 'versions' management.
2021-11-23 22:47:44 +01:00
Bruno Herbelin
ed7627af6f Fixed UI spacing proportional to screen DPI 2021-11-23 22:46:22 +01:00
BHBN
1ea9fc54b2 Create CODE_OF_CONDUCT.md 2021-11-22 00:22:18 +01:00
Bruno Herbelin
3819571ec0 Fixed UI display time in readable form 2021-11-21 22:39:11 +01:00
Bruno Herbelin
94f131fc57 Fixed panel window show/hide 2021-11-21 22:10:17 +01:00
Bruno Herbelin
3c20314aab Metronome and Stopwatch User Interface
New Timer window in UI for Metronome (Ableton Link management) and replaces Timers. Former Timers in Metrics are replaced with Runtime (of session, of program and of total vimix runtime in settings). Temporarily disconnected Metronome from MediaPlayer actions.
2021-11-21 16:54:56 +01:00
Bruno Herbelin
1506d36407 Readable GST time is at 1/10th second precision 2021-11-21 16:52:09 +01:00
Bruno Herbelin
aa4b2967c7 Adding a timestamp to Session instanciation
Used to compute runtime of a session
2021-11-21 16:51:19 +01:00
Bruno Herbelin
a42881d31f Texture view slider UI fix 2021-11-21 16:46:18 +01:00
Bruno Herbelin
6a3ff2f235 More freedom of grab translation for all views 2021-11-17 23:11:15 +01:00
Bruno Herbelin
fc4e3dc362 Metronome settings and UI improvements 2021-11-14 00:18:32 +01:00
Bruno Herbelin
d6c689c5bb Cleanup include ImGuiToolkit 2021-11-14 00:18:10 +01:00
Bruno Herbelin
8676e9b900 Integration of Ableton link in vimix application
No useful functionality yet. Only connecting, set parameters, show metrics and save settings.
2021-11-13 15:01:02 +01:00
Bruno Herbelin
c271cad9aa Cleanup headers and dependencies 2021-11-13 00:14:05 +01:00
Bruno Herbelin
8e3bf786c0 Initial implementation of Metronome from Ableton LINK
Added submodule for github ableton link, and compiled draft of Metronome class.
2021-11-13 00:13:50 +01:00
Bruno Herbelin
a6ba694fbd Code warning cleanup and add GPL license header to all CPP files 2021-11-10 23:19:38 +01:00
Bruno
790ccc320e OSX bundle install of Frei0r plugins 2021-11-10 21:16:16 +01:00
Bruno Herbelin
26e951e59b Update website screenshot 2021-11-10 11:02:05 +01:00
Bruno Herbelin
a97581f5d7 semi-transparent icon of lock to inform its not interactive
need to CTRL+clic to unlock, as opposed to other handles: this is not perfect but shows the difference
2021-11-10 00:13:57 +01:00
Bruno Herbelin
5bf280ca4d warning on not found pattern 2021-11-10 00:13:08 +01:00
Bruno Herbelin
fe00baa701 Fixed snap to find frei0r plugins
added the package to install and the PATH to find in $SNAP
2021-11-10 00:12:55 +01:00
Bruno Herbelin
d3cb1d7f42 oops 2021-11-08 00:08:19 +01:00
Bruno Herbelin
593363732a Pattern generator improvement
Testing gstreamer feature to provide only available patterns, and added many more patterns to choose from.
2021-11-08 00:05:16 +01:00
Bruno Herbelin
d00f4cf715 Cosmetics
More adapted icons and link to user manual
2021-11-07 12:25:51 +01:00
Bruno Herbelin
cac31dbb21 Help info for mask file open 2021-11-07 12:25:06 +01:00
Bruno Herbelin
eb1fa6ca04 clean file dialog after cancel 2021-11-07 12:24:46 +01:00
Bruno Herbelin
0ac515ea5a Yet more update graphical manual 2021-11-07 01:42:39 +01:00
Bruno Herbelin
190e2a4952 Continue update graphical manual 2021-11-06 22:50:59 +01:00
Bruno Herbelin
0857b1bab6 Update graphical user manual
New screenshots from vimix 6.1
2021-11-06 18:08:52 +01:00
Bruno Herbelin
f3e42fdc95 Bugfix window resize log window 2021-10-31 00:06:08 +02:00
Bruno Herbelin
d617f3308a Added Cancel button to Transition view
And minor code improvements.
2021-10-30 19:57:43 +02:00
Bruno Herbelin
27cec85443 Do not re-open previous session if new session last created 2021-10-26 23:50:26 +02:00
Bruno Herbelin
63f7cab508 Improved gstreamer support for GPU decoding in Linux 2021-10-26 23:38:41 +02:00
Bruno Herbelin
ce0ac1bee1 Minor improvement precision media player gap timing 2021-10-12 23:20:16 +02:00
Bruno Herbelin
2c2584c8df Keyboard shortcut END for Disable output 2021-10-11 23:17:29 +02:00
Bruno Herbelin
14fd4d96c3 Shortcut for output window fullscreen and raise 2021-10-11 22:46:38 +02:00
Bruno Herbelin
dd7a63413c Fixed keyboard arrows control 2021-10-09 23:40:18 +02:00
Bruno Herbelin
6d0c2301c1 Keyboard input for Source Controller
SPACE toggle play/pause, B for begin restart
2021-10-09 00:16:55 +02:00
Bruno Herbelin
8bf8f05add compilation warnings 2021-09-24 00:46:20 +02:00
Bruno Herbelin
bd773d54c6 Improve stability FPS measure in timecounter 2021-09-24 00:45:47 +02:00
Bruno Herbelin
f4c52b7ed3 Fixed output monitor disablling 2021-09-19 11:07:13 +02:00
Bruno Herbelin
5b1504c8f6 Added general DISABLE output action menu
Makes sure the output is black, unrelated to session openning or opacity
2021-09-17 11:31:52 +02:00
Bruno
06187b9a1a work-in progress Helper and keyboard shortcuts 2021-08-26 15:51:07 +02:00
Bruno
7fb6e57829 Added 1200px height selection (e.g. for WUXGA displays) 2021-08-20 21:32:12 +02:00
Bruno
5ec954dbb5 UI fix 2021-08-16 22:55:21 +02:00
Bruno
a6bc30cf62 Fixed Frame grabber 2021-08-16 22:26:59 +02:00
Bruno
df165252fa Fixed OSX vtenc_h264_hw support for Recording 2021-08-16 15:52:58 +02:00
Bruno
da9c94f675 Temporarily disable v4l loopback: not working anymore 2021-08-15 00:32:20 +02:00
Bruno
031cef6357 optimize jpegenc 2021-08-15 00:30:28 +02:00
Bruno
ef5f3efd2e BugFix changing resolution of session 2021-08-14 23:15:18 +02:00
Bruno
bc8c4e3c7b Cleanup UI for centralized Recording settings 2021-08-14 21:57:59 +02:00
Bruno
f5da4c8bc2 Recording: support for NVIDIA nvenc and improved stability
Let gstreamer appsrc generate PTS automatically (seems to fix crash of encoding after long duration). Added test for GPU encoders and switch if enabled and available.
2021-08-14 13:41:53 +02:00
Bruno
644741a1ab Attempt at improving recoding when buffer if full 2021-08-12 00:05:41 +02:00
Bruno
09f46e7a27 Minor GUI layout improvement 2021-08-12 00:05:22 +02:00
Bruno
db4e1d214f BugFix drop Session file 2021-08-11 22:18:08 +02:00
Bruno
79433dd45c Improved Log message Video recording 2021-08-11 22:17:43 +02:00
Bruno
fe72c9b829 Cleanup and improve stability of FrameGrabber 2021-08-11 20:48:18 +02:00
Bruno
b37d22ba47 Improved FrameGrabber with clock duration and priority strategies
Keep track of actual FrameGrabber duration (different from timestamp). Two strategies for frame PTS: clock and framerate priorities. Implemented variable Framerate selection for VideoRecorder.  Integration of all this in UserInterface and Settings.
2021-08-11 00:20:28 +02:00
Bruno
7fb08e618f Added a READABLE time string conversion 2021-08-11 00:17:07 +02:00
Bruno
63c6f1169b Add icons on info and warning Logs 2021-08-11 00:16:19 +02:00
Bruno
0eff8fd24d Minor compilation warning fixed 2021-08-09 10:08:32 +02:00
Bruno
818e554d35 removing debuging info 2021-08-08 23:58:54 +02:00
Bruno
5a18dbaf37 Video Recoding Buffer management
Implemented methods to supervise encoding in FrameGrabber, avoid running out of buffer, and give user a selection of buffer sizes for recording.
2021-08-08 23:58:35 +02:00
Bruno
ddd9bb4e99 minor compilation fix 2021-08-07 20:26:59 +02:00
Bruno
38a2aa90e0 Improved FrameBufferSuface API 2021-08-07 20:26:30 +02:00
Bruno
139137770c BugFix: prevent missing symbol when attach 2021-08-07 20:25:52 +02:00
Bruno
789bf1bd00 BugFix prevent failed FrameBuffer fill 2021-08-07 20:23:20 +02:00
Bruno
563e762dde Store mask after fill 2021-08-07 20:22:07 +02:00
Bruno
28da5f8f39 BugFix Restore fading when cross fading 2021-08-07 20:21:37 +02:00
Bruno
5c42061fd9 Work in progress - towards display initials on sources 2021-08-07 20:21:37 +02:00
Bruno
843224ca35 oops.. correct Mesh file parse 2021-08-07 14:14:16 +02:00
Bruno
e47e76962b Fixed Recording (timing and UI)
Improved frame grabber timing and fixed UserInterface to show the "saving file" info.
2021-08-07 12:34:05 +02:00
Bruno
2f0e4e3212 Improved recording time acuracy 2021-08-07 01:02:39 +02:00
Bruno
fb3e1d0d25 Detecting EOF recording and unexpected termination 2021-08-06 21:23:01 +02:00
Bruno
e9b7e55570 work in progress recording probe 2021-08-06 17:56:48 +02:00
Bruno
8c206898f0 Dialog media include more formats
Integrate exotic file extensions and uppercase equivalent of all possible files to select with dialogs. 
Code cleanup
2021-08-06 16:43:25 +02:00
Bruno
a9c9683b8b longer recording timeout 2021-08-06 13:26:19 +02:00
Bruno
4f43ddf088 Draw a glyph in IMGUI
Proof of concept to show how to access Font texture in opengl to draw one glygh
2021-08-06 13:25:19 +02:00
Bruno
a9c8b67975 Implementation of custom Masks
FrameBuffer accepts to fill any size of FrameBufferImage as input, and a Dialog in TextureView allows to select a JPG or PNG.
2021-08-06 13:23:59 +02:00
Bruno
d1b7073ff9 Reimplementation of Dialogs
Cleanup code to integrate multithreading process for dialogs into the DialogToolkit (avoid poluting UserInterfaceManager and improves reliability)
2021-08-06 13:21:16 +02:00
Bruno
58afcacab9 BugFix thumbnailing
1. avoid crash by cathing the correct exception and 2. ensure we capture a frame by waiting a little
2021-08-04 12:55:51 +02:00
Bruno
5eddfcf196 Add tag icon in thumbnail to identify as user defined 2021-08-04 00:29:31 +02:00
Bruno
9a87764949 Improved UI for inactive videos
Display Player for videos even in disabled state, but with disabled controls
2021-08-03 20:02:04 +02:00
Bruno
fc4e40fba3 Display mixing source original texture when inactive
Re-using activesurface_ for manipulation and display of the source's input texture in the Mixer icon when inactive.
2021-08-02 22:27:06 +02:00
Bruno
e8acfc1c26 New Media Player option to Rewind on Disabled 2021-08-01 19:10:46 +02:00
Bruno
eaadc210ae Performance improvement for transliteration
Tracing CPU usage identified the cost of ICU transliteration: using a static dictionnary to improve performance
2021-08-01 16:44:46 +02:00
Bruno
8002f3164c Confirmed performance improvement without glBufferSubData 2021-08-01 16:43:25 +02:00
Bruno
48f92bc52b Cleanup session properties panel 2021-08-01 12:13:38 +02:00
Bruno
d1e833e0a1 Properties pannel of Session
Also added custom thumbnail of session.
2021-08-01 00:29:44 +02:00
Bruno
c5f0be2b32 Compilation Linux 2021-07-30 21:36:47 +02:00
Bruno
dbcf3bb0ea backward compatibility title window 2021-07-30 16:48:26 +02:00
Bruno
e7a79f6cdc Cleanup path_relative_to_path and path_absolute_from_path 2021-07-30 16:08:24 +02:00
Bruno
63b043dc4b Improved windows titles management
Display filename (no path) before APP_NAME, clean APP_TITLE when no file, bugs fixed.
2021-07-30 16:08:00 +02:00
Bruno
d2a576c99c Support for relative path for files in mix
File path in mix session file add a relative reference to the location of the session mix file. If SessionCreator cannot find the absolute path, it tries to load the file at the relative location. Done for MediaSource, SessionFileSource and SequenceSource.
2021-07-30 00:22:44 +02:00
Bruno
fc91e7cbdd Draft Function path_relative_to_path 2021-07-28 19:03:38 +02:00
Bruno
0555361a57 BugFix glfw set Window Title
Function is not thread safe, causing crash when saving.
2021-07-27 20:05:39 +02:00
Bruno
c923815a01 Added Apple Code signing script in cmake 2021-07-27 20:05:01 +02:00
Bruno
7a4d2ac027 Merge remote-tracking branch 'origin/master' 2021-07-27 09:15:47 +02:00
Bruno
442e1096be Compilation and packaging OSX 10.14 2021-07-27 09:12:53 +02:00
Bruno
6eaf8852ae OSX compilation 2021-07-27 09:06:53 +02:00
Bruno
3612fca707 Add keyboard shortcut play/pause
Space bar to toggle play/pause current source, B  for 'beginning' and N for 'next frame'
2021-07-26 12:51:07 +02:00
Bruno
4736d403a1 bugfix save as 2021-07-26 12:21:06 +02:00
Bruno
a18fd3177c Follow clang-tidy and clazy suggestions
variables non-POD should not be 'static' outside a class. Always use and init variables. Delete useless classes.
2021-07-17 16:45:01 +02:00
Bruno
5930b0f8fe UI bugfix locked source in texture view 2021-07-17 11:55:23 +02:00
Bruno
1c7c64db59 Merge remote-tracking branch 'origin/master' 2021-07-17 10:33:53 +02:00
Bruno
9bc780bcda Update CMAKE for OSX
minor text message changes
2021-07-17 10:33:43 +02:00
Bruno
b3f89e0464 for OSX 2021-07-17 10:32:13 +02:00
Bruno
1de4822c67 OSX compile 2021-07-03 11:27:08 +02:00
Bruno
c846e4072a postponing the dev of snapshot interpolation 2021-07-03 10:19:00 +02:00
Bruno
c4f26bd500 added -v and -t command line options 2021-07-02 22:16:55 +02:00
Bruno
041c01135a Small improvement timing fade in and out
Adding a buffer of 0 opacity before or after fading to avoid jumps to previous or next frame of a segment
2021-06-28 23:43:44 +02:00
Bruno
aa904f26ad Recording timeout with timing slider
Changed timout recording in uint milisecond.
2021-06-28 21:33:17 +02:00
Bruno
ff99d37eb6 Player Video Fading dialog
New dialog to apply fade in & out with parameters. Fixed Timeline fading functions. New ImGuiToolkit items to draw icons in Combo boxes.
2021-06-28 00:21:29 +02:00
Bruno
e8a500dc99 BugFix negative play speed Selection 2021-06-24 23:15:50 +02:00
Bruno
9f4f247cd2 Bugfix jump gaps MediaPlayer 2
Timeline copy should not overwrite pts of first frame.
2021-06-23 20:34:00 +02:00
Bruno
e1ac930dd6 Pedantic tooltip 2021-06-21 23:15:17 +02:00
Bruno
c20ed94f46 Bugfix jump gaps MediaPlayer
now that we use first frame time, testing jumps should be done with beginning time
2021-06-21 23:14:43 +02:00
Bruno
4efe754a8d MediaPlayer decoder information improved 2021-06-20 23:54:19 +02:00
Bruno
bb83f7fcb7 Timeline fade in and fade out 2021-06-20 23:53:52 +02:00
Bruno
79fa6082b0 Player: shoft slider on first frame of MediaPlayer 2021-06-20 18:50:12 +02:00
Bruno
f2ecc88955 Clean string from infor visitor on media player 2021-06-20 18:49:39 +02:00
Bruno
7253c1ec1a Merge remote-tracking branch 'origin/master' 2021-06-19 09:49:53 +02:00
BHBN
cf32c9fc12 Merge pull request #39 from brunoherbelin/dev
Accept new Player (dev)
2021-06-19 09:49:11 +02:00
Bruno
3086735be1 Merge branch 'HEAD' 2021-06-19 01:04:11 +02:00
Bruno
5a54e84dd8 Player slight improvements
tick marks count adapted to fps, clamped refresh frequency computation, listing of all sources playable from menu
2021-06-19 01:03:21 +02:00
Bruno
1ef26c0c95 Warning on failed discovery of MediaPlayer framerate
Default to 30fps
2021-06-19 01:03:21 +02:00
Bruno
887142079b Fixed Timeline display 2021-06-19 01:03:21 +02:00
Bruno
b75ea00c0d Unique play/pause button for multiple sources 2021-06-19 01:03:21 +02:00
Bruno
319fbfa84d Bugfix display STRING time 2021-06-19 01:03:21 +02:00
Bruno
3874252797 Bugfix computation time with gaps 2021-06-19 01:03:21 +02:00
Bruno
5dfc45af5f Fixed Timeline ticks display 2021-06-19 01:03:21 +02:00
Bruno
1f203801db Player: reset selection on session change 2021-06-19 01:03:21 +02:00
Bruno
291410a2b3 Player UI: video menu and speed reset icon
+ rename private variables to follow usual style
2021-06-19 01:03:21 +02:00
Bruno
dfc4937688 Player: move up timeline and adjust size
keep play button bar at the bottom for all configurations, avoid text and buttons overlay when Player is small. Fix cut timing in selection
2021-06-19 01:03:21 +02:00
Bruno
a0b763ab71 Timeline management in Player
Actions at key times (durations of all videos) to allow to adjust other videos duration (change speed of cut)
2021-06-19 01:03:21 +02:00
Bruno
ad36ac5cd9 Player timeline for selection
Selection of media sources now displays in a list with proportional timelines, showing actual play time and cursor on effective timeline with opacity curve.
2021-06-19 01:03:21 +02:00
Bruno
cd40d6d7e8 Improved management of selection in Player 2021-06-19 01:03:21 +02:00
Bruno
ec4214ebf8 improved quality realtime recorder h264 2021-06-19 01:03:21 +02:00
Bruno
a403d40b6c Stick window on current view
menu item for media player and output preview to pin the window in current view
2021-06-19 01:03:21 +02:00
Bruno
7dcfc97f33 UI details 2021-06-19 01:03:21 +02:00
Bruno
5ea056a483 Bugfix timeline display array 2021-06-19 01:03:21 +02:00
Bruno
cd1702bb53 Define UNICODE symbols 2021-06-19 01:03:21 +02:00
Bruno
6ff266581a work in progress selection timeline 2021-06-19 01:03:21 +02:00
Bruno
6b7d108407 Minor improvements timeline display 2021-06-19 01:03:21 +02:00
Bruno
473e24bcd7 Fixed and improved TimeCounter 2021-06-19 01:03:21 +02:00
Bruno
1f5056bf15 BugFix IconButton (pop id) 2021-06-19 01:03:21 +02:00
Bruno
61fa062794 Correct implementation of DeviceSource resize
previous commit was bad...
2021-06-19 01:03:21 +02:00
Bruno
0e48cf4505 Bugfix and cleanup Info on source in UI 2021-06-19 01:03:21 +02:00
Bruno
b606f479e9 Bugfix change device source resolution 2021-06-19 01:03:21 +02:00
Bruno
2ccbf1ec12 Bugfix closing single frame stream 2021-06-19 01:03:21 +02:00
Bruno
ac6e84bb1c New InfoVisitor: get string to describe sources
Unified code in ImGui visitor and Player
2021-06-19 01:03:21 +02:00
Bruno
11d12c1f29 New Timeline actions
Smooth and auto cut actions added on the side of the timeline UI.
2021-06-19 01:03:21 +02:00
Bruno
c9707e7335 Improved link between ImGuiVisitor and SourcePlayer
Source panel shows description and icon to open player UI. Changed icon player, and fixed source selection.
2021-06-19 01:03:21 +02:00
Bruno
2c0be68a3c Cleaup UI Selection source Player 2021-06-19 01:03:21 +02:00
Bruno
2add317106 Improved UI media player (info media) 2021-06-19 01:03:21 +02:00
Bruno
60ec11982a OSX compilation 2021-06-19 01:03:21 +02:00
Bruno
b2284cf1b4 Improved cursor EditPlotHistoLines 2021-06-19 01:02:12 +02:00
Bruno
e87ef2774b New SourcePlayer
Work in progress; Sources now have play/pause and associated play functions. Media player can play all playable sources, and adapts to control a media player when possible. Selection of play groups (to finalize)
2021-06-19 01:02:12 +02:00
Bruno
7a9fcaefd6 Minor code improvements 2021-06-19 01:02:12 +02:00
Bruno
2333a7a11a Bugfix Do not lock session in action manager
This was causing mutex deadlock
2021-06-19 01:02:12 +02:00
Bruno
2a7857c499 Bugfix; verify frame grabbers before use 2021-06-19 01:02:12 +02:00
Bruno
e892dc1eb5 Implemented delayed start of recording 2021-06-19 01:02:12 +02:00
Bruno
9c8d1f31f6 bugfix linux shared webcam ui 2021-06-19 01:02:12 +02:00
Bruno
048db7a44b Merge remote-tracking branch 'origin/master' 2021-06-19 01:01:59 +02:00
Bruno
1d94d494b6 Merge remote-tracking branch 'origin/dev' into dev 2021-06-19 00:50:31 +02:00
Bruno
c6ac35addb Player slight improvements
tick marks count adapted to fps, clamped refresh frequency computation, listing of all sources playable from menu
2021-06-19 00:49:20 +02:00
Bruno
9ec279754b Warning on failed discovery of MediaPlayer framerate
Default to 30fps
2021-06-19 00:49:20 +02:00
Bruno
bdcf28c5da Fixed Timeline display 2021-06-19 00:49:20 +02:00
Bruno
edf0f8074a Unique play/pause button for multiple sources 2021-06-19 00:49:20 +02:00
Bruno
c83a946cbd Bugfix display STRING time 2021-06-19 00:49:20 +02:00
Bruno
8604babeb6 Bugfix computation time with gaps 2021-06-19 00:49:20 +02:00
Bruno
7252b74539 Fixed Timeline ticks display 2021-06-19 00:49:20 +02:00
Bruno
08fbaa039f Player: reset selection on session change 2021-06-19 00:49:20 +02:00
Bruno
30f9fb50eb Player UI: video menu and speed reset icon
+ rename private variables to follow usual style
2021-06-19 00:49:20 +02:00
Bruno
e3578df8a0 Player: move up timeline and adjust size
keep play button bar at the bottom for all configurations, avoid text and buttons overlay when Player is small. Fix cut timing in selection
2021-06-19 00:49:20 +02:00
Bruno
37445b8857 Timeline management in Player
Actions at key times (durations of all videos) to allow to adjust other videos duration (change speed of cut)
2021-06-19 00:49:20 +02:00
Bruno
99ea14fab0 Player timeline for selection
Selection of media sources now displays in a list with proportional timelines, showing actual play time and cursor on effective timeline with opacity curve.
2021-06-19 00:49:20 +02:00
Bruno
1717c143b2 Improved management of selection in Player 2021-06-19 00:49:20 +02:00
Bruno
53223d0876 improved quality realtime recorder h264 2021-06-19 00:49:20 +02:00
Bruno
096bcb4132 Stick window on current view
menu item for media player and output preview to pin the window in current view
2021-06-19 00:49:20 +02:00
Bruno
05cc70bdbd UI details 2021-06-19 00:49:20 +02:00
Bruno
45653b52b5 Bugfix timeline display array 2021-06-19 00:49:20 +02:00
Bruno
d1841f2863 Define UNICODE symbols 2021-06-19 00:49:20 +02:00
Bruno
f85de11711 work in progress selection timeline 2021-06-19 00:49:20 +02:00
Bruno
9d81a105ee Minor improvements timeline display 2021-06-19 00:49:20 +02:00
Bruno
deb6af9dea Fixed and improved TimeCounter 2021-06-19 00:49:20 +02:00
Bruno
ab512b76aa BugFix IconButton (pop id) 2021-06-19 00:49:20 +02:00
Bruno
bcbeee7247 Correct implementation of DeviceSource resize
previous commit was bad...
2021-06-19 00:49:20 +02:00
Bruno
bcdc94c3b9 Bugfix and cleanup Info on source in UI 2021-06-19 00:49:20 +02:00
Bruno
6ebcf49758 Bugfix change device source resolution 2021-06-19 00:49:20 +02:00
Bruno
a936ab6851 Bugfix closing single frame stream 2021-06-19 00:49:20 +02:00
Bruno
95378660dd New InfoVisitor: get string to describe sources
Unified code in ImGui visitor and Player
2021-06-19 00:49:20 +02:00
Bruno
e49bdac3e8 New Timeline actions
Smooth and auto cut actions added on the side of the timeline UI.
2021-06-19 00:49:20 +02:00
Bruno
48380fab7e Improved link between ImGuiVisitor and SourcePlayer
Source panel shows description and icon to open player UI. Changed icon player, and fixed source selection.
2021-06-19 00:49:20 +02:00
Bruno
ce92529a84 Cleaup UI Selection source Player 2021-06-19 00:49:20 +02:00
Bruno
8e29a555c8 Improved UI media player (info media) 2021-06-19 00:49:20 +02:00
Bruno
a1b6ec066b OSX compilation 2021-06-19 00:49:20 +02:00
Bruno
fb59bf491f Improved cursor EditPlotHistoLines 2021-06-19 00:48:11 +02:00
Bruno
86aec7d2ba New SourcePlayer
Work in progress; Sources now have play/pause and associated play functions. Media player can play all playable sources, and adapts to control a media player when possible. Selection of play groups (to finalize)
2021-06-19 00:48:11 +02:00
Bruno
579f7d5609 Minor code improvements 2021-06-19 00:48:11 +02:00
Bruno
c87b1ac363 Bugfix Do not lock session in action manager
This was causing mutex deadlock
2021-06-19 00:48:11 +02:00
Bruno
543648112b Bugfix; verify frame grabbers before use 2021-06-19 00:48:11 +02:00
Bruno
daa3b9e978 Implemented delayed start of recording 2021-06-19 00:48:11 +02:00
Bruno
fb8da181da bugfix linux shared webcam ui 2021-06-19 00:48:11 +02:00
Bruno
6cc5a8af9e Player slight improvements
tick marks count adapted to fps, clamped refresh frequency computation, listing of all sources playable from menu
2021-06-19 00:47:47 +02:00
Bruno
1a1956962a Warning on failed discovery of MediaPlayer framerate
Default to 30fps
2021-06-18 23:58:23 +02:00
Bruno
e422a1b403 Fixed Timeline display 2021-06-18 23:57:42 +02:00
Bruno
295ece79ae Unique play/pause button for multiple sources 2021-06-18 00:22:07 +02:00
Bruno
08f8ee159a Bugfix display STRING time 2021-06-18 00:21:36 +02:00
Bruno
e2d416b3fb Bugfix computation time with gaps 2021-06-18 00:21:09 +02:00
Bruno
16ed97b4cb Fixed Timeline ticks display 2021-06-17 21:42:15 +02:00
Bruno
82739702bd Player: reset selection on session change 2021-06-16 23:47:42 +02:00
Bruno
0010c9e3d5 Player UI: video menu and speed reset icon
+ rename private variables to follow usual style
2021-06-16 23:12:31 +02:00
Bruno
f59d4af92b Player: move up timeline and adjust size
keep play button bar at the bottom for all configurations, avoid text and buttons overlay when Player is small. Fix cut timing in selection
2021-06-15 23:51:59 +02:00
Bruno
a7df619a05 Timeline management in Player
Actions at key times (durations of all videos) to allow to adjust other videos duration (change speed of cut)
2021-06-14 23:42:20 +02:00
Bruno
f3759c2ef5 Player timeline for selection
Selection of media sources now displays in a list with proportional timelines, showing actual play time and cursor on effective timeline with opacity curve.
2021-06-13 00:24:45 +02:00
Bruno
d547f3a8a8 Improved management of selection in Player 2021-06-07 22:53:29 +02:00
Bruno
583e53d8a8 improved quality realtime recorder h264 2021-06-07 00:04:23 +02:00
Bruno
a27bf08ce0 Stick window on current view
menu item for media player and output preview to pin the window in current view
2021-06-07 00:04:06 +02:00
Bruno
060fb5ad2d UI details 2021-06-07 00:03:06 +02:00
Bruno
ffc00d9035 Bugfix timeline display array 2021-06-06 14:54:55 +02:00
Bruno
83a9d281c2 Define UNICODE symbols 2021-06-06 14:54:21 +02:00
Bruno
b6c853c308 work in progress selection timeline 2021-06-06 00:17:19 +02:00
Bruno
552c09d377 Minor improvements timeline display 2021-05-30 22:56:13 +02:00
Bruno
61164e627b Fixed and improved TimeCounter 2021-05-26 23:31:34 +02:00
Bruno
3c71ee1ff2 BugFix IconButton (pop id) 2021-05-25 22:17:57 +02:00
Bruno
07f610e84a Correct implementation of DeviceSource resize
previous commit was bad...
2021-05-25 20:20:43 +02:00
Bruno
faf344bc03 Bugfix and cleanup Info on source in UI 2021-05-25 09:09:23 +02:00
Bruno
e9482a3dfc Bugfix change device source resolution 2021-05-25 09:08:51 +02:00
Bruno
d4a7ce3487 Bugfix closing single frame stream 2021-05-25 09:08:24 +02:00
Bruno
3ef2737d82 New InfoVisitor: get string to describe sources
Unified code in ImGui visitor and Player
2021-05-24 20:39:56 +02:00
BHBN
582b67f4e1 Add ref to GLP 3 or later 2021-05-24 12:10:51 +02:00
Bruno
5dd6c0af78 New Timeline actions
Smooth and auto cut actions added on the side of the timeline UI.
2021-05-24 00:58:21 +02:00
Bruno
893e4f4723 Improved link between ImGuiVisitor and SourcePlayer
Source panel shows description and icon to open player UI. Changed icon player, and fixed source selection.
2021-05-23 12:32:32 +02:00
Bruno
d137e87f0e Cleaup UI Selection source Player 2021-05-23 00:55:24 +02:00
Bruno
7f152077e5 Improved UI media player (info media) 2021-05-22 01:34:19 +02:00
Bruno
74a9b229d0 OSX compilation 2021-05-19 23:30:07 +02:00
Bruno
80cf57a979 Improved cursor EditPlotHistoLines 2021-05-19 23:29:57 +02:00
Bruno
19ba943075 New SourcePlayer
Work in progress; Sources now have play/pause and associated play functions. Media player can play all playable sources, and adapts to control a media player when possible. Selection of play groups (to finalize)
2021-05-19 00:31:37 +02:00
Bruno
ba0e25a272 Minor code improvements 2021-05-17 16:13:21 +02:00
Bruno
575c487fa6 Bugfix Do not lock session in action manager
This was causing mutex deadlock
2021-05-17 16:10:46 +02:00
Bruno
1e91b2aa29 Bugfix; verify frame grabbers before use 2021-05-13 23:15:47 +02:00
Bruno
e10cf40f38 Implemented delayed start of recording 2021-05-13 22:15:50 +02:00
Bruno
23defd2117 bugfix linux shared webcam ui 2021-05-12 21:01:19 +02:00
Bruno
1227b87565 Merge remote-tracking branch 'origin/master' 2021-05-08 23:19:23 +02:00
Bruno
424ef16831 ignore local OSX files 2021-05-08 12:34:47 +02:00
Bruno
87059df28a Merge remote-tracking branch 'origin/master' 2021-05-08 12:33:41 +02:00
BHBN
520ff24ac2 Merge pull request #33 from brunoherbelin/dev
Dev
2021-05-08 12:32:48 +02:00
Bruno
920304773b Merge remote-tracking branch 'origin/dev' 2021-05-08 12:27:07 +02:00
Bruno
e55059c82c OSX update 2021-05-08 12:24:37 +02:00
Bruno
6a96c91fe1 Merge branch 'dev' 2021-05-08 12:19:13 +02:00
Bruno
f995e1cf72 Reordering source type in UI 2021-05-08 12:17:35 +02:00
Bruno
3be09553cf Multiple file selection for OSX
and finetuning creation UI for MultiFile source
2021-05-07 18:56:54 +02:00
Bruno
ee28a03a6c clean MultiFileSource 2021-05-06 23:56:31 +02:00
Bruno
d56700a9d5 Saving, undo and dynamic change of MultiFileSource 2021-05-06 23:44:15 +02:00
Bruno
250df8b651 Bugfix: allow changing resolution of stream 2021-05-06 22:18:46 +02:00
Bruno
e071ffe590 Create new Source type MultiFile
MultiFileSource plays a sequence of numbered images.
2021-05-06 00:24:01 +02:00
brunoherbelin
737b45a18c bugfix test initialization before render source 2021-05-04 21:40:24 +02:00
Bruno
1d2b7b17e8 CTRL + clic to lock/unlock 2021-05-01 20:03:42 +02:00
Bruno
bd71a4b581 restoring copy of transform_ matrix
would be possible to optimize and avoid this copy, but should be verified everywhere that this change of paradigm is taken into account (i.e. run update after copy transform if needed)
2021-05-01 19:12:09 +02:00
Bruno
451ff64b6f Cosmetics
Moved string truncate to BaseToolkit, fixed SystemToolkit max memory, clean left panel UI
2021-05-01 16:39:01 +02:00
Bruno
5e0dd60adb re-open should not change gl texture
rename 'ready' to 'opened' to avoid confusion
2021-05-01 15:35:36 +02:00
Bruno
a05cd380fb Using source mode UNINITIALIZED to replace initialized_ bool
info about source initialization was duplicated; using the mode state machine only avoids to keep a flag
2021-05-01 10:29:34 +02:00
Bruno
fd3102c0d3 memory monitor on latest value (not average) 2021-05-01 09:38:21 +02:00
Bruno
1bdd52232c compile fix 2021-05-01 00:36:02 +02:00
Bruno
381f68aaae Change READY state of source
a source is ready after rendering one frame (which is after being initialized)
2021-05-01 00:34:58 +02:00
Bruno
058fde19ce Fixed merging and action manager bug 2021-04-30 12:33:23 +02:00
Bruno
63544c603d Fixed Session thumbnail
wait for all sources to be ready before creating the thumbnail.
2021-04-30 10:17:10 +02:00
Bruno
92cd8f945e align behavior with stream 2021-04-29 23:13:30 +02:00
Bruno
5244941d9b remove commented code 2021-04-29 23:13:03 +02:00
Bruno
877fb09fa3 more elegant session source init 2021-04-29 23:12:46 +02:00
Bruno
34827ab068 ensure execute open immediately
and various code cleanup
2021-04-29 23:12:05 +02:00
Bruno
9bbe875690 Cleanup and bigsfix UI for thumbnail and preview source 2021-04-29 23:11:04 +02:00
Bruno
c7f09fb12d Prevent crash on exit
Global objects are deleted before  glfw terminates, thus crashing opengl access. Omitting glfw terminate on program exit is harmless, so...
2021-04-29 23:08:23 +02:00
Bruno
3f6d2bb6e3 Unifying list selection UI in session panel 2021-04-28 13:52:38 +02:00
Bruno
bd2500314f decide for byte aligned opengl textures all over 2021-04-28 13:18:01 +02:00
Bruno
a28f46a9eb perform render thumbnail only if framebuffer available 2021-04-28 11:23:11 +02:00
Bruno
7b7bd763c9 clear code copy vec4 2021-04-28 11:22:27 +02:00
Bruno
1118e4bfe0 add source propose a name, does not change it yet
and use filename only if provided
2021-04-28 11:21:47 +02:00
Bruno
b0bc88e9c2 unified behavior stream and media player 2021-04-28 11:19:59 +02:00
Bruno
038fea3539 opengl good practice: unbind texture after set 2021-04-28 11:18:45 +02:00
Bruno
ee20718c51 remove debug code 2021-04-27 23:21:33 +02:00
Bruno
f46ffc004a Validate list of filenames 2021-04-27 23:20:18 +02:00
Bruno
d2f0f42c2d imgui code cleanup 2021-04-27 23:19:58 +02:00
Bruno
be36662efc Fixed unique source name algorithm 2021-04-26 23:51:47 +02:00
Bruno
c7d6d37a8e oops 2021-04-26 22:06:06 +02:00
Bruno
7ba87fcee8 Fixed ButtonOpenUrl 2021-04-26 18:49:01 +02:00
Bruno
c3713c9ce7 work in progress tooltips with thumbnails of sessions 2021-04-26 13:48:20 +02:00
Bruno
98861cea6c Fixed Mixer delete and rename 2021-04-26 13:47:48 +02:00
brunoherbelin
d89290f9b2 alphabetically sort list of files in a dir 2021-04-26 09:22:22 +02:00
Bruno
1b6b2ecd4d Bugfix undo of multiple sources delete 2021-04-26 00:29:26 +02:00
Bruno
0e3575c1ca Using new basetoolkit function for unique naming
applied to source and snapshot names
2021-04-25 23:59:18 +02:00
Bruno
055f5c4c4e Creating a base toolkit for functions independent from other toolkits 2021-04-25 20:09:22 +02:00
Bruno
129d5445c3 Implementation of UI for snapshot manipulation
with thumbnails appearing on mouse over and in edit context menu
2021-04-25 14:02:06 +02:00
Bruno
6e202def1e Bugfix Action Snapshot replace 2021-04-25 11:39:45 +02:00
Bruno
0c51b16353 use framebuffer blit for thumbnail of RenderView 2021-04-25 01:27:51 +02:00
Bruno
c5ee77e969 Fixed blit of framebuffer 2021-04-25 01:27:32 +02:00
Bruno
c7962abfbb Save thumbnail of session when storing history or snapshot 2021-04-25 00:27:59 +02:00
Bruno
d371f6ae8e Cleanup FrameBufferImage API 2021-04-25 00:27:32 +02:00
Bruno
8336f6a595 Fixed RenderView thumbnailer 2021-04-25 00:26:38 +02:00
Bruno
c3a24a6d7f Cleanup XML read & write utility functions 2021-04-25 00:26:05 +02:00
Bruno
f643e80de7 Using std future promises to get thumbnail of render view 2021-04-24 13:14:57 +02:00
Bruno
5473c0b38b Store image size in XML
and discard loaded image if size does not match
2021-04-24 13:14:03 +02:00
Bruno
eb54b67caa New function to get thumbnail of render view 2021-04-22 23:38:00 +02:00
Bruno
97e7e5f4a1 Cleanup image saving and loading in xml session 2021-04-22 23:37:39 +02:00
brunoherbelin
da64172848 Work-in-progress: Interpolation of snapshot in Action manager 2021-04-21 23:35:34 +02:00
Bruno
e2d2e6ddd8 prefix ++View::need_deep_update_ 2021-04-19 19:24:50 +02:00
Bruno
896cae2d07 Fixed window resize 2021-04-19 18:29:10 +02:00
Bruno
409870dddb OSX cmake fix 2021-04-19 18:28:17 +02:00
Bruno
c19acda62d Added Snapshot Replace 2021-04-18 21:02:23 +02:00
Bruno
a50a6e129c Better implementation of SessionSnapshots saving 2021-04-18 18:22:21 +02:00
Bruno
d68987be0f C++ improved declaration of singleton managers 2021-04-18 13:27:19 +02:00
Bruno
bb64579fa5 Cleanup FileDialog (unused) 2021-04-18 13:15:18 +02:00
Bruno
2392d844d9 Making classes non-assignable
Following CppCheck recomendation, all classes that should not be manipulated by value are made non-assignable to ensure no mistake is made.
2021-04-18 13:04:16 +02:00
Bruno
c6d01c1420 Optimizing iteration
prefix ++i is faster than post i++
2021-04-18 11:38:03 +02:00
Bruno
8389010002 CoreSource complement
The CORE of a source is all what can be interpolated
2021-04-18 10:59:39 +02:00
Bruno
31eb13e16d Unused =operator: copy function instead 2021-04-18 10:58:03 +02:00
Bruno
7cafbc032b Working on source interpolation 2021-04-18 10:56:37 +02:00
brunoherbelin
cc752050f8 SourceCore to isolate core properties of a source 2021-04-17 14:40:00 +02:00
Bruno
c90bec36c5 clean useless ptr 2021-04-17 14:10:42 +02:00
Bruno
c1415b021a convert linklist to list of sources 2021-04-17 14:10:14 +02:00
brunoherbelin
1081b4a54d allow undo of trigger snapshot 2021-04-17 14:09:09 +02:00
brunoherbelin
ebb5fd16bb Draft implementation of Snapshots, with saving and UI 2021-04-17 10:28:12 +02:00
brunoherbelin
2d4a6d1fe6 Snapshots in Action manager 2021-04-15 22:50:28 +02:00
brunoherbelin
11df7c28b4 More robust clone XML mechanism: use ID 2021-04-13 22:41:57 +02:00
brunoherbelin
17d2a63132 Important change: sources keep their id all lifelong.
This simplifies a lot history and testing in session.
2021-04-13 22:26:26 +02:00
brunoherbelin
268486b652 std::string compatible imgui text input 2021-04-13 21:28:36 +02:00
brunoherbelin
f5af24b384 Update settings 2021-04-13 21:27:51 +02:00
brunoherbelin
6d522876ad Loading session with menu do not use smooth transition 2021-04-13 21:24:56 +02:00
brunoherbelin
2814763b97 std::string compatible imgui text input 2021-04-13 21:23:42 +02:00
brunoherbelin
765133a3bd BugFix 2021-04-11 15:24:24 +02:00
brunoherbelin
ab41a0c5d8 First implementation of Sticky Notes 2021-04-11 15:13:46 +02:00
brunoherbelin
eee9f49c05 Refurbishing the left panel
Toggle settings to show whole panel of settings
More space for main session panel (added notes)
2021-04-11 01:27:21 +02:00
Bruno
d7102809fc Auto stash before checking out "origin/dev" 2021-04-10 00:47:05 +02:00
Bruno
e792c119ea Merge branch 'master' into origin/dev 2021-04-10 00:45:00 +02:00
brunoherbelin
6e4ced8dcb Unified undo history messages 2021-04-10 00:22:16 +02:00
brunoherbelin
e69be79aed Compilation defines to cleanup old code 2021-04-09 22:50:16 +02:00
brunoherbelin
87dc282fb7 Improved MediaPlayer memory consumption:
Avoid duplicating Timeline object and limit number of URI discoverers to
two parallel threads.
2021-04-09 11:23:05 +02:00
brunoherbelin
38f7fb7c16 Bugfix timeline (prevent zero div) 2021-04-09 11:22:06 +02:00
brunoherbelin
6173e8279f Improved dev toolbox (saving statistics of memory) 2021-04-09 11:21:43 +02:00
brunoherbelin
4f661c5c05 Merge branch 'master' of github.com:brunoherbelin/vimix 2021-04-08 00:27:20 +02:00
brunoherbelin
28172430dc Added 'Source' to metrics (moved to UserInterfaceManager) 2021-04-08 00:26:52 +02:00
brunoherbelin
5a9d4dd55e Temporary disabling feature 'follow image processing' 2021-04-07 23:00:09 +02:00
brunoherbelin
b3880ad380 Limiting memory for media player 2021-04-07 22:57:29 +02:00
BHBN
b45c846a85 Update README.md 2021-04-07 13:23:22 +02:00
brunoherbelin
788fa693fd Draft implementation of Following mechanism for Image processing 2021-04-06 23:20:13 +02:00
brunoherbelin
1d45ab1d20 Cleanup DummySource (bad bad bad) 2021-04-05 14:55:21 +02:00
brunoherbelin
ae1c3d85ab bugfix: store mask after applying effect 2021-04-05 13:31:31 +02:00
brunoherbelin
c22df2eb2a (continue) Migrating clipboard manipulation to Session XML management 2021-04-05 13:06:31 +02:00
brunoherbelin
d3a130d9ba (continue) Migrating clipboard manipulation to Session XML management 2021-04-05 13:05:38 +02:00
brunoherbelin
8a57b52fcc Migrating clipboard manipulation to Session XML management 2021-04-05 13:04:44 +02:00
brunoherbelin
dbc9803f9e center on source only if source is not visible 2021-04-04 22:21:42 +02:00
brunoherbelin
3e376eb166 ensure output and media player window are visible 2021-04-04 20:55:55 +02:00
brunoherbelin
12aca05aef prevent potential memoryleak 2021-04-04 14:38:04 +02:00
brunoherbelin
ce1de27618 Improved README 2021-04-04 14:19:36 +02:00
brunoherbelin
66d5148e3a Prevent potential memory leak 2021-04-04 13:40:17 +02:00
brunoherbelin
d2b4a825eb avoid pedantic compilation warning 2021-04-04 13:27:56 +02:00
brunoherbelin
f443720319 Programming style improvement: following Cppcheck suggestions. 2021-04-04 13:13:06 +02:00
brunoherbelin
b4627a1613 Various potential memory leak fixed 2021-04-04 01:25:35 +02:00
brunoherbelin
ceea9c10d5 gstreamer memory cleanup in mediaplayer and stream 2021-04-04 01:24:13 +02:00
brunoherbelin
a143360497 Memory leak fix 2021-04-02 22:38:34 +02:00
brunoherbelin
163757cb69 Improved layout and menu Media Player UI 2021-04-02 13:57:11 +02:00
brunoherbelin
4537b986ca Support to forced software decoding option
With reload of media player when option is changed
2021-04-02 12:14:20 +02:00
Bruno
aafac2a7a8 merge 2021-04-01 20:46:46 +02:00
brunoherbelin
7344258b2f fixed hardware decoding detection OSX 2021-04-01 09:12:41 +02:00
brunoherbelin
c59994b7e5 Implemented a detection of hardware decoding used in pipeline
Simple check for names of decoder inside uridecodebin and cross check
with the list of known hardware Decoder Names
2021-04-01 00:14:02 +02:00
brunoherbelin
b089f59e2a Implemented a detection of hardware decoding used in pipeline
Simple check for names of decoder inside uridecodebin and cross check
with the list of known hardware Decoder Names
2021-04-01 00:11:05 +02:00
Bruno
649d2b7ef7 Merge remote-tracking branch 'origin/master' 2021-03-31 19:24:48 +02:00
brunoherbelin
8bef575e8b minor changes to media player pipeline (improved performance?) 2021-03-31 15:40:02 +02:00
brunoherbelin
559a036e6d BugFix: reload list of recent sessions after any change to history 2021-03-30 23:51:06 +02:00
brunoherbelin
0b845591f9 Improved transition view
Responsive buttons placement and clarified actions.
2021-03-30 23:02:24 +02:00
brunoherbelin
a8ef68ed59 Thought of the day. 2021-03-30 19:14:34 +02:00
brunoherbelin
7293b8b9dd BugFix: clean interrupt stream when ending abruptly 2021-03-30 19:03:33 +02:00
brunoherbelin
8eef5465c9 eyecandy: better icons for file menu 2021-03-29 23:18:14 +02:00
brunoherbelin
c08cb95dc1 Bugfix: restating correct order session loading properties 2021-03-29 23:17:54 +02:00
brunoherbelin
010166e7b0 renaming mediaplayer attribute force software decoding 2021-03-29 23:17:16 +02:00
brunoherbelin
4c7fb94616 Small update of webpage (link to installation guide) 2021-03-29 22:23:00 +02:00
Bruno
46f486a367 Documenting installation for wiki 2021-03-29 22:05:41 +02:00
brunoherbelin
ea195dcf11 add link to vimeo 2021-03-28 21:03:43 +02:00
brunoherbelin
e6979acded Revert "Try to integrate embedded video in Jekyll webpage"
This reverts commit 43b4fc81b9.
2021-03-28 20:59:46 +02:00
brunoherbelin
43b4fc81b9 Try to integrate embedded video in Jekyll webpage 2021-03-28 20:56:30 +02:00
brunoherbelin
d4ce6ebee6 trying snap eextensions: [gnome-3-28] 2021-03-28 18:37:29 +02:00
brunoherbelin
1c9a5ece83 setLocale in C (not std C++) 2021-03-27 23:36:51 +01:00
brunoherbelin
8a75664264 Preventing display glitch from invalid scaling of view 2021-03-27 23:31:18 +01:00
brunoherbelin
6687bdd258 BugFix: mixed-up Locale for XML I/O caused by GTK Dialogs 2021-03-27 23:17:19 +01:00
brunoherbelin
e525ecad36 Cleanup main 2021-03-27 23:15:49 +01:00
brunoherbelin
e8b5dc0649 BugFix: not using GST g_main_context to avoid GTK conflict 2021-03-27 19:21:18 +01:00
brunoherbelin
3a0f96c1ec fixed add extension on saved filename 2021-03-27 18:23:54 +01:00
brunoherbelin
e4c06ba1bb Fixed #ifdef compilation 2021-03-27 18:21:13 +01:00
brunoherbelin
bc4eadfd08 Bugfix view config loading 2021-03-27 18:13:09 +01:00
Bruno
ee2ce3802f Linux Dialogs in GTK for SNAP compatibility
Discarding use of ZENITY under linux (previously used with the tinyfiledialog) because snapcraft makes  it impossible to use :(. Reimplementation of GTK+ dialogs directly inside vimix code. Note: no changes for OSX. Complete cleanup of cmake file.
2021-03-27 13:03:22 +01:00
brunoherbelin
43d44634f7 Trying to fix the tinyfiledialog zenity integration 2021-03-22 16:25:51 +01:00
brunoherbelin
41bd7fc958 problem snap and zenity 2021-03-22 14:34:47 +01:00
brunoherbelin
1e458a642c Merge branch 'master' of github.com:brunoherbelin/vimix 2021-03-22 13:59:05 +01:00
brunoherbelin
b255e41091 Work in progress: force sofware decoder for a media player 2021-03-22 13:58:55 +01:00
brunoherbelin
bc22832ad6 information on tinyfiledialog in about. 2021-03-22 13:35:17 +01:00
brunoherbelin
f59ac505b7 shift grab source (even on rotation) 2021-03-21 14:23:30 +01:00
brunoherbelin
e15b962221 Cosmetics: improve reordering source in left panel 2021-03-21 14:09:11 +01:00
brunoherbelin
28d4d4acc4 Bugfix: prevent crash with current source when reordering 2021-03-21 13:24:54 +01:00
brunoherbelin
5f800f3723 Creating texture only on draw 2021-03-20 23:29:30 +01:00
brunoherbelin
2537ca03c8 fix 2021-03-20 22:05:30 +01:00
brunoherbelin
1860402452 Bugfix un-understandable crash on texture mixing quadratic. 2021-03-20 22:03:57 +01:00
brunoherbelin
bec9385c68 BugFix (apparently problematic memmove under OSX) 2021-03-20 18:38:46 +01:00
brunoherbelin
798139e097 Cosmetic: add label to button in source imgui visitor 2021-03-20 14:57:13 +01:00
brunoherbelin
6683d76222 OSX package name with patch version 2021-03-20 13:49:56 +01:00
brunoherbelin
6d2d16b644 updated OSX icon 2021-03-20 13:31:09 +01:00
brunoherbelin
4e83cdf30f hide history with ESC 2021-03-20 13:01:00 +01:00
brunoherbelin
71891292b4 Cosmetics: improved naming and actions on SessionSources (Groups and
File)
2021-03-20 11:51:46 +01:00
brunoherbelin
10ac384e7e Cosmetics: mouse over MixingCircle global opacity slider. 2021-03-20 10:46:06 +01:00
brunoherbelin
6e7df60f2c Minor bugfix and Actionmanager undo message improvement. 2021-03-20 10:03:54 +01:00
brunoherbelin
112b583379 Entire cleanup of ActionManager
History of previous id of sources is now obtained in SessionLoader; no
need to store the id of the source in action manager XML (so also
removed in View current id).
2021-03-19 23:09:49 +01:00
brunoherbelin
b07009f3ce BugFix: SessionGroupSource creation and update in ActionManager and
SessionCreator.
2021-03-19 22:53:08 +01:00
brunoherbelin
74e9553d56 bugfix textureview lock source 2021-03-19 17:52:02 +01:00
brunoherbelin
2c3d6ff02e Implement lock source mechanism in TextureView 2021-03-19 13:30:58 +01:00
brunoherbelin
8dd47b3a41 Flatten selection to lower depth 2021-03-19 00:21:47 +01:00
brunoherbelin
09f052a5d6 Added undo-redo to locking of sources. 2021-03-18 21:56:06 +01:00
brunoherbelin
ac5e885fb3 Brute force implementation of undo-redo of mixing group 2021-03-18 21:44:38 +01:00
brunoherbelin
dd9c8ac0b8 Added option to choose mirror or repeat texture on source 2021-03-18 19:43:51 +01:00
brunoherbelin
0de1b87028 reorder ESC sequence 2021-03-18 14:42:51 +01:00
brunoherbelin
e830a6eefe Mixing Group improved UI feedback 2021-03-18 14:42:33 +01:00
brunoherbelin
3c875a064e Active usual function keys without focus on workspace 2021-03-17 23:08:17 +01:00
brunoherbelin
2227c97a57 New action when clic on source symbol in Mixing or Layer views: open
editor in UI
2021-03-17 22:50:21 +01:00
brunoherbelin
ea211cb8ab Prevent action on source after locking it from side panel 2021-03-17 22:20:49 +01:00
brunoherbelin
6d2112fcd9 missing initialization layer view default appearance 2021-03-17 22:19:54 +01:00
brunoherbelin
05cb1db020 Minor UX improvement when mixing group rotation does not have the
expected effect
2021-03-17 22:03:19 +01:00
brunoherbelin
cd4d8f02cb Fixed source picking problems
Allow unlock of source in geometry, do not allow selection of locked
source with CTRL
2021-03-17 21:56:35 +01:00
brunoherbelin
b8fe0d7c69 Improved selection action in mixing and layer views 2021-03-17 21:13:22 +01:00
brunoherbelin
81c173e9c3 prevent null scale texture UV 2021-03-17 20:03:40 +01:00
brunoherbelin
63c954dedc Improved overlay grid 2021-03-17 18:49:20 +01:00
brunoherbelin
91d1ff1eb1 Mixing center action takes barycenter 2021-03-17 05:18:27 +01:00
brunoherbelin
41efc572e0 Improved keyboard manipulation of selection of sources in Views. 2021-03-17 05:12:00 +01:00
brunoherbelin
77764248b5 Added ALT modifier to selection rotation 2021-03-16 22:09:15 +01:00
brunoherbelin
ca0058c741 Action manager for undo action of keyboard arrow keys 2021-03-16 21:29:38 +01:00
brunoherbelin
8bd74ec725 Geometry selection Mirror action 2021-03-15 23:39:39 +01:00
brunoherbelin
9a5983d6de Selection pick bug fix 2021-03-15 23:25:54 +01:00
brunoherbelin
ce38bf72b8 Action manager for undo of context menu actions 2021-03-15 22:55:22 +01:00
brunoherbelin
ecba54196f Mixing and Geometry Selection menu actions 2021-03-15 21:26:30 +01:00
brunoherbelin
3b09bc877c Introducing Oriented bounding box for GeometryView selection
First implementation of MixingView selection manipulation (scale and
rotate)
2021-03-15 11:56:16 +01:00
brunoherbelin
92663aa171 Select group sources with ctrl+clic 2021-03-13 09:23:39 +01:00
brunoherbelin
c41d7ee067 BugFix select current 2021-03-12 23:56:49 +01:00
brunoherbelin
5ab5f1b60f bruteforce and efficient implementation of mixing groups management in
session.
2021-03-12 20:25:36 +01:00
brunoherbelin
10f9c1b329 Work in progress Implementation of mixing group
link and unlink methods, integration in MixingView, update groups on
source change, undo-redo improved.
2021-03-10 23:38:09 +01:00
brunoherbelin
2d62ab969c Work in progress: undo & redo of mixing group creation and delete
actions.
2021-03-10 00:16:49 +01:00
Bruno
7656113dcc Large commit for implementation of load&save of MixingGroups 2021-03-07 19:27:00 +01:00
Bruno
56f0165d75 Implementation of mixing group actions 2021-03-06 11:40:00 +01:00
Bruno
d79c4cbfe1 Fixed rendering LineStrip 2021-03-06 11:39:01 +01:00
Bruno
a55765c100 Add Symbol rotation 2021-03-06 11:38:17 +01:00
Bruno
134617bbd1 Created new Object MixingGoup 2021-03-03 22:39:36 +01:00
Bruno
2ccedd42e4 Cleanup code and includes 2021-03-03 22:39:17 +01:00
Bruno
d6d1ab5099 Clean code and includes 2021-03-03 22:37:56 +01:00
Bruno
b8d323ad59 Longer notification time 2021-03-03 22:37:18 +01:00
Bruno
737269bf5a New Primitive LineLoop (and cleanup associated visitors) 2021-03-03 22:36:59 +01:00
brunoherbelin
e54389b79c Improve context menu (icons and labels) 2021-02-28 17:38:18 +01:00
brunoherbelin
2906c50642 Change terminology sub-session 2021-02-28 14:10:55 +01:00
brunoherbelin
8123e61e34 Cleanup depth management 2021-02-28 14:10:32 +01:00
brunoherbelin
70cc66a7f4 Added edit menu in New source panel 2021-02-28 10:19:30 +01:00
brunoherbelin
13672a9d01 Use dichotomic algorithm to converge to new Alpha 2021-02-28 10:18:42 +01:00
brunoherbelin
f2cd18f754 Cleanup and unify views interface (combo) 2021-02-28 10:18:10 +01:00
brunoherbelin
7e723f4142 Use SourceTrail to analyse structure 2021-02-28 10:15:50 +01:00
brunoherbelin
adcd735127 Clean include tree for view cpp 2021-02-26 23:33:50 +01:00
brunoherbelin
70c28d4226 Renamed Appearance view to Texture view. 2021-02-26 23:15:14 +01:00
Bruno
004e1aaead Compile Views in separate source files 2021-02-26 23:09:51 +01:00
Bruno
e7a5d341e4 Dispatch code of Views in separate source files 2021-02-26 23:09:22 +01:00
brunoherbelin
f7b93478ed Reimplementation of LineStrip primitive using DYNAMIC vertext array and
triangle strips (basic mesh).
2021-02-26 17:01:24 +01:00
brunoherbelin
afc0c7af0e Fixed FPS stable computation 2021-02-23 23:44:04 +01:00
brunoherbelin
0ee5eebf91 Linux compilation fix 2021-02-23 23:43:41 +01:00
brunoherbelin
d0fdbeb14f Changed dt and fps computation in mixer 2021-02-23 23:11:16 +01:00
brunoherbelin
38f1288571 Reading version from git 2021-02-23 20:04:37 +01:00
brunoherbelin
4093170599 New blending: hard light 2021-02-22 18:26:14 +01:00
brunoherbelin
27112a2b57 AlphaShader for mapping alpha in pre-render 2021-02-22 18:26:00 +01:00
Bruno
ef7722bb5c Better terminology and icons for SessionGroup 2021-02-22 14:06:10 +01:00
brunoherbelin
8019f4ea25 Cleanup blending update 2021-02-21 22:02:04 +01:00
Bruno
a612395ca3 Added Lighten only blending mode 2021-02-20 00:26:21 +01:00
brunoherbelin
4718bf166f Shading pre-multiplied alpha for simple shapes too 2021-02-19 16:53:38 +01:00
Bruno
f51bc1f1f4 New Blending with pre-multiplied alpha
Finally found how to improve blending modes by pre-multiplying color by alpha in the shader, so that the blending equations can be applied on top of the apha manipulation.
2021-02-18 23:36:01 +01:00
Bruno
64071a4a55 Merge remote-tracking branch 'origin/master' 2021-02-16 23:01:21 +01:00
Bruno
678bdf066e Temporarily acceptable SessionGroup with opaque background 2021-02-16 23:01:02 +01:00
Bruno
cb5562eca2 Blending with separate alpha and color functions 2021-02-16 23:01:02 +01:00
Bruno
23386fccc2 Minor improvement XML
Do not save timeline for single frame media
2021-02-16 23:01:02 +01:00
Bruno
4b1d6a8ac0 Temporarily acceptable SessionGroup with opaque background 2021-02-16 22:58:45 +01:00
Bruno
146408607a Blending with separate alpha and color functions 2021-02-16 22:58:19 +01:00
Bruno
ffee2f067a Minor improvement XML
Do not same timeline for single frame media
2021-02-16 22:57:40 +01:00
Bruno
935762506d Bugfix: frae grabber should be called in Mixer
Grab frames in session update fails with SessionSource and SessionGroups.
2021-02-16 22:50:15 +01:00
brunoherbelin
885ce67174 OSX compile fix 2021-02-15 09:03:30 +01:00
Bruno
e37b21760e BugFix: interrupting recursive session loading
Prevent crash on  recursive (infinite) loading of session file (containing itself).
2021-02-14 18:56:48 +01:00
Bruno
25c2bb59f5 Draft searchFileVisitor 2021-02-13 13:45:00 +01:00
brunoherbelin
a1e4709910 OGL optimization (no mipmap, antialias lines) 2021-02-13 12:39:21 +01:00
brunoherbelin
0593e46e62 Changed colors a bit
Selection area, group and pain tools matching the highlight color. White
mask tool.
2021-02-11 21:14:21 +01:00
brunoherbelin
dca3033c06 Bugfix; correcting introduced bug with RenderSource and new Session
resolution.
2021-02-11 20:28:57 +01:00
brunoherbelin
d45554e162 Eyecandy: better color and transparency for icons in Mixing and Layer
views
2021-02-09 18:52:26 +01:00
brunoherbelin
8c4d3f3a18 Unified use of SessionSource in Mixer (import) for SessionFile and
SessionGroup sources.
2021-02-09 18:47:54 +01:00
Bruno
6bb5c0d208 Merge remote-tracking branch 'origin/master' 2021-02-09 18:35:55 +01:00
brunoherbelin
209caadd44 Bugfix in realtime vtenc OSX recording (allow-frame-reordering=0) 2021-02-08 12:09:53 +01:00
Bruno
89fa11447a New decoration frame for group in Layers view 2021-02-07 23:22:15 +01:00
Bruno
84416f566b Early implementation of groups: SessionGroupSource.
Rename SessionSource to SessionFileSource.
2021-02-07 22:01:07 +01:00
Bruno
65564065d9 New Symbol cube 2021-02-07 20:48:32 +01:00
Bruno
79540c0232 cleanup header 2021-02-07 20:48:10 +01:00
Bruno
5d23a285b4 get color of highlight 2021-02-07 20:47:55 +01:00
Bruno
1964a26fc3 add source find by depth 2021-02-07 20:46:30 +01:00
Bruno
e37a189bae add pop of source in selection 2021-02-07 20:45:13 +01:00
Bruno
5328995a79 added force non visible to BBox visitor 2021-02-07 20:43:56 +01:00
brunoherbelin
6929eb3307 Minor improvement log window 2021-02-05 22:27:47 +01:00
brunoherbelin
33f00f9da4 Bugfix (crash when reordering source) 2021-02-05 19:04:13 +01:00
brunoherbelin
34380e8592 BugFix: copy-paste a selection containing a source and its clone: fixed
that the clone is created (after the source).
2021-02-05 18:16:13 +01:00
brunoherbelin
8185c93457 Fixed replacement of failed RenderView after sessionSource import (if a
sessionSource contains a RenderView, the later should be re-created).
2021-02-05 18:11:16 +01:00
brunoherbelin
93b6bc9ca4 Bugfix in Recursive loopback of RenderView inside a SessionSource: fixed
loading and import into main session.
2021-02-04 23:25:49 +01:00
brunoherbelin
d76dfa4a9d Revert "Cleanup tooltips."
This reverts commit d23267d333.
2021-02-04 22:45:13 +01:00
brunoherbelin
d23267d333 Cleanup tooltips. 2021-01-31 20:09:11 +01:00
brunoherbelin
e8a258094f Eye candy on help markers and icon; added display of shortcut on the
side (grey text).
2021-01-31 14:18:43 +01:00
brunoherbelin
ffb30bc292 Slight modification of button play behavior in transition view (allows to
stop animation)
2021-01-30 23:51:39 +01:00
brunoherbelin
fa798c8809 Fixed position of UI in views to match ImGui size 2021-01-30 23:40:31 +01:00
brunoherbelin
ac15bbc840 Display preview of source centered in fixed-size preview area. 2021-01-30 23:23:30 +01:00
brunoherbelin
e26052013c Matching creation of new session source with recent changes on
SessionSource.
2021-01-30 22:45:27 +01:00
brunoherbelin
9215be6bfc ..and also reset fading after new empty session is created. 2021-01-30 22:43:22 +01:00
brunoherbelin
691c6d174b Bugfix in rare cases of smooth transition and combined session fading. 2021-01-30 22:34:16 +01:00
brunoherbelin
4bc9bf581e Cleanup pattern and session sources 2021-01-30 16:03:26 +01:00
brunoherbelin
3686106dab Bugfix restoring aspect ratio action. 2021-01-30 16:02:38 +01:00
brunoherbelin
62bc779dee Import of SessionSource: the merging of sources in session now applies
transformations of the sessionsource; so visually nothing (almost)
should change on the output.
2021-01-30 12:26:49 +01:00
brunoherbelin
843fa86c00 Depth management: layer actions operate on depth only (Z), and update of
source places the icon in LayerView (X,Y)
2021-01-30 12:24:18 +01:00
brunoherbelin
9bfc5b269a Fixed session source import; merge sources from the inside session,
adjust their alpha and depth, and delete former session source
immediately.
2021-01-29 22:32:02 +01:00
brunoherbelin
a7b6a67a92 reimplementation of LineSquare using rectangular polygons for horizontal
and vertical lines.
2021-01-28 13:50:31 +01:00
brunoherbelin
9b795a0df7 Improved time management for software framerate limiter. 2021-01-27 09:35:46 +01:00
brunoherbelin
29c40036b2 have to use ALT+TAB for view switcher in OSX 2021-01-26 22:35:59 +01:00
brunoherbelin
49e845137a Make CTRL+TAB compatible for OSX 2021-01-26 22:23:28 +01:00
brunoherbelin
394bfe2da4 Size dependent spaces for combo box in views. 2021-01-26 22:17:28 +01:00
brunoherbelin
6607bd319c New view navigation with [CTRL+TAB] 2021-01-26 22:16:57 +01:00
brunoherbelin
54c5eb6155 Reordering of Sources in list. 2021-01-25 22:24:08 +01:00
brunoherbelin
49ec387cfa New icon. 2021-01-25 19:17:43 +01:00
brunoherbelin
0ef6164b24 Added close icon to widgets. 2021-01-24 23:02:27 +01:00
brunoherbelin
87a25ca19f Improved transition view interface. 2021-01-24 22:31:09 +01:00
brunoherbelin
e564b63f77 Added icon to toggle lock in pannel (and fixed icon) 2021-01-24 22:18:31 +01:00
brunoherbelin
0e6ad3e25c BugFix changing workspace current selected source. 2021-01-24 20:41:06 +01:00
brunoherbelin
c3442a1090 Using brush settings in AppearanceView 2021-01-24 20:21:26 +01:00
brunoherbelin
83e5c37b60 Use settings for global brush parmeters. 2021-01-24 19:23:51 +01:00
Bruno
2dda3da8b1 thematic color of View UI 2021-01-24 18:21:14 +01:00
brunoherbelin
7e6ee0806d oops; terminate properly painting action. 2021-01-24 17:44:09 +01:00
Bruno
9c0adb4ce6 Important feature: source locking and workspace.
Source locking property, views ability to test if a source is selectable, change of selection when switch view, picking testing locking and workspace.
2021-01-24 17:19:41 +01:00
Bruno
b17136d23a Improved DrawVisitor to accept list of nodes 2021-01-24 17:16:28 +01:00
Bruno
edeec9568e Mixer Utility to deselect quickly a source 2021-01-24 10:55:19 +01:00
Bruno
e5ed27180f New buttons and icon modes 2021-01-24 10:54:25 +01:00
Bruno
207ac11ded Improved and new icons 2021-01-24 10:53:18 +01:00
brunoherbelin
2bc8420c24 New decoration handle for locked/unlocked. Bugfix picking mirrored
handles.
2021-01-23 10:08:26 +01:00
brunoherbelin
f4048fca04 Increased size of source icon 2021-01-21 23:02:50 +01:00
brunoherbelin
9942d8e628 Do not warn about canceled session set. Information message when user
quits transtition.
2021-01-21 22:47:58 +01:00
brunoherbelin
2fe282ef6a new Gui icon button 2021-01-21 22:31:43 +01:00
brunoherbelin
12dcd34b3d New eye icon 2021-01-21 21:14:13 +01:00
brunoherbelin
0cf4732347 (no change - keep code for later) 2021-01-19 19:08:19 +01:00
brunoherbelin
4e6a402142 Improved message and log. 2021-01-19 19:07:24 +01:00
brunoherbelin
9449936df0 Making sure disabling accelerated hardware acceleration on codec
decoding discards the corresponding gstreamer decoders.
2021-01-18 18:30:16 +01:00
brunoherbelin
7c555465b8 Bugfix copy imageprocessing shader should not copy shader properties 2021-01-18 18:24:36 +01:00
brunoherbelin
5262b8ae29 System configuration in main pannel: toggled with config button. Cleanup
the About vimix dialog, giving access to other about dialogs.
2021-01-17 23:59:25 +01:00
Bruno
1028aeea9f VERSION 0.5 2021-01-17 12:55:02 +01:00
Bruno
e02071047a Fine tuning appearance of layers view 2021-01-17 12:54:50 +01:00
brunoherbelin
227658d2fc Improved error message on different xml version. 2021-01-17 00:29:12 +01:00
brunoherbelin
56dc299fc9 Changed Mixing alpha transition function (less abrupt on the sides). 2021-01-17 00:28:45 +01:00
brunoherbelin
f7e1ff14d9 Fixed alpha blending and stippling 2021-01-16 23:37:43 +01:00
Bruno
9e865b3677 Preliminary implementation of source locking and layer stage levels 2021-01-16 22:32:02 +01:00
Bruno
e4da7de06f eye candy - changing icon 2021-01-16 15:17:11 +01:00
brunoherbelin
67f45793da Bugfix: forced DrawVisitor was not forcing actual draw() 2021-01-15 23:22:51 +01:00
brunoherbelin
5a2949609e reload view after clear new session 2021-01-13 23:46:35 +01:00
brunoherbelin
f20597656e Eye candy in texturing view 2021-01-13 23:37:02 +01:00
brunoherbelin
aaf700baba Implementation of arrow keys to move objects in views layer and
transition
2021-01-13 21:19:48 +01:00
brunoherbelin
a3e121d6a0 Fixed softwar FPS limiter when not v-sync 2021-01-13 18:38:44 +01:00
brunoherbelin
d3269e8aaa Merge commit 2021-01-13 18:38:08 +01:00
Bruno
b9104df26e Merge remote-tracking branch 'origin/master' 2021-01-13 18:23:29 +01:00
brunoherbelin
717f560326 software framerate limiter 60FPS if not v-sync 2021-01-13 18:20:55 +01:00
brunoherbelin
6fdb93a020 Support for Shift-Tab to loop backward in list of sources. 2021-01-13 14:06:54 +01:00
brunoherbelin
767b0d8084 Link zoom and grab in unified way for all views. 2021-01-12 21:49:05 +01:00
brunoherbelin
52eb9284f7 UI bugfix 2021-01-11 23:34:06 +01:00
brunoherbelin
c355486955 Improved interface mask, eye candies and new icons. 2021-01-11 23:09:52 +01:00
brunoherbelin
0e8f87d6c6 OSX compilation 2021-01-11 18:31:38 +01:00
Bruno
dbd3c071e8 Improved GUI for mask editing, added effects. 2021-01-10 23:56:50 +01:00
Bruno
398995648a Mask Paint!! New MaskShader for mouse paiting of masks and associated changes.
UI for pain mask, load & save of FrameBuffer Image.
2021-01-10 14:52:57 +01:00
brunoherbelin
3fc9401d97 Bugfix: do not forget settings for AppearanceView 2021-01-10 09:54:43 +01:00
brunoherbelin
d31320ae4b Code cleaning in screenshot 2021-01-10 09:53:55 +01:00
brunoherbelin
fe54afbe1c Cleanup and securing XMLElementEncode and DecodeArray 2021-01-10 09:52:58 +01:00
brunoherbelin
6b5ccb4450 Bugfix draw visitor (ensure clean start when visiting scene) 2021-01-10 09:51:22 +01:00
brunoherbelin
805baa75f4 Bugfix handle rotation 2021-01-02 13:59:21 +01:00
brunoherbelin
b1dd2f0bc9 Avoid unavailable pattern generators with versions of gstreamer < 18 2021-01-01 23:02:35 +01:00
brunoherbelin
f8e926040a Display transliterated filename in GUI 2021-01-01 20:41:39 +01:00
brunoherbelin
11690dfb8c ICU compilation error 2021-01-01 17:13:18 +01:00
brunoherbelin
63369223ca Compilation and snap with ICU libs 2021-01-01 15:41:31 +01:00
brunoherbelin
a1e81b58b1 OSX compilation fix 2021-01-01 14:36:44 +01:00
brunoherbelin
cf2b6b4b39 Improved information icon for source preview 2021-01-01 12:17:49 +01:00
brunoherbelin
c4e584a1da cleanup framebuffer info string 2021-01-01 12:00:30 +01:00
brunoherbelin
25b58b76f3 Enable resize of session frame buffer resolution 2021-01-01 11:54:40 +01:00
Bruno
b346403887 Try to use GPU video decoding plugins when possible 2021-01-01 10:09:17 +01:00
Bruno
e0cd560dfb Implementation of 2 corner masks 2020-12-31 18:27:33 +01:00
brunoherbelin
4313e51530 Minor GUI bugfix 2020-12-31 10:51:41 +01:00
brunoherbelin
e2bb90208e Bugs fixed and eye candies 2020-12-31 00:50:50 +01:00
Bruno
85d72a1c0e Transliteration of source name 2020-12-30 17:23:31 +01:00
Bruno
a073ab41dd Improved procedural masks 2020-12-27 21:43:33 +01:00
Bruno
34c24d99df Integration procedural GLSL masks 2020-12-27 14:05:03 +01:00
Bruno
69d9d9473b Implemented procedural GLSL masks
Create MaskShader and added manipulation of masks in Appearance view
2020-12-27 14:04:23 +01:00
brunoherbelin
a58c06c617 Fixed display cropped source in AppearanceView and code cleanup. 2020-12-08 23:43:50 +01:00
brunoherbelin
b7a54d0512 BugFix deep update views (depth and layout) and crop. 2020-12-08 23:04:12 +01:00
brunoherbelin
1677582034 Bug fix on deep update of views and scenes: incrementing a counter of
updates needed (instead of only a flag).
2020-12-07 23:39:41 +01:00
brunoherbelin
44b888fd04 Work in progress - implementation of cropping in Geometry view instead
of AppearanceView. Display of scaled mixing surface in Mixing and Layers
view. Changed stippling shading.
2020-12-07 00:17:10 +01:00
brunoherbelin
78f9216d32 Hiding grips in geometry manipulation when operating. 2020-12-05 00:22:46 +01:00
brunoherbelin
1ea0ec53af Minor fixed GUI and mouse cursor 2020-12-03 23:21:30 +01:00
brunoherbelin
688823e63f New doc images for Appearance view 2020-12-01 23:37:52 +01:00
BHBN
78f4b80b84 Merge pull request #13 from brunoherbelin/dev
Dev
2020-12-01 21:58:28 +01:00
brunoherbelin
bb8f536f0a BugFix user interface 2020-12-01 21:28:37 +01:00
brunoherbelin
ca51c5348e keep iTransform and color when replacing shader 2020-11-30 23:16:58 +01:00
brunoherbelin
cc4d9ede97 fixed activation of current source in selection when entering
AppearanceView
2020-11-30 23:04:38 +01:00
brunoherbelin
053c2a3f1f Cosmetics in views and GUI 2020-11-30 22:59:15 +01:00
brunoherbelin
1538e7b85b Cleanup display AppearanceView 2020-11-30 22:21:06 +01:00
brunoherbelin
61d2a4dcb9 Cleanup GUI and user feedback with crop in AppearanceView. 2020-11-30 21:39:41 +01:00
brunoherbelin
3c55e25432 Finally a working implementation of crop and UV manipulation in
AppearanceView! Added saving and loading.
2020-11-30 00:25:02 +01:00
brunoherbelin
93ad971fc0 Improved implementation of crop in AppearanceView. Not yet fully
satisfying though...
2020-11-29 23:33:53 +01:00
brunoherbelin
5200de2e3e Implementation of image transformation in shaders: iTransform is a
generic UV coordinates transformation matrix (for translation, scaling
and rotation) edited in AppearanceView. Removing previous UV editing
functions.
2020-11-29 12:31:06 +01:00
brunoherbelin
d92736b38f cleanup 2020-11-26 22:20:11 +01:00
brunoherbelin
20f1320e2d Implementation of vertical crop (2 axis projection manipulation in frame
buffer). Cleanup of UI for appearance view.
2020-11-26 20:30:37 +01:00
brunoherbelin
b6af17f283 Add soft shadow behind icons decoration to improve visibility in white
background.
2020-11-24 19:22:41 +01:00
brunoherbelin
4a6a110e3d Fixed behavior for current and edit source selection in AppearanceView. 2020-11-23 23:35:48 +01:00
brunoherbelin
7f161a0a49 Add Reference to original scale of image in AppearanceView (in
preparation to crop)
2020-11-23 00:04:03 +01:00
brunoherbelin
30301b51d4 Soft shadow behind frame handles to make them more visible in contrast. 2020-11-23 00:03:21 +01:00
brunoherbelin
c33796e97c Beta implementation of FrameBuffer projection change for cropping. 2020-11-22 21:58:04 +01:00
brunoherbelin
61ee23455b update source after action on view context menu 2020-11-22 09:16:35 +01:00
brunoherbelin
1cd36b6134 bugfix too much updating when set currentSource 2020-11-21 23:05:20 +01:00
brunoherbelin
59087f9198 Fixed current source selection behavior with swich to appearance view. 2020-11-21 21:29:08 +01:00
brunoherbelin
bb231868b4 Bugfix in UV Apprearance update. Fixed Context menu. 2020-11-18 23:16:38 +01:00
brunoherbelin
c841c0e342 Change MediaSource timeline curve to make darker instead of transparent. 2020-11-18 23:16:01 +01:00
brunoherbelin
4630d39663 New context menu in Geometry and Appearance Views: special handle (upper
left corner) with new icon and view-specific context menu on current
source.
2020-11-17 23:28:11 +01:00
brunoherbelin
3b529222d8 Completing the user actions in appearance view. 2020-11-16 23:47:02 +01:00
brunoherbelin
1ab2ae0df0 Operational implementation of UV texture coordinates changes in
Appearance View.
2020-11-16 21:43:39 +01:00
brunoherbelin
8c9b753544 First operational version of AppearanceView. Cleanup of symbols for
sources and other bugfix.
2020-11-15 23:49:56 +01:00
brunoherbelin
196ce3df1b Cleanup of surface management in Sources (centralize texturesurface_ in
Source class, avoid mistakes in subclasses). Integration of sources in
AppearanceView (not functionnal yet).
2020-11-15 13:01:06 +01:00
brunoherbelin
15a0bab925 Creating view for APPEARANCE control 2020-11-13 22:35:32 +01:00
brunoherbelin
95ed47934d making snap access /dev/video 2020-11-13 22:34:48 +01:00
brunoherbelin
8c2c2302d1 making snap access /dev/video* 2020-11-13 22:31:22 +01:00
brunoherbelin
187a6132fc fixed loop EOS 2020-11-12 22:39:14 +01:00
brunoherbelin
b3fd29056e saving uv in mix session file 2020-11-12 22:11:52 +01:00
brunoherbelin
11a58b5adf Adding UV texture coordinates to Surface and ImageShader. 2020-11-12 22:07:00 +01:00
brunoherbelin
7c5374552d set unique surface_ pointer for all source types 2020-11-12 18:38:51 +01:00
brunoherbelin
d33ff427b5 Fix single frame image (e.g. GIF) 2020-11-12 18:09:14 +01:00
brunoherbelin
32a4607673 Fixed loading and playing of GIF animation 2020-11-11 19:38:57 +01:00
brunoherbelin
6f37ca8a84 more documentation pics 2020-11-10 23:39:32 +01:00
brunoherbelin
f9dcd7348e Force stable fps for v4l2loopback (crashing drivers otherwise) 2020-11-10 22:58:05 +01:00
brunoherbelin
f4baa67089 Cleanup dialog v4l2loopback 2020-11-10 22:16:14 +01:00
brunoherbelin
39f8b56c99 Simplified v4l2loopback system 2020-11-10 20:27:03 +01:00
brunoherbelin
ea1192c334 bugfix 2020-11-10 11:02:04 +01:00
brunoherbelin
56dfbc737d Deep redesign of frame grabbers to prevent multiple frame captures
(slow) and optimize distribution of gabbed frames to multiple recording
and streaming pipelines (e.g. record H264 *and* share stream on the
network). New implementation of Loopback source for LINUX using
v4l2loopback (experimental).
2020-11-09 23:56:41 +01:00
brunoherbelin
1c1a0e9b33 Using system wide temp directory for shared memory socket 9for linux
snaps to be able to share).
2020-11-07 18:54:33 +01:00
brunoherbelin
fcc014e5d1 compilation warning fix 2020-11-07 18:36:52 +01:00
brunoherbelin
bfb0576e26 Attempt to fix vsync problem (tearing frames) under linux. 2020-11-07 18:36:34 +01:00
brunoherbelin
71140a8c6c Documenting source creation 2020-11-07 14:49:01 +01:00
brunoherbelin
6d80c798f5 Implemented Timers in Metrics toolkit 2020-11-06 23:03:20 +01:00
brunoherbelin
d3f6f2f87d switch to v0.4 confirmed 2020-11-06 19:25:35 +01:00
brunoherbelin
d1050e9fdf Merge branch 'master' of github.com:brunoherbelin/vimix 2020-11-06 19:16:49 +01:00
brunoherbelin
105294fdaf Document video share feature 2020-11-06 19:16:25 +01:00
brunoherbelin
4755f47286 Change the way to include gst-plugins-bad in OSX package 2020-11-06 19:04:43 +01:00
brunoherbelin
77da91efa5 Fix OSX cpack 2020-11-04 23:06:47 +01:00
brunoherbelin
e679f18d93 Fix OSX compilation GST Bad plugins 2020-11-04 22:47:43 +01:00
brunoherbelin
c2531cf035 BugFix stop stream without deleting it 2020-11-04 22:23:37 +01:00
brunoherbelin
2124dfc718 BugFix update frame in stream after reset 2020-11-04 22:22:48 +01:00
brunoherbelin
ce5369a0ef Default settings to not accept connections 2020-11-03 22:31:40 +01:00
brunoherbelin
ec797f8d67 Various GUI terminology changes for unified wording and clarity 2020-11-03 21:52:03 +01:00
brunoherbelin
ce7f30fa63 Minor GUI improvement connection 2020-11-03 19:13:20 +01:00
brunoherbelin
79482d3d1b Offer to reconnect a network source at anytime (there is no way to
really know if it was disconnected)
2020-11-03 18:44:12 +01:00
brunoherbelin
93e7027f48 Fixed Connection and Streamer mechanisms 2020-11-03 18:34:38 +01:00
brunoherbelin
34580ab5ea Fixup OSX system session file loading request 2020-11-03 17:56:18 +01:00
brunoherbelin
bab0e9b710 OSX support for 'OpenFile' system message (aka open vimix when selecting
session file in finder).
2020-11-02 20:55:38 +01:00
brunoherbelin
88d4e3d9d5 Added support for filename argument when running vimix (open session) 2020-11-01 23:59:24 +01:00
brunoherbelin
47c338341d Fix exit crash 2020-11-01 23:49:36 +01:00
brunoherbelin
3cae0cd66f Improved memory management Stream 2020-11-01 23:33:28 +01:00
brunoherbelin
0738c25fb4 Fix memory leak stream UDP 2020-11-01 23:32:40 +01:00
brunoherbelin
b8ebab5766 Fixing Streamer and NetworkSource dialog 2020-11-01 18:13:37 +01:00
brunoherbelin
954b35032a Fix Connection broadcaster 2020-11-01 15:11:26 +01:00
brunoherbelin
46b9a8f663 Fixed fullscreen main window for OSX 2020-11-01 13:18:49 +01:00
brunoherbelin
41f87aa927 Fix OSX fullscreen crash 2020-11-01 11:00:46 +01:00
brunoherbelin
05a4ac164e Merge branch 'master' of github.com:brunoherbelin/vimix 2020-10-31 19:23:47 +01:00
brunoherbelin
44901b1e78 various minor OSX compilation update 2020-10-31 19:21:21 +01:00
brunoherbelin
8ef79a6dbd Added frame buffer information display in session preview 2020-10-31 19:21:05 +01:00
brunoherbelin
940dd0f2a5 Using OSX avenc hardware decoder 2020-10-31 19:19:34 +01:00
brunoherbelin
4fa7e06e19 oops missing include 2020-10-26 21:43:33 +01:00
brunoherbelin
7f2c3d531c OSX compatibility posix for NetworkToolkit 2020-10-26 21:40:21 +01:00
brunoherbelin
a4621f31e3 OSX compilation compatibility 2020-10-26 19:32:19 +01:00
brunoherbelin
7438b257ae Added icon for NetworkSource (sharing logo) 2020-10-25 23:26:04 +01:00
brunoherbelin
cb6a0aefa4 Minor improvements in connection and IPC (multiple instances not fully
supported yet)
2020-10-25 23:14:47 +01:00
brunoherbelin
7fba62bc49 minor rename 2020-10-25 22:03:49 +01:00
brunoherbelin
01410a59cf Improved connection robustness and diconnection/connection behaviors
(added connection rejection to streamer).
2020-10-25 22:01:04 +01:00
brunoherbelin
e60c7a4cad Managing client name and disconnection (e.g. end vimix) 2020-10-25 18:56:56 +01:00
brunoherbelin
8fa14bda1a Fixing bugs with Network source ans Video Streamer. 2020-10-25 14:31:27 +01:00
brunoherbelin
469ee4c26a Finalizing NetworkSource (Visitors) 2020-10-25 10:00:32 +01:00
brunoherbelin
2627174fc0 To confirm: working implementation of SHM and UDP streaming connection 2020-10-25 00:23:44 +02:00
brunoherbelin
7246dfa08e Work-in progress: connection manager now used in Streamer and
NetworkSource to identify possible connections, and exchange streaming
configuration.
2020-10-24 23:53:11 +02:00
brunoherbelin
db0892d25b Defining a name for a Connection 2020-10-23 21:54:45 +02:00
brunoherbelin
509416d5a0 Connection manager seems to work... 2020-10-23 19:01:44 +02:00
brunoherbelin
43f444f07b Creation of the Connection Manager : this new mechanism continuously
checks for the presence of vimix programs in the network neibourhood.
The list of connections can then be used for indentifying streaming
requests and offers.
2020-10-23 01:02:28 +02:00
brunoherbelin
bbeb99056a Update to OSCPack v1.1 2020-10-20 18:27:26 +02:00
brunoherbelin
65aefc9fb8 Complete integration of original OSCPack lib 2020-10-20 18:18:44 +02:00
brunoherbelin
27239b7513 working on streaming and clients 2020-10-20 00:28:44 +02:00
brunoherbelin
15285ec151 Added lib OSCPack 2020-10-20 00:28:16 +02:00
brunoherbelin
d7893be541 First working implementation of Streamer, with TCP and SharedMemory. 2020-10-18 13:13:07 +02:00
brunoherbelin
59c07ceb96 First working implementation of VideoStreamer 2020-10-17 11:32:29 +02:00
brunoherbelin
007d876dbc Initial commit of Video Streamer. bugFix delete Pbos. 2020-10-14 22:58:02 +02:00
brunoherbelin
3a41e59f00 Management of recorders by id in user interface. 2020-10-14 22:37:53 +02:00
brunoherbelin
3a34da9322 Renaming Recorder to FrameGrabber 2020-10-14 21:04:22 +02:00
brunoherbelin
b3ee400b1a Hack to prevent re-openning automatically a session file in case vimix
was not properly closed (to avoid crash at start that prevent vimix from
restarting after loading a faulty session file).
2020-10-13 23:42:33 +02:00
brunoherbelin
102413c7f4 Minor compilation fixes 2020-10-12 16:41:34 +02:00
brunoherbelin
c674fa0897 Implementation of Copy, Cut & Paste of sources. Keeps description (xml)
of source in clipboard for pasting in another session or in the same
(then it clones existing sources).
2020-10-11 23:41:24 +02:00
brunoherbelin
bd922f5bcc Improved Esc key and Ctrl+Q behavior 2020-10-11 16:54:30 +02:00
brunoherbelin
1390eff646 Action manager follows View of restored action (user settings) 2020-10-11 16:02:41 +02:00
brunoherbelin
34b508a8dd BugFix: PatternSource pattern type is unsigned and undefined when
created
2020-10-11 16:01:57 +02:00
brunoherbelin
8297c85220 Cosmetic improvement of Action manager and Log messages. 2020-10-11 12:05:38 +02:00
brunoherbelin
795c0ed30f BugFix: ensure update of source after update by SessionLoader 2020-10-11 12:04:58 +02:00
brunoherbelin
babbddcf28 Improved Action manager labels of stored actions 2020-10-11 00:37:49 +02:00
brunoherbelin
650017c8f3 BugFix: history manager undo and redo for delete and recreation of
source, delete multiple sources or clones, etc.
2020-10-11 00:37:04 +02:00
brunoherbelin
2c1eaff476 improvement in order of delete in selection (for better history of
delete)
2020-10-10 15:30:28 +02:00
brunoherbelin
c0e135993c BugFix: prevent visitors for failed sources. Avoid duplicate list of
source ids.
2020-10-10 15:16:47 +02:00
brunoherbelin
22011ffd54 Avoid extension specific opengl calls (not always working...) 2020-10-10 12:02:09 +02:00
brunoherbelin
31ebccd248 Hack to prevent font oversampling for low-memory graphics card. 2020-10-10 10:48:39 +02:00
brunoherbelin
af11408ee9 Heuristics to prevent font displaying issues. 2020-10-10 10:29:11 +02:00
brunoherbelin
99f5236959 Compile issues for 64bits int under i386 2020-10-08 20:26:17 +02:00
brunoherbelin
67463d2214 Prevent erroneous font size 2020-10-07 22:04:20 +02:00
brunoherbelin
3aabb83ccf BugFix: remove session filename from list or recent files if failed
loading.
2020-10-07 20:18:11 +02:00
brunoherbelin
82b755db84 Merge branch 'master' of github.com:brunoherbelin/vimix 2020-10-07 19:50:09 +02:00
brunoherbelin
10dc426119 Fixed compilation issue (OSX) 2020-10-07 12:07:03 +02:00
brunoherbelin
233fc64c4e Increased size of unique identifier of objects: using uint64 instead of
int. Deep change in all concerned objects (Node, Source, Shader, etc.).
No behavior change, just more robust in duration.
2020-10-06 22:45:52 +02:00
brunoherbelin
977ae76f9b Eye candy; rounding up the font size in monitor. 2020-10-06 21:40:16 +02:00
brunoherbelin
77d9b17ac8 HistoryManager: new widget and extending scope of historized user
actions.
2020-10-06 21:39:37 +02:00
brunoherbelin
6f4b75ec1c Cleanup z compression XML array 2020-10-06 09:11:16 +02:00
brunoherbelin
2faa499ace Z-compression of the timeline fading when saving to XML; data on disk
are much faster to load, and files smaller.
2020-10-06 00:03:26 +02:00
brunoherbelin
2493d8d9f9 Added ImGUI actions to ActionManager history. 2020-10-04 23:34:59 +02:00
brunoherbelin
616c6c8bdf First working implementation of ActionManager, but incomplete. 2020-10-04 22:52:23 +02:00
brunoherbelin
5421b5e926 Cleanup Session loading (prepare for session history) 2020-10-03 18:45:30 +02:00
brunoherbelin
d563ee14a9 Cleanup source id management, and improved session merging and source
renaming.
2020-10-03 17:54:34 +02:00
brunoherbelin
3e5b1e74e8 Adding ActionManager 2020-10-03 14:05:58 +02:00
brunoherbelin
f32b85a656 Centralizing and unifying the generator of object identifiers. 2020-10-03 14:05:28 +02:00
brunoherbelin
61e5c046c0 possible implementation of a confirmation action when deleting source 2020-10-02 18:24:51 +02:00
brunoherbelin
0eaffe213a Changed order of filter sliders, and publish related documentation 2020-10-02 13:24:39 +02:00
brunoherbelin
b2a316b813 Updated description (link to user manual) 2020-10-02 12:06:31 +02:00
brunoherbelin
fac798df93 BugFix: prevent from creating twice a source with the same device:
create a clone of the original device source instead.
2020-10-01 23:44:14 +02:00
brunoherbelin
83a2da6b2b Setup icon (i,j coordinates in ImGui Toolkit) for each Source class, and
use this icon in GUI to indicate the type of class.
2020-10-01 22:57:49 +02:00
brunoherbelin
467ed23b37 Optimizing size of icon file 2020-10-01 22:11:56 +02:00
brunoherbelin
41e0a6f0be updtate gitignore 2020-09-30 23:40:41 +02:00
brunoherbelin
00ebacc9db Clean source icons 2020-09-30 23:38:38 +02:00
brunoherbelin
e0d44d4db1 LICENSE for icons 2020-09-30 23:23:19 +02:00
brunoherbelin
e8a88fcbb9 Improve icons 2020-09-30 23:21:43 +02:00
brunoherbelin
d4b014188e Fixed DeviceSource pannel config 2020-09-30 22:32:29 +02:00
brunoherbelin
b05207b27d Implementation of Device source for OSX. Improved support for various
frame formats and fps
2020-09-30 20:32:05 +02:00
brunoherbelin
c777a3d153 work in progress: implementation of stash in MixingView 2020-09-30 12:01:40 +02:00
brunoherbelin
1bada746dc Increase snap version to 0.3 (matching vimix internal version) 2020-09-28 23:04:55 +02:00
brunoherbelin
0d53afb6fd Fixed order for new patterns 2020-09-28 23:00:15 +02:00
brunoherbelin
3b31d33c90 Improved zoom slider scaling and display 2020-09-28 22:59:53 +02:00
brunoherbelin
dcffb1cbaa Change 'error' message for canceled (not failed) loading of session 2020-09-27 23:57:47 +02:00
brunoherbelin
bbd105983d Playing with patterns 2020-09-27 23:57:15 +02:00
brunoherbelin
1d7e0838fa New UI for scaling (zoom) view from view pannel icon. 2020-09-27 21:04:40 +02:00
brunoherbelin
d9a205d9ab More images for manual 2020-09-26 21:28:10 +02:00
brunoherbelin
39ceea9690 Remove debug info 2020-09-26 20:02:36 +02:00
brunoherbelin
89891a18e5 Minor bug fix PatternSource. 2020-09-26 20:02:17 +02:00
brunoherbelin
2b59a0e6ed Added images for wiki 2020-09-26 19:38:56 +02:00
brunoherbelin
688aee8831 Fixed resolution issue with different monitor DPI. 2020-09-26 14:25:11 +02:00
brunoherbelin
047163a38c Merge branch 'master' of github.com:brunoherbelin/vimix into testing_gst 2020-09-26 12:31:47 +02:00
brunoherbelin
df2a66484b First minimal implementation of Screen device for screen capture under
Linux (ximagesrc). Cleanup code.
2020-09-26 12:22:15 +02:00
brunoherbelin
69c74aa103 Save & Load Device Source. 2020-09-25 22:03:31 +02:00
brunoherbelin
a4ff2a325f Improved detection of unplugged device 2020-09-25 21:44:38 +02:00
brunoherbelin
7109b94484 Cleanup DeviceSource and PatternSource (no feature change) 2020-09-25 21:20:24 +02:00
brunoherbelin
202db9eaa2 First draft of an automatic discoverer for gst device source caps
(framerate, resolution and image format) to enable auto creation of
DeviceSource.
2020-09-25 00:05:35 +02:00
brunoherbelin
84caf2da9a Integrated preliminary implementation of Device class with monitoring of
v4l2 device connected to the machine using GstDeviceMonitor.
2020-09-23 23:29:45 +02:00
brunoherbelin
9e160fec51 Fixed Device source by enabling/disabling the sync option of GstAppSink
depending on the live mode of the pipeline (detected at pipeline first
status change). Cleanup and unified info debug messages of all stream
sources.
2020-09-23 17:28:45 +02:00
brunoherbelin
b7d54dfadf Creation of the base class StreamSource. It is intended to become the
base class for all gstreamer pipeline. DeviceSource and PatternSource
inherit from it. A generic stream source class is created for
development tests and hack.
2020-09-22 22:58:37 +02:00
brunoherbelin
04e03456bf Updated OSX gst-bad plugin to 18.0 for install. 2020-09-21 23:25:29 +02:00
brunoherbelin
e84b16c9ce Unfortunately some frei0r patterns are not available under OSX; removing
them for the default patterns.
2020-09-21 23:01:54 +02:00
brunoherbelin
9251aff19f Create Device Source and integration of Stream 2020-09-21 22:41:20 +02:00
brunoherbelin
519baf7a3b Unified GUI behavior for source creation. cleanup of history of recent
files after loading error.
2020-09-20 11:28:09 +02:00
brunoherbelin
59db2cf57c Implementation of new type of source: Pattern generator (GUI, icons,
saving). A new class for gstreamer stream (Stream) is defined for
generic pipeline sources; to be integrated (inheritance) into
MediaPlayer.
2020-09-20 00:26:39 +02:00
brunoherbelin
db6d3a6fa0 Support for 21:9 aspect ratio 2020-09-19 20:45:16 +02:00
brunoherbelin
1209d337bc Updated webpage image + link to wiki 2020-09-19 01:04:05 +02:00
brunoherbelin
b0e54c6ff5 Increased range for UI scaling 2020-09-16 22:04:30 +02:00
brunoherbelin
76f067de55 Merge branch 'master' of github.com:brunoherbelin/vimix 2020-09-16 21:36:32 +02:00
brunoherbelin
2127c53d50 Fixed OSX gst-bad plugin missing 2020-09-16 21:21:35 +02:00
brunoherbelin
bf5913fb3d Fixed OSX compilation of Bundle. TODO: script localization of libs 2020-09-16 21:09:07 +02:00
brunoherbelin
9e32e4f5b2 Improved user feedback on session loading 2020-09-16 08:34:53 +02:00
brunoherbelin
76926f433c Also draw frames of all sources in GeometryView 2020-09-15 20:19:10 +02:00
brunoherbelin
e03db22092 Fixed selection behavior: bounding box now correctly takes into account
transformations of the sources, and selects only those inside the
selection bounding box.
2020-09-14 23:04:59 +02:00
brunoherbelin
34659c4d8a Bugfix (crash on close after failed open) 2020-09-14 21:38:40 +02:00
brunoherbelin
caa39237ac Merge branch 'master' of github.com:brunoherbelin/vimix 2020-09-13 23:21:53 +02:00
brunoherbelin
68b219eef2 BugFix: prevent crash and report correct warning message on media player
loading error.
2020-09-13 23:21:37 +02:00
brunoherbelin
5ebf80b0cd Bugfix: do not add recent folder if user cancel dialog 2020-09-13 23:20:59 +02:00
brunoherbelin
fb2d43b022 Prevent smooth cursor during mouse multiple selection 2020-09-13 22:40:19 +02:00
brunoherbelin
67fa3c9ec8 Visual feedback on smooth cursor 2020-09-13 22:32:52 +02:00
brunoherbelin
041551535e Added visual feedback on source active/deactive area in MixingView 2020-09-13 22:18:10 +02:00
brunoherbelin
5895e203ba Initial implementation of cursor smoothing 2020-09-13 22:02:49 +02:00
brunoherbelin
3152e420dc osx package update 2020-09-13 19:31:03 +02:00
brunoherbelin
fa7257fe92 Compilation warnings 2020-09-13 17:44:40 +02:00
brunoherbelin
077bf3430b Merge branch 'master' of github.com:brunoherbelin/vimix 2020-09-13 17:33:40 +02:00
brunoherbelin
bcfbf184c6 modifiers for other views 2020-09-13 17:33:22 +02:00
brunoherbelin
b9f0c259e3 OSX compile 2020-09-13 12:23:43 +02:00
brunoherbelin
6ef5642e63 Added visual indicator of current rotation in geometryview 2020-09-13 10:31:40 +02:00
brunoherbelin
29a9b1daf8 Fixed picking visitor and source node inclusion test for source
manipulation in GeometryView
2020-09-13 00:06:23 +02:00
brunoherbelin
526e0f29cb Added overlay for Translation in GeometryView 2020-09-12 13:55:30 +02:00
brunoherbelin
d290b058eb Added overlay of active resize corner in GeometryView, and overlay to
show fixe-size rotation.
2020-09-12 12:24:25 +02:00
brunoherbelin
68c7262aac Eye candy for GeometryView 2020-09-12 11:41:01 +02:00
brunoherbelin
68d3c1aee1 new meshes for Geometry View 2020-09-12 11:29:46 +02:00
brunoherbelin
a5545147f0 Improved user visual feedback on geometryview actions (rotation and
scaling).
2020-09-09 23:39:08 +02:00
brunoherbelin
32234c4d7c Starting implementation of overlay in GeometryView to inform on the
current action (Rotation, Scaling).
2020-09-08 23:45:36 +02:00
brunoherbelin
2c52530a92 User feedback for geometry actions 2020-09-07 23:08:53 +02:00
brunoherbelin
69b1f792ba Fixed SHIFT+border rescale for mirror scaling 2020-09-06 22:40:11 +02:00
brunoherbelin
e80b174db3 Fixed (again) display of Rotation and Scaling handles (robust to
negative scaling mirroring the rendering)
2020-09-06 22:28:47 +02:00
brunoherbelin
90715173f7 Cosmetics. Fixed orientation of mouse cursor for resize 2020-09-06 19:19:25 +02:00
brunoherbelin
4e1611aa07 Fixed mirroring of scaling and rotation handles 2020-09-06 14:19:44 +02:00
brunoherbelin
1b4d49e80e Finally a unified behavior for scaling and rotation of sources in
GeometryView: SHIFT to enable proportional Aspect-Ratio, ALT to stap to
grid
2020-09-06 12:23:53 +02:00
brunoherbelin
e546214018 New handle in GeometryView for Proportional scaling of source: added
drawing of Handle, Picking visitor and View Geometry scaling.
2020-09-05 00:19:22 +02:00
brunoherbelin
764259f93a improved SHIFT action on scaling in geometry view (discretize on node
scale value, not on node transform)
2020-09-03 22:27:45 +02:00
brunoherbelin
cc3f824bfa Unified behavior in Geometry view: SHIFT for discrete transform (unit
translation, rotation, scaling) and ALT key for alternative transform
(central scaling, axis translation)
2020-09-03 00:07:57 +02:00
brunoherbelin
3ca6bfa396 Implementation of corner scaling in geometry view. 2020-09-02 22:26:40 +02:00
brunoherbelin
c8ac4b2d95 Added ALT keyboard modifier handling for alternative GUI actions 2020-08-29 13:09:11 +02:00
brunoherbelin
5f86afac0c Tests with GstDeviceMonitor 2020-08-29 09:56:18 +02:00
brunoherbelin
6213f3da59 Fixed interpolation alpha in timeline 2020-08-28 22:29:20 +02:00
brunoherbelin
f90964bac8 Do not use first key frame in timeline. 2020-08-24 22:18:43 +02:00
brunoherbelin
e41868d405 Improved GUI context menu timeline 2020-08-24 12:17:18 +02:00
brunoherbelin
d49bea5723 Fixed compilation issue OSX 2020-08-24 12:16:59 +02:00
brunoherbelin
240f1fde0a Saving and loading of timeline, with fading and gaps. Applying fading to
MediaSource. Playing with timeline options to facilitate its use.
2020-08-24 00:23:03 +02:00
brunoherbelin
86fd5f21f3 Creation of a new widget to display and edit timeline: combined plot of
lines (for alpha) and histogram (for gaps).
2020-08-23 00:40:44 +02:00
brunoherbelin
0d934c3590 Fixed User seek request with timeline constraints (request go to
position instead of directly seek)
2020-08-22 14:20:00 +02:00
brunoherbelin
e44832a419 Fixed behavior seek in timeline: prevent multiple successive seek
events, save and load gaps in XML session.
2020-08-22 00:03:22 +02:00
brunoherbelin
9f954d258f tiny bugfix timeline gaps 2020-08-21 23:03:36 +02:00
brunoherbelin
710514b478 Revert behavior of MediaPlayer position to normal and instead fixed the
GUI to match the [start end] range of timeline (instead of shifting
position in MediaPlayer). Fixed Loop mode for bi-directional and stop
modes to react according to Timeline gaps.
2020-08-21 00:58:20 +02:00
brunoherbelin
13867e2192 Unified identifyer mechanism (tested and confirmed to produce unique
integer < MAX_INT)
2020-08-20 20:51:42 +02:00
brunoherbelin
d7f6461415 Changed the way the MediaPlayer is not missing an EOS: former
implementation was jumping forward too early.
2020-08-20 20:33:23 +02:00
brunoherbelin
182f204d80 Working but dirty implementation of GUI for Timeline and gaps of
MediaPlayer.
2020-08-19 23:15:54 +02:00
brunoherbelin
a4b61927bc minor improvement codec recorder 2020-08-16 23:36:26 +02:00
brunoherbelin
857274c2f3 Re-implemented multi-threaded openning of file dialogs (with tinyfd)
using std::future for cleaner thread-safety.
2020-08-16 22:17:42 +02:00
brunoherbelin
3469e50f0a better end of init 2020-08-16 20:41:52 +02:00
brunoherbelin
23800b17b4 Fixed creation of empty session source. 2020-08-16 20:31:09 +02:00
brunoherbelin
f6588de023 Unified use of std::future for loading sessions in Mixer and
SessionSource.
2020-08-16 19:10:23 +02:00
brunoherbelin
c6d8c7189f Cleanup after all these changes in MediaPlayer and Mixer. 2020-08-16 16:16:05 +02:00
brunoherbelin
36b57c1499 upgrade 2020-08-15 22:42:06 +02:00
brunoherbelin
f3487d2074 Re-activating threaded loading of session. Seems stable now. 2020-08-15 22:41:24 +02:00
brunoherbelin
35cd5c6a21 unref gst discoverer 2020-08-15 22:40:33 +02:00
brunoherbelin
ab031cf340 Fixed deletion of clone: remove from origin!!! 2020-08-15 22:40:12 +02:00
brunoherbelin
0e2af5b04f fighting the crash everywhere: random crash at random location. Changing
computer might be better idea than changing the code indefinitely...
2020-08-15 18:05:18 +02:00
brunoherbelin
44b9169cdc Changed MediaPlayer discovering process: using thread to perform
discovery (instead of async gstreamer callback).
2020-08-15 09:12:06 +02:00
brunoherbelin
5763a9e756 Thread safe loading and saving of session: use of std::future. 2020-08-14 22:28:36 +02:00
brunoherbelin
e73ebeab93 Disabling threaded session loading: crashing :( 2020-08-12 23:12:20 +02:00
brunoherbelin
ce6f198f08 Prevent possible invalid access to origin in clone 2020-08-12 22:54:16 +02:00
brunoherbelin
2f6f67bdd3 SessionCreator xmldoc not by pointer. 2020-08-12 22:53:35 +02:00
brunoherbelin
a7ba118562 cleanup thread behavior for file dialog. Added keyboard shortcut
SHIFT+CTRL+O for re-openning current file: not public yet (to validate)
2020-08-12 22:52:25 +02:00
brunoherbelin
bb1682768a Fixed seek behavior: sync if necessary in update. 2020-08-12 22:49:48 +02:00
brunoherbelin
3c5c6ef8ed Improve thread safety of Mixer (loading and importing sessions) 2020-08-12 22:46:58 +02:00
brunoherbelin
3d77642d3b Simplified Node id 2020-08-12 22:09:38 +02:00
brunoherbelin
675856d57c Fixed memory leak in gst media player (Valgrind) 2020-08-11 23:02:28 +02:00
brunoherbelin
bb8dcf088e work in progress cleanum memory leak and crash :( 2020-08-11 00:11:22 +02:00
brunoherbelin
c829e5a40c Minor improvement display timeline 2020-08-07 18:36:40 +02:00
brunoherbelin
98f9f4a225 New Timeline class to manage segments of media player. 2020-08-06 23:18:35 +02:00
brunoherbelin
3f568f714a Cleanup of Media Player class 2020-08-06 23:17:22 +02:00
brunoherbelin
2863a1f3c9 improved text display of time with 3 modes depending on the needs. 2020-08-04 19:05:03 +02:00
brunoherbelin
6f844f722d Improved Media player timeline: adding time indication and enabling to
scroll in a zoomed-in timeline. Display current time in overlay on
frame.
2020-08-04 00:01:30 +02:00
brunoherbelin
763d8ac423 Updated webpage with link to snapcraft 2020-08-02 21:22:21 +02:00
brunoherbelin
fa652d74dc Removed dependency snapcraft interface personal-files 2020-08-02 20:16:43 +02:00
brunoherbelin
96fb3ab951 does not cpack anymore under OSX :( 2020-08-02 17:59:01 +02:00
brunoherbelin
929bf7981a Changed my mind: using an even more clear toggle button for image
processing on/off.
2020-08-02 13:49:02 +02:00
brunoherbelin
37eb845fe4 Improved icon and tooltip for GPU image processing button. 2020-08-02 13:41:18 +02:00
brunoherbelin
e9440c2326 Avoid unsupported x264 image format (4:4:4 is not standard) 2020-08-02 13:20:25 +02:00
brunoherbelin
f19958d744 Fixed for high dpi 2020-08-02 13:05:44 +02:00
brunoherbelin
66977453e1 Update About dialog to link to new github web page. 2020-08-02 11:41:38 +02:00
brunoherbelin
ed596f0ba5 Fixed system toolkit: use $HOME for location of settings. Compilation
warning fixed.
2020-08-02 11:25:28 +02:00
brunoherbelin
96d71387dc Fixing access to settings path for Linux snap. 2020-08-02 00:52:42 +02:00
brunoherbelin
cfd94317cd improved webpage 2020-08-01 22:10:41 +02:00
brunoherbelin
ec2a65cbba Change github page template 2020-08-01 21:59:18 +02:00
BHBN
6941d9e999 added screenshot to page 2020-08-01 21:39:47 +02:00
BHBN
7eb5ffaa0d Set theme jekyll-theme-midnight 2020-08-01 20:43:26 +02:00
brunoherbelin
a3f5ae9e71 github page content 2020-08-01 20:39:57 +02:00
brunoherbelin
2fb3c2baf2 Merge branch 'master' of github.com:brunoherbelin/vimix 2020-08-01 20:38:38 +02:00
brunoherbelin
25b8d59570 github page 2020-08-01 20:38:07 +02:00
BHBN
1e67720c2a Set theme jekyll-theme-slate 2020-08-01 20:34:22 +02:00
BHBN
531c053db4 Set theme jekyll-theme-midnight 2020-08-01 20:28:56 +02:00
brunoherbelin
d591e24a46 Create Docs folder 2020-08-01 20:26:26 +02:00
brunoherbelin
1acf409b58 cleanup Readme 2020-08-01 19:51:05 +02:00
brunoherbelin
676b69cf1b Fixed snap & readme 2020-08-01 18:51:48 +02:00
brunoherbelin
e3563190d3 vimix snap for Core18. 2020-08-01 13:36:47 +02:00
brunoherbelin
6e002a8451 backward compatibility with glfw v3.2 2020-08-01 12:06:18 +02:00
brunoherbelin
cb62706791 updated readme for v0.2 2020-07-31 21:06:02 +02:00
brunoherbelin
93e3242aba packaging snap for linux 2020-07-31 21:05:24 +02:00
brunoherbelin
0bd611998d increase to v0.2 2020-07-31 00:15:22 +02:00
brunoherbelin
fcb4819341 validate v0.2 on OSX. 2020-07-31 00:12:19 +02:00
brunoherbelin
cc42e5581a Added (hidden) vimix config options in vimix about. 2020-07-30 23:28:28 +02:00
brunoherbelin
066b40723f Stabilized implementation of fading control, with change of view and
trigger of smooth transition. Bugfix with image processing shader
change.
2020-07-30 23:24:59 +02:00
brunoherbelin
c9882190b0 Enable dynamic change of image processing Shader on source. 2020-07-30 09:39:04 +02:00
brunoherbelin
dbdcaab6b2 Source imageProcessingEnabled on/off with storage of previous state and
saving in mix file.
2020-07-30 08:45:01 +02:00
brunoherbelin
fd0979887a First implementation of image processing shader de-activation for
sources.
2020-07-30 02:03:01 +02:00
brunoherbelin
a85ded6b5a Merge branch 'master' of github.com:brunoherbelin/vimix 2020-07-30 01:02:54 +02:00
brunoherbelin
0379d59d53 disabled the uridecodebin buffering: not working. 2020-07-30 01:00:15 +02:00
brunoherbelin
8f9bb45956 need to add gst plugins ugly in OSX package 2020-07-30 00:51:27 +02:00
brunoherbelin
2c87aab671 testing disabling image processing for performance 2020-07-30 00:49:38 +02:00
brunoherbelin
6bcacdaa4e clear depth buffer 2020-07-30 00:49:17 +02:00
brunoherbelin
4f3114770d Cleanup OpenGL texture for optimal performance: using GL4 glTexStorage2D
with RGBA8 (most efficient implementation in hardware).
2020-07-30 00:13:46 +02:00
brunoherbelin
4f17620cae Intregration of session fading with transition and session source
management.
2020-07-29 19:02:43 +02:00
brunoherbelin
837eb2d569 New: implementation of fading slider in MixingView. Needed to implement
decoration Disk and to update picking visitor.
2020-07-29 17:06:08 +02:00
brunoherbelin
714f2bea3c Tuning mediaplayer pipeiine (buffering and color conversion( and add
more info
2020-07-29 00:10:36 +02:00
brunoherbelin
2eb59f2ffe Fixed mediaplayer loop on EOS for both rate directions. 2020-07-28 21:52:18 +02:00
brunoherbelin
fd30b742b8 Enable using smooth transition when closing/new session. 2020-07-28 19:08:59 +02:00
brunoherbelin
d914eb622f bugfix; enable creating empty session 2020-07-28 19:08:04 +02:00
brunoherbelin
650066d995 Smoother alpha transition in mixing view. Also force use of opacity
blending in mixing view for clarity.
2020-07-28 17:29:53 +02:00
brunoherbelin
acd0689899 Finetuning recorder options 2020-07-28 12:50:31 +02:00
brunoherbelin
4023b6d32f bugfix: do not use global pointer to recorder 2020-07-28 12:36:40 +02:00
brunoherbelin
b04fce5031 Added recorder H265 encoder profiles 2020-07-28 12:26:41 +02:00
brunoherbelin
5c6a5b57b1 Minor adjustments video recorder 2020-07-28 11:24:30 +02:00
brunoherbelin
e7107ca6c0 Added Timeout to recorder in User Interface and Settings, and duration
query on Recorder.
2020-07-27 23:19:12 +02:00
brunoherbelin
5010ec85cd Finetuning options for ProRes and VP8 encoders to achieve reasonable
performance and quality. Added MultipleJpeg recording profile.
2020-07-27 22:11:47 +02:00
brunoherbelin
c788187e3b Bugfix: display gstreamer plugins after filter 2020-07-27 16:21:10 +02:00
brunoherbelin
d9a93bb6c6 display Recorder information of actualy running recorder(s). 2020-07-27 16:16:52 +02:00
brunoherbelin
e7634941ad pedantic clang compiler 2020-07-27 16:16:16 +02:00
brunoherbelin
73efc1fd67 Merge branch 'master' of https://github.com/brunoherbelin/vimix 2020-07-27 16:00:18 +02:00
brunoherbelin
3bb3e66f55 Implementation of Recorder with dual PBO mechanism for best efficiency
and compatibility. Fixed user interface and avoid user creating multiple
recorders.
2020-07-27 15:56:24 +02:00
brunoherbelin
371ccb3445 Merge branch 'master' of https://github.com/brunoherbelin/vimix 2020-07-27 11:46:02 +02:00
brunoherbelin
3f782736ac Fixed Recorder and Session to allow transfer of recorders when changing
session.
2020-07-27 11:45:15 +02:00
brunoherbelin
60880a1a8b First operational implementation of video recorder. 2020-07-26 23:54:29 +02:00
brunoherbelin
ab7ce4aa40 Video recorder parameters and process figured out. 2020-07-26 19:33:39 +02:00
brunoherbelin
9fdc9e6c1a Early testing of video Recorder 2020-07-26 01:28:20 +02:00
brunoherbelin
bc83f8a41c cleanup includes 2020-07-26 01:27:33 +02:00
brunoherbelin
41d0ef9132 cleanup 2020-07-25 11:48:51 +02:00
brunoherbelin
ffc700c127 Buttons to navigate (< and >) in list of media in media player. 2020-07-24 19:54:36 +02:00
brunoherbelin
18a538a0e9 just a 'next video' button for media player. 2020-07-24 10:29:46 +02:00
brunoherbelin
533d372f9a Changed label and keyboard shortcuts for media player and output
preview.
2020-07-24 00:45:26 +02:00
brunoherbelin
978bbff9a7 Implementation of Recorder class. For now, only a capture to PNG is
available, but the mechanism is in place for video capture.
2020-07-23 23:50:32 +02:00
brunoherbelin
ad15f2096b Fixup OSX execution & packaging. 2020-07-23 15:35:59 +02:00
brunoherbelin
cec49a9a62 Cleanup MediaPlayer 2020-07-23 12:59:42 +02:00
brunoherbelin
8e9439104c Entire rebuild of gstreamer sinkapp: using callbacks instead of signals
(more efficient) and always displaying the last read frame. Using frame
status to manage End-of-stream and pre-roll special cases.
2020-07-22 23:44:55 +02:00
862 changed files with 82891 additions and 19058 deletions

50
.github/workflows/jekyll-gh-pages.yml vendored Normal file
View File

@@ -0,0 +1,50 @@
# Sample workflow for building and deploying a Jekyll site to GitHub Pages
name: Deploy Jekyll with GitHub Pages dependencies preinstalled
on:
# Runs on pushes targeting the default branch
push:
branches: ["master"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Pages
uses: actions/configure-pages@v2
- name: Build with Jekyll
uses: actions/jekyll-build-pages@v1
with:
source: ./docs
destination: ./_site
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1

18
.gitignore vendored
View File

@@ -14,3 +14,21 @@ libTINYXML2.a
libvmix-resources.a
rules.ninja
/vmix
/vimix_*.snap
/CMakeLists.txt.user.*
rsc/shaders/paint.fs
osx/.DS_Store
.DS_Store
osx/runvimix
*.autosave
flatpak/.flatpak-builder
flatpak/repo/
flatpak/build/

9
.gitmodules vendored
View File

@@ -13,9 +13,12 @@
[submodule "ext/Dirent"]
path = ext/Dirent
url = https://github.com/tronkko/dirent.git
[submodule "ext/tfd"]
path = ext/tfd
url = https://github.com/native-toolkit/tinyfiledialogs.git
[submodule "ext/glm"]
path = ext/glm
url = https://github.com/g-truc/glm.git
[submodule "ext/link"]
path = ext/link
url = https://github.com/Ableton/link.git
[submodule "ext/tfd"]
path = ext/tfd
url = https://git.code.sf.net/p/tinyfiledialogs/code

View File

@@ -1,66 +0,0 @@
#include <glm/gtc/matrix_transform.hpp>
#include "BoundingBoxVisitor.h"
#include "Log.h"
#include "Primitives.h"
#include "Decorations.h"
BoundingBoxVisitor::BoundingBoxVisitor(): Visitor()
{
modelview_ = glm::identity<glm::mat4>();
}
void BoundingBoxVisitor::setModelview(glm::mat4 modelview)
{
modelview_ = modelview;
}
GlmToolkit::AxisAlignedBoundingBox BoundingBoxVisitor::bbox()
{
return bbox_;
}
void BoundingBoxVisitor::visit(Node &n)
{
// use the transform modified during update modelview_ *= n.transform_;
glm::mat4 transform_local = GlmToolkit::transform(n.translation_, n.rotation_, n.scale_);
modelview_ *= transform_local;
}
void BoundingBoxVisitor::visit(Group &n)
{
if (!n.visible_)
return;
glm::mat4 mv = modelview_;
for (NodeSet::iterator node = n.begin(); node != n.end(); node++) {
if ( (*node)->visible_ )
(*node)->accept(*this);
modelview_ = mv;
}
}
void BoundingBoxVisitor::visit(Switch &n)
{
if (!n.visible_ || n.numChildren() < 1)
return;
glm::mat4 mv = modelview_;
n.activeChild()->accept(*this);
modelview_ = mv;
}
void BoundingBoxVisitor::visit(Primitive &n)
{
if (!n.visible_)
return;
bbox_.extend(n.bbox().transformed(modelview_));
// Log::Info("visitor box (%f, %f)-(%f, %f)", bbox_.min().x, bbox_.min().y, bbox_.max().x, bbox_.max().y);
}
void BoundingBoxVisitor::visit(Scene &n)
{
n.ws()->accept(*this);
}

View File

@@ -1,186 +1,143 @@
#####
##### This file is part of vimix - video live mixer
##### **Copyright** (C) 2019-2023 Bruno Herbelin <bruno.herbelin@gmail.com>
#####
cmake_minimum_required(VERSION 3.8.0)
cmake_minimum_required(VERSION 3.8.2)
project(vimix VERSION 0.0.1 LANGUAGES CXX C)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "ON")
set(CMAKE_INCLUDE_CURRENTDIR ON)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules )
#####
##### Use git to read version from tags
#####
find_package (Git)
if(GIT_EXECUTABLE)
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_DESCRIBE_VERSION
RESULT_VARIABLE GIT_DESCRIBE_ERROR_CODE
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(NOT GIT_DESCRIBE_ERROR_CODE)
string(SUBSTRING ${GIT_DESCRIBE_VERSION} 0 1 VIMIX_VERSION_MAJOR)
string(SUBSTRING ${GIT_DESCRIBE_VERSION} 2 1 VIMIX_VERSION_MINOR)
string(LENGTH ${GIT_DESCRIBE_VERSION} VIMIX_VERSION_LENGTH)
if (VIMIX_VERSION_LENGTH GREATER 4)
string(SUBSTRING ${GIT_DESCRIBE_VERSION} 4 1 VIMIX_VERSION_PATCH)
else()
set(VIMIX_VERSION_PATCH "0")
endif()
add_definitions(-DVIMIX_VERSION_MAJOR=${VIMIX_VERSION_MAJOR})
add_definitions(-DVIMIX_VERSION_MINOR=${VIMIX_VERSION_MINOR})
add_definitions(-DVIMIX_VERSION_PATCH=${VIMIX_VERSION_PATCH})
message(STATUS "Compiling vimix version ${VIMIX_VERSION_MAJOR}.${VIMIX_VERSION_MINOR}.${VIMIX_VERSION_PATCH}")
endif()
endif()
#####
##### Find the cmake modules
#####
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} /usr/share/cmake ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules )
include(MacroLogFeature)
include(MacroFindGStreamerLibrary)
#####
##### Configure cmake
#####
set(BUILD_STATIC_LIBS ON)
set(CMAKE_INCLUDE_CURRENTDIR ON)
if(UNIX)
if (APPLE)
add_definitions(-DAPPLE)
# the RPATH to be used when installing
set(CMAKE_SKIP_RPATH TRUE)
set(OpenGL_DIR /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/)
set(CMAKE_OSX_ARCHITECTURES x86_64)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13")
set(CMAKE_OSX_ARCHITECTURES "x86_64")
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.14")
# CPACK
set(CPACK_SYSTEM_NAME "OSX_${CMAKE_OSX_DEPLOYMENT_TARGET}_${CMAKE_OSX_ARCHITECTURES}")
set(CPACK_GENERATOR DragNDrop)
set(CPACK_BINARY_DRAGNDROP ON)
set(APPLE_CODESIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/osx/entitlements.plist")
# find icu4c in OSX (pretty well hidden...)
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/opt/icu4c/lib/pkgconfig")
else()
add_definitions(-DLINUX)
# CPACK
set(CPACK_SYSTEM_NAME "${CMAKE_HOST_SYSTEM_NAME}")
# linux opengl
set(OpenGL_GL_PREFERENCE "GLVND")
# linux dialogs use GTK
find_package(GTK 3.0 REQUIRED)
macro_log_feature(GTK_FOUND "GTK" "GTK cross-platform widget toolkit" "http://www.gtk.org" TRUE)
endif()
add_definitions(-DUNIX)
elseif(WIN32)
add_definitions(-DWIN32)
add_definitions(-DMINGW32)
endif(UNIX)
endif()
#####
##### Dependencies
#####
# Include the CMake RC module
include(CMakeRC)
#
# Basics
#
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
find_package(ZLIB REQUIRED)
#
# GSTREAMER
#
find_package(GLIB2 REQUIRED)
macro_log_feature(GLIB2_FOUND "GLib" "GTK general-purpose utility library" "http://www.gtk.org" TRUE)
find_package(GObject REQUIRED)
macro_log_feature(GOBJECT_FOUND "GObject" "GTK object-oriented framework" "http://www.gtk.org" TRUE)
find_package(GStreamer 1.0.0 COMPONENTS base)
macro_log_feature(GSTREAMER_FOUND "GStreamer"
"Open Source Multiplatform Multimedia Framework"
"http://gstreamer.freedesktop.org/" TRUE "1.0.0")
macro_log_feature(GSTREAMER_BASE_LIBRARY_FOUND "GStreamer base library"
"${GSTREAMER_BASE_LIBRARY}"
"http://gstreamer.freedesktop.org/" FALSE "1.0.0")
find_package(GStreamerPluginsBase 1.0.0 COMPONENTS app audio video pbutils gl)
macro_log_feature(GSTREAMER_APP_LIBRARY_FOUND "GStreamer app library"
"${GSTREAMER_APP_LIBRARY}"
macro_log_feature(GSTREAMER_APP_LIBRARY_FOUND "GStreamerPluginsBase" "GStreamer app library"
"http://gstreamer.freedesktop.org/" TRUE "1.0.0")
macro_log_feature(GSTREAMER_AUDIO_LIBRARY_FOUND "GStreamer audio library"
"${GSTREAMER_AUDIO_LIBRARY}"
macro_log_feature(GSTREAMER_AUDIO_LIBRARY_FOUND "GStreamerPluginsBase" "GStreamer audio library"
"http://gstreamer.freedesktop.org/" TRUE "1.0.0")
macro_log_feature(GSTREAMER_VIDEO_LIBRARY_FOUND "GStreamer video library"
"${GSTREAMER_VIDEO_LIBRARY}"
macro_log_feature(GSTREAMER_VIDEO_LIBRARY_FOUND "GStreamerPluginsBase" "GStreamer video library"
"http://gstreamer.freedesktop.org/" TRUE "1.0.0")
macro_log_feature(GSTREAMER_PBUTILS_LIBRARY_FOUND "GStreamer pbutils library"
"${GSTREAMER_PBUTILS_LIBRARY}"
macro_log_feature(GSTREAMER_PBUTILS_LIBRARY_FOUND "GStreamerPluginsBase" "GStreamer pbutils library"
"http://gstreamer.freedesktop.org/" TRUE "1.0.0")
macro_log_feature(GSTREAMER_GL_LIBRARY_FOUND "GStreamer opengl library"
"${GSTREAMER_GL_LIBRARY}"
macro_log_feature(GSTREAMER_GL_LIBRARY_FOUND "GStreamerPluginsBase" "GStreamer opengl library"
"http://gstreamer.freedesktop.org/" TRUE "1.0.0")
#find_package(GStreamerPluginsBad 1.0.0 COMPONENTS player)
#macro_log_feature(GSTREAMER_PLAYER_LIBRARY_FOUND "GStreamer player library"
#"${GSTREAMER_PLAYER_LIBRARY}"
#"http://gstreamer.freedesktop.org/" TRUE "1.0.0")
# Various preprocessor definitions for GST
add_definitions(-DGST_DISABLE_XML -DGST_DISABLE_LOADSAVE)
# Basics
find_package(GLIB2)
macro_log_feature(GLIB2_FOUND "GLib" "GTK general-purpose utility library" "http://www.gtk.org/" TRUE)
find_package(GObject)
macro_log_feature(GOBJECT_FOUND "GObject" "GTK object-oriented framework" "http://www.gtk.org/" TRUE)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
set(THREAD_LIBRARY Threads::Threads)
find_package(PNG REQUIRED)
set(PNG_LIBRARY PNG::PNG)
#
# GLFW3
#
find_package(glfw3 3.2 REQUIRED)
macro_log_feature(glfw3_FOUND "GLFW3" "Open Source, multi-platform library for OpenGL" "http://www.glfw.org/" TRUE)
set(GLFW_LIBRARY glfw)
find_package(OpenGL REQUIRED)
#
# GLM
#
set(BUILD_STATIC_LIBS ON)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/ext/glm)
message(STATUS "Compiling 'GLM' OpenGL Mathematics https://glm.g-truc.net.")
#
# GLAD
#
set(GLAD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/glad/include)
add_library(GLAD "${CMAKE_CURRENT_SOURCE_DIR}/ext/glad/src/glad.c")
message(STATUS "Compiling 'GLAD' generated at https://glad.dav1d.de/ -- ${GLAD_INCLUDE_DIR}.")
#
# DEAR IMGUI
#
set(IMGUI_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui/imgui.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui//imgui_demo.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui//imgui_draw.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui//imgui_widgets.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui/examples/imgui_impl_glfw.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui/examples/imgui_impl_opengl3.cpp
)
set(IMGUI_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui)
add_library(IMGUI "${IMGUI_SRCS}")
target_compile_definitions(IMGUI PRIVATE "IMGUI_IMPL_OPENGL_LOADER_GLAD")
message(STATUS "Compiling 'Dear ImGui' from https://github.com/ocornut/imgui.git -- ${IMGUI_INCLUDE_DIR}.")
#
# ImGui Color Text Editor
#
set(IMGUITEXTEDIT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/ImGuiColorTextEdit)
set(IMGUITEXTEDIT_SRC
${CMAKE_CURRENT_SOURCE_DIR}/ext/ImGuiColorTextEdit/TextEditor.cpp
)
message(STATUS "Including 'ImGuiColorTextEdit' from https://github.com/BalazsJako/ImGuiColorTextEdit -- ${IMGUITEXTEDIT_INCLUDE_DIR}.")
#
# TINY XML 2
#
set(TINYXML2_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/tinyxml2)
add_library(TINYXML2 "${CMAKE_CURRENT_SOURCE_DIR}/ext/tinyxml2/tinyxml2.cpp")
message(STATUS "Compiling 'TinyXML2' from https://github.com/leethomason/tinyxml2.git -- ${TINYXML2_INCLUDE_DIR}.")
#
# STB
#
set(STB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/stb)
add_definitions(-DIMGUI_USE_STB_SPRINTF)
message(STATUS "Including 'STB Nothings' from https://github.com/nothings/stb -- ${STB_INCLUDE_DIR}.")
#
# DIRENT
#
if(WIN32)
set(DIRENT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/Dirent/include)
message(STATUS "Including 'Dirent' from https://github.com/tronkko/dirent -- ${DIRENT_INCLUDE_DIR}.")
endif( WIN32 )
#
# TINY FILE DIALOG
#
set(TINYFD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd)
add_library(TINYFD "${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd/tinyfiledialogs.c")
message(STATUS "Compiling 'TinyFileDialog' from https://github.com/native-toolkit/tinyfiledialogs.git -- ${TINYFD_INCLUDE_DIR}.")
#
# OBJ LOADER
#
#set(OBJLOADER_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/obj)
#add_library(OBJLOADER "${CMAKE_CURRENT_SOURCE_DIR}/ext/obj/ObjLoader.cpp")
#message(STATUS "Compiling 'ObjLoader' from https://github.com/mortennobel/OpenGL_3_2_Utils -- ${OBJLOADER_INCLUDE_DIR}.")
# find_package(PkgConfig REQUIRED)
# pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
#
# Application
#
# Setup the environment
include_directories(
${GLIB2_INCLUDE_DIR}
${GSTREAMER_INCLUDE_DIR}
${GSTREAMER_AUDIO_INCLUDE_DIR}
${GSTREAMER_VIDEO_INCLUDE_DIR}
@@ -188,74 +145,344 @@ include_directories(
${GSTREAMER_APP_INCLUDE_DIR}
${GSTREAMER_PBUTILS_INCLUDE_DIR}
${GSTREAMER_GL_INCLUDE_DIR}
${GLIB2_INCLUDE_DIR}
${GLAD_INCLUDE_DIR}
)
#
# ICU4C
#
if (PKG_CONFIG_FOUND)
pkg_check_modules(ICU REQUIRED icu-i18n icu-uc icu-io)
else ()
find_package(ICU REQUIRED COMPONENTS i18n io uc)
endif ()
macro_log_feature(ICU_FOUND "ICU" "International Components for Unicode" "http://site.icu-project.org" TRUE)
include_directories(
${ICU_INCLUDE_DIRS}
)
link_directories(
${ICU_LIBRARY_DIRS}
)
#
# GLFW3
#
if (PKG_CONFIG_FOUND)
pkg_check_modules(GLFW3 REQUIRED glfw3>=3.2)
else ()
find_package(glfw3 3.2 REQUIRED)
endif()
macro_log_feature(GLFW3_FOUND "glfw3" "Open Source multi-platform library for OpenGL" "http://www.glfw.org" TRUE)
include_directories(
${GLFW3_INCLUDE_DIRS}
)
link_directories(
${GLFW3_LIBRARY_DIRS}
)
#
# GLM
#
if (PKG_CONFIG_FOUND)
pkg_check_modules(GLM QUIET glm>=0.9.9)
else ()
find_package(glm 0.9.9 QUIET)
endif()
if (GLM_FOUND)
macro_log_feature(GLM_FOUND "GLM" "OpenGL mathematics" "https://glm.g-truc.net" TRUE)
else ()
set(GLM_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/glm)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/ext/glm)
message(STATUS "Compiling 'GLM' OpenGL mathematics https://glm.g-truc.net -- ${CMAKE_CURRENT_SOURCE_DIR}/ext/glm")
endif()
include_directories(
${GLM_INCLUDE_DIRS}
${IMGUI_INCLUDE_DIR}
${IMGUI_INCLUDE_DIR}/examples
)
#
# TINY XML 2
#
if (PKG_CONFIG_FOUND)
pkg_check_modules(TINYXML2 QUIET tinyxml2>=8.0)
else ()
find_package(tinyxml2 8.0 QUIET)
endif()
if (TINYXML2_FOUND)
macro_log_feature(TINYXML2_FOUND "TinyXML2" "TinyXML2 library" "https://github.com/leethomason/tinyxml2.git" TRUE)
else ()
set(TINYXML2_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/tinyxml2)
set(TINYXML2_LIBRARIES TINYXML2)
add_library(TINYXML2 "${CMAKE_CURRENT_SOURCE_DIR}/ext/tinyxml2/tinyxml2.cpp")
message(STATUS "Compiling 'TinyXML2' from https://github.com/leethomason/tinyxml2.git -- ${TINYXML2_INCLUDE_DIRS}")
endif()
include_directories(
${TINYXML2_INCLUDE_DIRS}
)
#
# STB
#
if (PKG_CONFIG_FOUND)
pkg_check_modules(STB QUIET stb)
else ()
find_package(stb QUIET)
endif()
if (STB_FOUND)
macro_log_feature(STB_FOUND "STB" "single-file image and audio processing" "https://github.com/nothings/stb" TRUE)
else ()
set(STB_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/stb)
message(STATUS "Including 'STB' single-file image and audio processing from https://github.com/nothings/stb -- ${STB_INCLUDE_DIRS}")
endif()
include_directories(
${STB_INCLUDE_DIRS}
)
#
# Ableton LINK
#
find_package(AbletonLink QUIET)
if (AbletonLink_FOUND)
macro_log_feature(AbletonLink_FOUND "AbletonLink" "Ableton Link synchronizer" "https://github.com/Ableton/link" TRUE)
else ()
include(${CMAKE_CURRENT_SOURCE_DIR}/ext/link/AbletonLinkConfig.cmake)
message(STATUS "Compiling 'Ableton Link' from https://github.com/Ableton/link -- ${CMAKE_CURRENT_SOURCE_DIR}/ext/link")
endif()
include_directories(
${link_HEADERS}
)
#
# FILE DIALOG: use tinyfiledialog for all except Linux
#
if(APPLE OR WIN32)
set(TINYFD_LIBRARIES TINYFD)
set(TINYFD_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd)
include_directories(
${TINYFD_INCLUDE_DIR}
)
add_library(TINYFD "${CMAKE_CURRENT_SOURCE_DIR}/ext/tfd/tinyfiledialogs.c")
message(STATUS "Compiling 'TinyFileDialog' from https://git.code.sf.net/p/tinyfiledialogs/code -- ${TINYFD_INCLUDE_DIR}.")
endif()
#
# DIRENT (windows only)
if(WIN32)
set(DIRENT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/Dirent/include)
include_directories(
${DIRENT_INCLUDE_DIR}
)
message(STATUS "Including 'Dirent' from https://github.com/tronkko/dirent -- ${DIRENT_INCLUDE_DIR}.")
endif()
#
# SHMDATA (Unix only)
#
if(UNIX)
if (PKG_CONFIG_FOUND)
pkg_check_modules(SHMDATA QUIET shmdata-1.3)
endif()
if(SHMDATA_FOUND)
find_library(GSTREAMER_SHMDATA_LIBRARY
NAMES gstshmdata
HINTS ${SHMDATA_LIBRARY_DIRS}/gstreamer-1.0
)
if(GSTREAMER_SHMDATA_LIBRARY)
add_definitions(-DGSTREAMER_SHMDATA_PLUGIN=\"${GSTREAMER_SHMDATA_LIBRARY}\")
endif()
macro_log_feature(GSTREAMER_SHMDATA_LIBRARY "GStreamerPluginShmdata" "Plugin to share any flow" "https://gitlab.com/sat-mtl/tools/shmdata" FALSE)
endif(SHMDATA_FOUND)
endif(UNIX)
# show message about found libs
macro_display_feature_log()
#####
##### Locally built libraries
#####
#
# GLAD
#
set(GLAD_LIBRARIES GLAD)
set(GLAD_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/glad/include)
include_directories(
${GLAD_INCLUDE_DIRS}
)
add_library(GLAD "${CMAKE_CURRENT_SOURCE_DIR}/ext/glad/src/glad.c")
message(STATUS "Including 'GLAD' Open source multi-language OpenGL loader https://glad.dav1d.de -- ${GLAD_INCLUDE_DIRS}")
#
# DEAR IMGUI
#
set(IMGUI_LIBRARIES IMGUI IMGUITEXTEDIT)
set(IMGUI_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui)
set(IMGUI_BACKEND_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui/examples)
include_directories(
${IMGUI_INCLUDE_DIRS}
${IMGUI_BACKEND_INCLUDE_DIRS}
)
set(IMGUI_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui/imgui.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui//imgui_demo.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui//imgui_draw.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui//imgui_widgets.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui/examples/imgui_impl_glfw.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/imgui/examples/imgui_impl_opengl3.cpp
)
add_library(IMGUI "${IMGUI_SRCS}")
target_compile_definitions(IMGUI PRIVATE "IMGUI_IMPL_OPENGL_LOADER_GLAD")
target_compile_definitions(IMGUI PRIVATE "IMGUI_USE_STB_SPRINTF")
message(STATUS "Compiling 'Dear ImGui' from https://github.com/ocornut/imgui.git -- ${IMGUI_INCLUDE_DIRS}")
#
# ImGui Color Text Editor
#
set(IMGUITEXTEDIT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/ImGuiColorTextEdit)
include_directories(
${IMGUITEXTEDIT_INCLUDE_DIR}
${TINYXML2_INCLUDE_DIR}
${TINYFD_INCLUDE_DIR}
${STB_INCLUDE_DIR}
${DIRENT_INCLUDE_DIR}
${OBJLOADER_INCLUDE_DIR}
)
add_library(IMGUITEXTEDIT "${CMAKE_CURRENT_SOURCE_DIR}/ext/ImGuiColorTextEdit/TextEditor.cpp")
set_property(TARGET IMGUITEXTEDIT PROPERTY CXX_STANDARD 17)
message(STATUS "Compiling 'ImGuiColorTextEdit' from https://github.com/BalazsJako/ImGuiColorTextEdit -- ${IMGUITEXTEDIT_INCLUDE_DIR}")
#
# OSCPack
#
if(UNIX)
set(OSCPACK_PLATFORM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/OSCPack/ip/posix/)
elseif(WIN32)
set(OSCPACK_PLATFORM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/OSCPack/ip/win32/)
endif()
set(OSCPACK_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/ext/OSCPack/osc/OscTypes.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/OSCPack/osc/OscReceivedElements.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/OSCPack/osc/OscPrintReceivedElements.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/OSCPack/osc/OscOutboundPacketStream.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext/OSCPack/ip/IpEndpointName.cpp
${OSCPACK_PLATFORM_DIR}/NetworkingUtils.cpp
${OSCPACK_PLATFORM_DIR}/UdpSocket.cpp
)
set(OSCPACK_LIBRARIES OSCPACK)
set(OSCPACK_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/OSCPack)
include_directories(
${OSCPACK_INCLUDE_DIR}
)
add_library(OSCPACK "${OSCPACK_SRCS}")
message(STATUS "Compiling 'OSCPack' from http://www.rossbencina.com/code/oscpack -- ${OSCPACK_INCLUDE_DIR}")
#####
##### Ressources
#####
set(RSC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/rsc)
#
# Fonts
#
file(GLOB_RECURSE ROBOTO_REGULAR "${RSC_DIR}/*/Roboto-Regular.ttf")
if(NOT ROBOTO_REGULAR)
file(GLOB_RECURSE ROBOTO_REGULAR "/usr/share/fonts/*/Roboto-Regular.ttf")
message(STATUS "Copy ${ROBOTO_REGULAR} to ${RSC_DIR}/fonts")
file(COPY ${ROBOTO_REGULAR} DESTINATION ${RSC_DIR}/fonts)
set(ROBOTO_REGULAR "${RSC_DIR}/fonts/Roboto-Regular.ttf")
endif()
file(GLOB_RECURSE ROBOTO_BOLD "${RSC_DIR}/*/Roboto-Bold.ttf")
if(NOT ROBOTO_BOLD)
file(GLOB_RECURSE ROBOTO_BOLD "/usr/share/fonts/*/Roboto-Bold.ttf")
message(STATUS "Copy ${ROBOTO_BOLD} to ${RSC_DIR}/fonts")
file(COPY ${ROBOTO_BOLD} DESTINATION ${RSC_DIR}/fonts)
set(ROBOTO_BOLD "${RSC_DIR}/fonts/Roboto-Bold.ttf")
endif()
file(GLOB_RECURSE ROBOTO_ITALIC "${RSC_DIR}/*/Roboto-Italic.ttf")
if(NOT ROBOTO_ITALIC)
file(GLOB_RECURSE ROBOTO_ITALIC "/usr/share/fonts/*/Roboto-Italic.ttf")
message(STATUS "Copy ${ROBOTO_ITALIC} to ${RSC_DIR}/fonts")
file(COPY ${ROBOTO_ITALIC} DESTINATION ${RSC_DIR}/fonts)
set(ROBOTO_ITALIC "${RSC_DIR}/fonts/Roboto-Italic.ttf")
endif()
file(GLOB_RECURSE HACK_REGULAR "${RSC_DIR}/*/Hack-Regular.ttf")
if(NOT HACK_REGULAR)
file(GLOB_RECURSE HACK_REGULAR "/usr/share/fonts/*/Hack-Regular.ttf")
message(STATUS "Copy ${HACK_REGULAR} to ${RSC_DIR}/fonts")
file(COPY ${HACK_REGULAR} DESTINATION ${RSC_DIR}/fonts)
set(HACK_REGULAR "${RSC_DIR}/fonts/Hack-Regular.ttf")
endif()
file(GLOB_RECURSE AWESOME_SOLID "${RSC_DIR}/*/fa-solid-900.ttf")
if(NOT AWESOME_SOLID)
file(GLOB_RECURSE AWESOME_SOLID "/usr/share/fonts/*/fa-solid-900.ttf")
message(STATUS "Copy ${AWESOME_SOLID} to ${RSC_DIR}/fonts")
file(COPY ${AWESOME_SOLID} DESTINATION ${RSC_DIR}/fonts)
set(AWESOME_SOLID "${RSC_DIR}/fonts/fa-solid-900.ttf")
endif()
file(GLOB_RECURSE AWESOME_REGULAR "${RSC_DIR}/*/fa-regular-400.ttf")
if(NOT AWESOME_REGULAR)
file(GLOB_RECURSE AWESOME_REGULAR "/usr/share/fonts/*/fa-regular-400.ttf")
message(STATUS "Copy ${AWESOME_REGULAR} to ${RSC_DIR}/fonts")
file(COPY ${AWESOME_REGULAR} DESTINATION ${RSC_DIR}/fonts)
set(AWESOME_REGULAR "${RSC_DIR}/fonts/fa-regular-400.ttf")
endif()
include_directories(
"${RSC_DIR}/fonts"
)
set(VMIX_BINARY "vimix")
set(VMIX_SRCS
main.cpp
Log.cpp
Shader.cpp
ImageShader.cpp
ImageProcessingShader.cpp
UpdateCallback.cpp
Scene.cpp
Primitives.cpp
Mesh.cpp
Decorations.cpp
View.cpp
Source.cpp
Session.cpp
Selection.cpp
SessionSource.cpp
SessionVisitor.cpp
GarbageVisitor.cpp
SessionCreator.cpp
Mixer.cpp
Settings.cpp
Screenshot.cpp
Resource.cpp
FileDialog.cpp
MediaPlayer.cpp
MediaSource.cpp
FrameBuffer.cpp
RenderingManager.cpp
UserInterfaceManager.cpp
PickingVisitor.cpp
BoundingBoxVisitor.cpp
DrawVisitor.cpp
SearchVisitor.cpp
ImGuiToolkit.cpp
ImGuiVisitor.cpp
GstToolkit.cpp
GlmToolkit.cpp
SystemToolkit.cpp
tinyxml2Toolkit.cpp
)
#
# CMake RC module
#
# Include the CMake RC module
include(CMakeRC)
message(STATUS "Using 'CMakeRC ' from https://github.com/vector-of-bool/cmrc.git -- ${CMAKE_MODULE_PATH}.")
# set the files to package
set(VMIX_RSC_FILES
${ROBOTO_REGULAR}
${ROBOTO_BOLD}
${ROBOTO_ITALIC}
${HACK_REGULAR}
${AWESOME_REGULAR}
${AWESOME_SOLID}
./rsc/shaders/simple.fs
./rsc/shaders/simple.vs
./rsc/shaders/image.fs
./rsc/shaders/mask_elipse.fs
./rsc/shaders/mask_box.fs
./rsc/shaders/mask_round.fs
./rsc/shaders/mask_horizontal.fs
./rsc/shaders/mask_vertical.fs
./rsc/shaders/mask_draw.fs
./rsc/shaders/image.vs
./rsc/shaders/imageprocessing.fs
./rsc/fonts/Hack-Regular.ttf
./rsc/fonts/Roboto-Regular.ttf
./rsc/fonts/Roboto-Bold.ttf
./rsc/fonts/Roboto-Italic.ttf
./rsc/fonts/fa-regular-400.ttf
./rsc/fonts/fa-solid-900.ttf
./rsc/shaders/imageblending.fs
./rsc/images/mask_vignette.png
./rsc/images/mask_halo.png
./rsc/images/mask_glow.png
@@ -266,6 +493,7 @@ set(VMIX_RSC_FILES
./rsc/images/mask_linear_left.png
./rsc/images/mask_linear_right.png
./rsc/images/vimix_256x256.png
./rsc/images/vimix_crow_white.png
./rsc/images/icons.dds
./rsc/images/gradient_0_cross_linear.png
./rsc/images/gradient_1_black_linear.png
@@ -274,180 +502,151 @@ set(VMIX_RSC_FILES
./rsc/images/transparencygrid.png
./rsc/images/shadow.dds
./rsc/images/glow.dds
./rsc/images/checker.dds
./rsc/images/shadow_perspective.dds
./rsc/images/soft_shadow.dds
./rsc/mesh/disk.ply
./rsc/mesh/circle.ply
./rsc/mesh/corner.ply
./rsc/mesh/shadow.ply
./rsc/mesh/glow.ply
./rsc/mesh/target.ply
./rsc/mesh/border_round_left.ply
./rsc/mesh/border_round.ply
./rsc/mesh/border_top.ply
./rsc/mesh/border_perspective_round_left.ply
./rsc/mesh/border_perspective_round.ply
./rsc/mesh/border_perspective_top.ply
./rsc/mesh/border_sharp.ply
./rsc/mesh/border_large_round_left.ply
./rsc/mesh/border_large_round.ply
./rsc/mesh/border_large_top.ply
./rsc/mesh/border_handles_rotation.ply
./rsc/mesh/border_handles_scale.ply
./rsc/mesh/border_handles_overlay.ply
./rsc/mesh/border_handles_overlay_filled.ply
./rsc/mesh/border_handles_sharp.ply
./rsc/mesh/border_handles_menu.ply
./rsc/mesh/border_handles_crop.ply
./rsc/mesh/border_handles_lock.ply
./rsc/mesh/border_handles_lock_open.ply
./rsc/mesh/border_handles_shadow.ply
./rsc/mesh/border_large_sharp.ply
./rsc/mesh/border_vertical_overlay.ply
./rsc/mesh/perspective_layer.ply
./rsc/mesh/perspective_axis_left.ply
./rsc/mesh/perspective_axis_right.ply
./rsc/mesh/shadow_perspective.ply
./rsc/mesh/point.ply
./rsc/mesh/circle.ply
./rsc/mesh/square_point.ply
./rsc/mesh/triangle_point.ply
./rsc/mesh/icon_video.ply
./rsc/mesh/icon_image.ply
./rsc/mesh/icon_render.ply
./rsc/mesh/icon_gear.ply
./rsc/mesh/icon_camera.ply
./rsc/mesh/icon_share.ply
./rsc/mesh/icon_clone.ply
./rsc/mesh/icon_vimix.ply
./rsc/mesh/icon_group_vimix.ply
./rsc/mesh/icon_circles.ply
./rsc/mesh/icon_dots.ply
./rsc/mesh/icon_empty.ply
./rsc/mesh/icon_lock.ply
./rsc/mesh/icon_unlock.ply
./rsc/mesh/icon_circle.ply
./rsc/mesh/icon_square.ply
./rsc/mesh/icon_cross.ply
./rsc/mesh/icon_clock.ply
./rsc/mesh/icon_clock_hand.ply
./rsc/mesh/icon_grid.ply
./rsc/mesh/icon_rightarrow.ply
./rsc/mesh/icon_crop.ply
./rsc/mesh/icon_eye.ply
./rsc/mesh/icon_eye_slash.ply
./rsc/mesh/icon_tv.ply
./rsc/mesh/icon_cube.ply
./rsc/mesh/icon_sequence.ply
./rsc/mesh/icon_receive.ply
./rsc/mesh/h_line.ply
./rsc/mesh/h_mark.ply
./rsc/shaders/filters/default.glsl
./rsc/shaders/filters/bloom.glsl
./rsc/shaders/filters/bokeh.glsl
./rsc/shaders/filters/talk.glsl
./rsc/shaders/filters/fisheye.glsl
./rsc/shaders/filters/blur.glsl
./rsc/shaders/filters/blur_1.glsl
./rsc/shaders/filters/blur_2.glsl
./rsc/shaders/filters/lens_1.glsl
./rsc/shaders/filters/lens_2.glsl
./rsc/shaders/filters/hashedblur.glsl
./rsc/shaders/filters/circularblur.glsl
./rsc/shaders/filters/hashederosion.glsl
./rsc/shaders/filters/hasheddilation.glsl
./rsc/shaders/filters/sharp.glsl
./rsc/shaders/filters/sharpen.glsl
./rsc/shaders/filters/sharpen_1.glsl
./rsc/shaders/filters/sharpen_2.glsl
./rsc/shaders/filters/contour_2.glsl
./rsc/shaders/filters/sharpenedge.glsl
./rsc/shaders/filters/chromakey.glsl
./rsc/shaders/filters/lumakey.glsl
./rsc/shaders/filters/coloralpha.glsl
./rsc/shaders/filters/bilinear.glsl
./rsc/shaders/filters/edge.glsl
./rsc/shaders/filters/sobel.glsl
./rsc/shaders/filters/freichen.glsl
./rsc/shaders/filters/kuwahara.glsl
./rsc/shaders/filters/pixelate.glsl
./rsc/shaders/filters/focus.glsl
./rsc/shaders/filters/denoise.glsl
./rsc/shaders/filters/noise.glsl
./rsc/shaders/filters/grain.glsl
./rsc/shaders/filters/stippling.glsl
./rsc/shaders/filters/dithering.glsl
./rsc/shaders/filters/erosion.glsl
./rsc/shaders/filters/dilation.glsl
./rsc/shaders/filters/tophat.glsl
./rsc/shaders/filters/blackhat.glsl
./rsc/shaders/filters/resample_double.glsl
./rsc/shaders/filters/resample_half.glsl
./rsc/shaders/filters/resample_quarter.glsl
./rsc/shaders/filters/earlybird.glsl
./rsc/shaders/filters/logo.glsl
./rsc/shaders/filters/whitebalance.glsl
)
### DEFINE THE TARGET (OS specific)
IF(APPLE)
# set icon
set(MACOSX_BUNDLE_ICON vimix.icns)
set(MACOSX_BUNDLE_ICON_FILE ${CMAKE_SOURCE_DIR}/osx/${MACOSX_BUNDLE_ICON})
# set where in the bundle to put the icns file
set_source_files_properties(${MACOSX_BUNDLE_ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
# create the application
add_executable(${VMIX_BINARY} MACOSX_BUNDLE
${VMIX_SRCS}
${IMGUITEXTEDIT_SRC}
${MACOSX_BUNDLE_ICON_FILE}
)
# set the Info.plist file
set(MACOSX_BUNDLE_PLIST_FILE ${CMAKE_SOURCE_DIR}/osx/Info.plist)
set_target_properties(${VMIX_BINARY} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${MACOSX_BUNDLE_PLIST_FILE})
ELSE(APPLE)
add_executable(${VMIX_BINARY}
${VMIX_SRCS}
${IMGUITEXTEDIT_SRC}
)
ENDIF(APPLE)
### COMPILE THE TARGET (all OS)
set_property(TARGET ${VMIX_BINARY} PROPERTY CXX_STANDARD 17)
set_property(TARGET ${VMIX_BINARY} PROPERTY C_STANDARD 11)
target_compile_definitions(${VMIX_BINARY} PUBLIC "IMGUI_IMPL_OPENGL_LOADER_GLAD")
cmrc_add_resource_library(vmix-resources ALIAS vmix::rc NAMESPACE vmix WHENCE rsc ${VMIX_RSC_FILES})
message(STATUS "Using 'CMakeRC ' from https://github.com/vector-of-bool/cmrc.git -- ${CMAKE_MODULE_PATH}.")
target_link_libraries(${VMIX_BINARY} LINK_PRIVATE
${GLFW_LIBRARY}
${OPENGL_LIBRARY}
GLAD
${CMAKE_DL_LIBS}
${GOBJECT_LIBRARIES}
${GSTREAMER_LIBRARY}
${GSTREAMER_BASE_LIBRARY}
${GSTREAMER_APP_LIBRARY}
${GSTREAMER_AUDIO_LIBRARY}
${GSTREAMER_VIDEO_LIBRARY}
${GSTREAMER_PBUTILS_LIBRARY}
${GSTREAMER_GL_LIBRARY}
${GSTREAMER_PLAYER_LIBRARY}
${NFD_LIBRARY}
${PNG_LIBRARY}
${THREAD_LIBRARY}
TINYXML2
TINYFD
IMGUI
glm::glm
vmix::rc
)
macro_display_feature_log()
### DEFINE THE PACKAGING (all OS)
#####
##### DEFINE THE PACKAGING (all OS)
#####
SET(CPACK_PACKAGE_NAME "vimix")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "vimix\n Real-time video mixing for live performance.")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "vimix\nReal-time video mixing for live performance.")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md")
SET(CPACK_PACKAGE_CONTACT "bruno.herbelin@gmail.com")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING.txt")
SET(CPACK_PACKAGE_VERSION_MAJOR "0")
SET(CPACK_PACKAGE_VERSION_MINOR "1")
#SET(CPACK_PACKAGE_VERSION_PATCH "${GLMIXER_WC_REVISION}")
SET(CPACK_PACKAGE_CONTACT "bruno.herbelin@gmail.com")
SET(CPACK_PACKAGE_HOMEPAGE_URL "https://brunoherbelin.github.io/vimix")
SET(CPACK_PACKAGE_VERSION_MAJOR "${VIMIX_VERSION_MAJOR}")
SET(CPACK_PACKAGE_VERSION_MINOR "${VIMIX_VERSION_MINOR}")
SET(CPACK_PACKAGE_VERSION_PATCH "${VIMIX_VERSION_PATCH}")
SET(CPACK_PACKAGE_VENDOR "Bruno Herbelin")
SET(CPACK_SOURCE_IGNORE_FILES
"/\\\\.git/"
"/\\\\.gitignore$"
"/\\\\.gitmodules$"
)
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}_${CPACK_SYSTEM_NAME}")
set(CPACK_STRIP_FILES TRUE)
### DEFINE THE PACKAGING (OS specific)
#####
##### Build Application
#####
add_subdirectory(src)
IF(APPLE)
# Bundle target
set(CPACK_GENERATOR "DragNDrop")
# OSX cpack info
set(CPACK_SYSTEM_NAME "OSX_${CMAKE_OSX_DEPLOYMENT_TARGET}_${CMAKE_OSX_ARCHITECTURES}")
set(CPACK_BUNDLE_NAME ${CPACK_PACKAGE_NAME})
set(CPACK_BUNDLE_ICON ${MACOSX_BUNDLE_ICON_FILE})
set(CPACK_BUNDLE_PLIST ${MACOSX_BUNDLE_PLIST_FILE})
set(APPS "\${CMAKE_INSTALL_PREFIX}/vimix.app")
# set( APPS "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/vimix${CMAKE_EXECUTABLE_SUFFIX}")
install(TARGETS ${VMIX_BINARY}
CONFIGURATIONS Release RelWithDebInfo
BUNDLE DESTINATION . COMPONENT Runtime
RUNTIME DESTINATION bin COMPONENT Runtime
)
set(plugin_dest_dir vimix.app/Contents/MacOS/)
install(DIRECTORY "${PKG_GSTREAMER_PLUGIN_DIR}" DESTINATION "${plugin_dest_dir}" COMPONENT Runtime)
install(DIRECTORY "/usr/local/Cellar/gst-plugins-base/1.16.2/lib/gstreamer-1.0" DESTINATION "${plugin_dest_dir}" COMPONENT Runtime)
install(DIRECTORY "/usr/local/Cellar/gst-plugins-good/1.16.2/lib/gstreamer-1.0" DESTINATION "${plugin_dest_dir}" COMPONENT Runtime)
install(DIRECTORY "/usr/local/Cellar/gst-plugins-bad/1.16.2_3/lib/gstreamer-1.0" DESTINATION "${plugin_dest_dir}" COMPONENT Runtime)
install(DIRECTORY "/usr/local/Cellar/gst-plugins-ugly/1.16.2_1/lib/gstreamer-1.0" DESTINATION "${plugin_dest_dir}" COMPONENT Runtime)
install(DIRECTORY "/usr/local/Cellar/gst-libav/1.16.2/lib/gstreamer-1.0" DESTINATION "${plugin_dest_dir}" COMPONENT Runtime)
# package runtime fixup bundle
install(CODE "
file(GLOB_RECURSE GSTPLUGINS \"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/gstreamer-1.0/*.so\")
include(BundleUtilities)
set(BU_CHMOD_BUNDLE_ITEMS TRUE)
fixup_bundle(\"${APPS}\" \"\${GSTPLUGINS}\" \"\")
"
COMPONENT Runtime
)
set(CPACK_BINARY_DRAGNDROP ON)
ELSE(APPLE)
set(APPS "\${CMAKE_INSTALL_PREFIX}/bin/vimix")
install(TARGETS ${VMIX_BINARY}
CONFIGURATIONS Release RelWithDebInfo
RUNTIME DESTINATION bin COMPONENT Runtime
)
ENDIF(APPLE)
# Package full name
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}_${CPACK_SYSTEM_NAME}")
# To Create a package, run "cpack"
include(CPack)

128
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@@ -1,409 +0,0 @@
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/vector_angle.hpp>
#include <glm/gtx/component_wise.hpp>
#include "Decorations.h"
#include "Visitor.h"
#include "BoundingBoxVisitor.h"
#include "ImageShader.h"
#include "GlmToolkit.h"
#include "Log.h"
Frame::Frame(CornerType corner, BorderType border, ShadowType shadow) : Node(), side_(nullptr), top_(nullptr), shadow_(nullptr), square_(nullptr)
{
static Mesh *shadows[3] = {nullptr};
if (shadows[0] == nullptr) {
shadows[0] = new Mesh("mesh/glow.ply", "images/glow.dds");
shadows[1] = new Mesh("mesh/shadow.ply", "images/shadow.dds");
shadows[2] = new Mesh("mesh/shadow_perspective.ply", "images/shadow_perspective.dds");
}
static Mesh *frames[4] = {nullptr};
if (frames[0] == nullptr) {
frames[0] = new Mesh("mesh/border_round.ply");
frames[1] = new Mesh("mesh/border_top.ply");
frames[2] = new Mesh("mesh/border_large_round.ply");
frames[3] = new Mesh("mesh/border_large_top.ply");
}
static LineSquare *sharpframethin = new LineSquare( 3 );
static LineSquare *sharpframelarge = new LineSquare( 5 );
if (corner == SHARP) {
if (border == LARGE)
square_ = sharpframelarge;
else
square_ = sharpframethin;
}
else {
// Round corners
if (border == THIN) {
side_ = frames[0];
top_ = frames[1];
}
else{
side_ = frames[2];
top_ = frames[3];
}
}
switch (shadow) {
default:
case NONE:
break;
case GLOW:
shadow_ = shadows[0];
break;
case DROP:
shadow_ = shadows[1];
break;
case PERSPECTIVE:
shadow_ = shadows[2];
break;
}
// switch (type) {
// case SHARP_LARGE:
// square_ = sharpframe;
// shadow_ = shadows[0];
// break;
// case SHARP_THIN:
// square_ = sharpframe;
// break;
// case ROUND_LARGE:
// side_ = frames[2];
// top_ = frames[3];
// shadow_ = shadows[1];
// break;
// default:
// case ROUND_THIN:
// side_ = frames[0];
// top_ = frames[1];
// shadow_ = shadows[1];
// break;
// case ROUND_THIN_PERSPECTIVE:
// side_ = frames[0];
// top_ = frames[1];
// shadow_ = shadows[2];
// break;
// }
color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
}
Frame::~Frame()
{
}
void Frame::update( float dt )
{
Node::update(dt);
if(top_)
top_->update(dt);
if(side_)
side_->update(dt);
if(shadow_)
shadow_->update(dt);
if(square_)
square_->update(dt);
}
void Frame::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() ) {
if(side_ && !side_->initialized())
side_->init();
if(top_ && !top_->initialized())
top_->init();
if(shadow_ && !shadow_->initialized())
shadow_->init();
if(square_ && !square_->initialized())
square_->init();
init();
}
if ( visible_ ) {
glm::mat4 ctm = modelview * transform_;
// shadow (scaled)
if(shadow_){
shadow_->shader()->color.a = 0.98f;
shadow_->draw( ctm, projection);
}
// top (scaled)
if(top_) {
top_->shader()->color = color;
top_->draw( ctm, projection);
}
// top (scaled)
if(square_) {
square_->shader()->color = color;
square_->draw( ctm, projection);
}
if(side_) {
side_->shader()->color = color;
// get scale
glm::vec4 scale = ctm * glm::vec4(1.f, 1.0f, 0.f, 0.f);
// get rotation
glm::vec3 rot(0.f);
glm::vec4 vec = ctm * glm::vec4(1.f, 0.f, 0.f, 0.f);
rot.z = glm::orientedAngle( glm::vec3(1.f, 0.f, 0.f), glm::normalize(glm::vec3(vec)), glm::vec3(0.f, 0.f, 1.f) );
if(side_) {
// left side
vec = ctm * glm::vec4(1.f, 0.f, 0.f, 1.f);
side_->draw( GlmToolkit::transform(vec, rot, glm::vec3(scale.y, scale.y, 1.f)), projection );
// right side
vec = ctm * glm::vec4(-1.f, 0.f, 0.f, 1.f);
side_->draw( GlmToolkit::transform(vec, rot, glm::vec3(-scale.y, scale.y, 1.f)), projection );
}
}
}
}
void Frame::accept(Visitor& v)
{
Node::accept(v);
v.visit(*this);
}
Handles::Handles(Type type) : Node(), type_(type)
{
static Mesh *handle_rotation_ = new Mesh("mesh/border_handles_rotation.ply");
static Mesh *handle_corner = new Mesh("mesh/border_handles_overlay.ply");
color = glm::vec4( 1.f, 1.f, 0.f, 1.f);
if ( type_ == ROTATE ) {
handle_ = handle_rotation_;
}
else {
handle_ = handle_corner;
}
}
Handles::~Handles()
{
}
void Handles::update( float dt )
{
Node::update(dt);
handle_->update(dt);
}
void Handles::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() ) {
if(handle_ && !handle_->initialized())
handle_->init();
init();
}
if ( visible_ ) {
// set color
handle_->shader()->color = color;
glm::mat4 ctm;
glm::vec3 rot(0.f);
glm::vec4 vec = modelview * glm::vec4(1.f, 0.f, 0.f, 0.f);
rot.z = glm::orientedAngle( glm::vec3(1.f, 0.f, 0.f), glm::normalize(glm::vec3(vec)), glm::vec3(0.f, 0.f, 1.f) );
// vec = modelview * glm::vec4(0.f, 1.f, 0.f, 1.f);
// glm::vec3 scale( vec.x > 0.f ? 1.f : -1.f, vec.y > 0.f ? 1.f : -1.f, 1.f);
// glm::vec3 scale(1.f, 1.f, 1.f);
// Log::Info(" (0,1) becomes (%f, %f)", scale.x, scale.y);
if ( type_ == RESIZE ) {
// 4 corners
vec = modelview * glm::vec4(1.f, -1.f, 0.f, 1.f);
ctm = GlmToolkit::transform(vec, rot, glm::vec3(1.f));
handle_->draw( ctm, projection );
vec = modelview * glm::vec4(1.f, 1.f, 0.f, 1.f);
ctm = GlmToolkit::transform(vec, rot, glm::vec3(1.f));
handle_->draw( ctm, projection );
vec = modelview * glm::vec4(-1.f, -1.f, 0.f, 1.f);
ctm = GlmToolkit::transform(vec, rot, glm::vec3(1.f));
handle_->draw( ctm, projection );
vec = modelview * glm::vec4(-1.f, 1.f, 0.f, 1.f);
ctm = GlmToolkit::transform(vec, rot, glm::vec3(1.f));
handle_->draw( ctm, projection );
}
else if ( type_ == RESIZE_H ){
// left and right
vec = modelview * glm::vec4(1.f, 0.f, 0.f, 1.f);
ctm = GlmToolkit::transform(vec, rot, glm::vec3(1.f));
handle_->draw( ctm, projection );
vec = modelview * glm::vec4(-1.f, 0.f, 0.f, 1.f);
ctm = GlmToolkit::transform(vec, rot, glm::vec3(1.f));
handle_->draw( ctm, projection );
}
else if ( type_ == RESIZE_V ){
// top and bottom
vec = modelview * glm::vec4(0.f, 1.f, 0.f, 1.f);
ctm = GlmToolkit::transform(vec, rot, glm::vec3(1.f));
handle_->draw( ctm, projection );
vec = modelview * glm::vec4(0.f, -1.f, 0.f, 1.f);
ctm = GlmToolkit::transform(vec, rot, glm::vec3(1.f));
handle_->draw( ctm, projection );
}
else if ( type_ == ROTATE ){
// one icon in top right corner
// 1. Fixed displacement by (0.12,0.12) along the rotation..
ctm = GlmToolkit::transform(glm::vec4(0.f), rot, glm::vec3(1.f));
glm::vec4 pos = ctm * glm::vec4(0.12f, 0.12f, 0.f, 1.f);
// Log::Info(" (0.12,0.12) becomes (%f, %f)", pos.x, pos.y);
// 2. ..from the top right corner (1,1)
vec = ( modelview * glm::vec4(1.f, 1.f, 0.f, 1.f) ) + pos;
ctm = GlmToolkit::transform(vec, rot, glm::vec3(1.f));
// TODO fix problem with negative scale
// glm::vec4 target = modelview * glm::vec4(1.2f, 1.2f, 0.f, 1.f);
// vec = modelview * glm::vec4(1.f, 1.f, 0.f, 1.f);
// glm::vec4 dv = target - vec;
// Log::Info("dv (%f, %f)", dv.x, dv.y);
// float m = dv.x < dv.y ? dv.x : dv.y;
// Log::Info("min %f", m);
// ctm = GlmToolkit::transform( glm::vec3(target), rot, glm::vec3(1.f));
handle_->draw( ctm, projection );
}
}
}
void Handles::accept(Visitor& v)
{
Node::accept(v);
v.visit(*this);
}
Symbol::Symbol(Type t, glm::vec3 pos) : Node(), type_(t)
{
static Mesh *icons[9] = {nullptr};
if (icons[0] == nullptr) {
icons[POINT] = new Mesh("mesh/point.ply");
icons[IMAGE] = new Mesh("mesh/icon_image.ply");
icons[VIDEO] = new Mesh("mesh/icon_video.ply");
icons[SESSION] = new Mesh("mesh/icon_vimix.ply");
icons[CLONE] = new Mesh("mesh/icon_clone.ply");
icons[RENDER] = new Mesh("mesh/icon_render.ply");
icons[DOTS] = new Mesh("mesh/icon_dots.ply");
icons[CIRCLES] = new Mesh("mesh/icon_circles.ply");
icons[EMPTY] = new Mesh("mesh/icon_empty.ply");
}
symbol_ = icons[type_];
translation_ = pos;
color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
}
Symbol::~Symbol()
{
}
void Symbol::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() ) {
if(symbol_ && !symbol_->initialized())
symbol_->init();
init();
}
if ( visible_ && symbol_) {
// set color
symbol_->shader()->color = color;
glm::mat4 ctm = modelview * transform_;
// correct for aspect ratio
glm::vec4 vec = ctm * glm::vec4(1.f, 1.0f, 0.f, 0.f);
ctm *= glm::scale(glm::identity<glm::mat4>(), glm::vec3( vec.y / vec.x, 1.f, 1.f));
symbol_->draw( ctm, projection);
}
}
void Symbol::accept(Visitor& v)
{
Node::accept(v);
v.visit(*this);
}
SelectionBox::SelectionBox()
{
// color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
color = glm::vec4( 1.f, 0.f, 0.f, 1.f);
square_ = new LineSquare( 3 );
}
void SelectionBox::draw (glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() ) {
square_->init();
init();
}
if (visible_) {
// use a visitor bounding box to calculate extend of all selected nodes
BoundingBoxVisitor vbox;
// visit every child of the selection
for (NodeSet::iterator node = children_.begin();
node != children_.end(); node++) {
// reset the transform before
vbox.setModelview(glm::identity<glm::mat4>());
(*node)->accept(vbox);
}
// get the bounding box
bbox_ = vbox.bbox();
// Log::Info(" -------- visitor box (%f, %f)-(%f, %f)", bbox_.min().x, bbox_.min().y, bbox_.max().x, bbox_.max().y);
// set color
square_->shader()->color = color;
// compute transformation from bounding box
// glm::mat4 ctm = modelview * GlmToolkit::transform(glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f));
glm::mat4 ctm = modelview * GlmToolkit::transform(bbox_.center(), glm::vec3(0.f), bbox_.scale());
// draw bbox
// square_->draw( modelview, projection);
square_->draw( ctm, projection);
// DEBUG
// visible_=false;
}
}

View File

@@ -1,91 +0,0 @@
#ifndef DECORATIONS_H
#define DECORATIONS_H
#include <string>
#include <glm/glm.hpp>
#include "Primitives.h"
#include "Mesh.h"
class Frame : public Node
{
public:
typedef enum { ROUND = 0, SHARP } CornerType;
typedef enum { THIN = 0, LARGE } BorderType;
typedef enum { NONE = 0, GLOW, DROP, PERSPECTIVE } ShadowType;
Frame(CornerType corner, BorderType border, ShadowType shadow);
~Frame();
void update (float dt) override;
void draw (glm::mat4 modelview, glm::mat4 projection) override;
void accept (Visitor& v) override;
Mesh *border() const { return side_; }
glm::vec4 color;
protected:
Mesh *side_;
Mesh *top_;
Mesh *shadow_;
LineSquare *square_;
};
class Handles : public Node
{
public:
typedef enum { RESIZE = 0, RESIZE_H, RESIZE_V, ROTATE } Type;
Handles(Type type);
~Handles();
void update (float dt) override;
void draw (glm::mat4 modelview, glm::mat4 projection) override;
void accept (Visitor& v) override;
Type type() const { return type_; }
Primitive *handle() const { return handle_; }
glm::vec4 color;
protected:
Primitive *handle_;
Type type_;
};
class Symbol : public Node
{
public:
typedef enum { POINT = 0, IMAGE, VIDEO, SESSION, CLONE, RENDER, DOTS, CIRCLES, EMPTY } Type;
Symbol(Type t = POINT, glm::vec3 pos = glm::vec3(0.f));
~Symbol();
void draw (glm::mat4 modelview, glm::mat4 projection) override;
void accept (Visitor& v) override;
Type type() const { return type_; }
glm::vec4 color;
protected:
Mesh *symbol_;
Type type_;
};
class SelectionBox : public Group
{
public:
SelectionBox();
void draw (glm::mat4 modelview, glm::mat4 projection) override;
glm::vec4 color;
protected:
LineSquare *square_;
GlmToolkit::AxisAlignedBoundingBox bbox_;
};
#endif // DECORATIONS_H

View File

@@ -1,76 +0,0 @@
#include <glm/gtc/matrix_transform.hpp>
#include "defines.h"
#include "DrawVisitor.h"
#include "Scene.h"
DrawVisitor::DrawVisitor(Node *nodetodraw, glm::mat4 projection)
{
target_ = nodetodraw;
modelview_ = glm::identity<glm::mat4>();
projection_ = projection;
done_ = false;
num_duplicat_ = 1;
transform_duplicat_ = glm::identity<glm::mat4>();
}
void DrawVisitor::loop(int num, glm::mat4 transform)
{
num_duplicat_ = CLAMP(num, 1, 10000);
transform_duplicat_ = transform;
}
void DrawVisitor::visit(Node &n)
{
// draw the target
if ( n.id() == target_->id()) {
for (int i = 0; i < num_duplicat_; ++i) {
// draw multiple copies if requested
n.draw(modelview_, projection_);
modelview_ *= transform_duplicat_;
}
done_ = true;
}
if (done_) return;
// update transform
modelview_ *= n.transform_;
}
void DrawVisitor::visit(Group &n)
{
// no need to traverse deeper if this node was drawn already
if (done_) return;
// traverse children
glm::mat4 mv = modelview_;
for (NodeSet::iterator node = n.begin(); !done_ && node != n.end(); node++) {
if ( (*node)->visible_ )
(*node)->accept(*this);
modelview_ = mv;
}
}
void DrawVisitor::visit(Scene &n)
{
n.root()->accept(*this);
}
void DrawVisitor::visit(Switch &n)
{
glm::mat4 mv = modelview_;
n.activeChild()->accept(*this);
modelview_ = mv;
}
void DrawVisitor::visit(Primitive &n)
{
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,119 +0,0 @@
#ifndef __IMGUI_FILE_DIALOG_H_
#define __IMGUI_FILE_DIALOG_H_
#include "imgui.h"
#include <vector>
#include <string>
#include <map>
#include <future>
#include <functional>
#include <thread>
#include <atomic>
#include <mutex>
#include <string>
#include <vector>
#include <list>
#define MAX_FILE_DIALOG_NAME_BUFFER 1024
struct FileInfoStruct
{
char type = ' ';
std::string filePath;
std::string fileName;
std::string ext;
};
class FileDialog
{
private:
std::vector<FileInfoStruct> m_FileList;
std::map<std::string, ImVec4> m_FilterColor;
std::string m_SelectedFileName;
std::string m_SelectedExt;
std::string m_CurrentPath;
std::vector<std::string> m_CurrentPath_Decomposition;
std::string m_Name;
bool m_ShowDialog;
bool m_ShowDrives;
public:
static char FileNameBuffer[MAX_FILE_DIALOG_NAME_BUFFER];
static char DirectoryNameBuffer[MAX_FILE_DIALOG_NAME_BUFFER];
static char SearchBuffer[MAX_FILE_DIALOG_NAME_BUFFER];
static int FilterIndex;
bool IsOk;
bool m_AnyWindowsHovered;
bool m_CreateDirectoryMode;
private:
std::string dlg_key;
std::string dlg_name;
const char *dlg_filters;
std::string dlg_path;
std::string dlg_defaultFileName;
std::string dlg_defaultExt;
std::function<void(std::string, bool*)> dlg_optionsPane;
size_t dlg_optionsPaneWidth;
std::string searchTag;
std::string dlg_userString;
public:
static FileDialog* Instance()
{
static FileDialog *_instance = new FileDialog();
return _instance;
}
static void RenderCurrent();
// Open an Open File dialog for TEXT file
static void SetCurrentOpenText();
// Open an Open File dialog for IMAGE file
static void SetCurrentOpenImage();
// Open an Open File dialog for MEDIA file
static void SetCurrentOpenMedia();
protected:
FileDialog(); // Prevent construction
FileDialog(const FileDialog&) {}; // Prevent construction by copying
FileDialog& operator =(const FileDialog&) { return *this; }; // Prevent assignment
~FileDialog(); // Prevent unwanted destruction
public:
void OpenDialog(const std::string& vKey, const char* vName, const char* vFilters,
const std::string& vPath, const std::string& vDefaultFileName,
std::function<void(std::string, bool*)> vOptionsPane, size_t vOptionsPaneWidth = 250, const std::string& vUserString = "");
void OpenDialog(const std::string& vKey, const char* vName, const char* vFilters,
const std::string& vDefaultFileName,
std::function<void(std::string, bool*)> vOptionsPane, size_t vOptionsPaneWidth = 250, const std::string& vUserString = "");
void OpenDialog(const std::string& vKey, const char* vName, const char* vFilters,
const std::string& vPath, const std::string& vDefaultFileName, const std::string& vUserString = "");
void OpenDialog(const std::string& vKey, const char* vName, const char* vFilters,
const std::string& vFilePathName, const std::string& vUserString = "");
void CloseDialog(const std::string& vKey);
bool Render(const std::string& vKey, ImVec2 geometry);
std::string GetFilepathName();
std::string GetCurrentPath();
std::string GetCurrentFileName();
std::string GetCurrentFilter();
std::string GetUserString();
void SetFilterColor(std::string vFilter, ImVec4 vColor);
bool GetFilterColor(std::string vFilter, ImVec4 *vColor);
void ClearFilterColor();
private:
void SetPath(const std::string& vPath);
void ScanDir(const std::string& vPath);
void SetCurrentDir(const std::string& vPath);
bool CreateDir(const std::string& vPath);
void ComposeNewPath(std::vector<std::string>::iterator vIter);
void GetDrives();
};
#endif // __IMGUI_FILE_DIALOG_H_

View File

@@ -1,208 +0,0 @@
#include "FrameBuffer.h"
#include "ImageShader.h"
#include "Resource.h"
#include "Settings.h"
#include "Log.h"
#include <glad/glad.h>
const char* FrameBuffer::aspect_ratio_name[4] = { "4:3", "3:2", "16:10", "16:9" };
glm::vec2 FrameBuffer::aspect_ratio_size[4] = { glm::vec2(4.f,3.f), glm::vec2(3.f,2.f), glm::vec2(16.f,10.f), glm::vec2(16.f,9.f) };
const char* FrameBuffer::resolution_name[4] = { "720p", "1080p", "1440", "4K" };
float FrameBuffer::resolution_height[4] = { 720.f, 1080.f, 1440.f, 2160.f };
glm::vec3 FrameBuffer::getResolutionFromParameters(int ar, int h)
{
float width = aspect_ratio_size[ar].x * resolution_height[h] / aspect_ratio_size[ar].y;
glm::vec3 res = glm::vec3( width, resolution_height[h] , 0.f);
return res;
}
FrameBuffer::FrameBuffer(glm::vec3 resolution, bool useAlpha, bool multiSampling): textureid_(0), intermediate_textureid_(0), framebufferid_(0), intermediate_framebufferid_(0), use_alpha_(useAlpha), use_multi_sampling_(multiSampling)
{
attrib_.viewport = glm::ivec2(resolution);
attrib_.clear_color = glm::vec4(0.f, 0.f, 0.f, use_alpha_ ? 0.f : 1.f);
}
FrameBuffer::FrameBuffer(uint width, uint height, bool useAlpha, bool multiSampling): textureid_(0), intermediate_textureid_(0), framebufferid_(0), intermediate_framebufferid_(0), use_alpha_(useAlpha), use_multi_sampling_(multiSampling)
{
attrib_.viewport = glm::ivec2(width, height);
attrib_.clear_color = glm::vec4(0.f, 0.f, 0.f, use_alpha_ ? 0.f : 1.f);
}
void FrameBuffer::init()
{
// generate texture
glGenTextures(1, &textureid_);
glBindTexture(GL_TEXTURE_2D, textureid_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, use_alpha_ ? GL_RGBA : GL_RGB, attrib_.viewport.x, attrib_.viewport.y,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
// create a framebuffer object
glGenFramebuffers(1, &framebufferid_);
glBindFramebuffer(GL_FRAMEBUFFER, framebufferid_);
// take settings into account: no multisampling for level 0
use_multi_sampling_ &= Settings::application.render.multisampling > 0;
if (use_multi_sampling_){
// create a multisample texture
glGenTextures(1, &intermediate_textureid_);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, intermediate_textureid_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, Settings::application.render.multisampling,
use_alpha_ ? GL_RGBA : GL_RGB, attrib_.viewport.x, attrib_.viewport.y, GL_TRUE);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
// attach the multisampled texture to FBO (currently binded)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, intermediate_textureid_, 0);
// create an intermediate FBO
glGenFramebuffers(1, &intermediate_framebufferid_);
glBindFramebuffer(GL_FRAMEBUFFER, intermediate_framebufferid_);
// attach the 2D texture to intermediate FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, 0);
// Log::Info("New FBO %d Multi Sampling ", framebufferid_);
}
else {
// direct attach the 2D texture to FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, 0);
// Log::Info("New FBO %d Single Sampling ", framebufferid_);
}
checkFramebufferStatus();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
FrameBuffer::~FrameBuffer()
{
if (framebufferid_)
glDeleteFramebuffers(1, &framebufferid_);
}
uint FrameBuffer::texture() const
{
if (framebufferid_ == 0)
return Resource::getTextureBlack();
return textureid_;
}
float FrameBuffer::aspectRatio() const
{
return static_cast<float>(attrib_.viewport.x) / static_cast<float>(attrib_.viewport.y);
}
glm::vec3 FrameBuffer::resolution() const
{
return glm::vec3(attrib_.viewport.x, attrib_.viewport.y, 0.f);
}
void FrameBuffer::bind()
{
if (!framebufferid_)
init();
glBindFramebuffer(GL_FRAMEBUFFER, framebufferid_);
}
void FrameBuffer::begin()
{
bind();
Rendering::manager().pushAttrib(attrib_);
glClear(GL_COLOR_BUFFER_BIT);
}
void FrameBuffer::end()
{
// if multisampling frame buffer
if (use_multi_sampling_) {
// blit the multisample FBO into unisample FBO to generate 2D texture
// Doing this blit will automatically resolve the multisampled FBO.
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferid_);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, intermediate_framebufferid_);
glBlitFramebuffer(0, 0, attrib_.viewport.x, attrib_.viewport.y,
0, 0, attrib_.viewport.x, attrib_.viewport.y, GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
FrameBuffer::release();
Rendering::manager().popAttrib();
}
void FrameBuffer::release()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
bool FrameBuffer::blit(FrameBuffer *other)
{
if (!framebufferid_ || !other || !other->framebufferid_)
return false;
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferid_);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, other->framebufferid_);
// blit to the frame buffer object
glBlitFramebuffer(0, 0, attrib_.viewport.x, attrib_.viewport.y,
0, 0, other->width(), other->height(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
return true;
}
void FrameBuffer::checkFramebufferStatus()
{
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
switch (status){
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
Log::Warning("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT is returned if any of the framebuffer attachment points are framebuffer incomplete.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
Log::Warning("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT is returned if the framebuffer does not have at least one image attached to it.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
Log::Warning("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER is returned if the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for any color attachment point(s) named by GL_DRAWBUFFERi.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
Log::Warning("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER is returned if GL_READ_BUFFER is not GL_NONE and the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for the color attachment point named by GL_READ_BUFFER.");
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
Log::Warning("GL_FRAMEBUFFER_UNSUPPORTED is returned if the combination of internal formats of the attached images violates an implementation-dependent set of restrictions.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
Log::Warning("GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE is returned if the value of GL_RENDERBUFFER_SAMPLES is not the same for all attached renderbuffers; if the value of GL_TEXTURE_SAMPLES is the not same for all attached textures; or, if the attached images are a mix of renderbuffers and textures, the value of GL_RENDERBUFFER_SAMPLES does not match the value of GL_TEXTURE_SAMPLES.\nGL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE is also returned if the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not the same for all attached textures; or, if the attached images are a mix of renderbuffers and textures, the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not GL_TRUE for all attached textures.");
break;
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
Log::Warning("GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS is returned if any framebuffer attachment is layered, and any populated attachment is not layered, or if all populated color attachments are not from textures of the same target.");
break;
case GL_FRAMEBUFFER_UNDEFINED:
Log::Warning(" GL_FRAMEBUFFER_UNDEFINED is returned if target is the default framebuffer, but the default framebuffer does not exist.");
break;
case GL_FRAMEBUFFER_COMPLETE:
#ifndef NDEBUG
Log::Info("Framebuffer created %d x %d.", width(), height());
#endif
break;
}
}

View File

@@ -1,58 +0,0 @@
#ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H
#include "Scene.h"
#include "RenderingManager.h"
class FrameBuffer {
public:
// size descriptions
static const char* aspect_ratio_name[4];
static glm::vec2 aspect_ratio_size[4];
static const char* resolution_name[4];
static float resolution_height[4];
static glm::vec3 getResolutionFromParameters(int ar, int h);
FrameBuffer(glm::vec3 resolution, bool useAlpha = false, bool multiSampling = false);
FrameBuffer(uint width, uint height, bool useAlpha = false, bool multiSampling = false);
~FrameBuffer();
// bind the FrameBuffer as current to draw into
void bind();
// unbind any framebuffer object
static void release();
// Bind & push attribs to prepare draw
void begin();
// pop attrib and unbind to end draw
void end();
// blit copy to another, returns true on success
bool blit(FrameBuffer *other);
// clear color
inline void setClearColor(glm::vec4 color) { attrib_.clear_color = color; }
inline glm::vec4 clearColor() const { return attrib_.clear_color; }
// width & height
inline uint width() const { return attrib_.viewport.x; }
inline uint height() const { return attrib_.viewport.y; }
glm::vec3 resolution() const;
float aspectRatio() const;
// texture index for draw
uint texture() const;
private:
void init();
void checkFramebufferStatus();
RenderingAttrib attrib_;
uint textureid_, intermediate_textureid_;
uint framebufferid_, intermediate_framebufferid_;
bool use_alpha_, use_multi_sampling_;
};
#endif // FRAMEBUFFER_H

View File

@@ -1,159 +0,0 @@
#include <algorithm>
#include "Log.h"
#include "Scene.h"
#include "GarbageVisitor.h"
GarbageVisitor::GarbageVisitor(Node *nodetocollect) : Visitor()
{
targets_.push_front(nodetocollect);
current_ = nullptr;
found_ = false;
}
GarbageVisitor::GarbageVisitor(Source *sourcetocollect) : Visitor()
{
targets_.push_front(sourcetocollect->group(View::MIXING));
targets_.push_front(sourcetocollect->group(View::GEOMETRY));
targets_.push_front(sourcetocollect->group(View::RENDERING));
current_ = nullptr;
found_ = false;
}
void GarbageVisitor::visit(Node &n)
{
// found the target
// if (n.id() == target_->id())
// if ( &n == target_ )
if ( std::count(targets_.begin(), targets_.end(), &n) )
{
// end recursive
found_ = true;
// take the node out of the Tree
if (current_)
current_->detatch(&n);
}
}
GarbageVisitor::~GarbageVisitor()
{
// actually delete the Node
}
void GarbageVisitor::visit(Group &n)
{
// no need to go further if the node was found (or is this group)
if (found_)
return;
// current group
current_ = &n;
// loop over members of a group
// and stop when found
for (NodeSet::iterator node = n.begin(); !found_ && node != n.end(); node++) {
// visit the child node
(*node)->accept(*this);
// un-stack recursive browsing
current_ = &n;
}
}
void GarbageVisitor::visit(Scene &n)
{
n.root()->accept(*this);
}
void GarbageVisitor::visit(Switch &n)
{
}
void GarbageVisitor::visit(Primitive &n)
{
}
void GarbageVisitor::visit(Surface &n)
{
}
void GarbageVisitor::visit(ImageSurface &n)
{
}
void GarbageVisitor::visit(FrameBufferSurface &n)
{
}
void GarbageVisitor::visit(MediaSurface &n)
{
}
void GarbageVisitor::visit(MediaPlayer &n)
{
}
void GarbageVisitor::visit(Shader &n)
{
}
void GarbageVisitor::visit(ImageShader &n)
{
}
void GarbageVisitor::visit(ImageProcessingShader &n)
{
}
void GarbageVisitor::visit(LineStrip &n)
{
}
void GarbageVisitor::visit(LineSquare &)
{
}
void GarbageVisitor::visit(LineCircle &n)
{
}
void GarbageVisitor::visit(Mesh &n)
{
}
void GarbageVisitor::visit(Frame &n)
{
}
void GarbageVisitor::visit (Source& s)
{
}
void GarbageVisitor::visit (MediaSource& s)
{
}

View File

@@ -1,47 +0,0 @@
#ifndef GARBAGEVISITOR_H
#define GARBAGEVISITOR_H
#include <list>
#include "Source.h"
#include "Visitor.h"
class GarbageVisitor : public Visitor
{
Group *current_;
std::list<Node *> targets_;
bool found_;
public:
GarbageVisitor(Source *sourcetocollect);
GarbageVisitor(Node *nodetocollect);
~GarbageVisitor();
void visit(Scene& n) override;
void visit(Node& n) override;
void visit(Group& n) override;
void visit(Switch& n) override;
void visit(Primitive& n) override;
void visit(Surface& n) override;
void visit(ImageSurface& n) override;
void visit(MediaSurface& n) override;
void visit(FrameBufferSurface& n) override;
void visit(LineStrip& n) override;
void visit(LineSquare&) override;
void visit(LineCircle& n) override;
void visit(Mesh& n) override;
void visit(Frame& n) override;
void visit(MediaPlayer& n) override;
void visit(Shader& n) override;
void visit(ImageShader& n) override;
void visit(ImageProcessingShader& n) override;
void visit (Source& s) override;
void visit (MediaSource& s) override;
};
#endif // GARBAGEVISITOR_H

View File

@@ -1,168 +0,0 @@
// Freely inspired from https://github.com/alter-rokuz/glm-aabb.git
#include "GlmToolkit.h"
#include <glm/gtc/matrix_access.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/random.hpp>
glm::mat4 GlmToolkit::transform(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale)
{
glm::mat4 View = glm::translate(glm::identity<glm::mat4>(), translation);
View = glm::rotate(View, rotation.x, glm::vec3(1.f, 0.f, 0.f));
View = glm::rotate(View, rotation.y, glm::vec3(0.f, 1.f, 0.f));
View = glm::rotate(View, rotation.z, glm::vec3(0.f, 0.f, 1.f));
glm::mat4 Model = glm::scale(glm::identity<glm::mat4>(), scale);
return View * Model;
}
GlmToolkit::AxisAlignedBoundingBox::AxisAlignedBoundingBox() {
mMin = glm::vec3(1.f);
mMax = glm::vec3(-1.f);
}
void GlmToolkit::AxisAlignedBoundingBox::extend(const glm::vec3& point) // TODO why ref to point?
{
if (isNull()) {
mMin = point;
mMax = point;
}
// general case
else {
mMin = glm::min(point, mMin);
mMax = glm::max(point, mMax);
}
}
void GlmToolkit::AxisAlignedBoundingBox::extend(std::vector<glm::vec3> points)
{
for (auto p = points.begin(); p != points.end(); p++)
extend(*p);
}
void GlmToolkit::AxisAlignedBoundingBox::extend(const AxisAlignedBoundingBox& bb)
{
if (bb.isNull())
return;
if (isNull()) {
mMin = bb.mMin;
mMax = bb.mMax;
}
// general case
else {
mMin = glm::min(bb.mMin, mMin);
mMax = glm::max(bb.mMax, mMax);
}
}
glm::vec3 GlmToolkit::AxisAlignedBoundingBox::center(bool ignore_z) const
{
glm::vec3 ret = glm::vec3(0.f);
if (!isNull())
{
glm::vec3 d = mMax - mMin;
ret = mMin + (d * 0.5f);
}
if (ignore_z)
ret.z = 0.f;
return ret;
}
glm::vec3 GlmToolkit::AxisAlignedBoundingBox::scale(bool ignore_z) const
{
glm::vec3 ret = glm::vec3(1.f);
if (!isNull())
{
glm::vec3 d = mMax - mMin;
ret = d * 0.5f;
}
if (ignore_z)
ret.z = 1.f;
return ret;
}
bool GlmToolkit::AxisAlignedBoundingBox::intersect(const AxisAlignedBoundingBox& bb, bool ignore_z) const
{
if (isNull() || bb.isNull())
return false;
if ( (mMax.x < bb.mMin.x) || (mMin.x > bb.mMax.x) ||
(mMax.y < bb.mMin.y) || (mMin.y > bb.mMax.y) ||
( !ignore_z && ((mMax.z < bb.mMin.z) || (mMin.z > bb.mMax.z)) ) )
{
return false;
}
return true;
}
bool GlmToolkit::AxisAlignedBoundingBox::contains(const AxisAlignedBoundingBox& bb, bool ignore_z) const
{
if ( !intersect(bb, ignore_z))
return false;
if ( (mMin.x <= bb.mMin.x) && (mMax.x >= bb.mMax.x) &&
(mMin.y <= bb.mMin.y) && (mMax.y >= bb.mMax.y) &&
( ignore_z || ((mMin.z <= bb.mMin.z) && (mMax.z >= bb.mMax.z)) ) )
{
return true;
}
return false;
}
bool GlmToolkit::AxisAlignedBoundingBox::contains(glm::vec3 point, bool ignore_z) const
{
if ( (mMax.x < point.x) || (mMin.x > point.x) ||
(mMax.y < point.y) || (mMin.y > point.y) ||
( !ignore_z && ((mMax.z < point.z) || (mMin.z > point.z)) ) )
return false;
return true;
}
GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::translated(glm::vec3 t)
{
GlmToolkit::AxisAlignedBoundingBox bb;
bb = *this;
bb.mMin += t;
bb.mMax += t;
return bb;
}
GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::scaled(glm::vec3 s)
{
GlmToolkit::AxisAlignedBoundingBox bb;
bb = *this;
bb.mMin *= s;
bb.mMax *= s;
return bb;
}
GlmToolkit::AxisAlignedBoundingBox GlmToolkit::AxisAlignedBoundingBox::transformed(glm::mat4 m)
{
GlmToolkit::AxisAlignedBoundingBox bb;
glm::vec4 vec;
vec = m * glm::vec4(mMin, 1.f);
bb.mMin = glm::vec3(vec);
vec = m * glm::vec4(mMax, 1.f);
bb.mMax = glm::vec3(vec);
return bb;
}

View File

@@ -1,50 +0,0 @@
#ifndef GLMTOOLKIT_H
#define GLMTOOLKIT_H
#include <vector>
#include <glm/glm.hpp>
namespace GlmToolkit
{
glm::mat4 transform(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale);
class AxisAlignedBoundingBox
{
glm::vec3 mMin;
glm::vec3 mMax;
public:
AxisAlignedBoundingBox();
void operator = (const AxisAlignedBoundingBox &D ) {
mMin = D.mMin;
mMax = D.mMax;
}
// test
inline bool isNull() const { return mMin.x > mMax.x || mMin.y > mMax.y || mMin.z > mMax.z;}
inline glm::vec3 min() const { return mMin; }
inline glm::vec3 max() const { return mMax; }
glm::vec3 center(bool ignore_z = true) const;
glm::vec3 scale(bool ignore_z = true) const;
bool intersect(const AxisAlignedBoundingBox& bb, bool ignore_z = true) const;
bool contains(const AxisAlignedBoundingBox& bb, bool ignore_z = true) const;
bool contains(glm::vec3 point, bool ignore_z = true) const;
// build
void extend(const glm::vec3& point);
void extend(std::vector<glm::vec3> points);
void extend(const AxisAlignedBoundingBox& bb);
AxisAlignedBoundingBox translated(glm::vec3 t);
AxisAlignedBoundingBox scaled(glm::vec3 s);
AxisAlignedBoundingBox transformed(glm::mat4 m);
};
}
#endif // GLMTOOLKIT_H

View File

@@ -1,94 +0,0 @@
#include <sstream>
#include <iomanip>
using namespace std;
#include "GstToolkit.h"
string GstToolkit::time_to_string(guint64 t)
{
if (t == GST_CLOCK_TIME_NONE)
return "00:00:00.00";
guint ms = GST_TIME_AS_MSECONDS(t);
guint s = ms / 1000;
ostringstream oss;
if (s / 3600)
oss << setw(2) << setfill('0') << s / 3600 << ':';
if ((s % 3600) / 60)
oss << setw(2) << setfill('0') << (s % 3600) / 60 << ':';
oss << setw(2) << setfill('0') << (s % 3600) % 60 << '.';
oss << setw(2) << setfill('0') << (ms % 1000) / 10;
// fixed length string (11 chars) HH:mm:ss.ii"
return oss.str();
}
list<string> GstToolkit::all_plugins()
{
list<string> pluginlist;
GList *l, *g;
l = gst_registry_get_plugin_list (gst_registry_get ());
for (g = l; g; g = g->next) {
GstPlugin *plugin = GST_PLUGIN (g->data);
pluginlist.push_front( string( gst_plugin_get_name (plugin) ) );
}
gst_plugin_list_free (l);
return pluginlist;
}
list<string> GstToolkit::all_plugin_features(string pluginname)
{
list<string> featurelist;
GList *l, *g;
l = gst_registry_get_feature_list_by_plugin (gst_registry_get (), pluginname.c_str());
for (g = l; g; g = g->next) {
GstPluginFeature *feature = GST_PLUGIN_FEATURE (g->data);
featurelist.push_front( string( gst_plugin_feature_get_name (feature) ) );
}
gst_plugin_feature_list_free (l);
return featurelist;
}
bool GstToolkit::enable_feature (string name, bool enable) {
GstRegistry *registry = NULL;
GstElementFactory *factory = NULL;
registry = gst_registry_get();
if (!registry) return false;
factory = gst_element_factory_find (name.c_str());
if (!factory) return false;
if (enable) {
gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), GST_RANK_PRIMARY + 1);
}
else {
gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), GST_RANK_NONE);
}
gst_registry_add_feature (registry, GST_PLUGIN_FEATURE (factory));
return true;
}
string GstToolkit::gst_version()
{
std::ostringstream oss;
oss << GST_VERSION_MAJOR << '.' << GST_VERSION_MINOR << '.';
oss << std::setw(2) << setfill('0') << GST_VERSION_MICRO ;
if (GST_VERSION_NANO > 0)
oss << ( (GST_VERSION_NANO < 2 ) ? " - (CVS)" : " - (Prerelease)");
return oss.str();
}

View File

@@ -1,22 +0,0 @@
#ifndef __GSTGUI_TOOLKIT_H_
#define __GSTGUI_TOOLKIT_H_
#include <gst/gst.h>
#include <string>
#include <list>
namespace GstToolkit
{
std::string time_to_string(guint64 t);
std::string gst_version();
std::list<std::string> all_plugins();
std::list<std::string> all_plugin_features(std::string pluginname);
bool enable_feature (std::string name, bool enable);
}
#endif // __GSTGUI_TOOLKIT_H_

File diff suppressed because it is too large Load Diff

View File

@@ -1,63 +0,0 @@
#ifndef __IMGUI_TOOLKIT_H_
#define __IMGUI_TOOLKIT_H_
#include <glib.h>
#include <string>
#include <list>
#include <vector>
#include <utility>
#include "rsc/fonts/IconsFontAwesome5.h"
namespace ImGuiToolkit
{
// Icons from resource icon.dds
void Icon(int i, int j);
void ShowIconsWindow(bool* p_open);
// utility buttons
bool ButtonIcon (int i, int j);
bool ButtonIconToggle (int i, int j, int i_toggle, int j_toggle, bool* toggle);
bool ButtonIconMultistate (std::vector<std::pair<int, int> > icons, int* state);
void ButtonToggle (const char* label, bool* toggle);
void ButtonSwitch (const char* label, bool* toggle , const char *help = nullptr);
bool IconToggle (int i, int j, int i_toggle, int j_toggle, bool* toggle, const char *tooltips[] = nullptr);
void ButtonOpenUrl (const char* url, const ImVec2& size_arg = ImVec2(0,0));
void HelpMarker (const char* desc);
// utility sliders
void Bar (float value, float in, float out, float min, float max, const char* title, bool expand);
bool TimelineSlider (const char* label, guint64 *time, guint64 duration, guint64 step);
bool TimelineSliderEdit (const char* label, guint64 *time, guint64 duration, guint64 step,
std::list<std::pair<guint64, guint64> >& segments);
// fonts from ressources 'fonts/'
typedef enum {
FONT_DEFAULT =0,
FONT_BOLD,
FONT_ITALIC,
FONT_MONO,
FONT_LARGE
} font_style;
void SetFont (font_style type, const std::string &ttf_font_name, int pointsize, int oversample = 2);
void PushFont (font_style type);
void WindowText(const char* window_name, ImVec2 window_pos, const char* text);
bool WindowButton(const char* window_name, ImVec2 window_pos, const char* text);
void WindowDragFloat(const char* window_name, ImVec2 window_pos, float* v, float v_speed, float v_min, float v_max, const char* format);
// color of gui items
typedef enum {
ACCENT_BLUE =0,
ACCENT_ORANGE,
ACCENT_GREY
} accent_color;
void SetAccentColor (accent_color color);
struct ImVec4 GetHighlightColor ();
void ShowStats (bool* p_open, int* p_corner);
}
#endif // __IMGUI_TOOLKIT_H_

View File

@@ -1,331 +0,0 @@
#include "ImGuiVisitor.h"
#include <vector>
#include <algorithm>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/constants.hpp>
#include "defines.h"
#include "Log.h"
#include "Scene.h"
#include "Primitives.h"
#include "ImageShader.h"
#include "ImageProcessingShader.h"
#include "MediaPlayer.h"
#include "MediaSource.h"
#include "SessionSource.h"
#include "Settings.h"
#include "Mixer.h"
#include "imgui.h"
#include "ImGuiToolkit.h"
#include "UserInterfaceManager.h"
#include "SystemToolkit.h"
ImGuiVisitor::ImGuiVisitor()
{
}
void ImGuiVisitor::visit(Node &n)
{
}
void ImGuiVisitor::visit(Group &n)
{
// std::string id = std::to_string(n.id());
// if (ImGui::TreeNode(id.c_str(), "Group %d", n.id()))
// {
// MODEL VIEW
if (ImGuiToolkit::ButtonIcon(1, 16)) {
n.translation_.x = 0.f;
n.translation_.y = 0.f;
n.rotation_.z = 0.f;
n.scale_.x = 1.f;
n.scale_.y = 1.f;
}
ImGui::SameLine(0, 10);
ImGui::Text("Geometry");
if (ImGuiToolkit::ButtonIcon(6, 15)) {
n.translation_.x = 0.f;
n.translation_.y = 0.f;
}
ImGui::SameLine(0, 10);
float translation[2] = { n.translation_.x, n.translation_.y};
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if ( ImGui::SliderFloat2("Position", translation, -5.0, 5.0) )
{
n.translation_.x = translation[0];
n.translation_.y = translation[1];
}
if (ImGuiToolkit::ButtonIcon(18, 9))
n.rotation_.z = 0.f;
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderAngle("Angle", &(n.rotation_.z), -180.f, 180.f) ;
if (ImGuiToolkit::ButtonIcon(3, 15)) {
n.scale_.x = 1.f;
n.scale_.y = 1.f;
}
ImGui::SameLine(0, 10);
float scale[2] = { n.scale_.x, n.scale_.y} ;
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if ( ImGui::SliderFloat2("Scale", scale, -MAX_SCALE, MAX_SCALE, "%.2f") )
{
n.scale_.x = CLAMP_SCALE(scale[0]);
n.scale_.y = CLAMP_SCALE(scale[1]);
}
// // loop over members of a group
// for (NodeSet::iterator node = n.begin(); node != n.end(); node++) {
// (*node)->accept(*this);
// }
// ImGui::TreePop();
// }
}
void ImGuiVisitor::visit(Switch &n)
{
if (n.numChildren()>0)
n.activeChild()->accept(*this);
}
void ImGuiVisitor::visit(Scene &n)
{
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
if (ImGui::CollapsingHeader("Scene Property Tree"))
{
n.root()->accept(*this);
}
}
void ImGuiVisitor::visit(Primitive &n)
{
ImGui::PushID(n.id());
ImGui::Text("Primitive %d", n.id());
n.shader()->accept(*this);
ImGui::PopID();
}
void ImGuiVisitor::visit(FrameBufferSurface &n)
{
ImGui::Text("Framebuffer");
}
void ImGuiVisitor::visit(MediaSurface &n)
{
ImGui::Text("%s", n.path().c_str());
if (n.mediaPlayer())
n.mediaPlayer()->accept(*this);
}
void ImGuiVisitor::visit(MediaPlayer &n)
{
ImGui::Text("Media Player");
}
void ImGuiVisitor::visit(Shader &n)
{
ImGui::PushID(n.id());
// if (ImGuiToolkit::ButtonIcon(10, 2)) {
// n.blending = Shader::BLEND_OPACITY;
// n.color = glm::vec4(1.f, 1.f, 1.f, 1.f);
// }
// ImGui::SameLine(0, 10);
// ImGui::ColorEdit3("Color", glm::value_ptr(n.color), ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel ) ;
// ImGui::SameLine(0, 5);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
int mode = n.blending;
if (ImGui::Combo("Blending", &mode, "Normal\0Screen\0Inverse\0Addition\0Subtract\0") )
n.blending = Shader::BlendMode(mode);
ImGui::PopID();
}
void ImGuiVisitor::visit(ImageShader &n)
{
ImGui::PushID(n.id());
// get index of the mask used in this ImageShader
int item_current = n.mask;
// if (ImGuiToolkit::ButtonIcon(10, 3)) n.mask = 0;
// ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
// combo list of masks
if ( ImGui::Combo("Mask", &item_current, ImageShader::mask_names, IM_ARRAYSIZE(ImageShader::mask_names) ) )
{
if (item_current < (int) ImageShader::mask_presets.size())
n.mask = item_current;
else {
// TODO ask for custom mask
}
}
ImGui::PopID();
}
void ImGuiVisitor::visit(ImageProcessingShader &n)
{
ImGui::PushID(n.id());
if (ImGuiToolkit::ButtonIcon(6, 2)) {
ImageProcessingShader defaultvalues;
n = defaultvalues;
}
ImGui::SameLine(0, 10);
ImGui::Text("Filters");
if (ImGuiToolkit::ButtonIcon(6, 4)) n.gamma = glm::vec4(1.f, 1.f, 1.f, 1.f);
ImGui::SameLine(0, 10);
ImGui::ColorEdit3("GammaColor", glm::value_ptr(n.gamma), ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel) ;
ImGui::SameLine(0, 5);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderFloat("Gamma", &n.gamma.w, 0.5f, 10.f, "%.2f", 2.f);
// ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
// ImGui::SliderFloat4("Levels", glm::value_ptr(n.levels), 0.0, 1.0);
if (ImGuiToolkit::ButtonIcon(4, 1)) {
n.brightness = 0.f;
n.contrast = 0.f;
}
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
float bc[2] = { n.brightness, n.contrast};
if ( ImGui::SliderFloat2("B & C", bc, -1.0, 1.0) )
{
n.brightness = bc[0];
n.contrast = bc[1];
}
if (ImGuiToolkit::ButtonIcon(2, 1)) n.saturation = 0.f;
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderFloat("Saturation", &n.saturation, -1.0, 1.0);
if (ImGuiToolkit::ButtonIcon(12, 4)) n.hueshift = 0.f;
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderFloat("Hue shift", &n.hueshift, 0.0, 1.0);
if (ImGuiToolkit::ButtonIcon(3, 1)) n.lumakey = 0.f;
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderFloat("Lumakey", &n.lumakey, 0.0, 1.0);
if (ImGuiToolkit::ButtonIcon(8, 1)) n.threshold = 0.f;
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderFloat("Threshold", &n.threshold, 0.0, 1.0, n.threshold < 0.001 ? "None" : "%.2f");
if (ImGuiToolkit::ButtonIcon(18, 1)) n.nbColors = 0;
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderInt("Posterize", &n.nbColors, 0, 16, n.nbColors == 0 ? "None" : "%d colors");
if (ImGuiToolkit::ButtonIcon(1, 7)) n.filterid = 0;
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::Combo("Filter", &n.filterid, ImageProcessingShader::filter_names, IM_ARRAYSIZE(ImageProcessingShader::filter_names) );
if (ImGuiToolkit::ButtonIcon(7, 1)) n.invert = 0;
ImGui::SameLine(0, 10);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::Combo("Invert", &n.invert, "None\0Invert Color\0Invert Luminance\0");
if (ImGuiToolkit::ButtonIcon(13, 4)) {
n.chromakey = glm::vec4(0.f, 0.8f, 0.f, 1.f);
n.chromadelta = 0.f;
}
ImGui::SameLine(0, 10);
ImGui::ColorEdit3("Chroma color", glm::value_ptr(n.chromakey), ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel ) ;
ImGui::SameLine(0, 5);
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
ImGui::SliderFloat("Chromakey", &n.chromadelta, 0.0, 1.0, n.chromadelta < 0.001 ? "None" : "Tolerance %.2f");
ImGui::PopID();
}
void ImGuiVisitor::visit (Source& s)
{
// blending
s.blendingShader()->accept(*this);
// preview
float preview_width = ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN;
ImVec2 imagesize ( preview_width, preview_width / s.frame()->aspectRatio());
ImGui::Image((void*)(uintptr_t) s.frame()->texture(), imagesize);
// image processing pannel
s.processingShader()->accept(*this);
// geometry direct control
s.groupNode(View::GEOMETRY)->accept(*this);
}
void ImGuiVisitor::visit (MediaSource& s)
{
if ( s.mediaplayer()->duration() == GST_CLOCK_TIME_NONE) {
ImGuiToolkit::Icon(2,9);
ImGui::SameLine(0, 10);
ImGui::Text("Image File");
}
else {
ImGuiToolkit::Icon(18,13);
ImGui::SameLine(0, 10);
ImGui::Text("Video File");
if ( ImGui::Button(IMGUI_TITLE_MEDIAPLAYER, ImVec2(IMGUI_RIGHT_ALIGN, 0)) ) {
UserInterface::manager().showMediaPlayer( s.mediaplayer());
}
}
ImGuiToolkit::ButtonOpenUrl( SystemToolkit::path_filename(s.path()).c_str(), ImVec2(IMGUI_RIGHT_ALIGN, 0) );
}
void ImGuiVisitor::visit (SessionSource& s)
{
ImGuiToolkit::Icon(4,9);
ImGui::SameLine(0, 10);
ImGui::Text("Session File");
if ( ImGui::Button( ICON_FA_FILE_UPLOAD " Make Current", ImVec2(IMGUI_RIGHT_ALIGN, 0)) )
Mixer::manager().set( s.detach() );
if ( ImGui::Button( ICON_FA_FILE_EXPORT " Import", ImVec2(IMGUI_RIGHT_ALIGN, 0)) )
Mixer::manager().merge( s.detach() );
ImGuiToolkit::ButtonOpenUrl( SystemToolkit::path_filename(s.path()).c_str(), ImVec2(IMGUI_RIGHT_ALIGN, 0) );
}
void ImGuiVisitor::visit (RenderSource& s)
{
ImGuiToolkit::Icon(19,1);
ImGui::SameLine(0, 10);
ImGui::Text("Rendering Output");
if ( ImGui::Button(IMGUI_TITLE_PREVIEW, ImVec2(IMGUI_RIGHT_ALIGN, 0)) )
Settings::application.widget.preview = true;
}
void ImGuiVisitor::visit (CloneSource& s)
{
ImGuiToolkit::Icon(9,2);
ImGui::SameLine(0, 10);
ImGui::Text("Clone of %s", s.origin()->name().c_str());
std::string label = "Select " + s.origin()->name();
if ( ImGui::Button(label.c_str(), ImVec2(IMGUI_RIGHT_ALIGN, 0)) )
Mixer::manager().setCurrentSource(s.origin());
}

View File

@@ -1,32 +0,0 @@
#ifndef IMGUIVISITOR_H
#define IMGUIVISITOR_H
#include "Visitor.h"
class ImGuiVisitor: public Visitor
{
public:
ImGuiVisitor();
// Elements of Scene
void visit(Scene& n) override;
void visit(Node& n) override;
void visit(Group& n) override;
void visit(Switch& n) override;
void visit(Primitive& n) override;
void visit(MediaSurface& n) override;
void visit(FrameBufferSurface& n) override;
// Elements with attributes
void visit(MediaPlayer& n) override;
void visit(Shader& n) override;
void visit(ImageShader& n) override;
void visit(ImageProcessingShader& n) override;
void visit (Source& s) override;
void visit (MediaSource& s) override;
void visit (SessionSource& s) override;
void visit (RenderSource& s) override;
void visit (CloneSource& s) override;
};
#endif // IMGUIVISITOR_H

View File

@@ -1,79 +0,0 @@
#include <glad/glad.h>
#include "defines.h"
#include "Visitor.h"
#include "ImageShader.h"
#include "Resource.h"
static ShadingProgram imageShadingProgram("shaders/image.vs", "shaders/image.fs");
const char* ImageShader::mask_names[11] = { "None", "Glow", "Halo", "Circle", "Round", "Vignette", "Top", "Botton", "Left", "Right", "Custom" };
std::vector< uint > ImageShader::mask_presets;
ImageShader::ImageShader(): Shader(), custom_textureindex(0)
{
// first initialization
if ( mask_presets.empty() ) {
mask_presets.push_back(Resource::getTextureWhite());
mask_presets.push_back(Resource::getTextureImage("images/mask_glow.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_halo.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_circle.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_roundcorner.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_vignette.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_linear_top.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_linear_bottom.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_linear_left.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_linear_right.png"));
}
// static program shader
program_ = &imageShadingProgram;
// reset instance
reset();
}
void ImageShader::use()
{
Shader::use();
program_->setUniform("stipple", stipple);
glActiveTexture(GL_TEXTURE1);
if ( mask < 10 ) {
glBindTexture(GL_TEXTURE_2D, mask_presets[mask]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
else
glBindTexture(GL_TEXTURE_2D, custom_textureindex);
glActiveTexture(GL_TEXTURE0);
}
void ImageShader::reset()
{
Shader::reset();
// default mask
mask = 0;
custom_textureindex = mask_presets[0];
// no stippling
stipple = 0.f;
}
void ImageShader::operator = (const ImageShader &S )
{
Shader::operator =(S);
mask = S.mask;
custom_textureindex = S.custom_textureindex;
stipple = S.stipple;
}
void ImageShader::accept(Visitor& v) {
Shader::accept(v);
v.visit(*this);
}

View File

@@ -1,35 +0,0 @@
#ifndef IMAGESHADER_H
#define IMAGESHADER_H
#include <string>
#include <map>
#ifdef __APPLE__
#include <sys/types.h>
#endif
#include "Shader.h"
class ImageShader : public Shader
{
public:
ImageShader();
// virtual ~ImageShader() {}
void use() override;
void reset() override;
void accept(Visitor& v) override;
void operator = (const ImageShader &S);
uint mask;
uint custom_textureindex;
float stipple;
static const char* mask_names[11];
static std::vector< uint > mask_presets;
};
#endif // IMAGESHADER_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,307 +0,0 @@
#ifndef __GST_MEDIA_PLAYER_H_
#define __GST_MEDIA_PLAYER_H_
#include <string>
#include <atomic>
#include <sstream>
#include <set>
#include <list>
#include <map>
#include <utility>
#include <mutex>
#include <gst/gst.h>
#include <gst/gl/gl.h>
#include <gst/pbutils/pbutils.h>
// Forward declare classes referenced
class Visitor;
#define MAX_PLAY_SPEED 20.0
#define MIN_PLAY_SPEED 0.1
#define N_VFRAME 3
struct TimeCounter {
GstClockTime last_time;
GstClockTime tic_time;
int nbFrames;
float fps;
public:
TimeCounter();
GstClockTime dt();
void tic();
void reset();
float frameRate() const;
};
struct MediaSegment
{
GstClockTime begin;
GstClockTime end;
MediaSegment()
{
begin = GST_CLOCK_TIME_NONE;
end = GST_CLOCK_TIME_NONE;
}
MediaSegment(GstClockTime b, GstClockTime e)
{
if ( b < e ) {
begin = b;
end = e;
} else {
begin = GST_CLOCK_TIME_NONE;
end = GST_CLOCK_TIME_NONE;
}
}
inline bool is_valid() const
{
return begin != GST_CLOCK_TIME_NONE && end != GST_CLOCK_TIME_NONE && begin < end;
}
inline bool operator < (const MediaSegment b) const
{
return (this->is_valid() && b.is_valid() && this->end < b.begin);
}
inline bool operator == (const MediaSegment b) const
{
return (this->begin == b.begin && this->end == b.end);
}
inline bool operator != (const MediaSegment b) const
{
return (this->begin != b.begin || this->end != b.end);
}
};
struct containsTime: public std::unary_function<MediaSegment, bool>
{
inline bool operator()(const MediaSegment s) const
{
return ( s.is_valid() && _t > s.begin && _t < s.end );
}
containsTime(GstClockTime t) : _t(t) { }
private:
GstClockTime _t;
};
typedef std::set<MediaSegment> MediaSegmentSet;
class MediaPlayer {
public:
/**
* Constructor of a GStreamer Media
*/
MediaPlayer( std::string name = std::string() );
/**
* Destructor.
*/
~MediaPlayer();
/**
* Open a media using gstreamer URI
* */
void open( std::string path);
/**
* True if a media was oppenned
* */
bool isOpen() const;
/**
* True if problem occured
* */
bool failed() const;
/**
* Close the Media
* */
void close();
/**
* Update status
* Must be called in update loop
* */
void update();
void enable(bool on);
bool isEnabled() const;
/**
* Pause / Play
* Can play backward if play speed is negative
* */
void play(bool on);
/**
* Get Pause / Play
* */
bool isPlaying(bool testpipeline = false) const;
/**
* Speed factor for playing
* Can be negative.
* */
double playSpeed() const;
/**
* Set the speed factor for playing
* Can be negative.
* */
void setPlaySpeed(double s);
/**
* True if the player will loop when at begin or end
* */
typedef enum {
LOOP_NONE = 0,
LOOP_REWIND = 1,
LOOP_BIDIRECTIONAL = 2
} LoopMode;
LoopMode loop() const;
/**
* Set the player to loop
* */
void setLoop(LoopMode mode);
/**
* Restart from zero
* */
void rewind();
/**
* Seek to next frame when paused
* Can go backward if play speed is negative
* */
void seekNextFrame();
/**
* Seek to any position in media
* pos in nanoseconds.
* */
void seekTo(GstClockTime pos);
/**
* Jump by 10% of the duration
* */
void fastForward();
/**
* Get position time
* */
GstClockTime position();
/**
* Get total duration time
* */
GstClockTime duration();
/**
* Get duration of one frame
* */
GstClockTime frameDuration();
/**
* Get framerate of the media
* */
double frameRate() const;
/**
* Get name of Codec of the media
* */
std::string codec() const;
/**
* Get rendering update framerate
* measured during play
* */
double updateFrameRate() const;
/**
* Get the OpenGL texture
* Must be called in OpenGL context
* */
guint texture() const;
/**
* Get Image properties
* */
guint width() const;
guint height() const;
float aspectRatio() const;
/**
* Get name of the media
* */
std::string uri() const;
std::string filename() const;
/**
* Accept visitors
* */
void accept(Visitor& v);
/**
* @brief registered
* @return list of media players currently registered
*/
static std::list<MediaPlayer*> registered() { return registered_; }
static std::list<MediaPlayer*>::const_iterator begin() { return registered_.cbegin(); }
static std::list<MediaPlayer*>::const_iterator end() { return registered_.cend(); }
private:
bool addPlaySegment(GstClockTime begin, GstClockTime end);
bool addPlaySegment(MediaSegment s);
bool removePlaySegmentAt(GstClockTime t);
bool removeAllPlaySegmentOverlap(MediaSegment s);
std::list< std::pair<guint64, guint64> > getPlaySegments() const;
std::string id_;
std::string filename_;
std::string uri_;
guint textureindex_;
guint width_;
guint height_;
guint par_width_; // width to match pixel aspect ratio
GstClockTime position_;
GstClockTime start_position_;
GstClockTime duration_;
GstClockTime frame_duration_;
bool (*TimeComparator_)(GstClockTime,GstClockTime);
gdouble rate_;
LoopMode loop_;
std::atomic<bool> need_loop_;
TimeCounter timecount_;
gdouble framerate_;
GstState desired_state_;
GstElement *pipeline_;
GstDiscoverer *discoverer_;
std::stringstream discoverer_message_;
std::string codec_name_;
GstVideoInfo v_frame_video_info_;
guint vframe_read_index_;
guint vframe_write_index_;
GstVideoFrame vframe_[N_VFRAME];
std::atomic<bool> vframe_is_full_[N_VFRAME];
GstClockTime vframe_position_[N_VFRAME];
std::mutex vframe_lock_[N_VFRAME];
// for PBO
guint pbo_[2];
guint pbo_index_, pbo_next_index_;
guint pbo_size_;
MediaSegmentSet segments_;
MediaSegmentSet::iterator current_segment_;
bool ready_;
bool failed_;
bool seekable_;
bool isimage_;
bool interlaced_;
bool enabled_;
void init_texture();
void execute_open();
void execute_loop_command();
void execute_seek_command(GstClockTime target = GST_CLOCK_TIME_NONE);
bool fill_v_frame(GstBuffer *buf);
static GstFlowReturn callback_pull_sample_video (GstElement *bin, MediaPlayer *m);
static void callback_end_of_video (GstElement *, MediaPlayer *m);
static void callback_discoverer_process (GstDiscoverer *discoverer, GstDiscovererInfo *info, GError *err, MediaPlayer *m);
static void callback_discoverer_finished(GstDiscoverer *discoverer, MediaPlayer *m);
static std::list<MediaPlayer*> registered_;
};
#endif // __GST_MEDIA_PLAYER_H_

View File

@@ -1,143 +0,0 @@
#include <glm/gtc/matrix_transform.hpp>
#include "MediaSource.h"
#include "defines.h"
#include "ImageShader.h"
#include "ImageProcessingShader.h"
#include "Resource.h"
#include "Primitives.h"
#include "MediaPlayer.h"
#include "Visitor.h"
#include "Log.h"
MediaSource::MediaSource() : Source(), path_("")
{
// create media player
mediaplayer_ = new MediaPlayer;
// create media surface:
// - textured with original texture from media player
// - crop & repeat UV can be managed here
// - additional custom shader can be associated
mediasurface_ = new Surface(rendershader_);
}
MediaSource::~MediaSource()
{
// delete media surface & player
delete mediasurface_;
delete mediaplayer_;
}
void MediaSource::setPath(const std::string &p)
{
path_ = p;
mediaplayer_->open(path_);
mediaplayer_->play(true);
Log::Notify("Opening %s", p.c_str());
}
std::string MediaSource::path() const
{
return path_;
}
MediaPlayer *MediaSource::mediaplayer() const
{
return mediaplayer_;
}
bool MediaSource::failed() const
{
return mediaplayer_->failed();
}
uint MediaSource::texture() const
{
return mediaplayer_->texture();
}
void MediaSource::init()
{
if ( mediaplayer_->isOpen() ) {
// update video
mediaplayer_->update();
// once the texture of media player is created
if (mediaplayer_->texture() != Resource::getTextureBlack()) {
// get the texture index from media player, apply it to the media surface
mediasurface_->setTextureIndex( mediaplayer_->texture() );
// create Frame buffer matching size of media player
float height = float(mediaplayer()->width()) / mediaplayer()->aspectRatio();
FrameBuffer *renderbuffer = new FrameBuffer(mediaplayer()->width(), (uint)height, true);
// set the renderbuffer of the source and attach rendering nodes
attach(renderbuffer);
// icon in mixing view
if (mediaplayer_->duration() == GST_CLOCK_TIME_NONE) {
overlays_[View::MIXING]->attach( new Symbol(Symbol::IMAGE, glm::vec3(0.8f, 0.8f, 0.01f)) );
overlays_[View::LAYER]->attach( new Symbol(Symbol::IMAGE, glm::vec3(0.8f, 0.8f, 0.01f)) );
}
else {
overlays_[View::MIXING]->attach( new Symbol(Symbol::VIDEO, glm::vec3(0.8f, 0.8f, 0.01f)) );
overlays_[View::LAYER]->attach( new Symbol(Symbol::VIDEO, glm::vec3(0.8f, 0.8f, 0.01f)) );
}
// done init
initialized_ = true;
Log::Info("Source Media linked to Media %s.", mediaplayer()->uri().c_str());
// force update of activation mode
active_ = true;
touch();
}
}
}
void MediaSource::setActive (bool on)
{
bool was_active = active_;
Source::setActive(on);
// change status of media player (only if status changed)
if ( active_ != was_active ) {
mediaplayer()->enable(active_);
}
}
void MediaSource::update(float dt)
{
Source::update(dt);
// update video
if (active_)
mediaplayer_->update();
}
void MediaSource::render()
{
if (!initialized_)
init();
else {
// render the media player into frame buffer
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
renderbuffer_->begin();
mediasurface_->draw(glm::identity<glm::mat4>(), projection);
renderbuffer_->end();
}
}
void MediaSource::accept(Visitor& v)
{
Source::accept(v);
v.visit(*this);
}

735
Mixer.cpp
View File

@@ -1,735 +0,0 @@
#include <algorithm>
#include <thread>
#include <atomic>
#include <vector>
#include <chrono>
// GStreamer
#include <gst/gst.h>
#include <tinyxml2.h>
#include "tinyxml2Toolkit.h"
using namespace tinyxml2;
#include "defines.h"
#include "Settings.h"
#include "Log.h"
#include "View.h"
#include "SystemToolkit.h"
//#include "GarbageVisitor.h"
#include "SessionVisitor.h"
#include "SessionCreator.h"
#include "SessionSource.h"
#include "MediaSource.h"
#include "Mixer.h"
// static semaphore to prevent multiple threads for load / save
static std::atomic<bool> sessionThreadActive_ = false;
static std::atomic<bool> sessionSwapRequested_ = false;
// static multithreaded session loading
static void loadSession(const std::string& filename, Session *session)
{
while (sessionThreadActive_)
std::this_thread::sleep_for( std::chrono::milliseconds(50));
sessionThreadActive_ = true;
// actual loading of xml file
SessionCreator creator( session );
if (creator.load(filename)) {
// loaded ok
session->setFilename(filename);
// internal update flag
sessionSwapRequested_ = true;
// notification
Log::Notify("Session %s loaded. %d source(s) created.", filename.c_str(), session->numSource());
}
else {
// error loading
Log::Warning("Failed to load Session file %s.", filename.c_str());
}
sessionThreadActive_ = false;
}
static std::atomic<bool> sessionImportRequested_ = false;
static void importSession(const std::string& filename, Session *session)
{
while (sessionThreadActive_)
std::this_thread::sleep_for( std::chrono::milliseconds(50));
sessionThreadActive_ = true;
// actual loading of xml file
SessionCreator creator( session );
if (creator.load(filename)) {
// internal update flag
sessionImportRequested_ = true;
Log::Notify("Session %s loaded. %d source(s) imported.", filename.c_str(), session->numSource());
}
else {
// error loading
Log::Warning("Failed to import Session file %s.", filename.c_str());
}
sessionThreadActive_ = false;
}
// static multithreaded session saving
static void saveSession(const std::string& filename, Session *session)
{
// reset
while (sessionThreadActive_)
std::this_thread::sleep_for( std::chrono::milliseconds(50));
sessionThreadActive_ = true;
// creation of XML doc
XMLDocument xmlDoc;
XMLElement *version = xmlDoc.NewElement(APP_NAME);
version->SetAttribute("major", XML_VERSION_MAJOR);
version->SetAttribute("minor", XML_VERSION_MINOR);
version->SetAttribute("size", session->numSource());
version->SetAttribute("date", SystemToolkit::date_time_string().c_str());
xmlDoc.InsertEndChild(version);
// 1. list of sources
XMLElement *sessionNode = xmlDoc.NewElement("Session");
xmlDoc.InsertEndChild(sessionNode);
SourceList::iterator iter;
for (iter = session->begin(); iter != session->end(); iter++)
{
SessionVisitor sv(&xmlDoc, sessionNode);
// source visitor
(*iter)->accept(sv);
}
// 2. config of views
XMLElement *views = xmlDoc.NewElement("Views");
xmlDoc.InsertEndChild(views);
{
XMLElement *mixing = xmlDoc.NewElement( "Mixing" );
mixing->InsertEndChild( SessionVisitor::NodeToXML(*session->config(View::MIXING), &xmlDoc));
views->InsertEndChild(mixing);
XMLElement *geometry = xmlDoc.NewElement( "Geometry" );
geometry->InsertEndChild( SessionVisitor::NodeToXML(*session->config(View::GEOMETRY), &xmlDoc));
views->InsertEndChild(geometry);
XMLElement *layer = xmlDoc.NewElement( "Layer" );
layer->InsertEndChild( SessionVisitor::NodeToXML(*session->config(View::LAYER), &xmlDoc));
views->InsertEndChild(layer);
XMLElement *render = xmlDoc.NewElement( "Rendering" );
render->InsertEndChild( SessionVisitor::NodeToXML(*session->config(View::RENDERING), &xmlDoc));
views->InsertEndChild(render);
}
// save file to disk
if ( XMLSaveDoc(&xmlDoc, filename) ) {
// all ok
session->setFilename(filename);
// cosmetics saved ok
Rendering::manager().mainWindow().setTitle(filename);
Settings::application.recentSessions.push(filename);
Log::Notify("Session %s saved.", filename.c_str());
// set session filename
}
else {
// error loading
Log::Warning("Failed to save Session file %s.", filename.c_str());
}
sessionThreadActive_ = false;
}
Mixer::Mixer() : session_(nullptr), back_session_(nullptr), current_view_(nullptr),
update_time_(GST_CLOCK_TIME_NONE), dt_(0.f)
{
// unsused initial empty session
session_ = new Session;
current_source_ = session_->end();
current_source_index_ = -1;
// auto load if Settings ask to
if ( Settings::application.recentSessions.load_at_start &&
Settings::application.recentSessions.valid_file &&
Settings::application.recentSessions.filenames.size() > 0 )
load( Settings::application.recentSessions.filenames.front() );
else
// initializes with a new empty session
clear();
// this initializes with the current view
setView( (View::Mode) Settings::application.current_view );
}
void Mixer::update()
{
// change session when threaded loading is finished
if (sessionSwapRequested_) {
sessionSwapRequested_ = false;
// successfully loading
if ( back_session_ ) {
// swap front and back sessions
swap();
// set session filename
Rendering::manager().mainWindow().setTitle(session_->filename());
Settings::application.recentSessions.push(session_->filename());
}
}
// merge session when threaded loading is finished
if (sessionImportRequested_) {
sessionImportRequested_ = false;
merge(back_session_);
back_session_ = nullptr;
}
// insert source candidate for this session
if (candidate_sources_.size() > 0) {
// NB: only make the last candidate the current source in Mixing view
insertSource(candidate_sources_.front(), candidate_sources_.size() > 1 ? View::INVALID : View::MIXING);
candidate_sources_.pop_front();
}
// compute dt
if (update_time_ == GST_CLOCK_TIME_NONE)
update_time_ = gst_util_get_timestamp ();
gint64 current_time = gst_util_get_timestamp ();
// dt is in milisecond, with fractional precision (from micro seconds)
dt_ = static_cast<float>( GST_TIME_AS_USECONDS(current_time - update_time_) * 0.001f);
update_time_ = current_time;
// update session and associated sources
session_->update(dt_);
// delete sources which failed update (one by one)
if (session()->failedSource() != nullptr)
deleteSource(session()->failedSource());
// update views
mixing_.update(dt_);
geometry_.update(dt_);
layer_.update(dt_);
transition_.update(dt_);
// optimize the reordering in depth for views;
// deep updates shall be performed only 1 frame
View::need_deep_update_ = false;
}
void Mixer::draw()
{
// draw the current view in the window
current_view_->draw();
// make sure we disable fading of session rendering
if (current_view_ != &transition_)
session_->fadeIn();
}
// manangement of sources
Source * Mixer::createSourceFile(std::string path)
{
// ready to create a source
Source *s = nullptr;
// sanity check
if ( SystemToolkit::file_exists( path ) ) {
// test type of file by extension
std::string ext = SystemToolkit::extension_filename(path);
if ( ext == "mix" )
{
// create a session source
SessionSource *ss = new SessionSource();
ss->load(path);
s = ss;
}
else {
// (try to) create media source by default
MediaSource *ms = new MediaSource;
ms->setPath(path);
s = ms;
}
// remember in recent media
Settings::application.recentImport.push(path);
Settings::application.recentImport.path = SystemToolkit::path_filename(path);
// propose a new name based on uri
renameSource(s, SystemToolkit::base_filename(path));
}
else
Log::Notify("File %s does not exist.", path.c_str());
return s;
}
Source * Mixer::createSourceRender()
{
// ready to create a source
RenderSource *s = new RenderSource(session_);
// propose a new name based on session name
renameSource(s, SystemToolkit::base_filename(session_->filename()));
return s;
}
Source * Mixer::createSourceClone(std::string namesource)
{
// ready to create a source
Source *s = nullptr;
// origin to clone is either the given name or the current
SourceList::iterator origin = session_->end();
if ( !namesource.empty() )
origin =session_->find(namesource);
else if (current_source_ != session_->end())
origin = current_source_;
// have an origin, can clone it
if (origin != session_->end()) {
// create a source
s = (*origin)->clone();
// get new name
renameSource(s, (*origin)->name());
}
return s;
}
void Mixer::addSource(Source *s)
{
if (s != nullptr)
candidate_sources_.push_back(s);
}
void Mixer::insertSource(Source *s, View::Mode m)
{
if ( s != nullptr )
{
// Add source to Session
SourceList::iterator sit = session_->addSource(s);
// set a default depth to the new source
layer_.setDepth(s);
// set a default alpha to the new source
mixing_.setAlpha(s);
// add sources Nodes to all views
mixing_.scene.ws()->attach(s->group(View::MIXING));
geometry_.scene.ws()->attach(s->group(View::GEOMETRY));
layer_.scene.ws()->attach(s->group(View::LAYER));
// if requested to show the source in a given view
// (known to work for View::MIXING et TRANSITION: other views untested)
if (m != View::INVALID) {
// switch to this view to show source created
setView(m);
current_view_->update(0.f);
current_view_->centerSource(s);
// set this new source as current
setCurrentSource( sit );
}
}
}
void Mixer::deleteSource(Source *s)
{
if ( s != nullptr )
{
// in case it was the current source...
unsetCurrentSource();
// in case it was selected..
selection().remove(s);
// keep name for log
std::string name = s->name();
// remove source Nodes from all views
mixing_.scene.ws()->detatch( s->group(View::MIXING) );
geometry_.scene.ws()->detatch( s->group(View::GEOMETRY) );
layer_.scene.ws()->detatch( s->group(View::LAYER) );
transition_.scene.ws()->detatch( s->group(View::TRANSITION) );
// delete source
session_->deleteSource(s);
// log
Log::Notify("Source %s deleted.", name.c_str());
}
// cancel transition source in TRANSITION view
if ( current_view_ == &transition_ ) {
// cancel attachment
transition_.attach(nullptr);
// revert to mixing view
setView(View::MIXING);
}
}
void Mixer::deleteSelection()
{
while ( !selection().empty() )
deleteSource( selection().front());
}
void Mixer::renameSource(Source *s, const std::string &newname)
{
if ( s != nullptr )
{
// tentative new name
std::string tentativename = newname;
// refuse to rename to an empty name
if ( newname.empty() )
tentativename = "source";
// trivial case : same name as current
if ( tentativename == s->name() )
return;
// search for a source of the name 'tentativename'
std::string basename = tentativename;
int count = 1;
while ( std::find_if(session_->begin(), session_->end(), Source::hasName(tentativename)) != session_->end() ) {
tentativename = basename + std::to_string(++count);
}
// ok to rename
s->setName(tentativename);
}
}
void Mixer::setCurrentSource(SourceList::iterator it)
{
// nothing to do if already current
if ( current_source_ == it )
return;
// clear current (even if it is invalid)
unsetCurrentSource();
// change current if it is valid
if ( it != session_->end() ) {
current_source_ = it;
current_source_index_ = session_->index(current_source_);
// set selection for this only source if not already part of a selection
if (!selection().contains(*current_source_))
selection().set(*current_source_);
// show status as current
(*current_source_)->setMode(Source::CURRENT);
(*current_source_)->group(View::MIXING)->update_callbacks_.push_back(new BounceScaleCallback);
(*current_source_)->group(View::LAYER)->update_callbacks_.push_back(new BounceScaleCallback);
}
}
Source * Mixer::findSource (Node *node)
{
SourceList::iterator it = session_->find(node);
if (it != session_->end())
return *it;
return nullptr;
}
Source * Mixer::findSource (std::string namesource)
{
SourceList::iterator it = session_->find(namesource);
if (it != session_->end())
return *it;
return nullptr;
}
void Mixer::setCurrentSource(Node *node)
{
setCurrentSource( session_->find(node) );
}
void Mixer::setCurrentSource(std::string namesource)
{
setCurrentSource( session_->find(namesource) );
}
void Mixer::setCurrentSource(Source *s)
{
setCurrentSource( session_->find(s) );
}
void Mixer::setCurrentSource(int index)
{
setCurrentSource( session_->find(index) );
}
void Mixer::setCurrentNext()
{
SourceList::iterator it = current_source_;
it++;
if (it == session_->end()) {
it = session_->begin();
}
setCurrentSource( it );
}
void Mixer::unsetCurrentSource()
{
// discard overlay for previously current source
if ( current_source_ != session_->end() ) {
// current source is part of a selection, just change status
if (selection().size() > 1) {
(*current_source_)->setMode(Source::SELECTED);
}
// current source is the only selected source, unselect too
else
{
// remove from selection
selection().remove( *current_source_ );
}
// deselect current source
current_source_ = session_->end();
current_source_index_ = -1;
}
}
int Mixer::indexCurrentSource()
{
return current_source_index_;
}
Source *Mixer::currentSource()
{
if ( current_source_ == session_->end() )
return nullptr;
else {
return *(current_source_);
}
}
// management of view
void Mixer::setView(View::Mode m)
{
// special case when leaving transition view
if ( current_view_ == &transition_ ) {
// get the session detached from the transition view and set it as current session
// NB: detatch() can return nullptr, which is then ignored.
set ( transition_.detach() );
}
switch (m) {
case View::TRANSITION:
current_view_ = &transition_;
break;
case View::GEOMETRY:
current_view_ = &geometry_;
break;
case View::LAYER:
current_view_ = &layer_;
break;
case View::MIXING:
default:
current_view_ = &mixing_;
break;
}
Settings::application.current_view = (int) m;
}
View *Mixer::view(View::Mode m)
{
switch (m) {
case View::TRANSITION:
return &transition_;
case View::GEOMETRY:
return &geometry_;
case View::LAYER:
return &layer_;
case View::MIXING:
return &mixing_;
default:
return current_view_;
}
}
void Mixer::save()
{
if (!session_->filename().empty())
saveas(session_->filename());
}
void Mixer::saveas(const std::string& filename)
{
// optional copy of views config
session_->config(View::MIXING)->copyTransform( mixing_.scene.root() );
session_->config(View::GEOMETRY)->copyTransform( geometry_.scene.root() );
session_->config(View::LAYER)->copyTransform( layer_.scene.root() );
// launch a thread to save the session
std::thread (saveSession, filename, session_).detach();
}
void Mixer::load(const std::string& filename)
{
if (back_session_)
delete back_session_;
// create empty session
back_session_ = new Session;
// launch a thread to load the session into back_session
std::thread (loadSession, filename, back_session_).detach();
}
void Mixer::open(const std::string& filename)
{
if (Settings::application.smooth_transition)
{
// create special SessionSource to be used for the smooth transition
SessionSource *ts = new SessionSource();
ts->load(filename);
// propose a new name based on uri
renameSource(ts, SystemToolkit::base_filename(filename));
// insert source and switch to transition view
insertSource(ts, View::TRANSITION);
// attach the SessionSource to the transition view
transition_.attach(ts);
}
else
load(filename);
}
void Mixer::import(const std::string& filename)
{
if (back_session_)
delete back_session_;
// create empty session
back_session_ = new Session;
// launch a thread to load the session into back_session
std::thread (importSession, filename, back_session_).detach();
}
void Mixer::merge(Session *session)
{
if (session) {
for ( Source *s = session->popSource(); s != nullptr; s = session->popSource())
insertSource(s);
delete session;
}
}
void Mixer::swap()
{
if (!back_session_)
return;
if (session_) {
// clear selection
selection().clear();
// detatch current session's nodes from views
for (auto source_iter = session_->begin(); source_iter != session_->end(); source_iter++)
{
mixing_.scene.ws()->detatch( (*source_iter)->group(View::MIXING) );
geometry_.scene.ws()->detatch( (*source_iter)->group(View::GEOMETRY) );
layer_.scene.ws()->detatch( (*source_iter)->group(View::LAYER) );
transition_.scene.ws()->detatch( (*source_iter)->group(View::TRANSITION) );
}
}
// swap back and front
Session *tmp = session_;
session_ = back_session_;
back_session_ = tmp;
// attach new session's nodes to views
for (auto source_iter = session_->begin(); source_iter != session_->end(); source_iter++)
{
mixing_.scene.ws()->attach( (*source_iter)->group(View::MIXING) );
geometry_.scene.ws()->attach( (*source_iter)->group(View::GEOMETRY) );
layer_.scene.ws()->attach( (*source_iter)->group(View::LAYER) );
}
// optional copy of views config
mixing_.scene.root()->copyTransform( session_->config(View::MIXING) );
geometry_.scene.root()->copyTransform( session_->config(View::GEOMETRY) );
layer_.scene.root()->copyTransform( session_->config(View::LAYER) );
// set resolution
session_->setResolution( session_->config(View::RENDERING)->scale_ );
// request complete update for views
View::need_deep_update_ = true;
// no current source
current_source_ = session_->end();
current_source_index_ = -1;
// reset timer
update_time_ = GST_CLOCK_TIME_NONE;
// delete back
delete back_session_;
back_session_ = nullptr;
}
void Mixer::clear()
{
// delete previous back session if needed
if (back_session_)
delete back_session_;
// create empty session
back_session_ = new Session;
// swap current with empty
sessionSwapRequested_ = true;
Log::Info("New session ready.");
}
void Mixer::set(Session *s)
{
if ( s == nullptr )
return;
// delete previous back session if needed
if (back_session_)
delete back_session_;
// set to new given session
back_session_ = s;
// swap current with given session
sessionSwapRequested_ = true;
}

101
Mixer.h
View File

@@ -1,101 +0,0 @@
#ifndef MIXER_H
#define MIXER_H
#include "View.h"
#include "Session.h"
#include "Selection.h"
class Mixer
{
// Private Constructor
Mixer();
Mixer(Mixer const& copy); // Not Implemented
Mixer& operator=(Mixer const& copy); // Not Implemented
public:
static Mixer& manager()
{
// The only instance
static Mixer _instance;
return _instance;
}
static Selection& selection()
{
// The only instance
static Selection _selection;
return _selection;
}
// update session and all views
void update();
inline float dt() const { return dt_;}
// draw session and current view
void draw();
// creation of sources
Source * createSourceFile (std::string path);
Source * createSourceClone (std::string namesource = "");
Source * createSourceRender ();
// operations on sources
void addSource (Source *s);
void deleteSource (Source *s);
void renameSource (Source *s, const std::string &newname);
void deleteSelection();
// current source
void setCurrentSource (Source *s);
void setCurrentSource (std::string namesource);
void setCurrentSource (Node *node);
void setCurrentSource (int index);
void setCurrentNext ();
void unsetCurrentSource ();
int indexCurrentSource ();
Source * currentSource ();
// browsing into sources
Source * findSource (Node *node);
Source * findSource (std::string name);
// management of view
View *view (View::Mode m = View::INVALID);
void setView (View::Mode m);
// manipulate, load and save sessions
inline Session *session () const { return session_; }
void clear ();
void save ();
void saveas (const std::string& filename);
void load (const std::string& filename);
void open (const std::string& filename);
void import (const std::string& filename);
void merge (Session *s);
void set (Session *s);
protected:
Session *session_;
Session *back_session_;
void swap();
SourceList candidate_sources_;
void insertSource(Source *s, View::Mode m = View::INVALID);
void setCurrentSource(SourceList::iterator it);
SourceList::iterator current_source_;
int current_source_index_;
View *current_view_;
MixingView mixing_;
GeometryView geometry_;
LayerView layer_;
TransitionView transition_;
gint64 update_time_;
float dt_;
};
#endif // MIXER_H

View File

@@ -1,177 +0,0 @@
#include "PickingVisitor.h"
#include "Log.h"
#include "Primitives.h"
#include "Decorations.h"
#include "GlmToolkit.h"
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_access.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/string_cast.hpp>
#include <glm/gtx/vector_angle.hpp>
PickingVisitor::PickingVisitor(glm::vec3 coordinates) : Visitor()
{
modelview_ = glm::mat4(1.f);
points_.push_back( coordinates );
}
PickingVisitor::PickingVisitor(glm::vec3 selectionstart, glm::vec3 selection_end) : Visitor()
{
modelview_ = glm::mat4(1.f);
points_.push_back( selectionstart );
points_.push_back( selection_end );
}
void PickingVisitor::visit(Node &n)
{
// use the transform modified during update
modelview_ *= n.transform_;
// modelview_ *= transform(n.translation_, n.rotation_, n.scale_);
// Log::Info("Node %d", n.id());
// Log::Info("%s", glm::to_string(modelview_).c_str());
}
void PickingVisitor::visit(Group &n)
{
if (!n.visible_)
return;
glm::mat4 mv = modelview_;
for (NodeSet::iterator node = n.begin(); node != n.end(); node++) {
if ( (*node)->visible_ )
(*node)->accept(*this);
modelview_ = mv;
}
}
void PickingVisitor::visit(Switch &n)
{
if (!n.visible_ || n.numChildren()<1)
return;
glm::mat4 mv = modelview_;
n.activeChild()->accept(*this);
modelview_ = mv;
}
void PickingVisitor::visit(Primitive &n)
{
// TODO: generic visitor for primitive with random shape ?
}
void PickingVisitor::visit(Surface &n)
{
if (!n.visible_)
return;
// if more than one point given for testing: test overlap
if (points_.size() > 1) {
// create bounding box for those points (2 in practice)
GlmToolkit::AxisAlignedBoundingBox bb_points;
bb_points.extend(points_);
// apply inverse transform
bb_points = bb_points.transformed(glm::inverse(modelview_)) ;
// test bounding box for overlap with inverse transform bbox
if ( bb_points.intersect( n.bbox() ) )
// if ( n.bbox().contains( bb_points ) )
// add this surface to the nodes picked
nodes_.push_back( std::pair(&n, glm::vec2(0.f)) );
}
// only one point
else if (points_.size() > 0) {
// apply inverse transform to the point of interest
glm::vec4 P = glm::inverse(modelview_) * glm::vec4( points_[0], 1.f );
// test bounding box for picking from a single point
if ( n.bbox().contains( glm::vec3(P)) )
// add this surface to the nodes picked
nodes_.push_back( std::pair(&n, glm::vec2(P)) );
}
}
void PickingVisitor::visit(Frame &n)
{
// if (n.border())
// n.border()->accept(*this);
}
void PickingVisitor::visit(Handles &n)
{
// discard if not visible or if not exactly one point given for picking
if (!n.visible_ || points_.size() != 1)
return;
// apply inverse transform to the point of interest
glm::vec4 P = glm::inverse(modelview_) * glm::vec4( points_[0], 1.f );
// inverse transform to check the scale
glm::vec4 S = glm::inverse(modelview_) * glm::vec4( 0.05f, 0.05f, 0.f, 0.f );
float scale = glm::length( glm::vec2(S) );
bool picked = false;
if ( n.type() == Handles::RESIZE ) {
// 4 corners
picked = ( glm::length(glm::vec2(+1.f, +1.f)- glm::vec2(P)) < scale ||
glm::length(glm::vec2(+1.f, -1.f)- glm::vec2(P)) < scale ||
glm::length(glm::vec2(-1.f, +1.f)- glm::vec2(P)) < scale ||
glm::length(glm::vec2(-1.f, -1.f)- glm::vec2(P)) < scale );
}
else if ( n.type() == Handles::RESIZE_H ){
// left & right
picked = ( glm::length(glm::vec2(+1.f, 0.f)- glm::vec2(P)) < scale ||
glm::length(glm::vec2(-1.f, 0.f)- glm::vec2(P)) < scale );
}
else if ( n.type() == Handles::RESIZE_V ){
// top & bottom
picked = ( glm::length(glm::vec2(0.f, +1.f)- glm::vec2(P)) < scale ||
glm::length(glm::vec2(0.f, -1.f)- glm::vec2(P)) < scale );
}
else if ( n.type() == Handles::ROTATE ){
// the icon for rotation is on the right top corner at (0.12, 0.12) in scene coordinates
glm::vec4 vec = glm::inverse(modelview_) * glm::vec4( 0.1f, 0.1f, 0.f, 0.f );
float l = glm::length( glm::vec2(vec) );
picked = glm::length( glm::vec2( 1.f + l, 1.f + l) - glm::vec2(P) ) < 1.5f * scale;
}
if ( picked )
// add this to the nodes picked
nodes_.push_back( std::pair(&n, glm::vec2(P)) );
}
void PickingVisitor::visit(LineSquare &)
{
// // apply inverse transform to the point of interest
// glm::vec4 P = glm::inverse(modelview_) * glm::vec4( point_A_, 0.f, 1.f );
// // lower left corner
// glm::vec3 LL = glm::vec3( -1.f, -1.f, 0.f );
// // up right corner
// glm::vec3 UR = glm::vec3( 1.f, 1.f, 0.f );
// // if P is over a line [LL UR] rectangle:
// // TODO
}
void PickingVisitor::visit(LineCircle &n)
{
// // apply inverse transform to the point of interest
// glm::vec4 P = glm::inverse(modelview_) * glm::vec4( point_A_, 0.f, 1.f );
// float r = glm::length( glm::vec2(P) );
// if ( r < 1.02 && r > 0.98)
// nodes_.push_back( std::pair(&n, glm::vec2(P)) );
}
void PickingVisitor::visit(Scene &n)
{
n.root()->accept(*this);
}

View File

@@ -1,37 +0,0 @@
#ifndef PICKINGVISITOR_H
#define PICKINGVISITOR_H
#include <glm/glm.hpp>
#include <vector>
#include <utility>
#include "Visitor.h"
class PickingVisitor: public Visitor
{
std::vector<glm::vec3> points_;
glm::mat4 modelview_;
std::vector< std::pair<Node *, glm::vec2> > nodes_;
public:
PickingVisitor(glm::vec3 coordinates);
PickingVisitor(glm::vec3 selectionstart, glm::vec3 selection_end);
std::vector< std::pair<Node *, glm::vec2> > picked() { return nodes_; }
// Elements of Scene
void visit(Scene& n) override;
void visit(Node& n) override;
void visit(Group& n) override;
void visit(Switch& n) override;
void visit(Primitive& n) override;
void visit(Surface& n) override;
void visit(Frame& n) override;
void visit(Handles& n) override;
void visit(LineSquare&) override;
void visit(LineCircle& n) override;
};
#endif // PICKINGVISITOR_H

View File

@@ -1,391 +0,0 @@
#include "Primitives.h"
#include "ImageShader.h"
#include "Resource.h"
#include "FrameBuffer.h"
#include "MediaPlayer.h"
#include "Visitor.h"
#include "Log.h"
#include <glad/glad.h>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_access.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/constants.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/rotate_vector.hpp>
Surface::Surface(Shader *s) : Primitive(s), textureindex_(0)
{
// geometry for a trianglulated simple rectangle surface with UV
// (0,0) B +---+ D (1,0)
// |\ |
// | \ |
// | \|
// (0,1) A +---+ C (1,1)
points_ = std::vector<glm::vec3> { glm::vec3( -1.f, -1.f, 0.f ), glm::vec3( -1.f, 1.f, 0.f ),
glm::vec3( 1.f, -1.f, 0.f ), glm::vec3( 1.f, 1.f, 0.f ) };
colors_ = std::vector<glm::vec4> { glm::vec4( 1.f, 1.f, 1.f , 1.f ), glm::vec4( 1.f, 1.f, 1.f, 1.f ),
glm::vec4( 1.f, 1.f, 1.f, 1.f ), glm::vec4( 1.f, 1.f, 1.f, 1.f ) };
texCoords_ = std::vector<glm::vec2> { glm::vec2( 0.f, 1.f ), glm::vec2( 0.f, 0.f ),
glm::vec2( 1.f, 1.f ), glm::vec2( 1.f, 0.f ) };
indices_ = std::vector<uint> { 0, 1, 2, 3 };
drawMode_ = GL_TRIANGLE_STRIP;
}
Surface::~Surface()
{
// do NOT delete vao_ (unique)
vao_ = 0;
}
void Surface::init()
{
// use static unique vertex array object
static uint unique_vao_ = 0;
static uint unique_drawCount = 0;
if (unique_vao_) {
// 1. only init Node (not the primitive vao)
Node::init();
// 2. use the global vertex array object
vao_ = unique_vao_;
drawCount_ = unique_drawCount;
// compute AxisAlignedBoundingBox
bbox_.extend(points_);
// arrays of vertices are not needed anymore
points_.clear();
colors_.clear();
texCoords_.clear();
indices_.clear();
}
else {
// 1. init the Primitive (only once)
Primitive::init();
// 2. remember global vertex array object
unique_vao_ = vao_;
unique_drawCount = drawCount_;
// 3. unique_vao_ will NOT be deleted
}
}
void Surface::accept(Visitor& v)
{
Primitive::accept(v);
v.visit(*this);
}
void Surface::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() )
init();
if ( textureindex_ )
glBindTexture(GL_TEXTURE_2D, textureindex_);
else
glBindTexture(GL_TEXTURE_2D, Resource::getTextureBlack());
Primitive::draw(modelview, projection);
glBindTexture(GL_TEXTURE_2D, 0);
}
ImageSurface::ImageSurface(const std::string& path, Shader *s) : Surface(s), resource_(path)
{
}
void ImageSurface::init()
{
Surface::init();
// load image if specified (should always be the case)
if ( !resource_.empty()) {
textureindex_ = Resource::getTextureImage(resource_);
}
}
void ImageSurface::accept(Visitor& v)
{
Surface::accept(v);
v.visit(*this);
}
MediaSurface::MediaSurface(const std::string& p, Shader *s) : Surface(s)
{
path_ = p;
mediaplayer_ = new MediaPlayer;
}
MediaSurface::~MediaSurface()
{
delete mediaplayer_;
}
void MediaSurface::init()
{
Surface::init();
mediaplayer_->open(path_);
mediaplayer_->play(true);
}
void MediaSurface::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() )
init();
// set the texture to the media player once openned
// TODO: avoid to repeat with a static flag?
if ( mediaplayer_->isOpen() )
textureindex_ = mediaplayer_->texture();
Surface::draw(modelview, projection);
}
void MediaSurface::update( float dt )
{
if ( mediaplayer_->isOpen() ) {
mediaplayer_->update();
scale_.x = mediaplayer_->aspectRatio();
}
Primitive::update( dt );
}
void MediaSurface::accept(Visitor& v)
{
Surface::accept(v);
v.visit(*this);
}
FrameBufferSurface::FrameBufferSurface(FrameBuffer *fb, Shader *s) : Surface(s), frame_buffer_(fb)
{
}
void FrameBufferSurface::init()
{
Surface::init();
// set aspect ratio
scale_.x = frame_buffer_->aspectRatio();
}
void FrameBufferSurface::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() )
init();
glBindTexture(GL_TEXTURE_2D, frame_buffer_->texture());
Primitive::draw(modelview, projection);
glBindTexture(GL_TEXTURE_2D, 0);
}
void FrameBufferSurface::accept(Visitor& v)
{
Surface::accept(v);
v.visit(*this);
}
Points::Points(std::vector<glm::vec3> points, glm::vec4 color, uint pointsize) : Primitive(new Shader)
{
for(size_t i = 0; i < points.size(); ++i)
{
points_.push_back( points[i] );
colors_.push_back( color );
indices_.push_back ( i );
}
drawMode_ = GL_POINTS; // TODO implement drawing of points as Mesh
pointsize_ = pointsize;
}
void Points::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() )
init();
glPointSize(pointsize_);
Primitive::draw(modelview, projection);
glPointSize(1);
}
void Points::accept(Visitor& v)
{
Primitive::accept(v);
v.visit(*this);
}
LineStrip::LineStrip(std::vector<glm::vec3> points, std::vector<glm::vec4> colors, uint linewidth) : Primitive(new Shader), linewidth_(linewidth)
{
for(size_t i = 0; i < points.size(); ++i)
{
points_.push_back( points[i] );
colors_.push_back( colors[i] );
indices_.push_back ( i );
}
drawMode_ = GL_LINE_STRIP;
}
void LineStrip::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() )
init();
// glLineWidth(linewidth_ * 2.f * Rendering::manager().mainWindow().dpiScale());
glm::mat4 mv = modelview;
glm::mat4 scale = glm::scale(glm::identity<glm::mat4>(), glm::vec3(1.001f, 1.001f, 1.f));
// TODO FIXME drawing multiple times is not correct to draw lines of different width
// TODO Draw LineStrip using polygons
for (uint i = 0 ; i < linewidth_ ; ++i ) {
Primitive::draw(mv, projection);
mv *= scale;
}
// glLineWidth(1);
}
void LineStrip::accept(Visitor& v)
{
Primitive::accept(v);
v.visit(*this);
}
static const std::vector<glm::vec3> square_points {
glm::vec3( -1.f, -1.f, 0.f ), glm::vec3( -1.f, 1.f, 0.f ),
glm::vec3( 1.f, 1.f, 0.f ), glm::vec3( 1.f, -1.f, 0.f ),
glm::vec3( -1.f, -1.f, 0.f )
};
static const std::vector<glm::vec4> square_colors {
glm::vec4( 1.f, 1.f, 1.f, 1.f ), glm::vec4( 1.f, 1.f, 1.f, 1.f ),
glm::vec4( 1.f, 1.f, 1.f, 1.f ), glm::vec4( 1.f, 1.f, 1.f, 1.f ),
glm::vec4( 1.f, 1.f, 1.f, 1.f )
};
LineSquare::LineSquare(uint linewidth) : LineStrip(square_points, square_colors, linewidth)
{
}
void LineSquare::init()
{
// use static unique vertex array object
static uint unique_vao_ = 0;
static uint unique_drawCount = 0;
if (unique_vao_) {
// 1. only init Node (not the primitive vao)
Node::init();
// 2. use the global vertex array object
vao_ = unique_vao_;
drawCount_ = unique_drawCount;
// compute AxisAlignedBoundingBox
bbox_.extend(points_);
// arrays of vertices are not needed anymore
points_.clear();
colors_.clear();
texCoords_.clear();
indices_.clear();
}
else {
// 1. init the Primitive (only once)
Primitive::init();
// 2. remember global vertex array object
unique_vao_ = vao_;
unique_drawCount = drawCount_;
}
}
void LineSquare::accept(Visitor& v)
{
Primitive::accept(v);
v.visit(*this);
}
LineSquare::~LineSquare()
{
// do NOT delete vao_ (unique)
vao_ = 0;
}
LineCircle::LineCircle(uint linewidth) : LineStrip(std::vector<glm::vec3>(), std::vector<glm::vec4>(), linewidth)
{
static int N = 72;
static float a = glm::two_pi<float>() / static_cast<float>(N);
static glm::vec4 circle_color_points = glm::vec4(1.f, 1.f, 1.f, 1.f);
// loop to build a circle
glm::vec3 P(1.f, 0.f, 0.f);
for (int i = 0; i < N ; i++ ){
points_.push_back( glm::vec3(P) );
colors_.push_back( circle_color_points );
indices_.push_back ( i );
P = glm::rotateZ(P, a);
}
// close loop
points_.push_back( glm::vec3(1.f, 0.f, 0.f) );
colors_.push_back( circle_color_points );
indices_.push_back ( N );
}
void LineCircle::init()
{
// use static unique vertex array object
static uint unique_vao_ = 0;
static uint unique_drawCount = 0;
if (unique_vao_) {
// 1. only init Node (not the primitive vao)
Node::init();
// 2. use the global vertex array object
vao_ = unique_vao_;
drawCount_ = unique_drawCount;
// replace AxisAlignedBoundingBox
bbox_.extend(points_);
// arrays of vertices are not needed anymore (STATIC DRAW of vertex object)
points_.clear();
colors_.clear();
texCoords_.clear();
indices_.clear();
}
else {
// 1. init the Primitive (only once)
Primitive::init();
// 2. remember global vertex array object
unique_vao_ = vao_;
unique_drawCount = drawCount_;
// 3. unique_vao_ will NOT be deleted because LineCircle::deleteGLBuffers_() is empty
}
}
void LineCircle::accept(Visitor& v)
{
Primitive::accept(v);
v.visit(*this);
}
LineCircle::~LineCircle()
{
// do NOT delete vao_ (unique)
vao_ = 0;
}

113
README.md
View File

@@ -1,43 +1,122 @@
# vimix
Live Video Mixer
Live Video Mixing
*/!\ Work in progress*
vimix performs graphical mixing and blending of several movie clips and
computer generated graphics, with image processing effects in real-time.
v-mix is the successor for GLMixer - https://sourceforge.net/projects/glmixer/
Its intuitive and hands-on user interface gives direct control on image opacity and
shape for producing live graphics during concerts and VJ-ing sessions.
The output image is typically projected full-screen on an external
monitor or a projector, and can be streamed live (SRT, Shmdata) or recorded (without audio).
vimix is the successor for GLMixer - https://sourceforge.net/projects/glmixer/
# License
GPL-3.0-or-later
See [LICENSE](https://github.com/brunoherbelin/vimix/blob/master/LICENSE)
# Install vimix
Check the [Quick Installation Guide](https://github.com/brunoherbelin/vimix/wiki/Quick-Installation-Guide)
### Linux
Download and install a released [flatpak package](https://flathub.org/apps/details/io.github.brunoherbelin.Vimix)
~$ flatpak install --user vimix
NB: Building your flatpak package is an option for testing the latest beta version from git ; instructions are [here](https://github.com/brunoherbelin/vimix/tree/master/flatpak).
Download and install a released [snap package](https://snapcraft.io/vimix) (slower release frequency)
~$ snap install vimix
Install the stable debian package (slower release frequency)
~$ sudo apt install vimix
### Mac OSX
Download and open a release package from https://github.com/brunoherbelin/vimix/releases
NB: You'll need to accept the exception in OSX security preference.
# Build vimix
## Clone
git clone --recursive https://github.com/brunoherbelin/vimix.git
~$ git clone --recursive https://github.com/brunoherbelin/vimix.git
This will create the directory 'vimix', download the latest version of vimix code,
and (recursively) clone all the internal git dependencies.
To only update a cloned git copy:
~$ git pull
## Compile
```
cmake -G Ninja
ninja
```
First time after git clone:
~$ mkdir vimix-build
~$ cd vimix-build
~$ cmake -DCMAKE_BUILD_TYPE=Release ../vimix
Compile (or re-compile after pull):
~$ cmake --build .
### Dependencies
**Compiling tools:**
- gcc
- make
- cmake
- Ninja
- git
**Libraries:**
- gstreamer
- libpng
- gst-plugins (libav, base, good, bad & ugly)
- libglfw3
- libicu (icu-i18n icu-uc icu-io)
Optionnal:
- glm
- stb
- TinyXML2
- AbletonLink
- Shmdata
#### Install Dependencies
**Ubuntu**
~$ apt-get install build-essential cmake libpng-dev libglfw3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-libav libicu-dev libgtk-3-dev
Optionnal:
~$ apt-get install libglm-dev libstb-dev libtinyxml2-dev ableton-link-dev
Follow the instructions to [install Shmdata](https://gitlab.com/sat-mtl/tools/shmdata).
**OSX with Brew**
~$ brew install cmake libpng glfw gstreamer gst-libav gst-plugins-bad gst-plugins-base gst-plugins-good gst-plugins-ugly icu4c
#### Ubuntu
### Memcheck
**tools:**
To generate memory usage plots in [massif format](https://valgrind.org/docs/manual/ms-manual.html):
apt-get install build-essential cmake ninja-build
**libs:**
apt-get install libpng-dev libglfw3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
$ G_SLICE=always-malloc valgrind --tool=massif ./vimix
To check for memory leaks:
$ G_SLICE=always-malloc valgrind --leak-check=full --log-file=vimix_mem.txt ./vimix

View File

@@ -1,823 +0,0 @@
#include <cstring>
#include <thread>
#include <mutex>
#include <chrono>
#include <stdlib.h>
// Desktop OpenGL function loader
#include <glad/glad.h> // Initialized with gladLoadGLLoader()
// Include glfw3.h after our OpenGL definitions
#define GLFW_INCLUDE_GLEXT
#include <GLFW/glfw3.h>
#ifdef APPLE
#include "osx/CocoaToolkit.h"
#define GLFW_EXPOSE_NATIVE_COCOA
#define GLFW_EXPOSE_NATIVE_NSGL
#else
#define GLFW_EXPOSE_NATIVE_X11
#define GLFW_EXPOSE_NATIVE_GLX
#endif
#include <GLFW/glfw3native.h>
#include <glm/gtc/matrix_transform.hpp> // glm::translate, glm::rotate, glm::scale
#include <glm/ext/matrix_clip_space.hpp> // glm::perspective
// Include GStreamer
#include <gst/gl/gl.h>
#include <gst/gl/gstglcontext.h>
#ifdef GLFW_EXPOSE_NATIVE_COCOA
#include <gst/gl/cocoa/gstgldisplay_cocoa.h>
#endif
#ifdef GLFW_EXPOSE_NATIVE_GLX
#include <gst/gl/x11/gstgldisplay_x11.h>
#endif
// standalone image loader
#include <stb_image.h>
// vmix
#include "defines.h"
#include "Log.h"
#include "Resource.h"
#include "Settings.h"
#include "Primitives.h"
#include "Mixer.h"
#include "SystemToolkit.h"
#include "UserInterfaceManager.h"
#include "RenderingManager.h"
// local statics
static GstGLContext *global_gl_context = NULL;
static GstGLDisplay *global_display = NULL;
static std::map<GLFWwindow *, RenderingWindow*> GLFW_window_;
static void glfw_error_callback(int error, const char* description)
{
Log::Error("Glfw Error %d: %s", error, description);
}
static void WindowRefreshCallback( GLFWwindow * )
{
Rendering::manager().draw();
}
static void WindowResizeCallback( GLFWwindow *w, int width, int height)
{
int id = GLFW_window_[w]->id();
if (!Settings::application.windows[id].fullscreen) {
Settings::application.windows[id].w = width;
Settings::application.windows[id].h = height;
}
}
static void WindowMoveCallback( GLFWwindow *w, int x, int y)
{
int id = GLFW_window_[w]->id();
if (!Settings::application.windows[id].fullscreen) {
Settings::application.windows[id].x = x;
Settings::application.windows[id].y = y;
}
}
static void WindowEscapeFullscreen( GLFWwindow *w, int key, int scancode, int action, int)
{
if (action == GLFW_PRESS && key == GLFW_KEY_ESCAPE)
{
// escape fullscreen
GLFW_window_[w]->setFullscreen(nullptr);
}
}
static void WindowToggleFullscreen( GLFWwindow *w, int button, int action, int)
{
static double seconds = 0.f;
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
{
// detect double clic
if ( glfwGetTime() - seconds < 0.2f ) {
// toggle fullscreen
GLFW_window_[w]->toggleFullscreen();
}
// for next clic detection
seconds = glfwGetTime();
}
}
Rendering::Rendering()
{
// main_window_ = nullptr;
request_screenshot_ = false;
}
bool Rendering::init()
{
// Setup window
glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit()){
Log::Error("Failed to Initialize GLFW.");
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
glfwSetWindowRefreshCallback( main_.window(), WindowRefreshCallback );
glfwSetDropCallback( main_.window(), Rendering::FileDropped);
//
// Gstreamer setup
//
std::string plugins_path = SystemToolkit::path_filename(Settings::application.executable);
plugins_path += "gstreamer-1.0";
if ( SystemToolkit::file_exists(plugins_path)) {
Log::Info("Found Gstreamer plugins in %s", plugins_path.c_str());
g_setenv ("GST_PLUGIN_SYSTEM_PATH", plugins_path.c_str(), TRUE);
}
g_setenv ("GST_GL_API", "opengl3", TRUE);
gst_init (NULL, NULL);
#if GST_GL_HAVE_PLATFORM_WGL
global_gl_context = gst_gl_context_new_wrapped (display, (guintptr) wglGetCurrentContext (),
GST_GL_PLATFORM_WGL, GST_GL_API_OPENGL);
#elif GST_GL_HAVE_PLATFORM_CGL
// global_display = GST_GL_DISPLAY ( glfwGetCocoaMonitor(main_.window()) );
global_display = GST_GL_DISPLAY (gst_gl_display_cocoa_new ());
global_gl_context = gst_gl_context_new_wrapped (global_display,
(guintptr) 0,
GST_GL_PLATFORM_CGL, GST_GL_API_OPENGL);
#elif GST_GL_HAVE_PLATFORM_GLX
global_display = (GstGLDisplay*) gst_gl_display_x11_new_with_display( glfwGetX11Display() );
global_gl_context = gst_gl_context_new_wrapped (global_display,
(guintptr) glfwGetGLXContext(main_.window()),
GST_GL_PLATFORM_GLX, GST_GL_API_OPENGL);
#endif
//
// output window
//
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
glfwSetKeyCallback( output_.window(), WindowEscapeFullscreen);
glfwSetMouseButtonCallback( output_.window(), WindowToggleFullscreen);
return true;
}
void Rendering::show()
{
// show output window
output_.show();
// show main window
main_.show();
// show menu on first show
UserInterface::manager().showPannel(NAV_MENU);
}
bool Rendering::isActive()
{
return !glfwWindowShouldClose(main_.window());
}
void Rendering::pushFrontDrawCallback(RenderingCallback function)
{
draw_callbacks_.push_front(function);
}
void Rendering::pushBackDrawCallback(RenderingCallback function)
{
draw_callbacks_.push_back(function);
}
void Rendering::draw()
{
// operate on main window context
main_.makeCurrent();
// User Interface step 1
UserInterface::manager().NewFrame();
// Custom draw
std::list<Rendering::RenderingCallback>::iterator iter;
for (iter=draw_callbacks_.begin(); iter != draw_callbacks_.end(); iter++)
{
(*iter)();
}
// User Interface step 2
UserInterface::manager().Render();
// perform screenshot if requested
if (request_screenshot_) {
// glfwMakeContextCurrent(main_window_);
screenshot_.captureGL(0, 0, main_.width(), main_.height());
request_screenshot_ = false;
}
// draw output window (and swap buffer output)
output_.draw( Mixer::manager().session()->frame() );
// swap GL buffers
glfwSwapBuffers(main_.window());
glfwSwapBuffers(output_.window());
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
glfwPollEvents();
// no g_main_loop_run(loop) : update global GMainContext
g_main_context_iteration(NULL, FALSE);
}
void Rendering::terminate()
{
// close window
glfwDestroyWindow(output_.window());
glfwDestroyWindow(main_.window());
glfwTerminate();
}
void Rendering::close()
{
glfwSetWindowShouldClose(main_.window(), true);
}
void Rendering::pushAttrib(RenderingAttrib ra)
{
// push it to top of pile
draw_attributes_.push_front(ra);
// apply Changes to OpenGL
glViewport(0, 0, ra.viewport.x, ra.viewport.y);
glClearColor(ra.clear_color.r, ra.clear_color.g, ra.clear_color.b, ra.clear_color.a);
}
void Rendering::popAttrib()
{
// pops the top of the pile
if (draw_attributes_.size() > 0)
draw_attributes_.pop_front();
// set attribute element to default
RenderingAttrib ra = currentAttrib();
// apply Changes to OpenGL
glViewport(0, 0, ra.viewport.x, ra.viewport.y);
glClearColor(ra.clear_color.r, ra.clear_color.g, ra.clear_color.b, ra.clear_color.a);
}
RenderingAttrib Rendering::currentAttrib()
{
// default rendering attrib is the main window's
RenderingAttrib ra = main_.attribs();
// but if there is an element at top, return it
if (draw_attributes_.size() > 0)
ra = draw_attributes_.front();
return ra;
}
glm::mat4 Rendering::Projection()
{
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, main_.aspectRatio(), 1.f));
return projection * scale;
}
glm::vec3 Rendering::unProject(glm::vec2 screen_coordinate, glm::mat4 modelview)
{
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_.width(), main_.height());
// Log::Info("unproject %d x %d", main_window_attributes_.viewport.x, main_window_attributes_.viewport.y);
glm::vec3 point = glm::unProject(coordinates, modelview, Projection(), viewport);
return point;
}
glm::vec2 Rendering::project(glm::vec3 scene_coordinate, glm::mat4 modelview, bool to_framebuffer)
{
glm::vec4 viewport;
if (to_framebuffer)
viewport= glm::vec4( 0.f, 0.f, main_.width(), main_.height());
else
viewport= glm::vec4( 0.f, 0.f, main_.width() / main_.dpiScale(), main_.height() / main_.dpiScale());
glm::vec3 P = glm::project( scene_coordinate, modelview, Projection(), viewport );
return glm::vec2(P.x, viewport.w - P.y);
}
void Rendering::FileDropped(GLFWwindow *, int path_count, const char* paths[])
{
for (int i = 0; i < path_count; ++i) {
std::string filename(paths[i]);
if (filename.empty())
break;
// try to create a source
Mixer::manager().addSource ( Mixer::manager().createSourceFile( filename ) );
}
if (path_count>0) {
UserInterface::manager().showPannel();
Rendering::manager().mainWindow().show();
}
}
Screenshot *Rendering::currentScreenshot()
{
return &screenshot_;
}
void Rendering::requestScreenshot()
{
request_screenshot_ = true;
}
// custom surface with a new VAO
class WindowSurface : public Primitive {
public:
WindowSurface(Shader *s = new ImageShader);
};
WindowSurface::WindowSurface(Shader *s) : Primitive(s)
{
points_ = std::vector<glm::vec3> { glm::vec3( -1.f, -1.f, 0.f ), glm::vec3( -1.f, 1.f, 0.f ),
glm::vec3( 1.f, -1.f, 0.f ), glm::vec3( 1.f, 1.f, 0.f ) };
colors_ = std::vector<glm::vec4> { glm::vec4( 1.f, 1.f, 1.f , 1.f ), glm::vec4( 1.f, 1.f, 1.f, 1.f ),
glm::vec4( 1.f, 1.f, 1.f, 1.f ), glm::vec4( 1.f, 1.f, 1.f, 1.f ) };
texCoords_ = std::vector<glm::vec2> { glm::vec2( 0.f, 1.f ), glm::vec2( 0.f, 0.f ),
glm::vec2( 1.f, 1.f ), glm::vec2( 1.f, 0.f ) };
indices_ = std::vector<uint> { 0, 1, 2, 3 };
drawMode_ = GL_TRIANGLE_STRIP;
}
RenderingWindow::RenderingWindow() : window_(nullptr), master_(nullptr),
id_(-1), dpi_scale_(1.f), textureid_(0), fbo_(0), surface_(nullptr)
{
}
RenderingWindow::~RenderingWindow()
{
if (surface_ != nullptr)
delete surface_;
if (fbo_ != 0)
glDeleteFramebuffers(1, &fbo_);
}
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)
{
size_t fpsize = 0;
const char *fp = Resource::getData(resource, &fpsize);
if (fp != nullptr) {
GLFWimage icon;
icon.pixels = stbi_load_from_memory( (const stbi_uc*)fp, fpsize, &icon.width, &icon.height, nullptr, 4 );
glfwSetWindowIcon( window_, 1, &icon );
free( icon.pixels );
}
}
bool RenderingWindow::isFullscreen ()
{
return (glfwGetWindowMonitor(window_) != nullptr);
// return Settings::application.windows[id_].fullscreen;
}
GLFWmonitor *RenderingWindow::monitorAt(int x, int y)
{
// default to primary monitor
GLFWmonitor *mo = glfwGetPrimaryMonitor();
// list all monitors
int count_monitors = 0;
GLFWmonitor** monitors = glfwGetMonitors(&count_monitors);
// if there is more than one monitor
if (count_monitors > 1) {
// pick at the coordinates given or at pos of window
// try every monitor
int i = 0;
for (; i < count_monitors; i++) {
int workarea_x, workarea_y, workarea_width, workarea_height;
glfwGetMonitorWorkarea(monitors[i], &workarea_x, &workarea_y, &workarea_width, &workarea_height);
if ( x >= workarea_x && x <= workarea_x + workarea_width &&
y >= workarea_y && y <= workarea_y + workarea_height)
break;
}
// found the monitor containing this point !
if ( i < count_monitors)
mo = monitors[i];
}
return mo;
}
GLFWmonitor *RenderingWindow::monitorNamed(const std::string &name)
{
// default to primary monitor
GLFWmonitor *mo = glfwGetPrimaryMonitor();
// list all monitors
int count_monitors = 0;
GLFWmonitor** monitors = glfwGetMonitors(&count_monitors);
// if there is more than one monitor
if (count_monitors > 1) {
// pick at the coordinates given or at pos of window
// try every monitor
int i = 0;
for (; i < count_monitors; i++) {
if ( std::string( glfwGetMonitorName(monitors[i])) == name )
break;
}
// found the monitor with this name
if ( i < count_monitors)
mo = monitors[i];
}
return mo;
}
GLFWmonitor *RenderingWindow::monitor()
{
// pick at the coordinates given or at pos of window
int x, y;
glfwGetWindowPos(window_, &x, &y);
return monitorAt(x, y);
}
void RenderingWindow::setFullscreen(GLFWmonitor *mo)
{
// if in fullscreen mode
if (mo == nullptr) {
// set to window mode
glfwSetInputMode( window_, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
glfwSetWindowMonitor( window_, nullptr, Settings::application.windows[id_].x,
Settings::application.windows[id_].y,
Settings::application.windows[id_].w,
Settings::application.windows[id_].h, 0 );
Settings::application.windows[id_].fullscreen = false;
}
// not in fullscreen mode
else {
// set to fullscreen mode
Settings::application.windows[id_].fullscreen = true;
Settings::application.windows[id_].monitor = glfwGetMonitorName(mo);
const GLFWvidmode * mode = glfwGetVideoMode(mo);
glfwSetWindowMonitor( window_, mo, 0, 0, mode->width, mode->height, mode->refreshRate);
glfwSetInputMode( window_, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
}
}
void RenderingWindow::toggleFullscreen()
{
// if in fullscreen mode
if (isFullscreen()) {
// exit fullscreen
setFullscreen(nullptr);
}
// not in fullscreen mode
else {
// enter fullscreen in monitor where the window is
setFullscreen(monitor());
}
}
int RenderingWindow::width()
{
return window_attributes_.viewport.x;
}
int RenderingWindow::height()
{
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()
{
return static_cast<float>(window_attributes_.viewport.x) / static_cast<float>(window_attributes_.viewport.y);
}
bool RenderingWindow::init(int id, GLFWwindow *share)
{
id_ = id;
master_ = share;
// access Settings
Settings::WindowConfig winset = Settings::application.windows[id_];
// do not show at creation
glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
// create the window normal
window_ = glfwCreateWindow(winset.w, winset.h, winset.name.c_str(), NULL, master_);
if (window_ == NULL){
Log::Error("Failed to create GLFW Window %d", id_);
return false;
}
// set position
glfwSetWindowPos(window_, winset.x, winset.y);
/// CALLBACKS
// store global ref to pointers (used by callbacks)
GLFW_window_[window_] = this;
// window position and resize callbacks
glfwSetWindowSizeCallback( window_, WindowResizeCallback );
// glfwSetFramebufferSizeCallback( window_, WindowResizeCallback );
glfwSetWindowPosCallback( window_, WindowMoveCallback );
// take opengl context ownership
glfwMakeContextCurrent(window_);
//
// Initialize OpenGL loader on first call
//
static bool glad_initialized = false;
if ( !glad_initialized ) {
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(Settings::application.render.vsync);
// no need for multisampling
glDisable(GL_MULTISAMPLE);
// clear to black
window_attributes_.clear_color = glm::vec4(0.f, 0.f, 0.f, 1.f);
// give back context ownership
glfwMakeContextCurrent(master_);
}
else {
// Enable vsync on main window
glfwSwapInterval(0);
// enable Antialiasing multisampling
if (Settings::application.render.multisampling > 0) {
glEnable(GL_MULTISAMPLE);
glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
}
// clear to grey
window_attributes_.clear_color = glm::vec4(COLOR_BGROUND, 1.f);
}
return true;
}
void RenderingWindow::show()
{
glfwShowWindow(window_);
if ( Settings::application.windows[id_].fullscreen ) {
GLFWmonitor *mo = monitorNamed(Settings::application.windows[id_].monitor);
setFullscreen(mo);
}
}
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);
}
// TODO update parameters for draw on resize event (not every frame)
void RenderingWindow::draw(FrameBuffer *fb)
{
if (!window_ || !fb)
return;
// only draw if window is not iconified
if( !glfwGetWindowAttrib(window_, GLFW_ICONIFIED ) ) {
// update viewport (could be done with callback)
glfwGetFramebufferSize(window_, &(window_attributes_.viewport.x), &(window_attributes_.viewport.y));
// take context ownership
glfwMakeContextCurrent(window_);
// setup attribs
Rendering::manager().pushAttrib(window_attributes_);
glClear(GL_COLOR_BUFFER_BIT);
// blit framebuffer
if (Settings::application.render.blit) {
if ( textureid_ != fb->texture()) {
textureid_ = fb->texture();
// create a new fbo in this opengl context
if (fbo_ != 0)
glDeleteFramebuffers(1, &fbo_);
glGenFramebuffers(1, &fbo_);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
// attach the 2D texture to local FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureid_, 0);
Log::Info("Blit to output window enabled.");
}
// calculate scaling factor of frame buffer inside window
int rx, ry, rw, rh;
float renderingAspectRatio = fb->aspectRatio();
if (aspectRatio() < renderingAspectRatio) {
int nh = (int)( float(window_attributes_.viewport.x) / renderingAspectRatio);
rx = 0;
ry = (window_attributes_.viewport.y - nh) / 2;
rw = window_attributes_.viewport.x;
rh = (window_attributes_.viewport.y + nh) / 2;
} else {
int nw = (int)( float(window_attributes_.viewport.y) * renderingAspectRatio );
rx = (window_attributes_.viewport.x - nw) / 2;
ry = 0;
rw = (window_attributes_.viewport.x + nw) / 2;
rh = window_attributes_.viewport.y;
}
// select fbo texture read target
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo_);
// select screen target
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
// blit operation from fbo (containing texture) to screen
glBlitFramebuffer(0, fb->height(), fb->width(), 0, rx, ry, rw, rh, GL_COLOR_BUFFER_BIT, GL_LINEAR);
}
// draw geometry
else
{
// 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
if (surface_ == 0)
surface_ = new WindowSurface;
// calculate scaling factor of frame buffer inside window
float windowAspectRatio = aspectRatio();
float renderingAspectRatio = fb->aspectRatio();
glm::vec3 scale;
if (windowAspectRatio < renderingAspectRatio)
scale = glm::vec3(1.f, windowAspectRatio / renderingAspectRatio, 1.f);
else
scale = glm::vec3(renderingAspectRatio / windowAspectRatio, 1.f, 1.f);
// make sure previous shader in another glcontext is disabled
ShadingProgram::enduse();
// draw
glBindTexture(GL_TEXTURE_2D, fb->texture());
// surface->shader()->color.a = 0.4f; // TODO alpha blending ?
static glm::mat4 projection = glm::ortho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f);
surface_->draw(glm::scale(glm::identity<glm::mat4>(), scale), projection);
// done drawing (unload shader from this glcontext)
ShadingProgram::enduse();
glBindTexture(GL_TEXTURE_2D, 0);
}
// restore attribs
Rendering::manager().popAttrib();
}
// give back context ownership
glfwMakeContextCurrent(master_);
}
//
// Discarded because not working under OSX - kept in case it would become useful
//
// Linking pipeline to the rendering instance ensures the opengl contexts
// created by gstreamer inside plugins (e.g. glsinkbin) is the same
//
static GstBusSyncReply
bus_sync_handler (GstBus *, GstMessage * msg, gpointer )
{
if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_NEED_CONTEXT) {
const gchar* contextType;
gst_message_parse_context_type(msg, &contextType);
if (!g_strcmp0(contextType, GST_GL_DISPLAY_CONTEXT_TYPE)) {
GstContext *displayContext = gst_context_new(GST_GL_DISPLAY_CONTEXT_TYPE, TRUE);
gst_context_set_gl_display(displayContext, global_display);
gst_element_set_context(GST_ELEMENT(msg->src), displayContext);
gst_context_unref (displayContext);
g_info ("Managed %s\n", contextType);
}
if (!g_strcmp0(contextType, "gst.gl.app_context")) {
GstContext *appContext = gst_context_new("gst.gl.app_context", TRUE);
GstStructure* structure = gst_context_writable_structure(appContext);
gst_structure_set(structure, "context", GST_TYPE_GL_CONTEXT, global_gl_context, nullptr);
gst_element_set_context(GST_ELEMENT(msg->src), appContext);
gst_context_unref (appContext);
g_info ("Managed %s\n", contextType);
}
}
gst_message_unref (msg);
return GST_BUS_DROP;
}
void Rendering::LinkPipeline( GstPipeline *pipeline )
{
// capture bus signals to force a unique opengl context for all GST elements
GstBus* m_bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_set_sync_handler (m_bus, (GstBusSyncHandler) bus_sync_handler, pipeline, NULL);
gst_object_unref (m_bus);
// GstBus* m_bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
// gst_bus_enable_sync_message_emission (m_bus);
// g_signal_connect (m_bus, "sync-message", G_CALLBACK (bus_sync_handler), pipeline);
// gst_object_unref (m_bus);
}

View File

@@ -1,135 +0,0 @@
#include "Screenshot.h"
#include <memory.h>
#include <assert.h>
#include <thread>
#include <atomic>
#include <glad/glad.h>
// standalone image loader
#include <stb_image.h>
#include <stb_image_write.h>
Screenshot::Screenshot()
{
Width = Height = 0;
Data = nullptr;
Pbo = 0;
Pbo_size = 0;
Pbo_full = false;
}
Screenshot::~Screenshot()
{
if (Data) free(Data);
}
bool Screenshot::isFull()
{
return Pbo_full;
}
void Screenshot::captureGL(int x, int y, int w, int h)
{
Width = w - x;
Height = h - y;
unsigned int size = Width * Height * 4;
// create BPO
if (Pbo == 0)
glGenBuffers(1, &Pbo);
// bind
glBindBuffer(GL_PIXEL_PACK_BUFFER, Pbo);
// init
if (Pbo_size != size) {
Pbo_size = size;
if (Data) free(Data);
Data = (unsigned char*) malloc(Pbo_size);
glBufferData(GL_PIXEL_PACK_BUFFER, Pbo_size, NULL, GL_STREAM_READ);
}
// screenshot to PBO (fast)
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, 0);
Pbo_full = true;
// done
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
}
void Screenshot::save(std::string filename)
{
// is there something to save?
if (Pbo && Pbo_size > 0 && Pbo_full) {
// bind buffer
glBindBuffer(GL_PIXEL_PACK_BUFFER, Pbo);
// get pixels (quite fast)
unsigned char* ptr = (unsigned char*) glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
if (NULL != ptr) {
memmove(Data, ptr, Pbo_size);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
}
// initiate saving in thread (slow)
std::thread(storeToFile, this, filename).detach();
// ready for next
Pbo_full = false;
}
}
void Screenshot::RemoveAlpha()
{
unsigned int* p = (unsigned int*)Data;
int n = Width * Height;
while (n-- > 0)
{
*p |= 0xFF000000;
p++;
}
}
void Screenshot::FlipVertical()
{
int comp = 4;
int stride = Width * comp;
unsigned char* line_tmp = new unsigned char[stride];
unsigned char* line_a = (unsigned char*)Data;
unsigned char* line_b = (unsigned char*)Data + (stride * (Height - 1));
while (line_a < line_b)
{
memcpy(line_tmp, line_a, stride);
memcpy(line_a, line_b, stride);
memcpy(line_b, line_tmp, stride);
line_a += stride;
line_b -= stride;
}
delete[] line_tmp;
}
// Thread to perform slow operation of saving to file
void Screenshot::storeToFile(Screenshot *s, std::string filename)
{
static std::atomic<bool> ScreenshotSavePending_ = false;
// only one save at a time
if (ScreenshotSavePending_)
return;
ScreenshotSavePending_ = true;
// got data to save ?
if (s && s->Data) {
// make it usable
s->RemoveAlpha();
s->FlipVertical();
// save file
stbi_write_png(filename.c_str(), s->Width, s->Height, 4, s->Data, s->Width * 4);
}
ScreenshotSavePending_ = false;
}

View File

@@ -1,41 +0,0 @@
#include "SearchVisitor.h"
#include "Scene.h"
SearchVisitor::SearchVisitor(Node *node) : Visitor(), node_(node), found_(false)
{
}
void SearchVisitor::visit(Node &n)
{
if ( !found_ && node_ == &n ){
found_ = true;
}
}
void SearchVisitor::visit(Group &n)
{
if (found_)
return;
for (NodeSet::iterator node = n.begin(); node != n.end(); node++) {
(*node)->accept(*this);
if (found_)
break;
}
}
void SearchVisitor::visit(Switch &n)
{
if (n.numChildren()>0)
n.activeChild()->accept(*this);
}
void SearchVisitor::visit(Scene &n)
{
// search only in workspace
n.ws()->accept(*this);
}

View File

@@ -1,25 +0,0 @@
#ifndef SEARCHVISITOR_H
#define SEARCHVISITOR_H
#include "Visitor.h"
class SearchVisitor: public Visitor
{
Node *node_;
bool found_;
public:
SearchVisitor(Node *node);
inline bool found() const { return found_; }
inline Node *node() const { return found_ ? node_ : nullptr; }
// Elements of Scene
void visit(Scene& n);
void visit(Node& n);
void visit(Primitive&) {}
void visit(Group& n);
void visit(Switch& n);
};
#endif // SEARCHVISITOR_H

View File

@@ -1,212 +0,0 @@
#include <algorithm>
#include "defines.h"
#include "Settings.h"
#include "FrameBuffer.h"
#include "Session.h"
#include "GarbageVisitor.h"
#include "Log.h"
Session::Session() : filename_(""), failedSource_(nullptr), active_(true)
{
config_[View::RENDERING] = new Group;
config_[View::RENDERING]->scale_ = render_.resolution();
config_[View::GEOMETRY] = new Group;
config_[View::GEOMETRY]->scale_ = Settings::application.views[View::GEOMETRY].default_scale;
config_[View::GEOMETRY]->translation_ = Settings::application.views[View::GEOMETRY].default_translation;
config_[View::LAYER] = new Group;
config_[View::LAYER]->scale_ = Settings::application.views[View::LAYER].default_scale;
config_[View::LAYER]->translation_ = Settings::application.views[View::LAYER].default_translation;
config_[View::MIXING] = new Group;
config_[View::MIXING]->scale_ = Settings::application.views[View::MIXING].default_scale;
config_[View::MIXING]->translation_ = Settings::application.views[View::MIXING].default_translation;
}
Session::~Session()
{
// delete all sources
for(auto it = sources_.begin(); it != sources_.end(); ) {
// erase this source from the list
it = deleteSource(*it);
}
}
void Session::setActive (bool on)
{
if (active_ != on) {
active_ = on;
for(auto it = sources_.begin(); it != sources_.end(); it++) {
(*it)->setActive(active_);
}
}
}
// update all sources
void Session::update(float dt)
{
failedSource_ = nullptr;
// pre-render of all sources
for( SourceList::iterator it = sources_.begin(); it != sources_.end(); it++){
if ( (*it)->failed() ) {
failedSource_ = (*it);
}
else {
// render the source
(*it)->render();
// update the source
(*it)->update(dt);
}
}
// update the scene tree
render_.update(dt);
// draw render view in Frame Buffer
render_.draw();
}
SourceList::iterator Session::addSource(Source *s)
{
// insert the source in the rendering
render_.scene.ws()->attach(s->group(View::RENDERING));
// insert the source to the beginning of the list
sources_.push_front(s);
// return the iterator to the source created at the beginning
return sources_.begin();
}
SourceList::iterator Session::deleteSource(Source *s)
{
// find the source
SourceList::iterator its = find(s);
// ok, its in the list !
if (its != sources_.end()) {
// remove Node from the rendering scene
render_.scene.ws()->detatch( s->group(View::RENDERING) );
// erase the source from the update list & get next element
its = sources_.erase(its);
// delete the source : safe now
delete s;
}
// return end of next element
return its;
}
Source *Session::popSource()
{
Source *s = nullptr;
SourceList::iterator its = sources_.begin();
if (its != sources_.end())
{
s = *its;
// remove Node from the rendering scene
render_.scene.ws()->detatch( s->group(View::RENDERING) );
// erase the source from the update list & get next element
sources_.erase(its);
}
return s;
}
void Session::setResolution(glm::vec3 resolution)
{
render_.setResolution(resolution);
config_[View::RENDERING]->scale_ = resolution;
}
void Session::setFading(float f)
{
render_.setFading(f);
}
void Session::fadeIn() {
float f = render_.fading();
if ( f > EPSILON)
render_.setFading( f / 2.f);
}
void Session::fadeOut() {
float f = render_.fading();
if ( f < 1.f - EPSILON)
render_.setFading( f * 2.f);
}
SourceList::iterator Session::begin()
{
return sources_.begin();
}
SourceList::iterator Session::end()
{
return sources_.end();
}
SourceList::iterator Session::find(int index)
{
if (index<0)
return sources_.end();
int i = 0;
SourceList::iterator it = sources_.begin();
while ( i < index && it != sources_.end() ){
i++;
it++;
}
return it;
}
SourceList::iterator Session::find(Source *s)
{
return std::find(sources_.begin(), sources_.end(), s);
}
SourceList::iterator Session::find(std::string namesource)
{
return std::find_if(sources_.begin(), sources_.end(), Source::hasName(namesource));
}
SourceList::iterator Session::find(Node *node)
{
return std::find_if(sources_.begin(), sources_.end(), Source::hasNode(node));
}
uint Session::numSource() const
{
return sources_.size();
}
bool Session::empty() const
{
return sources_.empty();
}
int Session::index(SourceList::iterator it) const
{
int index = -1;
int count = 0;
for(auto i = sources_.begin(); i != sources_.end(); i++, count++) {
if ( i == it ) {
index = count;
break;
}
}
return index;
}

View File

@@ -1,72 +0,0 @@
#ifndef SESSION_H
#define SESSION_H
#include "View.h"
#include "Source.h"
class Session
{
public:
Session();
~Session();
// add given source into the session
SourceList::iterator addSource (Source *s);
// delete the source s from the session
SourceList::iterator deleteSource (Source *s);
// get ptr to front most source and remove it from the session
// Does not delete the source
Source *popSource();
// management of list of sources
bool empty() const;
uint numSource() const;
SourceList::iterator begin ();
SourceList::iterator end ();
SourceList::iterator find (int index);
SourceList::iterator find (Source *s);
SourceList::iterator find (std::string name);
SourceList::iterator find (Node *node);
int index (SourceList::iterator it) const;
// update all sources and mark sources which failed
void update (float dt);
// update mode (active or not)
void setActive (bool on);
inline bool active () { return active_; }
// return the last source which failed
Source *failedSource() { return failedSource_; }
// get frame result of render
inline FrameBuffer *frame () const { return render_.frame(); }
// configure rendering resolution
void setResolution(glm::vec3 resolution);
// manipulate fading of output
void setFading(float f);
void fadeIn();
void fadeOut();
// configuration for group nodes of views
inline Group *config (View::Mode m) const { return config_.at(m); }
// name of file containing this session (for transfer)
void setFilename(const std::string &filename) { filename_ = filename; }
std::string filename() const { return filename_; }
protected:
RenderView render_;
std::string filename_;
Source *failedSource_;
SourceList sources_;
std::map<View::Mode, Group*> config_;
bool active_;
};
#endif // SESSION_H

View File

@@ -1,295 +0,0 @@
#include "SessionCreator.h"
#include "Log.h"
#include "defines.h"
#include "Scene.h"
#include "Primitives.h"
#include "Mesh.h"
#include "Source.h"
#include "MediaSource.h"
#include "SessionSource.h"
#include "Session.h"
#include "ImageShader.h"
#include "ImageProcessingShader.h"
#include "MediaPlayer.h"
#include <tinyxml2.h>
using namespace tinyxml2;
std::string SessionCreator::info(const std::string& filename)
{
std::string ret = "";
XMLDocument doc;
XMLError eResult = doc.LoadFile(filename.c_str());
if ( XMLResultError(eResult))
return ret;
XMLElement *header = doc.FirstChildElement(APP_NAME);
if (header != nullptr && header->Attribute("date") != 0) {
int s = header->IntAttribute("size");
ret = std::to_string( s ) + " source" + ( s > 1 ? "s\n" : "\n");
std::string date( header->Attribute("date") );
ret += date.substr(6,2) + "/" + date.substr(4,2) + "/" + date.substr(0,4) + " ";
ret += date.substr(8,2) + ":" + date.substr(10,2) + "\n";
}
return ret;
}
SessionCreator::SessionCreator(Session *session): Visitor(), session_(session)
{
xmlDoc_ = new XMLDocument;
}
bool SessionCreator::load(const std::string& filename)
{
XMLError eResult = xmlDoc_->LoadFile(filename.c_str());
if ( XMLResultError(eResult))
return false;
XMLElement *header = xmlDoc_->FirstChildElement(APP_NAME);
if (header == nullptr) {
Log::Warning("%s is not a %s session file.", filename.c_str(), APP_NAME);
return false;
}
int version_major = -1, version_minor = -1;
header->QueryIntAttribute("major", &version_major); // TODO incompatible if major is different?
header->QueryIntAttribute("minor", &version_minor);
if (version_major != XML_VERSION_MAJOR || version_minor != XML_VERSION_MINOR){
Log::Warning("%s is in a different versions of session file. Loading might fail.", filename.c_str());
return false;
}
// ok, ready to read sources
loadSession( xmlDoc_->FirstChildElement("Session") );
// excellent, session was created: load optionnal config
if (session_){
loadConfig( xmlDoc_->FirstChildElement("Views") );
}
return true;
}
void SessionCreator::loadSession(XMLElement *sessionNode)
{
if (sessionNode != nullptr) {
// create a session if not provided
if (!session_)
session_ = new Session;
int counter = 0;
XMLElement* sourceNode = sessionNode->FirstChildElement("Source");
for( ; sourceNode ; sourceNode = sourceNode->NextSiblingElement())
{
xmlCurrent_ = sourceNode;
counter++;
const char *pType = xmlCurrent_->Attribute("type");
if (!pType)
continue;
if ( std::string(pType) == "MediaSource") {
MediaSource *new_media_source = new MediaSource();
new_media_source->accept(*this);
session_->addSource(new_media_source);
}
else if ( std::string(pType) == "SessionSource") {
SessionSource *new_session_source = new SessionSource();
new_session_source->accept(*this);
session_->addSource(new_session_source);
}
else if ( std::string(pType) == "RenderSource") {
RenderSource *new_render_source = new RenderSource(session_);
new_render_source->accept(*this);
session_->addSource(new_render_source);
}
// TODO : create other types of source
}
// create clones after all sources to potentially clone have been created
sourceNode = sessionNode->FirstChildElement("Source");
for( ; sourceNode ; sourceNode = sourceNode->NextSiblingElement())
{
xmlCurrent_ = sourceNode;
counter++;
const char *pType = xmlCurrent_->Attribute("type");
if (!pType)
continue;
if ( std::string(pType) == "CloneSource") {
XMLElement* originNode = xmlCurrent_->FirstChildElement("origin");
if (originNode) {
std::string sourcename = std::string ( originNode->GetText() );
SourceList::iterator origin = session_->find(sourcename);
if (origin != session_->end()) {
CloneSource *new_clone_source = (*origin)->clone();
new_clone_source->accept(*this);
session_->addSource(new_clone_source);
}
}
}
}
}
else
Log::Warning("Session seems empty.");
}
void SessionCreator::loadConfig(XMLElement *viewsNode)
{
if (viewsNode != nullptr) {
// ok, ready to read views
SessionCreator::XMLToNode( viewsNode->FirstChildElement("Mixing"), *session_->config(View::MIXING));
SessionCreator::XMLToNode( viewsNode->FirstChildElement("Geometry"), *session_->config(View::GEOMETRY));
SessionCreator::XMLToNode( viewsNode->FirstChildElement("Layer"), *session_->config(View::LAYER));
SessionCreator::XMLToNode( viewsNode->FirstChildElement("Rendering"), *session_->config(View::RENDERING));
}
}
void SessionCreator::XMLToNode(tinyxml2::XMLElement *xml, Node &n)
{
if (xml != nullptr){
XMLElement *node = xml->FirstChildElement("Node");
if ( !node || std::string(node->Name()).find("Node") == std::string::npos )
return;
XMLElement *scaleNode = node->FirstChildElement("scale");
tinyxml2::XMLElementToGLM( scaleNode->FirstChildElement("vec3"), n.scale_);
XMLElement *translationNode = node->FirstChildElement("translation");
tinyxml2::XMLElementToGLM( translationNode->FirstChildElement("vec3"), n.translation_);
XMLElement *rotationNode = node->FirstChildElement("rotation");
tinyxml2::XMLElementToGLM( rotationNode->FirstChildElement("vec3"), n.rotation_);
}
}
void SessionCreator::visit(Node &n)
{
XMLToNode(xmlCurrent_, n);
}
void SessionCreator::visit(MediaPlayer &n)
{
XMLElement* mediaplayerNode = xmlCurrent_->FirstChildElement("MediaPlayer");
if (mediaplayerNode) {
double speed = 1.0;
mediaplayerNode->QueryDoubleAttribute("speed", &speed);
n.setPlaySpeed(speed);
int loop = 1;
mediaplayerNode->QueryIntAttribute("loop", &loop);
n.setLoop( (MediaPlayer::LoopMode) loop);
bool play = true;
mediaplayerNode->QueryBoolAttribute("play", &play);
n.play(play);
}
}
void SessionCreator::visit(Shader &n)
{
XMLElement* color = xmlCurrent_->FirstChildElement("color");
tinyxml2::XMLElementToGLM( color->FirstChildElement("vec4"), n.color);
XMLElement* blending = xmlCurrent_->FirstChildElement("blending");
if (blending) {
int blend = 0;
blending->QueryIntAttribute("mode", &blend);
n.blending = (Shader::BlendMode) blend;
}
}
void SessionCreator::visit(ImageShader &n)
{
const char *pType = xmlCurrent_->Attribute("type");
if ( std::string(pType) != "ImageShader" )
return;
XMLElement* uniforms = xmlCurrent_->FirstChildElement("uniforms");
if (uniforms) {
uniforms->QueryFloatAttribute("stipple", &n.stipple);
uniforms->QueryUnsignedAttribute("mask", &n.mask);
}
}
void SessionCreator::visit(ImageProcessingShader &n)
{
const char *pType = xmlCurrent_->Attribute("type");
if ( std::string(pType) != "ImageProcessingShader" )
return;
XMLElement* uniforms = xmlCurrent_->FirstChildElement("uniforms");
if (uniforms) {
uniforms->QueryFloatAttribute("brightness", &n.brightness);
uniforms->QueryFloatAttribute("contrast", &n.contrast);
uniforms->QueryFloatAttribute("saturation", &n.saturation);
uniforms->QueryFloatAttribute("hueshift", &n.hueshift);
uniforms->QueryFloatAttribute("threshold", &n.threshold);
uniforms->QueryFloatAttribute("lumakey", &n.lumakey);
uniforms->QueryIntAttribute("nbColors", &n.nbColors);
uniforms->QueryIntAttribute("invert", &n.invert);
uniforms->QueryFloatAttribute("chromadelta", &n.chromadelta);
uniforms->QueryIntAttribute("filter", &n.filterid);
}
XMLElement* gamma = xmlCurrent_->FirstChildElement("gamma");
tinyxml2::XMLElementToGLM( gamma->FirstChildElement("vec4"), n.gamma);
XMLElement* levels = xmlCurrent_->FirstChildElement("levels");
tinyxml2::XMLElementToGLM( levels->FirstChildElement("vec4"), n.levels);
XMLElement* chromakey = xmlCurrent_->FirstChildElement("chromakey");
tinyxml2::XMLElementToGLM( chromakey->FirstChildElement("vec4"), n.chromakey);
}
void SessionCreator::visit (Source& s)
{
XMLElement* sourceNode = xmlCurrent_;
const char *pName = sourceNode->Attribute("name");
s.setName(pName);
xmlCurrent_ = sourceNode->FirstChildElement("Mixing");
s.groupNode(View::MIXING)->accept(*this);
xmlCurrent_ = sourceNode->FirstChildElement("Geometry");
s.groupNode(View::GEOMETRY)->accept(*this);
xmlCurrent_ = sourceNode->FirstChildElement("Layer");
s.groupNode(View::LAYER)->accept(*this);
xmlCurrent_ = sourceNode->FirstChildElement("Blending");
s.blendingShader()->accept(*this);
xmlCurrent_ = sourceNode->FirstChildElement("ImageProcessing");
s.processingShader()->accept(*this);
// restore current
xmlCurrent_ = sourceNode;
}
void SessionCreator::visit (MediaSource& s)
{
// set uri
XMLElement* uriNode = xmlCurrent_->FirstChildElement("uri");
if (uriNode) {
std::string uri = std::string ( uriNode->GetText() );
s.setPath(uri);
}
// set config media player
s.mediaplayer()->accept(*this);
}
void SessionCreator::visit (SessionSource& s)
{
// set uri
XMLElement* pathNode = xmlCurrent_->FirstChildElement("path");
if (pathNode) {
std::string path = std::string ( pathNode->GetText() );
s.load(path);
}
}

View File

@@ -1,56 +0,0 @@
#ifndef SESSIONCREATOR_H
#define SESSIONCREATOR_H
#include "Visitor.h"
#include "tinyxml2Toolkit.h"
class Session;
class SessionCreator : public Visitor {
tinyxml2::XMLDocument *xmlDoc_;
tinyxml2::XMLElement *xmlCurrent_;
Session *session_;
void loadSession(tinyxml2::XMLElement *sessionNode);
void loadConfig(tinyxml2::XMLElement *viewsNode);
public:
SessionCreator(Session *session = nullptr);
bool load(const std::string& filename);
inline Session *session() const { return session_; }
// Elements of Scene
void visit(Node& n) override;
void visit(Scene& n) override {}
void visit(Group& n) override {}
void visit(Switch& n) override {}
void visit(Primitive& n) override {}
void visit(Surface& n) override {}
void visit(ImageSurface& n) override {}
void visit(MediaSurface& n) override {}
void visit(FrameBufferSurface& n) override {}
void visit(LineStrip& n) override {}
void visit(LineSquare&) override {}
void visit(LineCircle& n) override {}
void visit(Mesh& n) override {}
// Elements with attributes
void visit(MediaPlayer& n) override;
void visit(Shader& n) override;
void visit(ImageShader& n) override;
void visit(ImageProcessingShader& n) override;
void visit (Source& s) override;
void visit (MediaSource& s) override;
void visit (SessionSource& s) override;
static std::string info(const std::string& filename);
static void XMLToNode(tinyxml2::XMLElement *xml, Node &n);
};
#endif // SESSIONCREATOR_H

View File

@@ -1,320 +0,0 @@
#include <glm/gtc/matrix_transform.hpp>
#include <thread>
#include <chrono>
#include "SessionSource.h"
#include "defines.h"
#include "Log.h"
#include "FrameBuffer.h"
#include "ImageShader.h"
#include "ImageProcessingShader.h"
#include "Resource.h"
#include "Primitives.h"
#include "Mesh.h"
#include "SearchVisitor.h"
#include "Session.h"
#include "SessionCreator.h"
#include "Mixer.h"
void SessionSource::loadSession(const std::string& filename, SessionSource *source)
{
source->loadFinished_ = false;
// actual loading of xml file
SessionCreator creator( source->session_ );
if (creator.load(filename)) {
// all ok, validate session filename
source->session_->setFilename(filename);
}
else {
// error loading
Log::Notify("Failed to load Session file %s.", filename.c_str());
source->loadFailed_ = true;
}
// end thread
source->loadFinished_ = true;
}
SessionSource::SessionSource() : Source(), path_("")
{
// specific node for transition view
groups_[View::TRANSITION]->visible_ = false;
groups_[View::TRANSITION]->scale_ = glm::vec3(0.1f, 0.1f, 1.f);
groups_[View::TRANSITION]->translation_ = glm::vec3(-1.f, 0.f, 0.f);
frames_[View::TRANSITION] = new Switch;
Frame *frame = new Frame(Frame::ROUND, Frame::THIN, Frame::DROP);
frame->translation_.z = 0.1;
frame->color = glm::vec4( COLOR_DEFAULT_SOURCE, 0.9f);
frames_[View::TRANSITION]->attach(frame);
frame = new Frame(Frame::ROUND, Frame::LARGE, Frame::DROP);
frame->translation_.z = 0.01;
frame->color = glm::vec4( COLOR_TRANSITION_SOURCE, 1.f);
frames_[View::TRANSITION]->attach(frame);
groups_[View::TRANSITION]->attach(frames_[View::TRANSITION]);
overlays_[View::TRANSITION] = new Group;
overlays_[View::TRANSITION]->translation_.z = 0.1;
overlays_[View::TRANSITION]->visible_ = false;
Symbol *loader = new Symbol(Symbol::DOTS);
loader->scale_ = glm::vec3(2.f, 2.f, 1.f);
loader->update_callbacks_.push_back(new InfiniteGlowCallback);
overlays_[View::TRANSITION]->attach(loader);
Symbol *center = new Symbol(Symbol::POINT, glm::vec3(0.f, -1.05f, 0.1f));
overlays_[View::TRANSITION]->attach(center);
groups_[View::TRANSITION]->attach(overlays_[View::TRANSITION]);
loadFailed_ = false;
loadFinished_ = false;
wait_for_sources_ = false;
session_ = new Session;
// create surface:
// - textured with original texture from session
// - crop & repeat UV can be managed here
// - additional custom shader can be associated
sessionsurface_ = new Surface(rendershader_);
}
SessionSource::~SessionSource()
{
// delete surface
delete sessionsurface_;
// delete session
if (session_)
delete session_;
}
void SessionSource::load(const std::string &p)
{
path_ = p;
// launch a thread to load the session
std::thread ( SessionSource::loadSession, path_, this).detach();
Log::Notify("Opening %s", p.c_str());
}
Session *SessionSource::detach()
{
// remember pointer to give away
Session *giveaway = session_;
// work on a new session
session_ = new Session;
// make disabled
initialized_ = false;
loadFailed_ = true;
return giveaway;
}
bool SessionSource::failed() const
{
return loadFailed_;
}
uint SessionSource::texture() const
{
if (session_ == nullptr)
return Resource::getTextureBlack();
return session_->frame()->texture();
}
void SessionSource::init()
{
if (session_ == nullptr)
return;
if (wait_for_sources_) {
// force update of of all sources
active_ = true;
touch();
// check that every source is ready..
bool ready = true;
for (SourceList::iterator iter = session_->begin(); iter != session_->end(); iter++)
{
// interrupt if any source is NOT ready
if ( !(*iter)->ready() ){
ready = false;
break;
}
}
// if all sources are ready, done with initialization!
if (ready) {
// remove the loading icon
Node *loader = overlays_[View::TRANSITION]->back();
overlays_[View::TRANSITION]->detatch(loader);
delete loader;
// done init
wait_for_sources_ = false;
initialized_ = true;
Log::Info("Source Session %s loaded %d sources.", path_.c_str(), session_->numSource());
}
}
if ( loadFinished_ && !loadFailed_ && session_ != nullptr) {
loadFinished_ = false;
// set resolution
session_->setResolution( session_->config(View::RENDERING)->scale_ );
// deep update once to draw framebuffer
View::need_deep_update_ = true;
session_->update(dt_);
// get the texture index from framebuffer of session, apply it to the surface
sessionsurface_->setTextureIndex( session_->frame()->texture() );
// create Frame buffer matching size of session
FrameBuffer *renderbuffer = new FrameBuffer( session_->frame()->resolution());
// set the renderbuffer of the source and attach rendering nodes
attach(renderbuffer);
// icon in mixing view
overlays_[View::MIXING]->attach( new Symbol(Symbol::SESSION, glm::vec3(0.8f, 0.8f, 0.01f)) );
overlays_[View::LAYER]->attach( new Symbol(Symbol::SESSION, glm::vec3(0.8f, 0.8f, 0.01f)) );
// wait for all sources to init
wait_for_sources_ = true;
}
}
void SessionSource::setActive (bool on)
{
Source::setActive(on);
// change status of session (recursive change of internal sources)
if (session_ != nullptr)
session_->setActive(active_);
}
void SessionSource::update(float dt)
{
if (session_ == nullptr)
loadFailed_ = true;
// update content
if (active_)
session_->update(dt);
// delete a source which failed
if (session_->failedSource() != nullptr) {
session_->deleteSource(session_->failedSource());
// fail session if all sources failed
if ( session_->numSource() < 1)
loadFailed_ = true;
}
Source::update(dt);
}
void SessionSource::render()
{
if (!initialized_)
init();
else {
// render the sesion into frame buffer
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
renderbuffer_->begin();
sessionsurface_->draw(glm::identity<glm::mat4>(), projection);
renderbuffer_->end();
}
}
void SessionSource::accept(Visitor& v)
{
Source::accept(v);
v.visit(*this);
}
RenderSource::RenderSource(Session *session) : Source(), session_(session)
{
// create surface:
sessionsurface_ = new Surface(rendershader_);
}
RenderSource::~RenderSource()
{
// delete surface
delete sessionsurface_;
}
bool RenderSource::failed() const
{
return session_ == nullptr;
}
uint RenderSource::texture() const
{
if (session_ == nullptr)
return Resource::getTextureBlack();
else
return session_->frame()->texture();
}
void RenderSource::init()
{
if (session_ == nullptr)
return;
if (session_ && session_->frame()->texture() != Resource::getTextureBlack()) {
FrameBuffer *fb = session_->frame();
// get the texture index from framebuffer of view, apply it to the surface
sessionsurface_->setTextureIndex( fb->texture() );
// create Frame buffer matching size of output session
FrameBuffer *renderbuffer = new FrameBuffer( fb->resolution());
// set the renderbuffer of the source and attach rendering nodes
attach(renderbuffer);
// icon in mixing view
overlays_[View::MIXING]->attach( new Symbol(Symbol::RENDER, glm::vec3(0.8f, 0.8f, 0.01f)) );
overlays_[View::LAYER]->attach( new Symbol(Symbol::RENDER, glm::vec3(0.8f, 0.8f, 0.01f)) );
// done init
initialized_ = true;
Log::Info("Source Render linked to session (%d x %d).", int(fb->resolution().x), int(fb->resolution().y) );
}
}
void RenderSource::render()
{
if (!initialized_)
init();
else {
// render the view into frame buffer
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
renderbuffer_->begin();
sessionsurface_->draw(glm::identity<glm::mat4>(), projection);
renderbuffer_->end();
}
}
void RenderSource::accept(Visitor& v)
{
Source::accept(v);
v.visit(*this);
}

View File

@@ -1,63 +0,0 @@
#ifndef SESSIONSOURCE_H
#define SESSIONSOURCE_H
#include <atomic>
#include "Source.h"
class SessionSource : public Source
{
public:
SessionSource();
~SessionSource();
// implementation of source API
void update (float dt) override;
void setActive (bool on) override;
void render() override;
bool failed() const override;
uint texture() const override;
void accept (Visitor& v) override;
// Session Source specific interface
void load(const std::string &p);
Session *detach();
inline std::string path() const { return path_; }
inline Session *session() const { return session_; }
protected:
void init() override;
static void loadSession(const std::string& filename, SessionSource *source);
Surface *sessionsurface_;
std::string path_;
Session *session_;
std::atomic<bool> loadFailed_;
std::atomic<bool> loadFinished_;
std::atomic<bool> wait_for_sources_;
};
class RenderSource : public Source
{
public:
RenderSource(Session *session);
~RenderSource();
// implementation of source API
void render() override;
bool failed() const override;
uint texture() const override;
void accept (Visitor& v) override;
protected:
void init() override;
Surface *sessionsurface_;
Session *session_;
};
#endif // SESSIONSOURCE_H

View File

@@ -1,361 +0,0 @@
#include "SessionVisitor.h"
#include "Log.h"
#include "Scene.h"
#include "Primitives.h"
#include "Mesh.h"
#include "Source.h"
#include "MediaSource.h"
#include "SessionSource.h"
#include "ImageShader.h"
#include "ImageProcessingShader.h"
#include "MediaPlayer.h"
#include <iostream>
#include <tinyxml2.h>
using namespace tinyxml2;
SessionVisitor::SessionVisitor(tinyxml2::XMLDocument *doc,
tinyxml2::XMLElement *root,
bool recursive) : Visitor(), xmlCurrent_(root), recursive_(recursive)
{
if (doc == nullptr)
xmlDoc_ = new XMLDocument;
else
xmlDoc_ = doc;
}
tinyxml2::XMLElement *SessionVisitor::NodeToXML(Node &n, tinyxml2::XMLDocument *doc)
{
XMLElement *newelement = doc->NewElement("Node");
newelement->SetAttribute("visible", n.visible_);
XMLElement *scale = doc->NewElement("scale");
scale->InsertEndChild( XMLElementFromGLM(doc, n.scale_) );
newelement->InsertEndChild(scale);
XMLElement *translation = doc->NewElement("translation");
translation->InsertEndChild( XMLElementFromGLM(doc, n.translation_) );
newelement->InsertEndChild(translation);
XMLElement *rotation = doc->NewElement("rotation");
rotation->InsertEndChild( XMLElementFromGLM(doc, n.rotation_) );
newelement->InsertEndChild(rotation);
return newelement;
}
void SessionVisitor::visit(Node &n)
{
XMLElement *newelement = NodeToXML(n, xmlDoc_);
// insert into hierarchy
xmlCurrent_->InsertEndChild(newelement);
// parent for next visits
xmlCurrent_ = newelement;
}
void SessionVisitor::visit(Group &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "Group");
if (recursive_) {
// loop over members of a group
XMLElement *group = xmlCurrent_;
for (NodeSet::iterator node = n.begin(); node != n.end(); node++) {
(*node)->accept(*this);
// revert to group as current
xmlCurrent_ = group;
}
}
}
void SessionVisitor::visit(Switch &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "Switch");
xmlCurrent_->SetAttribute("active", n.active());
if (recursive_) {
// loop over members of the group
XMLElement *group = xmlCurrent_;
for(uint i = 0; i < n.numChildren(); i++) {
n.child(i)->accept(*this);
// revert to group as current
xmlCurrent_ = group;
}
}
}
void SessionVisitor::visit(Primitive &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "Primitive");
if (recursive_) {
// go over members of a primitive
XMLElement *Primitive = xmlCurrent_;
xmlCurrent_ = xmlDoc_->NewElement("Shader");
n.shader()->accept(*this);
Primitive->InsertEndChild(xmlCurrent_);
// revert to primitive as current
xmlCurrent_ = Primitive;
}
}
void SessionVisitor::visit(Surface &n)
{
}
void SessionVisitor::visit(ImageSurface &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "ImageSurface");
XMLText *filename = xmlDoc_->NewText( n.resource().c_str() );
XMLElement *image = xmlDoc_->NewElement("resource");
image->InsertEndChild(filename);
xmlCurrent_->InsertEndChild(image);
}
void SessionVisitor::visit(FrameBufferSurface &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "FrameBufferSurface");
}
void SessionVisitor::visit(MediaSurface &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "MediaSurface");
n.mediaPlayer()->accept(*this);
}
void SessionVisitor::visit(MediaPlayer &n)
{
XMLElement *newelement = xmlDoc_->NewElement("MediaPlayer");
newelement->SetAttribute("play", n.isPlaying());
newelement->SetAttribute("loop", (int) n.loop());
newelement->SetAttribute("speed", n.playSpeed());
// TODO Segments
xmlCurrent_->InsertEndChild(newelement);
}
void SessionVisitor::visit(Shader &n)
{
// Shader of a simple type
xmlCurrent_->SetAttribute("type", "Shader");
XMLElement *color = xmlDoc_->NewElement("color");
color->InsertEndChild( XMLElementFromGLM(xmlDoc_, n.color) );
xmlCurrent_->InsertEndChild(color);
XMLElement *blend = xmlDoc_->NewElement("blending");
blend->SetAttribute("mode", int(n.blending) );
xmlCurrent_->InsertEndChild(blend);
}
void SessionVisitor::visit(ImageShader &n)
{
// Shader of a textured type
xmlCurrent_->SetAttribute("type", "ImageShader");
XMLElement *uniforms = xmlDoc_->NewElement("uniforms");
uniforms->SetAttribute("stipple", n.stipple);
uniforms->SetAttribute("mask", n.mask);
xmlCurrent_->InsertEndChild(uniforms);
}
void SessionVisitor::visit(ImageProcessingShader &n)
{
// Shader of a textured type
xmlCurrent_->SetAttribute("type", "ImageProcessingShader");
XMLElement *filter = xmlDoc_->NewElement("uniforms");
filter->SetAttribute("brightness", n.brightness);
filter->SetAttribute("contrast", n.contrast);
filter->SetAttribute("saturation", n.saturation);
filter->SetAttribute("hueshift", n.hueshift);
filter->SetAttribute("threshold", n.threshold);
filter->SetAttribute("lumakey", n.lumakey);
filter->SetAttribute("nbColors", n.nbColors);
filter->SetAttribute("invert", n.invert);
filter->SetAttribute("chromadelta", n.chromadelta);
filter->SetAttribute("filterid", n.filterid);
xmlCurrent_->InsertEndChild(filter);
XMLElement *gamma = xmlDoc_->NewElement("gamma");
gamma->InsertEndChild( XMLElementFromGLM(xmlDoc_, n.gamma) );
xmlCurrent_->InsertEndChild(gamma);
XMLElement *levels = xmlDoc_->NewElement("levels");
levels->InsertEndChild( XMLElementFromGLM(xmlDoc_, n.levels) );
xmlCurrent_->InsertEndChild(levels);
XMLElement *chromakey = xmlDoc_->NewElement("chromakey");
chromakey->InsertEndChild( XMLElementFromGLM(xmlDoc_, n.chromakey) );
xmlCurrent_->InsertEndChild(chromakey);
}
void SessionVisitor::visit(LineStrip &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "LineStrip");
XMLElement *points_node = xmlDoc_->NewElement("points");
std::vector<glm::vec3> points = n.getPoints();
for(size_t i = 0; i < points.size(); ++i)
{
XMLElement *p = XMLElementFromGLM(xmlDoc_, points[i]);
p->SetAttribute("index", (int) i);
points_node->InsertEndChild(p);
}
xmlCurrent_->InsertEndChild(points_node);
XMLElement *colors_node = xmlDoc_->NewElement("colors");
std::vector<glm::vec4> colors = n.getColors();
for(size_t i = 0; i < colors.size(); ++i)
{
XMLElement *p = XMLElementFromGLM(xmlDoc_, colors[i]);
p->SetAttribute("index", (int) i);
colors_node->InsertEndChild(p);
}
xmlCurrent_->InsertEndChild(colors_node);
}
void SessionVisitor::visit(LineSquare &)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "LineSquare");
}
void SessionVisitor::visit(LineCircle &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "LineCircle");
// XMLElement *color = xmlDoc_->NewElement("color");
// color->InsertEndChild( XMLElementFromGLM(xmlDoc_, n.getColor()) );
// xmlCurrent_->InsertEndChild(color);
}
void SessionVisitor::visit(Mesh &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "Mesh");
XMLText *filename = xmlDoc_->NewText( n.meshPath().c_str() );
XMLElement *obj = xmlDoc_->NewElement("resource");
obj->InsertEndChild(filename);
xmlCurrent_->InsertEndChild(obj);
filename = xmlDoc_->NewText( n.texturePath().c_str() );
XMLElement *tex = xmlDoc_->NewElement("texture");
tex->InsertEndChild(filename);
xmlCurrent_->InsertEndChild(tex);
}
void SessionVisitor::visit(Frame &n)
{
// Node of a different type
xmlCurrent_->SetAttribute("type", "Frame");
XMLElement *color = xmlDoc_->NewElement("color");
color->InsertEndChild( XMLElementFromGLM(xmlDoc_, n.color) );
xmlCurrent_->InsertEndChild(color);
}
void SessionVisitor::visit(Scene &n)
{
XMLElement *xmlRoot = xmlDoc_->NewElement("Scene");
xmlDoc_->InsertEndChild(xmlRoot);
// start recursive traverse from root node
recursive_ = true;
xmlCurrent_ = xmlRoot;
n.root()->accept(*this);
}
void SessionVisitor::visit (Source& s)
{
XMLElement *sourceNode = xmlDoc_->NewElement( "Source" );
sourceNode->SetAttribute("name", s.name().c_str() );
// insert into hierarchy
xmlCurrent_->InsertFirstChild(sourceNode);
xmlCurrent_ = xmlDoc_->NewElement( "Mixing" );
sourceNode->InsertEndChild(xmlCurrent_);
s.groupNode(View::MIXING)->accept(*this);
xmlCurrent_ = xmlDoc_->NewElement( "Geometry" );
sourceNode->InsertEndChild(xmlCurrent_);
s.groupNode(View::GEOMETRY)->accept(*this);
xmlCurrent_ = xmlDoc_->NewElement( "Layer" );
sourceNode->InsertEndChild(xmlCurrent_);
s.groupNode(View::LAYER)->accept(*this);
xmlCurrent_ = xmlDoc_->NewElement( "Blending" );
sourceNode->InsertEndChild(xmlCurrent_);
s.blendingShader()->accept(*this);
xmlCurrent_ = xmlDoc_->NewElement( "ImageProcessing" );
sourceNode->InsertEndChild(xmlCurrent_);
s.processingShader()->accept(*this);
xmlCurrent_ = sourceNode; // parent for next visits (other subtypes of Source)
}
void SessionVisitor::visit (MediaSource& s)
{
xmlCurrent_->SetAttribute("type", "MediaSource");
XMLElement *uri = xmlDoc_->NewElement("uri");
xmlCurrent_->InsertEndChild(uri);
XMLText *text = xmlDoc_->NewText( s.path().c_str() );
uri->InsertEndChild( text );
s.mediaplayer()->accept(*this);
}
void SessionVisitor::visit (SessionSource& s)
{
xmlCurrent_->SetAttribute("type", "SessionSource");
XMLElement *path = xmlDoc_->NewElement("path");
xmlCurrent_->InsertEndChild(path);
XMLText *text = xmlDoc_->NewText( s.path().c_str() );
path->InsertEndChild( text );
}
void SessionVisitor::visit (RenderSource& s)
{
xmlCurrent_->SetAttribute("type", "RenderSource");
}
void SessionVisitor::visit (CloneSource& s)
{
xmlCurrent_->SetAttribute("type", "CloneSource");
XMLElement *origin = xmlDoc_->NewElement("origin");
xmlCurrent_->InsertEndChild(origin);
XMLText *text = xmlDoc_->NewText( s.origin()->name().c_str() );
origin->InsertEndChild( text );
}

View File

@@ -1,51 +0,0 @@
#ifndef XMLVISITOR_H
#define XMLVISITOR_H
#include "Visitor.h"
#include "tinyxml2Toolkit.h"
class SessionVisitor : public Visitor {
bool recursive_;
tinyxml2::XMLDocument *xmlDoc_;
tinyxml2::XMLElement *xmlCurrent_;
public:
SessionVisitor(tinyxml2::XMLDocument *doc = nullptr,
tinyxml2::XMLElement *root = nullptr,
bool recursive = false);
inline tinyxml2::XMLDocument *doc() const { return xmlDoc_; }
// Elements of Scene
void visit(Scene& n) override;
void visit(Node& n) override;
void visit(Group& n) override;
void visit(Switch& n) override;
void visit(Primitive& n) override;
void visit(Surface& n) override;
void visit(ImageSurface& n) override;
void visit(MediaSurface& n) override;
void visit(FrameBufferSurface& n) override;
void visit(LineStrip& n) override;
void visit(LineSquare&) override;
void visit(LineCircle& n) override;
void visit(Mesh& n) override;
void visit(Frame& n) override;
// Elements with attributes
void visit(MediaPlayer& n) override;
void visit(Shader& n) override;
void visit(ImageShader& n) override;
void visit(ImageProcessingShader& n) override;
void visit (Source& s) override;
void visit (MediaSource& s) override;
void visit (SessionSource& s) override;
void visit (RenderSource& s) override;
void visit (CloneSource& s) override;
static tinyxml2::XMLElement *NodeToXML(Node &n, tinyxml2::XMLDocument *doc);
};
#endif // XMLVISITOR_H

View File

@@ -1,358 +0,0 @@
#include <algorithm>
#include <iostream>
using namespace std;
#include <tinyxml2.h>
#include "tinyxml2Toolkit.h"
using namespace tinyxml2;
#include "defines.h"
#include "Settings.h"
#include "SystemToolkit.h"
Settings::Application Settings::application;
static string settingsFilename = "";
void Settings::Save()
{
XMLDocument xmlDoc;
XMLDeclaration *pDec = xmlDoc.NewDeclaration();
xmlDoc.InsertFirstChild(pDec);
XMLElement *pRoot = xmlDoc.NewElement(application.name.c_str());
xmlDoc.InsertEndChild(pRoot);
string comment = "Settings for " + application.name;
comment += "Version " + std::to_string(APP_VERSION_MAJOR) + "." + std::to_string(APP_VERSION_MINOR);
XMLComment *pComment = xmlDoc.NewComment(comment.c_str());
pRoot->InsertEndChild(pComment);
// block: windows
{
XMLElement *windowsNode = xmlDoc.NewElement( "Windows" );
for (int i = 0; i < application.windows.size(); i++)
{
const Settings::WindowConfig& w = application.windows[i];
XMLElement *window = xmlDoc.NewElement( "Window" );
window->SetAttribute("id", i);
window->SetAttribute("name", w.name.c_str());
window->SetAttribute("x", w.x);
window->SetAttribute("y", w.y);
window->SetAttribute("w", w.w);
window->SetAttribute("h", w.h);
window->SetAttribute("f", w.fullscreen);
window->SetAttribute("m", w.monitor.c_str());
windowsNode->InsertEndChild(window);
}
pRoot->InsertEndChild(windowsNode);
}
// General application preferences
XMLElement *applicationNode = xmlDoc.NewElement( "Application" );
applicationNode->SetAttribute("scale", application.scale);
applicationNode->SetAttribute("accent_color", application.accent_color);
applicationNode->SetAttribute("pannel_stick", application.pannel_stick);
applicationNode->SetAttribute("smooth_transition", application.smooth_transition);
pRoot->InsertEndChild(applicationNode);
// Widgets
XMLElement *widgetsNode = xmlDoc.NewElement( "Widgets" );
widgetsNode->SetAttribute("preview", application.widget.preview);
widgetsNode->SetAttribute("media_player", application.widget.media_player);
widgetsNode->SetAttribute("shader_editor", application.widget.shader_editor);
widgetsNode->SetAttribute("stats", application.widget.stats);
widgetsNode->SetAttribute("stats_corner", application.widget.stats_corner);
widgetsNode->SetAttribute("logs", application.widget.logs);
widgetsNode->SetAttribute("toolbox", application.widget.toolbox);
pRoot->InsertEndChild(widgetsNode);
// Render
XMLElement *RenderNode = xmlDoc.NewElement( "Render" );
RenderNode->SetAttribute("vsync", application.render.vsync);
RenderNode->SetAttribute("multisampling", application.render.multisampling);
RenderNode->SetAttribute("blit", application.render.blit);
RenderNode->SetAttribute("ratio", application.render.ratio);
RenderNode->SetAttribute("res", application.render.res);
pRoot->InsertEndChild(RenderNode);
// Transition
XMLElement *TransitionNode = xmlDoc.NewElement( "Transition" );
TransitionNode->SetAttribute("auto_open", application.transition.auto_open);
TransitionNode->SetAttribute("hide_windows", application.transition.hide_windows);
TransitionNode->SetAttribute("cross_fade", application.transition.cross_fade);
TransitionNode->SetAttribute("duration", application.transition.duration);
TransitionNode->SetAttribute("profile", application.transition.profile);
pRoot->InsertEndChild(TransitionNode);
// bloc views
{
XMLElement *viewsNode = xmlDoc.NewElement( "Views" );
// save current view only if [mixing, geometry or layers]
int v = application.current_view > 3 ? 1 : application.current_view;
viewsNode->SetAttribute("current", v);
map<int, Settings::ViewConfig>::iterator iter;
for (iter=application.views.begin(); iter != application.views.end(); iter++)
{
const Settings::ViewConfig& v = iter->second;
XMLElement *view = xmlDoc.NewElement( "View" );
view->SetAttribute("name", v.name.c_str());
view->SetAttribute("id", iter->first);
XMLElement *scale = xmlDoc.NewElement("default_scale");
scale->InsertEndChild( XMLElementFromGLM(&xmlDoc, v.default_scale) );
view->InsertEndChild(scale);
XMLElement *translation = xmlDoc.NewElement("default_translation");
translation->InsertEndChild( XMLElementFromGLM(&xmlDoc, v.default_translation) );
view->InsertEndChild(translation);
viewsNode->InsertEndChild(view);
}
pRoot->InsertEndChild(viewsNode);
}
// bloc history
{
XMLElement *recent = xmlDoc.NewElement( "Recent" );
XMLElement *recentsession = xmlDoc.NewElement( "Session" );
recentsession->SetAttribute("path", application.recentSessions.path.c_str());
recentsession->SetAttribute("autoload", application.recentSessions.load_at_start);
recentsession->SetAttribute("autosave", application.recentSessions.save_on_exit);
recentsession->SetAttribute("valid", application.recentSessions.valid_file);
for(auto it = application.recentSessions.filenames.begin();
it != application.recentSessions.filenames.end(); it++) {
XMLElement *fileNode = xmlDoc.NewElement("path");
XMLText *text = xmlDoc.NewText( (*it).c_str() );
fileNode->InsertEndChild( text );
recentsession->InsertFirstChild(fileNode);
};
recent->InsertEndChild(recentsession);
XMLElement *recentfolder = xmlDoc.NewElement( "Folder" );
for(auto it = application.recentFolders.filenames.begin();
it != application.recentFolders.filenames.end(); it++) {
XMLElement *fileNode = xmlDoc.NewElement("path");
XMLText *text = xmlDoc.NewText( (*it).c_str() );
fileNode->InsertEndChild( text );
recentfolder->InsertFirstChild(fileNode);
};
recent->InsertEndChild(recentfolder);
XMLElement *recentmedia = xmlDoc.NewElement( "Import" );
recentmedia->SetAttribute("path", application.recentImport.path.c_str());
for(auto it = application.recentImport.filenames.begin();
it != application.recentImport.filenames.end(); it++) {
XMLElement *fileNode = xmlDoc.NewElement("path");
XMLText *text = xmlDoc.NewText( (*it).c_str() );
fileNode->InsertEndChild( text );
recentmedia->InsertFirstChild(fileNode);
}
recent->InsertEndChild(recentmedia);
pRoot->InsertEndChild(recent);
}
// First save : create filename
if (settingsFilename.empty())
settingsFilename = SystemToolkit::full_filename(SystemToolkit::settings_path(), APP_SETTINGS);
XMLError eResult = xmlDoc.SaveFile(settingsFilename.c_str());
XMLResultError(eResult);
}
void Settings::Load()
{
XMLDocument xmlDoc;
if (settingsFilename.empty())
settingsFilename = SystemToolkit::full_filename(SystemToolkit::settings_path(), APP_SETTINGS);
XMLError eResult = xmlDoc.LoadFile(settingsFilename.c_str());
// do not warn if non existing file
if (eResult == XML_ERROR_FILE_NOT_FOUND)
return;
// warn and return on other error
else if (XMLResultError(eResult))
return;
XMLElement *pRoot = xmlDoc.FirstChildElement(application.name.c_str());
if (pRoot == nullptr) return;
if (application.name.compare( string( pRoot->Value() ) ) != 0 )
// different root name
return;
XMLElement * applicationNode = pRoot->FirstChildElement("Application");
if (applicationNode != nullptr) {
applicationNode->QueryFloatAttribute("scale", &application.scale);
applicationNode->QueryIntAttribute("accent_color", &application.accent_color);
applicationNode->QueryBoolAttribute("pannel_stick", &application.pannel_stick);
applicationNode->QueryBoolAttribute("smooth_transition", &application.smooth_transition);
}
// Widgets
XMLElement * widgetsNode = pRoot->FirstChildElement("Widgets");
if (widgetsNode != nullptr) {
widgetsNode->QueryBoolAttribute("preview", &application.widget.preview);
widgetsNode->QueryBoolAttribute("media_player", &application.widget.media_player);
widgetsNode->QueryBoolAttribute("shader_editor", &application.widget.shader_editor);
widgetsNode->QueryBoolAttribute("stats", &application.widget.stats);
widgetsNode->QueryIntAttribute("stats_corner", &application.widget.stats_corner);
widgetsNode->QueryBoolAttribute("logs", &application.widget.logs);
widgetsNode->QueryBoolAttribute("toolbox", &application.widget.toolbox);
}
// Render
XMLElement * rendernode = pRoot->FirstChildElement("Render");
if (rendernode != nullptr) {
rendernode->QueryIntAttribute("vsync", &application.render.vsync);
rendernode->QueryIntAttribute("multisampling", &application.render.multisampling);
rendernode->QueryBoolAttribute("blit", &application.render.blit);
rendernode->QueryIntAttribute("ratio", &application.render.ratio);
rendernode->QueryIntAttribute("res", &application.render.res);
}
// Transition
XMLElement * transitionnode = pRoot->FirstChildElement("Transition");
if (transitionnode != nullptr) {
transitionnode->QueryBoolAttribute("hide_windows", &application.transition.hide_windows);
transitionnode->QueryBoolAttribute("auto_open", &application.transition.auto_open);
transitionnode->QueryBoolAttribute("cross_fade", &application.transition.cross_fade);
transitionnode->QueryFloatAttribute("duration", &application.transition.duration);
transitionnode->QueryIntAttribute("profile", &application.transition.profile);
}
// bloc windows
{
XMLElement * pElement = pRoot->FirstChildElement("Windows");
if (pElement)
{
XMLElement* windowNode = pElement->FirstChildElement("Window");
for( ; windowNode ; windowNode=windowNode->NextSiblingElement())
{
Settings::WindowConfig w;
w.name = std::string(windowNode->Attribute("name"));
windowNode->QueryIntAttribute("x", &w.x); // If this fails, original value is left as-is
windowNode->QueryIntAttribute("y", &w.y);
windowNode->QueryIntAttribute("w", &w.w);
windowNode->QueryIntAttribute("h", &w.h);
windowNode->QueryBoolAttribute("f", &w.fullscreen);
w.monitor = std::string(windowNode->Attribute("m"));
int i = 0;
windowNode->QueryIntAttribute("id", &i);
application.windows[i] = w;
}
}
}
// bloc views
{
application.views.clear(); // trash existing list
XMLElement * pElement = pRoot->FirstChildElement("Views");
if (pElement)
{
pElement->QueryIntAttribute("current", &application.current_view);
XMLElement* viewNode = pElement->FirstChildElement("View");
for( ; viewNode ; viewNode=viewNode->NextSiblingElement())
{
int id = 0;
viewNode->QueryIntAttribute("id", &id);
application.views[id].name = viewNode->Attribute("name");
XMLElement* scaleNode = viewNode->FirstChildElement("default_scale");
tinyxml2::XMLElementToGLM( scaleNode->FirstChildElement("vec3"),
application.views[id].default_scale);
XMLElement* translationNode = viewNode->FirstChildElement("default_translation");
tinyxml2::XMLElementToGLM( translationNode->FirstChildElement("vec3"),
application.views[id].default_translation);
}
}
}
// bloc history of recent
{
XMLElement * pElement = pRoot->FirstChildElement("Recent");
if (pElement)
{
// recent session filenames
XMLElement * pSession = pElement->FirstChildElement("Session");
if (pSession)
{
const char *path_ = pSession->Attribute("path");
if (path_)
application.recentSessions.path = std::string(path_);
else
application.recentSessions.path = SystemToolkit::home_path();
application.recentSessions.filenames.clear();
XMLElement* path = pSession->FirstChildElement("path");
for( ; path ; path = path->NextSiblingElement())
{
const char *p = path->GetText();
if (p)
application.recentSessions.push( std::string (p) );
}
pSession->QueryBoolAttribute("autoload", &application.recentSessions.load_at_start);
pSession->QueryBoolAttribute("autosave", &application.recentSessions.save_on_exit);
pSession->QueryBoolAttribute("valid", &application.recentSessions.valid_file);
}
// recent session filenames
XMLElement * pFolder = pElement->FirstChildElement("Folder");
if (pFolder)
{
application.recentFolders.filenames.clear();
XMLElement* path = pFolder->FirstChildElement("path");
for( ; path ; path = path->NextSiblingElement())
{
const char *p = path->GetText();
if (p)
application.recentFolders.push( std::string (p) );
}
}
// recent media uri
XMLElement * pImport = pElement->FirstChildElement("Import");
if (pImport)
{
const char *path_ = pImport->Attribute("path");
if (path_)
application.recentImport.path = std::string(path_);
else
application.recentImport.path = SystemToolkit::home_path();
application.recentImport.filenames.clear();
XMLElement* path = pImport->FirstChildElement("path");
for( ; path ; path = path->NextSiblingElement())
{
const char *p = path->GetText();
if (p)
application.recentImport.push( std::string (p) );
}
}
}
}
}
void Settings::Check()
{
Settings::Save();
XMLDocument xmlDoc;
XMLError eResult = xmlDoc.LoadFile(settingsFilename.c_str());
if (XMLResultError(eResult))
return;
xmlDoc.Print();
}

View File

@@ -1,184 +0,0 @@
#ifndef __SETTINGS_H_
#define __SETTINGS_H_
#include "defines.h"
#include <string>
#include <map>
#include <vector>
#include <list>
#include <glm/glm.hpp>
namespace Settings {
struct WidgetsConfig
{
bool stats;
int stats_corner;
bool logs;
bool preview;
bool media_player;
bool media_player_view;
bool shader_editor;
bool toolbox;
WidgetsConfig() {
stats = false;
stats_corner = 1;
logs = false;
preview = false;
media_player = false;
media_player_view = true;
shader_editor = false;
toolbox = false;
}
};
struct WindowConfig
{
std::string name;
int x,y,w,h;
bool fullscreen;
std::string monitor;
WindowConfig() : name(""), x(15), y(15), w(1280), h(720), fullscreen(false), monitor("") { }
};
struct ViewConfig
{
std::string name;
glm::vec3 default_scale;
glm::vec3 default_translation;
ViewConfig() : name("") {
default_scale = glm::vec3(1.f);
default_translation = glm::vec3(0.f);
}
};
struct History
{
std::string path;
std::list<std::string> filenames;
bool valid_file;
bool load_at_start;
bool save_on_exit;
History() {
path = IMGUI_LABEL_RECENT_FILES;
valid_file = false;
load_at_start = false;
save_on_exit = false;
}
void push(std::string filename) {
if (filename.empty()) {
valid_file = false;
return;
}
filenames.remove(filename);
filenames.push_front(filename);
if (filenames.size() > MAX_RECENT_HISTORY)
filenames.pop_back();
valid_file = true;
}
};
struct TransitionConfig
{
bool cross_fade;
bool auto_open;
bool hide_windows;
float duration;
int profile;
TransitionConfig() {
cross_fade = true;
auto_open = true;
hide_windows = true;
duration = 1.f;
profile = 0;
}
};
struct RenderConfig
{
bool blit;
int vsync;
int multisampling;
int ratio;
int res;
float fading;
RenderConfig() {
blit = false;
vsync = 1; // todo GUI selection
multisampling = 2; // todo GUI selection
ratio = 3;
res = 1;
fading = 0.0;
}
};
struct Application
{
// Verification
std::string name;
std::string executable;
// Global settings Application interface
float scale;
int accent_color;
bool pannel_stick;
bool smooth_transition;
// Settings of widgets
WidgetsConfig widget;
// Settings of Views
int current_view;
std::map<int, ViewConfig> views;
// settings render
RenderConfig render;
// settings transition
TransitionConfig transition;
// multiple windows handling
std::vector<WindowConfig> windows;
// recent files histories
History recentSessions;
History recentFolders;
History recentImport;
Application() : name(APP_NAME){
scale = 1.f;
accent_color = 0;
pannel_stick = false;
smooth_transition = true;
current_view = 1;
windows = std::vector<WindowConfig>(3);
windows[0].name = APP_NAME APP_TITLE;
windows[0].w = 1600;
windows[0].h = 900;
windows[1].name = APP_NAME " -- Output";
}
};
// minimal implementation of settings
// Can be accessed r&w anywhere
extern Application application;
// Save and Load store settings in XML file
void Save();
void Load();
void Check();
}
#endif /* __SETTINGS_H_ */

View File

@@ -1,234 +0,0 @@
#include "Shader.h"
#include "Resource.h"
#include "Log.h"
#include "Visitor.h"
#include "RenderingManager.h"
#include <fstream>
#include <sstream>
#include <iostream>
#include <chrono>
#include <ctime>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/string_cast.hpp>
// Globals
ShadingProgram *ShadingProgram::currentProgram_ = nullptr;
ShadingProgram simpleShadingProgram("shaders/simple.vs", "shaders/simple.fs");
// Blending presets for matching with Shader::BlendMode
GLenum blending_equation[6] = { GL_FUNC_ADD, GL_FUNC_ADD, GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD, GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD};
GLenum blending_source_function[6] = { GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA,GL_SRC_ALPHA};
GLenum blending_destination_function[6] = {GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE, GL_DST_COLOR, GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA};
ShadingProgram::ShadingProgram(const std::string& vertex_file, const std::string& fragment_file) : vertex_id_(0), fragment_id_(0), id_(0)
{
vertex_file_ = vertex_file;
fragment_file_ = fragment_file;
}
void ShadingProgram::init()
{
vertex_code_ = Resource::getText(vertex_file_);
fragment_code_ = Resource::getText(fragment_file_);
compile();
link();
}
bool ShadingProgram::initialized()
{
return (id_ != 0);
}
void ShadingProgram::compile()
{
const char* vcode = vertex_code_.c_str();
vertex_id_ = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_id_, 1, &vcode, NULL);
glCompileShader(vertex_id_);
const char* fcode = fragment_code_.c_str();
fragment_id_ = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_id_, 1, &fcode, NULL);
glCompileShader(fragment_id_);
checkCompileErr();
}
void ShadingProgram::link()
{
id_ = glCreateProgram();
glAttachShader(id_, vertex_id_);
glAttachShader(id_, fragment_id_);
glLinkProgram(id_);
checkLinkingErr();
glUseProgram(id_);
glUniform1i(glGetUniformLocation(id_, "iChannel0"), 0);
glUniform1i(glGetUniformLocation(id_, "iChannel1"), 1);
glUseProgram(0);
glDeleteShader(vertex_id_);
glDeleteShader(fragment_id_);
}
void ShadingProgram::use()
{
if (currentProgram_ == nullptr || currentProgram_ != this)
{
currentProgram_ = this;
glUseProgram(id_);
}
}
void ShadingProgram::enduse()
{
glUseProgram(0);
currentProgram_ = nullptr ;
}
template<>
void ShadingProgram::setUniform<int>(const std::string& name, int val) {
glUniform1i(glGetUniformLocation(id_, name.c_str()), val);
}
template<>
void ShadingProgram::setUniform<bool>(const std::string& name, bool val) {
glUniform1i(glGetUniformLocation(id_, name.c_str()), val);
}
template<>
void ShadingProgram::setUniform<float>(const std::string& name, float val) {
glUniform1f(glGetUniformLocation(id_, name.c_str()), val);
}
template<>
void ShadingProgram::setUniform<float>(const std::string& name, float val1, float val2) {
glUniform2f(glGetUniformLocation(id_, name.c_str()), val1, val2);
}
template<>
void ShadingProgram::setUniform<float>(const std::string& name, float val1, float val2, float val3) {
glUniform3f(glGetUniformLocation(id_, name.c_str()), val1, val2, val3);
}
template<>
void ShadingProgram::setUniform<glm::vec4>(const std::string& name, glm::vec4 val) {
glm::vec4 v(val);
glUniform4fv(glGetUniformLocation(id_, name.c_str()), 1, glm::value_ptr(v));
}
template<>
void ShadingProgram::setUniform<glm::vec3>(const std::string& name, glm::vec3 val) {
glm::vec3 v(val);
glUniform4fv(glGetUniformLocation(id_, name.c_str()), 1, glm::value_ptr(v));
}
template<>
void ShadingProgram::setUniform<glm::mat4>(const std::string& name, glm::mat4 val) {
glm::mat4 m(val);
glUniformMatrix4fv(glGetUniformLocation(id_, name.c_str()), 1, GL_FALSE, glm::value_ptr(m));
}
// template<>
// void ShadingProgram::setUniform<float*>(const std::string& name, float* val) {
// glUniformMatrix4fv(glGetUniformLocation(id_, name.c_str()), 1, GL_FALSE, val);
// }
void ShadingProgram::checkCompileErr()
{
int success;
char infoLog[1024];
glGetShaderiv(vertex_id_, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertex_id_, 1024, NULL, infoLog);
Log::Warning("Error compiling Vertex ShadingProgram:\n%s", infoLog);
}
glGetShaderiv(fragment_id_, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragment_id_, 1024, NULL, infoLog);
Log::Warning("Error compiling Fragment ShadingProgram:\n%s", infoLog);
}
}
void ShadingProgram::checkLinkingErr()
{
int success;
char infoLog[1024];
glGetProgramiv(id_, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(id_, 1024, NULL, infoLog);
Log::Warning("Error linking ShadingProgram:\n%s", infoLog);
}
}
Shader::Shader() : blending(BLEND_OPACITY)
{
// create unique id
auto duration = std::chrono::high_resolution_clock::now().time_since_epoch();
id_ = std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count() % 100000000;
program_ = &simpleShadingProgram;
reset();
}
void Shader::operator = (const Shader &S )
{
color = S.color;
blending = S.blending;
}
void Shader::accept(Visitor& v) {
v.visit(*this);
}
void Shader::use()
{
// initialization on first use
if (!program_->initialized())
program_->init();
// Use program and set uniforms
program_->use();
// set uniforms
program_->setUniform("projection", projection);
program_->setUniform("modelview", modelview);
program_->setUniform("color", color);
iResolution = glm::vec3( Rendering::manager().currentAttrib().viewport, 0.f);
program_->setUniform("iResolution", iResolution);
// Blending Function
if ( blending != BLEND_CUSTOM) {
glEnable(GL_BLEND);
glBlendEquation(blending_equation[blending]);
glBlendFunc(blending_source_function[blending], blending_destination_function[blending]);
// glBlendEquationSeparate(blending_equation[blending], GL_FUNC_ADD);
// glBlendFuncSeparate(blending_source_function[blending], blending_destination_function[blending], GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else
glDisable(GL_BLEND);
}
void Shader::reset()
{
projection = glm::identity<glm::mat4>();
modelview = glm::identity<glm::mat4>();
iResolution = glm::vec3(1280.f, 720.f, 0.f);
color = glm::vec4(1.f, 1.f, 1.f, 1.f);
}

View File

@@ -1,75 +0,0 @@
#ifndef __SHADER_H_
#define __SHADER_H_
#include <string>
#include <vector>
#include <glm/glm.hpp>
// Forward declare classes referenced
class Visitor;
class ShadingProgram
{
public:
ShadingProgram(const std::string& vertex_file, const std::string& fragment_file);
void init();
bool initialized();
void use();
template<typename T> void setUniform(const std::string& name, T val);
template<typename T> void setUniform(const std::string& name, T val1, T val2);
template<typename T> void setUniform(const std::string& name, T val1, T val2, T val3);
static void enduse();
private:
void checkCompileErr();
void checkLinkingErr();
void compile();
void link();
unsigned int vertex_id_, fragment_id_, id_;
std::string vertex_code_;
std::string fragment_code_;
std::string vertex_file_;
std::string fragment_file_;
static ShadingProgram *currentProgram_;
};
class Shader
{
int id_;
public:
Shader();
// unique identifyer generated at instanciation
inline int id () const { return id_; }
virtual void use();
virtual void reset();
virtual void accept(Visitor& v);
void operator = (const Shader &D );
glm::mat4 projection;
glm::mat4 modelview;
glm::vec4 color;
typedef enum {
BLEND_OPACITY = 0,
BLEND_ADD,
BLEND_SUBSTRACT,
BLEND_LAYER_ADD,
BLEND_LAYER_SUBSTRACT,
BLEND_CUSTOM
} BlendMode;
BlendMode blending;
protected:
ShadingProgram *program_;
glm::vec3 iResolution;
};
#endif /* __SHADER_H_ */

View File

@@ -1,431 +0,0 @@
#include <algorithm>
#include <glm/gtc/matrix_transform.hpp>
#include "Source.h"
#include "defines.h"
#include "FrameBuffer.h"
#include "Primitives.h"
#include "Decorations.h"
#include "Mesh.h"
#include "Resource.h"
#include "Session.h"
#include "SearchVisitor.h"
#include "ImageShader.h"
#include "ImageProcessingShader.h"
#include "Log.h"
#include "Mixer.h"
Source::Source() : initialized_(false), active_(true), need_update_(true)
{
sprintf(initials_, "__");
name_ = "Source";
mode_ = Source::UNINITIALIZED;
// create groups and overlays for each view
// default rendering node
groups_[View::RENDERING] = new Group;
groups_[View::RENDERING]->visible_ = false;
// default mixing nodes
groups_[View::MIXING] = new Group;
groups_[View::MIXING]->visible_ = false;
groups_[View::MIXING]->scale_ = glm::vec3(0.15f, 0.15f, 1.f);
groups_[View::MIXING]->translation_ = glm::vec3(-1.f, 1.f, 0.f);
frames_[View::MIXING] = new Switch;
Frame *frame = new Frame(Frame::ROUND, Frame::THIN, Frame::DROP);
frame->translation_.z = 0.1;
frame->color = glm::vec4( COLOR_DEFAULT_SOURCE, 0.9f);
frames_[View::MIXING]->attach(frame);
frame = new Frame(Frame::ROUND, Frame::LARGE, Frame::DROP);
frame->translation_.z = 0.01;
frame->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
frames_[View::MIXING]->attach(frame);
groups_[View::MIXING]->attach(frames_[View::MIXING]);
overlays_[View::MIXING] = new Group;
overlays_[View::MIXING]->translation_.z = 0.1;
overlays_[View::MIXING]->visible_ = false;
Symbol *center = new Symbol(Symbol::POINT, glm::vec3(0.f, 0.f, 0.1f));
overlays_[View::MIXING]->attach(center);
groups_[View::MIXING]->attach(overlays_[View::MIXING]);
// default geometry nodes
groups_[View::GEOMETRY] = new Group;
groups_[View::GEOMETRY]->visible_ = false;
frames_[View::GEOMETRY] = new Switch;
frame = new Frame(Frame::SHARP, Frame::THIN, Frame::NONE);
frame->translation_.z = 0.1;
frame->color = glm::vec4( COLOR_DEFAULT_SOURCE, 0.7f);
frames_[View::GEOMETRY]->attach(frame);
frame = new Frame(Frame::SHARP, Frame::LARGE, Frame::GLOW);
frame->translation_.z = 0.1;
frame->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
frames_[View::GEOMETRY]->attach(frame);
groups_[View::GEOMETRY]->attach(frames_[View::GEOMETRY]);
overlays_[View::GEOMETRY] = new Group;
overlays_[View::GEOMETRY]->translation_.z = 0.15;
overlays_[View::GEOMETRY]->visible_ = false;
handle_[Handles::RESIZE] = new Handles(Handles::RESIZE);
handle_[Handles::RESIZE]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
handle_[Handles::RESIZE]->translation_.z = 0.1;
overlays_[View::GEOMETRY]->attach(handle_[Handles::RESIZE]);
handle_[Handles::RESIZE_H] = new Handles(Handles::RESIZE_H);
handle_[Handles::RESIZE_H]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
handle_[Handles::RESIZE_H]->translation_.z = 0.1;
overlays_[View::GEOMETRY]->attach(handle_[Handles::RESIZE_H]);
handle_[Handles::RESIZE_V] = new Handles(Handles::RESIZE_V);
handle_[Handles::RESIZE_V]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
handle_[Handles::RESIZE_V]->translation_.z = 0.1;
overlays_[View::GEOMETRY]->attach(handle_[Handles::RESIZE_V]);
handle_[Handles::ROTATE] = new Handles(Handles::ROTATE);
handle_[Handles::ROTATE]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
handle_[Handles::ROTATE]->translation_.z = 0.1;
overlays_[View::GEOMETRY]->attach(handle_[Handles::ROTATE]);
frame = new Frame(Frame::SHARP, Frame::THIN, Frame::NONE);
frame->translation_.z = 0.1;
frame->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 0.7f);
overlays_[View::GEOMETRY]->attach(frame);
groups_[View::GEOMETRY]->attach(overlays_[View::GEOMETRY]);
// default layer nodes
groups_[View::LAYER] = new Group;
groups_[View::LAYER]->visible_ = false;
frames_[View::LAYER] = new Switch;
frame = new Frame(Frame::ROUND, Frame::THIN, Frame::PERSPECTIVE);
frame->translation_.z = 0.1;
frame->color = glm::vec4( COLOR_DEFAULT_SOURCE, 0.8f);
frames_[View::LAYER]->attach(frame);
frame = new Frame(Frame::ROUND, Frame::LARGE, Frame::PERSPECTIVE);
frame->translation_.z = 0.1;
frame->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
frames_[View::LAYER]->attach(frame);
groups_[View::LAYER]->attach(frames_[View::LAYER]);
overlays_[View::LAYER] = new Group;
overlays_[View::LAYER]->translation_.z = 0.15;
overlays_[View::LAYER]->visible_ = false;
groups_[View::LAYER]->attach(overlays_[View::LAYER]);
// empty transition node
groups_[View::TRANSITION] = new Group;
// create objects
stored_status_ = new Group;
// those will be associated to nodes later
blendingshader_ = new ImageShader;
rendershader_ = new ImageProcessingShader;
renderbuffer_ = nullptr;
rendersurface_ = nullptr;
}
Source::~Source()
{
// delete objects
delete stored_status_;
if (renderbuffer_)
delete renderbuffer_;
// all groups and their children are deleted in the scene
// this includes rendersurface_, overlays, blendingshader_ and rendershader_
delete groups_[View::RENDERING];
delete groups_[View::MIXING];
delete groups_[View::GEOMETRY];
delete groups_[View::LAYER];
delete groups_[View::TRANSITION];
groups_.clear();
frames_.clear();
overlays_.clear();
// inform clones that they lost their origin
for (auto it = clones_.begin(); it != clones_.end(); it++)
(*it)->origin_ = nullptr;
}
void Source::setName (const std::string &name)
{
name_ = name;
initials_[0] = std::toupper( name_.front() );
initials_[1] = std::toupper( name_.back() );
}
void Source::accept(Visitor& v)
{
v.visit(*this);
}
Source::Mode Source::mode() const
{
return mode_;
}
void Source::setMode(Source::Mode m)
{
// make visible on first time
if ( mode_ == Source::UNINITIALIZED ) {
for (auto g = groups_.begin(); g != groups_.end(); g++)
(*g).second->visible_ = true;
}
// choose frame if selected
uint index_frame = m == Source::VISIBLE ? 0 : 1;
for (auto f = frames_.begin(); f != frames_.end(); f++)
(*f).second->setActive(index_frame);
// show overlay if current
bool current = m == Source::CURRENT;
for (auto o = overlays_.begin(); o != overlays_.end(); o++)
(*o).second->visible_ = current;
mode_ = m;
}
void Source::attach(FrameBuffer *renderbuffer)
{
renderbuffer_ = renderbuffer;
// create the surfaces to draw the frame buffer in the views
rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_);
groups_[View::RENDERING]->attach(rendersurface_);
groups_[View::GEOMETRY]->attach(rendersurface_);
groups_[View::MIXING]->attach(rendersurface_);
// groups_[View::LAYER]->attach(rendersurface_);
// for mixing and layer views, add another surface to overlay
// (stippled view on top with transparency)
Surface *surfacemix = new FrameBufferSurface(renderbuffer_);
ImageShader *is = static_cast<ImageShader *>(surfacemix->shader());
if (is) is->stipple = 1.0;
groups_[View::MIXING]->attach(surfacemix);
groups_[View::LAYER]->attach(surfacemix);
// scale all icon nodes to match aspect ratio of the media
NodeSet::iterator node;
for (node = groups_[View::MIXING]->begin();
node != groups_[View::MIXING]->end(); node++) {
(*node)->scale_.x = renderbuffer_->aspectRatio();
}
for (node = groups_[View::GEOMETRY]->begin();
node != groups_[View::GEOMETRY]->end(); node++) {
(*node)->scale_.x = renderbuffer_->aspectRatio();
}
for (node = groups_[View::LAYER]->begin();
node != groups_[View::LAYER]->end(); node++) {
(*node)->scale_.x = renderbuffer_->aspectRatio();
}
// Transition group node is optionnal
if ( groups_[View::TRANSITION]->numChildren() > 0 ) {
groups_[View::TRANSITION]->attach(rendersurface_);
groups_[View::TRANSITION]->attach(surfacemix);
for (NodeSet::iterator node = groups_[View::TRANSITION]->begin();
node != groups_[View::TRANSITION]->end(); node++) {
(*node)->scale_.x = renderbuffer_->aspectRatio();
}
}
// make the source visible
if ( mode_ == UNINITIALIZED )
setMode(VISIBLE);
}
void Source::setActive (bool on)
{
active_ = on;
for(auto clone = clones_.begin(); clone != clones_.end(); clone++) {
if ( (*clone)->active() )
active_ = true;
}
groups_[View::RENDERING]->visible_ = active_;
groups_[View::GEOMETRY]->visible_ = active_;
groups_[View::LAYER]->visible_ = active_;
}
void Source::update(float dt)
{
// keep delta-t
dt_ = dt;
// update nodes if needed
if (need_update_)
{
// ADJUST alpha based on MIXING node
// read position of the mixing node and interpret this as transparency of render output
glm::vec2 dist = glm::vec2(groups_[View::MIXING]->translation_);
float alpha = 1.0 - CLAMP( ( dist.x * dist.x ) + ( dist.y * dist.y ), 0.f, 1.f );
blendingshader_->color.a = alpha;
// CHANGE update status based on limbo
setActive( glm::length(dist) < 1.3f );
// MODIFY geometry based on GEOMETRY node
groups_[View::RENDERING]->translation_ = groups_[View::GEOMETRY]->translation_;
groups_[View::RENDERING]->rotation_ = groups_[View::GEOMETRY]->rotation_;
// avoid any null scale
glm::vec3 s = groups_[View::GEOMETRY]->scale_;
s.x = CLAMP_SCALE(s.x);
s.y = CLAMP_SCALE(s.y);
s.z = 1.f;
groups_[View::GEOMETRY]->scale_ = s;
groups_[View::RENDERING]->scale_ = s;
// MODIFY depth based on LAYER node
groups_[View::MIXING]->translation_.z = groups_[View::LAYER]->translation_.z;
groups_[View::GEOMETRY]->translation_.z = groups_[View::LAYER]->translation_.z;
groups_[View::RENDERING]->translation_.z = groups_[View::LAYER]->translation_.z;
need_update_ = false;
}
}
FrameBuffer *Source::frame() const
{
if (initialized_ && renderbuffer_)
{
return renderbuffer_;
}
else {
static FrameBuffer *black = new FrameBuffer(640,480);
return black;
}
}
bool Source::contains(Node *node) const
{
if ( node == nullptr )
return false;
hasNode tester(node);
return tester(this);
}
bool Source::hasNode::operator()(const Source* elem) const
{
if (_n && elem)
{
// quick case (most frequent and easy to answer)
if (elem->rendersurface_ == _n)
return true;
// general case: traverse tree of all Groups recursively using a SearchVisitor
SearchVisitor sv(_n);
for (auto g = elem->groups_.begin(); g != elem->groups_.end(); g++) {
(*g).second->accept(sv);
if (sv.found())
return true;
}
}
return false;
}
CloneSource *Source::clone()
{
CloneSource *s = new CloneSource(this);
clones_.push_back(s);
return s;
}
CloneSource::CloneSource(Source *origin) : Source(), origin_(origin)
{
// create surface:
clonesurface_ = new Surface(rendershader_);
}
CloneSource::~CloneSource()
{
// delete surface
delete clonesurface_;
}
CloneSource *CloneSource::clone()
{
// do not clone a clone : clone the original instead
if (origin_)
return origin_->clone();
else
return nullptr;
}
void CloneSource::init()
{
if (origin_ && origin_->ready()) {
// get the texture index from framebuffer of view, apply it to the surface
clonesurface_->setTextureIndex( origin_->texture() );
// create Frame buffer matching size of session
FrameBuffer *renderbuffer = new FrameBuffer( origin_->frame()->resolution(), true);
// set the renderbuffer of the source and attach rendering nodes
attach(renderbuffer);
// icon in mixing view
overlays_[View::MIXING]->attach( new Symbol(Symbol::CLONE, glm::vec3(0.8f, 0.8f, 0.01f)) );
overlays_[View::LAYER]->attach( new Symbol(Symbol::CLONE, glm::vec3(0.8f, 0.8f, 0.01f)) );
// done init
initialized_ = true;
Log::Info("Source Clone linked to source %s).", origin_->name().c_str() );
}
}
void CloneSource::setActive (bool on)
{
active_ = on;
groups_[View::RENDERING]->visible_ = active_;
groups_[View::GEOMETRY]->visible_ = active_;
groups_[View::LAYER]->visible_ = active_;
if (origin_)
origin_->touch();
}
uint CloneSource::texture() const
{
if (origin_)
return origin_->texture();
else
return Resource::getTextureBlack();
}
void CloneSource::render()
{
if (!initialized_)
init();
else {
// render the view into frame buffer
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
renderbuffer_->begin();
clonesurface_->draw(glm::identity<glm::mat4>(), projection);
renderbuffer_->end();
}
}
void CloneSource::accept(Visitor& v)
{
Source::accept(v);
v.visit(*this);
}

192
Source.h
View File

@@ -1,192 +0,0 @@
#ifndef SOURCE_H
#define SOURCE_H
#include <string>
#include <map>
#include <list>
#include "View.h"
#include "Decorations.h"
class ImageShader;
class ImageProcessingShader;
class FrameBuffer;
class FrameBufferSurface;
class MediaPlayer;
class Surface;
class Session;
class Frame;
class Source;
class CloneSource;
typedef std::list<Source *> SourceList;
typedef std::list<CloneSource *> CloneList;
class Source
{
friend class View;
friend class MixingView;
friend class GeometryView;
friend class LayerView;
friend class TransitionView;
public:
// create a source and add it to the list
// only subclasses of sources can actually be instanciated
Source();
virtual ~Source();
// manipulate name of source
void setName (const std::string &name);
inline std::string name () const { return name_; }
inline const char *initials () const { return initials_; }
// cloning mechanism
virtual CloneSource *clone ();
inline size_t numClones() const { return clones_.size(); }
// Display mode
typedef enum {
UNINITIALIZED = 0,
VISIBLE = 1,
SELECTED = 2,
CURRENT = 3
} Mode;
Mode mode () const;
void setMode (Mode m);
// get handle on the nodes used to manipulate the source in a view
inline Group *group (View::Mode m) const { return groups_.at(m); }
inline Node *groupNode (View::Mode m) const { return static_cast<Node*>(groups_.at(m)); }
// tests if a given node is part of the source
bool contains (Node *node) const;
// a Source has a shader to control image processing effects
inline ImageProcessingShader *processingShader () const { return rendershader_; }
// a Source has a shader to control mixing effects
inline ImageShader *blendingShader () const { return blendingshader_; }
// every Source has a frame buffer from the renderbuffer
virtual FrameBuffer *frame () const;
// touch to request update
inline void touch () { need_update_ = true; }
// informs if its ready (i.e. initialized)
inline bool ready() const { return initialized_; }
// a Source shall be updated before displayed (Mixing, Geometry and Layer)
virtual void update (float dt);
// update mode
virtual void setActive (bool on);
inline bool active () { return active_; }
// a Source shall informs if the source failed (i.e. shall be deleted)
virtual bool failed() const = 0;
// a Source shall define a way to get a texture
virtual uint texture() const = 0;
// a Source shall define how to render into the frame buffer
virtual void render() = 0;
// accept all kind of visitors
virtual void accept (Visitor& v);
struct hasNode: public std::unary_function<Source*, bool>
{
bool operator()(const Source* elem) const;
hasNode(Node *n) : _n(n) { }
private:
Node *_n;
};
struct hasName: public std::unary_function<Source*, bool>
{
inline bool operator()(const Source* elem) const {
return (elem && elem->name() == _n);
}
hasName(std::string n) : _n(n) { }
private:
std::string _n;
};
protected:
// name
std::string name_;
char initials_[3];
// every Source shall be initialized on first draw
bool initialized_;
virtual void init() = 0;
// nodes
std::map<View::Mode, Group*> groups_;
// render() fills in the renderbuffer at every frame
// NB: rendershader_ is applied at render()
FrameBuffer *renderbuffer_;
void attach(FrameBuffer *renderbuffer);
// the rendersurface draws the renderbuffer in the scene
// It is associated to the rendershader for mixing effects
FrameBufferSurface *rendersurface_;
// rendershader performs image processing
ImageProcessingShader *rendershader_;
// blendingshader provides mixing controls
ImageShader *blendingshader_;
// mode for display
Mode mode_;
// overlays and frames to be displayed on top of source
std::map<View::Mode, Group*> overlays_;
std::map<View::Mode, Switch*> frames_;
Handles *handle_[4];
// update
bool active_;
bool need_update_;
float dt_;
Group *stored_status_;
// clones
CloneList clones_;
};
class CloneSource : public Source
{
friend class Source;
public:
~CloneSource();
// implementation of source API
void setActive (bool on) override;
void render() override;
uint texture() const override;
bool failed() const override { return origin_ == nullptr; }
void accept (Visitor& v) override;
CloneSource *clone() override;
inline Source *origin() const { return origin_; }
protected:
// only Source class can create new CloneSource via clone();
CloneSource(Source *origin);
void init() override;
Surface *clonesurface_;
Source *origin_;
};
#endif // SOURCE_H

View File

@@ -1,286 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <ctime>
#include <chrono>
using namespace std;
#ifdef WIN32
#include <windows.h>
#define mkdir(dir, mode) _mkdir(dir)
#include <include/dirent.h>
#include <sys/resource.h>
#define PATH_SEP '\\'
#define PATH_SETTINGS "\\\AppData\\Roaming\\"
#elif defined(LINUX) or defined(APPLE)
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <dirent.h>
#define PATH_SEP '/'
#endif
#if defined(APPLE)
#define PATH_SETTINGS "/Library/Application Support/"
#include <mach/task.h>
#include <mach/mach_init.h>
#elif defined(LINUX)
#include <sys/sysinfo.h>
#define PATH_SETTINGS "/.config/"
#endif
#include "defines.h"
#include "SystemToolkit.h"
/// The amount of memory currently being used by this process, in bytes.
/// it will try to report the resident set in RAM
long SystemToolkit::memory_usage()
{
#if defined(LINUX)
// Grabbing info directly from the /proc pseudo-filesystem. Reading from
// /proc/self/statm gives info on your own process, as one line of
// numbers that are: virtual mem program size, resident set size,
// shared pages, text/code, data/stack, library, dirty pages. The
// mem sizes should all be multiplied by the page size.
size_t size = 0;
FILE *file = fopen("/proc/self/statm", "r");
if (file) {
unsigned long m = 0;
fscanf (file, "%lu", &m); // virtual mem program size,
fscanf (file, "%lu", &m); // resident set size,
fclose (file);
size = (size_t)m * getpagesize();
}
return (long)size;
#elif defined(APPLE)
// Inspired from
// http://miknight.blogspot.com/2005/11/resident-set-size-in-mac-os-x.html
struct task_basic_info t_info;
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
task_info(current_task(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count);
return t_info.resident_size;
#elif defined(WIN32)
// According to MSDN...
PROCESS_MEMORY_COUNTERS counters;
if (GetProcessMemoryInfo (GetCurrentProcess(), &counters, sizeof (counters)))
return counters.PagefileUsage;
else return 0;
#else
return 0;
#endif
}
long SystemToolkit::memory_max_usage() {
struct rusage r_usage;
getrusage(RUSAGE_SELF,&r_usage);
return r_usage.ru_maxrss;
// return r_usage.ru_isrss;
}
string SystemToolkit::byte_to_string(long b)
{
double numbytes = static_cast<double>(b);
ostringstream oss;
std::list<std::string> list = {" Bytes", " KB", " MB", " GB", " TB"};
std::list<std::string>::iterator i = list.begin();
while(numbytes >= 1024.0 && i != list.end())
{
i++;
numbytes /= 1024.0;
}
oss << std::fixed << std::setprecision(2) << numbytes << *i;
return oss.str();
}
string SystemToolkit::date_time_string()
{
chrono::system_clock::time_point now = chrono::system_clock::now();
time_t t = chrono::system_clock::to_time_t(now);
tm* datetime = localtime(&t);
auto duration = now.time_since_epoch();
auto millis = chrono::duration_cast<chrono::milliseconds>(duration).count() % 1000;
ostringstream oss;
oss << setw(4) << setfill('0') << to_string(datetime->tm_year + 1900);
oss << setw(2) << setfill('0') << to_string(datetime->tm_mon + 1);
oss << setw(2) << setfill('0') << to_string(datetime->tm_mday );
oss << setw(2) << setfill('0') << to_string(datetime->tm_hour );
oss << setw(2) << setfill('0') << to_string(datetime->tm_min );
oss << setw(2) << setfill('0') << to_string(datetime->tm_sec );
oss << setw(3) << setfill('0') << to_string(millis);
// fixed length string (17 chars) YYYYMMDDHHmmssiii
return oss.str();
}
string SystemToolkit::filename(const string& path)
{
return path.substr(path.find_last_of(PATH_SEP) + 1);
}
string SystemToolkit::base_filename(const string& path)
{
string basefilename = SystemToolkit::filename(path);
const size_t period_idx = basefilename.rfind('.');
if (string::npos != period_idx)
{
basefilename.erase(period_idx);
}
return basefilename;
}
string SystemToolkit::path_filename(const string& path)
{
return path.substr(0, path.find_last_of(PATH_SEP) + 1);
}
string SystemToolkit::trunc_filename(const string& path, int lenght)
{
string trunc = path;
int l = path.size();
if ( l > lenght ) {
trunc = string("...") + path.substr( l - lenght + 3 );
}
return trunc;
}
string SystemToolkit::extension_filename(const string& filename)
{
string ext = filename.substr(filename.find_last_of(".") + 1);
return ext;
}
std::string SystemToolkit::home_path()
{
// 1. find home
char *mHomePath;
// try the system user info
struct passwd* pwd = getpwuid(getuid());
if (pwd)
mHomePath = pwd->pw_dir;
else
// try the $HOME environment variable
mHomePath = getenv("HOME");
return string(mHomePath) + PATH_SEP;
}
std::string SystemToolkit::username()
{
// 1. find home
char *user;
// try the system user info
struct passwd* pwd = getpwuid(getuid());
if (pwd)
user = pwd->pw_name;
else
// try the $USER environment variable
user = getenv("USER");
return string(user);
}
bool create_directory(const string& path)
{
return !mkdir(path.c_str(), 0755) || errno == EEXIST;
// TODO : verify WIN32 implementation
}
string SystemToolkit::settings_path()
{
string home(home_path());
// 2. try to access user settings folder
string settingspath = home + PATH_SETTINGS;
if (SystemToolkit::file_exists(settingspath)) {
// good, we have a place to put the settings file
// settings should be in 'vmix' subfolder
settingspath += APP_NAME;
// 3. create the vmix subfolder in settings folder if not existing already
if ( !SystemToolkit::file_exists(settingspath)) {
if ( !create_directory(settingspath) )
// fallback to home if settings path cannot be created
settingspath = home;
}
return settingspath;
}
else {
// fallback to home if settings path does not exists
return home;
}
}
string SystemToolkit::full_filename(const std::string& path, const string &filename)
{
string fullfilename = path;
fullfilename += PATH_SEP;
fullfilename += filename;
return fullfilename;
}
bool SystemToolkit::file_exists(const string& path)
{
if (path.empty())
return false;
return access(path.c_str(), R_OK) == 0;
// TODO : WIN32 implementation
}
list<string> SystemToolkit::list_directory(const string& path, const string& filter)
{
list<string> ls;
DIR *dir;
struct dirent *ent;
if ((dir = opendir (path.c_str())) != NULL) {
// list all the files and directories within directory
while ((ent = readdir (dir)) != NULL) {
if ( ent->d_type == DT_REG)
{
string filename = string(ent->d_name);
if ( extension_filename(filename) == filter)
ls.push_back( full_filename(path, filename) );
}
}
closedir (dir);
}
return ls;
}
void SystemToolkit::open(const string& url)
{
#ifdef WIN32
ShellExecuteA( nullptr, nullptr, url.c_str(), nullptr, nullptr, 0 );
#elif defined APPLE
char buf[2048];
sprintf( buf, "open '%s'", url.c_str() );
system( buf );
#else
char buf[2048];
sprintf( buf, "xdg-open '%s'", url.c_str() );
int r = system( buf );
#endif
}

View File

@@ -1,62 +0,0 @@
#ifndef SYSTEMTOOLKIT_H
#define SYSTEMTOOLKIT_H
#ifdef WIN32
#define PATH_SEP '\\'
#elif defined(LINUX) or defined(APPLE)
#define PATH_SEP '/'
#endif
#include <string>
#include <list>
namespace SystemToolkit
{
// get fixed length string (17 chars) YYYYMMDDHHmmssiii
std::string date_time_string();
// get the OS dependent username
std::string username();
// get the OS dependent home path
std::string home_path();
// get the OS dependent path where to store settings
std::string settings_path();
// builds the OS dependent complete file name
std::string full_filename(const std::string& path, const std::string& filename);
// extract the filename from a full path / URI (e.g. file:://home/me/toto.mpg -> toto.mpg)
std::string filename(const std::string& path);
// extract the base filename from a full path / URI (e.g. file:://home/me/toto.mpg -> toto)
std::string base_filename(const std::string& path);
// extract the path of a filename from a full URI (e.g. file:://home/me/toto.mpg -> file:://home/me/)
std::string path_filename(const std::string& path);
// Truncate a full filename to display the right part (e.g. file:://home/me/toto.mpg -> ...ome/me/toto.mpg)
std::string trunc_filename(const std::string& path, int lenght);
// extract the extension of a filename
std::string extension_filename(const std::string& filename);
// list all files of a directory mathing the given filter extension (if any)
std::list<std::string> list_directory(const std::string& path, const std::string& filter = "");
// true of file exists
bool file_exists(const std::string& path);
// try to open the file with system
void open(const std::string& path);
// return memory resident set size used (in bytes)
long memory_usage();
long memory_max_usage();
// get a string to display memory size with unit KB, MB, GB, TB
std::string byte_to_string(long b);
}
#endif // SYSTEMTOOLKIT_H

View File

@@ -1,87 +0,0 @@
#include "UpdateCallback.h"
#include "defines.h"
#include "Scene.h"
#include "Log.h"
#include <glm/gtc/type_ptr.hpp>
UpdateCallback::UpdateCallback() : enabled_(true), finished_(false)
{
}
MoveToCallback::MoveToCallback(glm::vec3 target, float duration) : UpdateCallback(),
target_(target), duration_(duration), progress_(0.f), initialized_(false)
{
}
void MoveToCallback::update(Node *n, float dt)
{
// set start position on first run or upon call of reset()
if (!initialized_){
startingpoint_ = n->translation_;
target_.z = startingpoint_.z; // ignore depth
initialized_ = true;
}
// calculate amplitude of movement
progress_ += dt / duration_;
// perform movement
n->translation_ = startingpoint_ + progress_ * (target_ - startingpoint_);
// end of movement
if ( progress_ > 1.f ) {
n->translation_ = target_;
finished_ = true;
}
}
BounceScaleCallback::BounceScaleCallback(float duration) : UpdateCallback(),
duration_(duration), progress_(0.f), initialized_(false)
{
}
void BounceScaleCallback::update(Node *n, float dt)
{
// set start scale on first run or upon call of reset()
if (!initialized_){
initial_scale_ = n->scale_;
initialized_ = true;
}
// calculate amplitude of movement
progress_ += dt / duration_;
n->scale_.x = initial_scale_.x + (initial_scale_.x * 0.05f) * sin(M_PI * progress_);
n->scale_.y = initial_scale_.y + (initial_scale_.y * 0.05f) * sin(M_PI * progress_);
// end of movement
if ( progress_ > 1.f) {
n->scale_ = initial_scale_;
finished_ = true;
}
}
InfiniteGlowCallback::InfiniteGlowCallback(float amplitude) : UpdateCallback(),
amplitude_(amplitude), time_(0.f), initialized_(false)
{
}
void InfiniteGlowCallback::update(Node *n, float dt)
{
// set start scale on first run
if (!initialized_){
initial_scale_ = n->scale_;
initialized_ = true;
}
time_ += dt / 600.f;
n->scale_.x = initial_scale_.x + amplitude_ * sin(M_PI * time_);
n->scale_.y = initial_scale_.y + amplitude_ * sin(M_PI * time_);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,172 +0,0 @@
#ifndef __UI_MANAGER_H_
#define __UI_MANAGER_H_
#include <string>
#include <list>
using namespace std;
#define NAV_COUNT 68
#define NAV_MAX 64
#define NAV_NEW 65
#define NAV_MENU 66
#define NAV_TRANS 67
struct ImVec2;
class Source;
class MediaPlayer;
class SourcePreview {
Source *source_;
std::string label_;
public:
SourcePreview();
void setSource(Source *s = nullptr, std::string label = "");
Source *getSource();
void Render(float width, bool controlbutton = false);
inline bool ready() const { return source_ != nullptr; }
};
class Navigator
{
// geometry left bar & pannel
float width_;
float height_;
float pannel_width_;
float sourcelist_height_;
float padding_width_;
// behavior pannel
bool pannel_visible_;
bool selected_button[NAV_COUNT];
void clearButtonSelection();
void applyButtonSelection(int index);
// side pannels
void RenderSourcePannel(Source *s);
void RenderMainPannel();
void RenderTransitionPannel();
void RenderNewPannel();
int new_source_type_;
char file_browser_path_[2048];
SourcePreview new_source_preview_;
public:
Navigator();
bool pannelVisible() { return pannel_visible_; }
void hidePannel();
void showPannelSource(int index);
void togglePannelMenu();
void togglePannelNew();
void Render();
};
class ToolBox
{
bool show_demo_window;
bool show_icons_window;
public:
ToolBox();
void Render();
};
class MediaController
{
MediaPlayer *mp_;
std::string current_;
bool follow_active_source_;
bool media_playing_mode_;
bool slider_pressed_;
public:
MediaController();
void setMediaPlayer(MediaPlayer *mp = nullptr);
void followCurrentSource();
void Render();
};
class UserInterface
{
friend class Navigator;
Navigator navigator;
ToolBox toolbox;
MediaController mediacontrol;
bool keyboard_modifier_active;
bool show_about;
bool show_imgui_about;
bool show_gst_about;
bool show_opengl_about;
unsigned int screenshot_step;
// typedef enum {
// FILE_DIALOG_INACTIVE = 0,
// FILE_DIALOG_ACTIVE,
// FILE_DIALOG_FINISHED
// } FileDialogStatus;
// FileDialogStatus filestatus_;
// std::string filename_;
// void startOpenFileDialog();
// Private Constructor
UserInterface();
UserInterface(UserInterface const& copy); // Not Implemented
UserInterface& operator=(UserInterface const& copy); // Not Implemented
public:
static UserInterface& manager()
{
// The only instance
static UserInterface _instance;
return _instance;
}
// pre-loop initialization
bool Init();
// loop update start new frame
void NewFrame();
// loop update rendering
void Render();
// Post-loop termination
void Terminate();
// status querries
inline bool keyboardModifier() { return keyboard_modifier_active; }
void StartScreenshot();
void showPannel(int id = 0);
void showMediaPlayer(MediaPlayer *mp);
// TODO implement the shader editor
std::string currentTextEdit;
void fillShaderEditor(std::string text);
protected:
void showMenuFile();
void showMenuOptions();
void RenderPreview();
void RenderShaderEditor();
void handleKeyboard();
void handleMouse();
void handleScreenshot();
};
#endif /* #define __UI_MANAGER_H_ */

1129
View.cpp

File diff suppressed because it is too large Load Diff

186
View.h
View File

@@ -1,186 +0,0 @@
#ifndef VIEW_H
#define VIEW_H
#include <glm/glm.hpp>
#include "Scene.h"
#include "FrameBuffer.h"
class Source;
class SessionSource;
class Surface;
class View
{
public:
typedef enum {RENDERING = 0, MIXING=1, GEOMETRY=2, LAYER=3, TRANSITION=4, INVALID=5 } Mode;
View(Mode m);
virtual ~View() {}
inline Mode mode() const { return mode_; }
virtual void update (float dt);
virtual void draw ();
virtual void zoom (float) {}
virtual void centerSource(Source *) {}
typedef enum {
Cursor_Arrow = 0,
Cursor_TextInput,
Cursor_ResizeAll,
Cursor_ResizeNS,
Cursor_ResizeEW,
Cursor_ResizeNESW,
Cursor_ResizeNWSE,
Cursor_Hand,
Cursor_NotAllowed
} CursorType;
typedef struct Cursor {
CursorType type;
std::string info;
Cursor() { type = Cursor_Arrow; info = "";}
Cursor(CursorType t, std::string i = "") { type = t; info = i;}
} Cursor;
// picking of nodes in a view provided a point coordinates in screen coordinates
virtual std::pair<Node *, glm::vec2> pick(glm::vec2);
// select sources provided a start and end selection points in screen coordinates
virtual void select(glm::vec2, glm::vec2);
virtual void selectAll();
// drag the view provided a start and an end point in screen coordinates
virtual Cursor drag (glm::vec2, glm::vec2);
// grab a source provided a start and an end point in screen coordinates and the picking point
virtual Cursor grab (Source*, glm::vec2, glm::vec2, std::pair<Node *, glm::vec2>) {
return Cursor();
}
// test mouse over provided a point in screen coordinates and the picking point
virtual Cursor over (Source*, glm::vec2, std::pair<Node *, glm::vec2>) {
return Cursor();
}
virtual void initiate();
virtual void recenter();
// accessible scene
Scene scene;
// reordering scene when necessary
static bool need_deep_update_;
protected:
virtual void restoreSettings();
virtual void saveSettings();
Mode mode_;
};
class MixingView : public View
{
public:
MixingView();
void zoom (float factor) override;
void centerSource(Source *) override;
void selectAll() override;
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2>) override;
Cursor drag (glm::vec2, glm::vec2) override;
void setAlpha (Source *s);
inline float limboScale() { return limbo_scale_; }
private:
uint textureMixingQuadratic();
float limbo_scale_;
};
class RenderView : public View
{
FrameBuffer *frame_buffer_;
Surface *fading_overlay_;
public:
RenderView ();
~RenderView ();
void draw () override;
void setResolution (glm::vec3 resolution = glm::vec3(0.f));
glm::vec3 resolution() const { return frame_buffer_->resolution(); }
void setFading(float f = 0.f);
float fading() const;
inline FrameBuffer *frame () const { return frame_buffer_; }
};
class GeometryView : public View
{
public:
GeometryView();
void draw () override;
void update (float dt) override;
void zoom (float factor) override;
std::pair<Node *, glm::vec2> pick(glm::vec2 P) override;
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
Cursor over (Source *s, glm::vec2 pos, std::pair<Node *, glm::vec2> pick) override;
Cursor drag (glm::vec2, glm::vec2) override;
// void select(glm::vec2, glm::vec2) override;
// class Box *selection_box_;
};
class LayerView : public View
{
public:
LayerView();
void update (float dt) override;
void zoom (float factor) override;
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
Cursor drag (glm::vec2, glm::vec2) override;
float setDepth (Source *, float d = -1.f);
private:
float aspect_ratio;
};
class TransitionView : public View
{
public:
TransitionView();
void attach(SessionSource *ts);
class Session *detach();
void play(bool open);
void draw () override;
void update (float dt) override;
void zoom (float factor) override;
std::pair<Node *, glm::vec2> pick(glm::vec2 P) override;
void selectAll() override;
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
Cursor drag (glm::vec2, glm::vec2) override;
private:
class Surface *output_surface_;
class Mesh *mark_100ms_, *mark_1s_;
Switch *gradient_;
SessionSource *transition_source_;
};
#endif // VIEW_H

View File

@@ -1,69 +0,0 @@
#ifndef VISITOR_H
#define VISITOR_H
#include <string>
// Forward declare different kind of Node
class Node;
class Group;
class Switch;
class Primitive;
class Scene;
class Surface;
class ImageSurface;
class MediaSurface;
class FrameBufferSurface;
class LineStrip;
class LineSquare;
class LineCircle;
class Mesh;
class Frame;
class Handles;
class MediaPlayer;
class Shader;
class ImageShader;
class ImageProcessingShader;
class Source;
class MediaSource;
class SessionSource;
class RenderSource;
class CloneSource;
// Declares the interface for the visitors
class Visitor {
public:
// Need to declare overloads for basic kind of Nodes to visit
virtual void visit (Scene&) = 0;
virtual void visit (Node&) = 0;
virtual void visit (Primitive&) = 0;
virtual void visit (Group&) = 0;
virtual void visit (Switch&) = 0;
// not mandatory for all others
virtual void visit (Surface&) {}
virtual void visit (ImageSurface&) {}
virtual void visit (MediaSurface&) {}
virtual void visit (FrameBufferSurface&) {}
virtual void visit (LineStrip&) {}
virtual void visit (LineSquare&) {}
virtual void visit (LineCircle&) {}
virtual void visit (Mesh&) {}
virtual void visit (Frame&) {}
virtual void visit (Handles&) {}
virtual void visit (MediaPlayer&) {}
virtual void visit (Shader&) {}
virtual void visit (ImageShader&) {}
virtual void visit (ImageProcessingShader&) {}
// utility
virtual void visit (Source&) {}
virtual void visit (MediaSource&) {}
virtual void visit (SessionSource&) {}
virtual void visit (RenderSource&) {}
virtual void visit (CloneSource&) {}
};
#endif // VISITOR_H

1
_config.yml Normal file
View File

@@ -0,0 +1 @@
theme: jekyll-theme-midnight

View File

@@ -0,0 +1,41 @@
set(BUNDLE_NAME @BUNDLE_NAME@)
set(BUNDLE_LIBS_DIR @BUNDLE_LIBS_DIR@)
set(BUNDLE_DIRS @BUNDLE_DIRS@)
set(APPLE_CODESIGN_IDENTITY @APPLE_CODESIGN_IDENTITY@)
set(APPLE_CODESIGN_ENTITLEMENTS @APPLE_CODESIGN_ENTITLEMENTS@)
set(BUNDLE_PATH "${CMAKE_INSTALL_PREFIX}/${BUNDLE_NAME}")
include(BundleUtilities)
#fixup_bundle tries to copy system libraries without this. Wtf?
function(gp_resolved_file_type_override file type)
if(file MATCHES "^(/usr/lib)")
set(type "system" PARENT_SCOPE)
endif()
endfunction()
file(GLOB_RECURSE BUNDLE_LIBS "${CMAKE_INSTALL_PREFIX}/${BUNDLE_LIBS_DIR}/*.dylib")
set(BU_CHMOD_BUNDLE_ITEMS ON)
fixup_bundle("${BUNDLE_PATH}" "${BUNDLE_LIBS}" "${BUNDLE_DIRS}")
if(DEFINED APPLE_CODESIGN_IDENTITY AND DEFINED APPLE_CODESIGN_ENTITLEMENTS)
# execute_process(COMMAND
# codesign --verbose=4 --deep --force --options runtime
# --entitlements "${APPLE_CODESIGN_ENTITLEMENTS}"
# --sign "${APPLE_CODESIGN_IDENTITY}"
# "${BUNDLE_NAME}"
# )
foreach(PATH_TO_SIGN IN LISTS BUNDLE_LIBS BUNDLE_PATH)
execute_process(COMMAND
codesign --verbose=4 --deep --force
--entitlements "${APPLE_CODESIGN_ENTITLEMENTS}"
--sign "${APPLE_CODESIGN_IDENTITY}"
"${PATH_TO_SIGN}"
)
endforeach()
else()
message(STATUS "Not signing bundle. Specify -DAPPLE_CODESIGN_IDENTITY and -DAPPLE_CODESIGN_ENTITLEMENTS to cmake before running cpack to sign")
endif()

View File

@@ -0,0 +1,76 @@
# - Try to find gst-plugins-base
# Once done this will define
#
# GSTREAMER_PLUGINS_BASE_FOUND - system has gst-plugins-base
#
# And for all the plugin libraries specified in the COMPONENTS
# of find_package, this module will define:
#
# GSTREAMER_<plugin_lib>_LIBRARY_FOUND - system has <plugin_lib>
# GSTREAMER_<plugin_lib>_LIBRARY - the <plugin_lib> library
# GSTREAMER_<plugin_lib>_INCLUDE_DIR - the <plugin_lib> include directory
#
# Copyright (c) 2010, Collabora Ltd.
# @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
set(GSTREAMER_ABI_VERSION "1.0")
# Find the pkg-config file for doing the version check
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(PKG_GSTREAMER_PLUGINS_BAD gstreamer-plugins-bad-${GSTREAMER_ABI_VERSION})
endif()
# Find the plugin libraries
include(MacroFindGStreamerLibrary)
macro(_find_gst_plugins_bad_component _name _header)
find_gstreamer_library(${_name} ${_header} ${GSTREAMER_ABI_VERSION})
set(_GSTREAMER_PLUGINS_BAD_EXTRA_VARIABLES ${_GSTREAMER_PLUGINS_BAD_EXTRA_VARIABLES}
GSTREAMER_${_name}_LIBRARY GSTREAMER_${_name}_INCLUDE_DIR)
endmacro()
foreach(_component ${GStreamerPluginsBad_FIND_COMPONENTS})
if (${_component} STREQUAL "player")
_find_gst_plugins_bad_component(PLAYER gstplayer.h)
elseif (${_component} STREQUAL "webrtc")
_find_gst_plugins_bad_component(WEBRTC webrtc.h)
elseif (${_component} STREQUAL "srtsrc")
_find_gst_plugins_bad_component(SRTSRC mpegts.h)
else()
message (AUTHOR_WARNING "FindGStreamerPluginBad.cmake: Invalid component \"${_component}\" was specified")
endif()
endforeach()
get_filename_component(_GSTREAMER_BAD_LIB_DIR ${GSTREAMER_PLAYER_LIBRARY} PATH)
set(PKG_GSTREAMER_BAD_PLUGIN_DIR ${_GSTREAMER_BAD_LIB_DIR}/gstreamer-${GSTREAMER_ABI_VERSION})
# Version check
if (GStreamerPluginsBad_FIND_VERSION)
if (PKG_GSTREAMER_PLUGINS_BAD_FOUND)
if("${PKG_GSTREAMER_PLUGINS_BAD_VERSION}" VERSION_LESS "${GStreamerPluginsBad_FIND_VERSION}")
message(STATUS "Found gst-plugins-base version ${PKG_GSTREAMER_PLUGINS_BAD_VERSION}, but at least version ${GStreamerPluginsBad_FIND_VERSION} is required")
set(GSTREAMER_PLUGINS_BAD_VERSION_COMPATIBLE FALSE)
else()
set(GSTREAMER_PLUGINS_BAD_VERSION_COMPATIBLE TRUE)
endif()
else()
# We can't make any version checks without pkg-config, just assume version is compatible and hope...
set(GSTREAMER_PLUGINS_BAD_VERSION_COMPATIBLE TRUE)
endif()
else()
# No version constrain was specified, thus we consider the version compatible
set(GSTREAMER_PLUGINS_BAD_VERSION_COMPATIBLE TRUE)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GStreamerPluginsBad DEFAULT_MSG
GSTREAMER_PLUGINS_BAD_VERSION_COMPATIBLE
${_GSTREAMER_PLUGINS_BAD_EXTRA_VARIABLES})

View File

@@ -64,6 +64,8 @@ foreach(_component ${GStreamerPluginsBase_FIND_COMPONENTS})
endif()
endforeach()
get_filename_component(_GSTREAMER_BASE_LIB_DIR ${GSTREAMER_APP_LIBRARY} PATH)
set(PKG_GSTREAMER_BASE_PLUGIN_DIR ${_GSTREAMER_BASE_LIB_DIR}/gstreamer-${GSTREAMER_ABI_VERSION})
# Version check
if (GStreamerPluginsBase_FIND_VERSION)

147
cmake/modules/FindGTK.cmake Normal file
View File

@@ -0,0 +1,147 @@
# - Try to find GTK+ 3.x or 4.x
#
# Copyright (C) 2012 Raphael Kubo da Costa <rakuco@webkit.org>
# Copyright (C) 2013, 2015, 2020 Igalia S.L.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS
# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#[=======================================================================[.rst:
FindGTK
-------
Find GTK headers and libraries.
Optional Components
^^^^^^^^^^^^^^^^^^^
The ``COMPONENTS`` (or ``OPTIONAL_COMPONENTS``) keyword can be passed to
``find_package()``, the following GTK components can be searched for:
- ``unix-print``
Imported Targets
^^^^^^^^^^^^^^^^
``GTK::GTK``
The GTK library, if found.
``GTK::UnixPrint``
The GTK unix-print library, if found.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables in your project:
``GTK_FOUND``
true if (the requested version of) GTK is available.
``GTK_UNIX_PRINT_FOUND``
true if the ``unix-print`` component is available.
``GTK_4``
whether GTK 4 was detected
``GTK_3``
whether GTK 3 was detected
``GTK_VERSION``
the version of GTK.
``GTK_SUPPORTS_BROADWAY``
true if the Broadway target is built into GTK.
``GTK_SUPPORTS_QUARTZ``
true if the Quartz target is built into GTK.
``GTK_SUPPORTS_WAYLAND``
true if the Wayland target is built into GTK.
``GTK_SUPPORTS_WIN32``
true if the Windows target is built into GTK.
``GTK_SUPPORTS_X11``
true if the X11 target is built into GTK.
#]=======================================================================]
if (GTK_FIND_VERSION VERSION_LESS 3.90)
set(GTK_PC_MODULE "gtk+-3.0")
set(GTK_PC_UNIX_PRINT_MODULE "gtk+-unix-print-3.0")
set(GTK_4 FALSE)
set(GTK_3 TRUE)
else ()
set(GTK_PC_MODULE "gtk4")
set(GTK_PC_UNIX_PRINT_MODULE "gtk4-unix-print")
set(GTK_4 TRUE)
set(GTK_3 FALSE)
endif ()
find_package(PkgConfig QUIET)
pkg_check_modules(GTK IMPORTED_TARGET ${GTK_PC_MODULE})
set(GTK_VERSION_OK TRUE)
if (GTK_VERSION)
if (GTK_FIND_VERSION_EXACT)
if (NOT("${GTK_FIND_VERSION}" VERSION_EQUAL "${GTK_VERSION}"))
set(GTK_VERSION_OK FALSE)
endif ()
else ()
if ("${GTK_VERSION}" VERSION_LESS "${GTK_FIND_VERSION}")
set(GTK_VERSION_OK FALSE)
endif ()
endif ()
endif ()
# Set all the GTK_SUPPORTS_<target> variables to FALSE initially.
foreach (gtk_target broadway quartz wayland win32 x11)
string(TOUPPER "GTK_SUPPORTS_${gtk_target}" gtk_target)
set(${gtk_target} FALSE)
endforeach ()
if (GTK_VERSION AND GTK_VERSION_OK)
# Fetch the "targets" variable and set GTK_SUPPORTS_<target>.
pkg_get_variable(GTK_TARGETS ${GTK_PC_MODULE} targets)
separate_arguments(GTK_TARGETS)
foreach (gtk_target ${GTK_TARGETS})
string(TOUPPER "GTK_SUPPORTS_${gtk_target}" gtk_target)
set(${gtk_target} TRUE)
endforeach ()
endif ()
if (TARGET PkgConfig::GTK AND NOT TARGET GTK::GTK)
add_library(GTK::GTK INTERFACE IMPORTED GLOBAL)
set_property(TARGET GTK::GTK PROPERTY
INTERFACE_LINK_LIBRARIES PkgConfig::GTK
)
endif ()
# Try to find additional components
foreach (gtk_component ${GTK_FIND_COMPONENTS})
if (NOT "${gtk_component}" STREQUAL unix-print)
message(FATAL_ERROR "Invalid component name: ${gtk_component}")
endif ()
pkg_check_modules(GTK_UNIX_PRINT IMPORTED_TARGET "${GTK_PC_UNIX_PRINT_MODULE}")
if (GTK_FIND_REQUIRED_unix-print AND NOT GTK_UNIX_PRINT_FOUND)
message(FATAL_ERROR "Component unix-print not found")
endif ()
if (TARGET PkgConfig::GTK_UNIX_PRINT AND NOT TARGET GTK::UnixPrint)
add_library(GTK::UnixPrint INTERFACE IMPORTED GLOBAL)
set_property(TARGET GTK::UnixPrint PROPERTY
INTERFACE_LINK_LIBRARIES PkgConfig::GTK_UNIX_PRINT)
endif ()
endforeach ()
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK DEFAULT_MSG GTK_VERSION GTK_VERSION_OK)

102
defines.h
View File

@@ -1,102 +0,0 @@
#ifndef VMIX_DEFINES_H
#define VMIX_DEFINES_H
#define APP_NAME "vimix"
#define APP_TITLE " -- Video Live Mixer"
#define APP_SETTINGS "vimix.xml"
#define APP_VERSION_MAJOR 0
#define APP_VERSION_MINOR 1
#define XML_VERSION_MAJOR 0
#define XML_VERSION_MINOR 1
#define MAX_RECENT_HISTORY 20
#define MINI(a, b) (((a) < (b)) ? (a) : (b))
#define MAXI(a, b) (((a) > (b)) ? (a) : (b))
#define ABS(a) (((a) < 0) ? -(a) : (a))
#define ABS_DIFF(a, b) ( (a) < (b) ? (b - a) : (a - b) )
#define SIGN(a) (((a) < 0) ? -1.0 : 1.0)
#define SQUARE(a) ((a) * (a))
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
#define EPSILON 0.00001
#define LOG100(val) (50.0/log(10.0)*log((float)val + 1.0))
#define EXP100(val) (exp(log(10.0)/50.0*(float)(val))-1.0)
#define EUCLIDEAN(P1, P2) sqrt((P1.x() - P2.x()) * (P1.x() - P2.x()) + (P1.y() - P2.y()) * (P1.y() - P2.y()))
#define SCENE_UNIT 5.f
#define SCENE_DEPTH 12.f
#define CIRCLE_SQUARE_DIST(x,y) ( (x*x + y*y) / (SCENE_UNIT * SCENE_UNIT * SCENE_UNIT * SCENE_UNIT) )
#define MIN_SCALE 0.01f
#define MAX_SCALE 10.f
#define CLAMP_SCALE(x) SIGN(x) * CLAMP( ABS(x), MIN_SCALE, MAX_SCALE)
#define MIXING_DEFAULT_SCALE 2.4f
#define MIXING_MIN_SCALE 0.8f
#define MIXING_MAX_SCALE 7.0f
#define GEOMETRY_DEFAULT_SCALE 1.2f
#define GEOMETRY_MIN_SCALE 0.2f
#define GEOMETRY_MAX_SCALE 10.0f
#define LAYER_DEFAULT_SCALE 0.8f
#define LAYER_MIN_SCALE 0.4f
#define LAYER_MAX_SCALE 1.7f
#define TRANSITION_DEFAULT_SCALE 3.0f
#define TRANSITION_MIN_DURATION 0.2f
#define TRANSITION_MAX_DURATION 10.f
#define IMGUI_TITLE_MAINWINDOW ICON_FA_CIRCLE_NOTCH " vimix"
#define IMGUI_TITLE_MEDIAPLAYER ICON_FA_FILM " Media Player"
#define IMGUI_TITLE_TOOLBOX ICON_FA_WRENCH " Tools"
#define IMGUI_TITLE_SHADEREDITOR ICON_FA_CODE " Shader Editor"
#define IMGUI_TITLE_PREVIEW ICON_FA_DESKTOP " Preview"
#define IMGUI_TITLE_DELETE ICON_FA_BROOM " Delete?"
#define IMGUI_LABEL_RECENT_FILES " Recent files"
#define IMGUI_RIGHT_ALIGN -3.5f * ImGui::GetTextLineHeightWithSpacing()
#define IMGUI_NOTIFICATION_DURATION 1.5f
#ifdef APPLE
#define CTRL_MOD "Cmd+"
#else
#define CTRL_MOD "Ctrl+"
#endif
#define COLOR_BGROUND 0.2f, 0.2f, 0.2f
#define COLOR_NAVIGATOR 0.1f, 0.1f, 0.1f
#define COLOR_DEFAULT_SOURCE 0.8f, 0.8f, 0.8f
#define COLOR_HIGHLIGHT_SOURCE 1.f, 1.f, 1.f
#define COLOR_TRANSITION_SOURCE 1.f, 0.5f, 1.f
#define COLOR_TRANSITION_LINES 0.9f, 0.9f, 0.9f
#define COLOR_FRAME 0.8f, 0.f, 0.8f
#define COLOR_LIMBO_CIRCLE 0.16f, 0.16f, 0.16f
// from glmixer
#define TEXTURE_REQUIRED_MAXIMUM 2048
#define CATALOG_TEXTURE_HEIGHT 96
#define SELECTBUFSIZE 512
#define CIRCLE_SIZE 8.0
#define DEFAULT_LIMBO_SIZE 1.5
#define MIN_LIMBO_SIZE 1.1
#define MAX_LIMBO_SIZE 3.0
#define DEFAULT_ICON_SIZE 1.75
#define MIN_ICON_SIZE 1.0
#define MAX_ICON_SIZE 2.5
#define MIN_DEPTH_LAYER 0.0
#define MAX_DEPTH_LAYER 40.0
#define DEPTH_EPSILON 0.1
#define DEPTH_DEFAULT_SPACING 1.0
#define BORDER_SIZE 0.4
#define CENTER_SIZE 1.2
#define PROPERTY_DECIMALS 8
#define COLOR_SOURCE 230, 230, 0
#define COLOR_SOURCE_STATIC 230, 40, 40
#define COLOR_SELECTION 10, 210, 40
#define COLOR_SELECTION_AREA 50, 210, 50
#define COLOR_CIRCLE 210, 30, 210
#define COLOR_CIRCLE_MOVE 230, 30, 230
#define COLOR_DRAWINGS 180, 180, 180
#define COLOR_LIMBO 35, 35, 35
//#define COLOR_LIMBO_CIRCLE 210, 160, 210
#define COLOR_FADING 25, 25, 25
#define COLOR_FLASHING 250, 250, 250
#define COLOR_FRAME_MOVE 230, 30, 230
#define COLOR_CURSOR 10, 100, 255
#endif // VMIX_DEFINES_H

6
docs/_config.yml Normal file
View File

@@ -0,0 +1,6 @@
theme: jekyll-theme-minimal
title: vimix
description: Video Live Mixer
logo: vimix_256x256.png
show_downloads: true

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 436 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 987 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 KiB

Some files were not shown because too many files have changed in this diff Show More