From da59e80dbe159043ced0d33f8d08af6c0ed25d75 Mon Sep 17 00:00:00 2001 From: BHBN <60393189+brunoherbelin@users.noreply.github.com> Date: Fri, 6 Mar 2020 21:23:51 +0100 Subject: [PATCH] Initial commit (2) --- CMakeLists.txt | 267 ++++++++++++ FileDialog.cpp | 1033 +++++++++++++++++++++++++++++++++++++++++++++ FileDialog.h | 110 +++++ GstToolkit.cpp | 27 ++ GstToolkit.h | 15 + SettingsManager.h | 52 +++ ShaderManager.cpp | 123 ++++++ ShaderManager.h | 31 ++ defines.h | 59 +++ 9 files changed, 1717 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 FileDialog.cpp create mode 100644 FileDialog.h create mode 100644 GstToolkit.cpp create mode 100644 GstToolkit.h create mode 100644 SettingsManager.h create mode 100644 ShaderManager.cpp create mode 100644 ShaderManager.h create mode 100644 defines.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..56b55f1 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,267 @@ + +cmake_minimum_required(VERSION 3.8.0) +project(vmix VERSION 0.0.1 LANGUAGES CXX C) + +set(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "ON") +set(CMAKE_INCLUDE_CURRENTDIR ON) +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ) +include(MacroLogFeature) + +if(UNIX) + if (APPLE) + add_definitions(-DAPPLE) + else() + add_definitions(-DLINUX) + endif() + add_definitions(-DUNIX) +elseif(WIN32) + add_definitions(-DWIN32) + add_definitions(-DMINGW32) +endif(UNIX) + +# Include the CMake RC module +include(CMakeRC) + +# +# GSTREAMER +# + +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}" +"http://gstreamer.freedesktop.org/" TRUE "1.0.0") + +macro_log_feature(GSTREAMER_AUDIO_LIBRARY_FOUND "GStreamer audio library" +"${GSTREAMER_AUDIO_LIBRARY}" +"http://gstreamer.freedesktop.org/" TRUE "1.0.0") + +macro_log_feature(GSTREAMER_VIDEO_LIBRARY_FOUND "GStreamer video library" +"${GSTREAMER_VIDEO_LIBRARY}" +"http://gstreamer.freedesktop.org/" TRUE "1.0.0") + +macro_log_feature(GSTREAMER_PBUTILS_LIBRARY_FOUND "GStreamer pbutils library" +"${GSTREAMER_PBUTILS_LIBRARY}" +"http://gstreamer.freedesktop.org/" TRUE "1.0.0") + +macro_log_feature(GSTREAMER_GL_LIBRARY_FOUND "GStreamer opengl library" +"${GSTREAMER_GL_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.3 REQUIRED) +macro_log_feature(glfw3_FOUND "GLFW3" "Open Source, multi-platform library for OpenGL" "http://www.glfw.org/" TRUE) +set(GLFW_LIBRARY glfw) + +set(OpenGL_GL_PREFERENCE "GLVND") +find_package(OpenGL REQUIRED) + +# +# GLM +# +find_package(glm REQUIRED) +macro_log_feature(glm_FOUND "GLM" "OpenGL Mathematics" "https://glm.g-truc.net" TRUE) +set(GLM_LIBRARY glm) + +# +# 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(TEXTEDIT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/ImGuiColorTextEdit) +set(TEXTEDIT_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/ext/ImGuiColorTextEdit/TextEditor.cpp +) +message(STATUS "Including 'ImGuiColorTextEdit' from https://github.com/BalazsJako/ImGuiColorTextEdit -- ${TEXTEDIT_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) + 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/tinyfiledialogs) +add_library(TINYFD "${CMAKE_CURRENT_SOURCE_DIR}/ext/tinyfiledialogs/tinyfiledialogs.c") +message(STATUS "Compiling 'TinyFileDialog' from https://github.com/native-toolkit/tinyfiledialogs.git -- ${TINYFD_INCLUDE_DIR}.") + +# +# BOXER - NATIVE MESSAGE DIALOG +# +#add_subdirectory(ext/Boxer) +#set(BOXER_INCLUDE_DIR ${Boxer_SOURCE_DIR}/include) +#set(BOXER_LIBRARY Boxer) +#message(STATUS "Including 'Boxer' from https://github.com/aaronmjacobs/Boxer.git -- ${BOXER_INCLUDE_DIR}.") + +# +# NATIVE FILE DIALOG +# +# add_subdirectory(ext/nfd) +# set(NFD_INCLUDE_DIR ${NFD_SOURCE_DIR}/include) +# set(NFD_LIBRARY NFD) +# message(STATUS "Including 'NativeFileDialog' from http://www.frogtoss.com/labs -- ${NFD_INCLUDE_DIR}.") + +# find_package(PkgConfig REQUIRED) +# pkg_check_modules(GTK3 REQUIRED gtk+-3.0) + +# +# Application +# + +# Setup the environment +include_directories( + ${GSTREAMER_INCLUDE_DIR} + ${GSTREAMER_AUDIO_INCLUDE_DIR} + ${GSTREAMER_VIDEO_INCLUDE_DIR} + ${GSTREAMER_BASE_INCLUDE_DIR} + ${GSTREAMER_APP_INCLUDE_DIR} + ${GSTREAMER_PBUTILS_INCLUDE_DIR} + ${GSTREAMER_GL_INCLUDE_DIR} + ${GLIB2_INCLUDE_DIR} + ${GLAD_INCLUDE_DIR} + ${GLM_INCLUDE_DIRS} + ${IMGUI_INCLUDE_DIR} + ${IMGUI_INCLUDE_DIR}/examples + ${TEXTEDIT_INCLUDE_DIR} + ${TINYXML2_INCLUDE_DIR} + ${TINYFD_INCLUDE_DIR} + ${STB_INCLUDE_DIR} + ${DIRENT_INCLUDE_DIR} +) + + +set(VMIX_BINARY "vmix") +set(VMIX_SRCS + main.cpp + ShaderManager.cpp + RenderingManager.cpp + SettingsManager.cpp + ResourceManager.cpp + UserInterfaceManager.cpp + FileDialog.cpp + ImGuiToolkit.cpp + GstToolkit.cpp + MediaPlayer.cpp + Log.cpp +) + +set(VMIX_RSC_FILES + ./rsc/shaders/simple-shader.fs + ./rsc/shaders/simple-shader.vs + ./rsc/shaders/texture-shader.fs + ./rsc/shaders/texture-shader.vs + ./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/images/glmixer_256x256.png + ./rsc/images/icons.dds + ./rsc/images/seed_512.jpg +) + +add_executable(${VMIX_BINARY} + ${VMIX_SRCS} + ${TEXTEDIT_SRCS} +) + +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} + ${GLM_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} + ${NFD_LIBRARY} + ${PNG_LIBRARY} + ${THREAD_LIBRARY} + TINYXML2 + IMGUI + TINYFD + vmix::rc +) + +macro_display_feature_log() diff --git a/FileDialog.cpp b/FileDialog.cpp new file mode 100644 index 0000000..5b943c7 --- /dev/null +++ b/FileDialog.cpp @@ -0,0 +1,1033 @@ +#include "FileDialog.h" +#include "ImGuiToolkit.h" + +#ifdef WIN32 +#include +#define PATH_SEP '\\' +#ifndef PATH_MAX +#define PATH_MAX 260 +#endif +#elif defined(LINUX) or defined(APPLE) +#include +#include +#define PATH_SEP '/' +#endif + +#include "imgui.h" +#ifndef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS +#endif +#include "imgui_internal.h" + +#include +#include +#include + +static std::string s_fs_root(1u, PATH_SEP); + +inline bool replaceString(::std::string& str, const ::std::string& oldStr, const ::std::string& newStr) +{ + bool found = false; + size_t pos = 0; + while ((pos = str.find(oldStr, pos)) != ::std::string::npos) + { + found = true; + str.replace(pos, oldStr.length(), newStr); + pos += newStr.length(); + } + return found; +} + +inline std::vector splitStringToVector(const ::std::string& text, char delimiter, bool pushEmpty) +{ + std::vector arr; + if (text.size() > 0) + { + std::string::size_type start = 0; + std::string::size_type end = text.find(delimiter, start); + while (end != std::string::npos) + { + std::string token = text.substr(start, end - start); + if (token.size() > 0 || (token.size() == 0 && pushEmpty)) + arr.push_back(token); + start = end + 1; + end = text.find(delimiter, start); + } + arr.push_back(text.substr(start)); + } + return arr; +} + +inline std::vector GetDrivesList() +{ + std::vector res; + +#ifdef WIN32 + DWORD mydrives = 2048; + char lpBuffer[2048]; + + DWORD countChars = GetLogicalDriveStrings(mydrives, lpBuffer); + + if (countChars > 0) + { + std::string var = std::string(lpBuffer, countChars); + replaceString(var, "\\", ""); + res = splitStringToVector(var, '\0', false); + } +#endif + + return res; +} + +inline bool IsDirectoryExist(const std::string& name) +{ + bool bExists = false; + + if (name.size() > 0) + { + DIR *pDir = 0; + pDir = opendir(name.c_str()); + if (pDir != NULL) + { + bExists = true; + (void)closedir(pDir); + } + } + + return bExists; // this is not a directory! +} + +inline bool CreateDirectoryIfNotExist(const std::string& name) +{ + bool res = false; + + if (name.size() > 0) + { + if (!IsDirectoryExist(name)) + { + res = true; + +#ifdef WIN32 + CreateDirectory(name.c_str(), NULL); +#elif defined(LINUX) or defined(APPLE) + char buffer[PATH_MAX] = {}; + snprintf(buffer, PATH_MAX, "mkdir -p %s", name.c_str()); + const int dir_err = std::system(buffer); + if (dir_err == -1) + { + std::cout << "Error creating directory " << name << std::endl; + res = false; + } +#endif + } + } + + return res; +} + +struct PathStruct +{ + std::string path; + std::string name; + std::string ext; + + bool isOk; + + PathStruct() + { + isOk = false; + } +}; + +inline PathStruct ParsePathFileName(const std::string& vPathFileName) +{ + PathStruct res; + + if (vPathFileName.size() > 0) + { + std::string pfn = vPathFileName; + std::string separator(1u, PATH_SEP); + replaceString(pfn, "\\", separator); + replaceString(pfn, "/", separator); + + size_t lastSlash = pfn.find_last_of(separator); + if (lastSlash != std::string::npos) + { + res.name = pfn.substr(lastSlash + 1); + res.path = pfn.substr(0, lastSlash); + res.isOk = true; + } + + size_t lastPoint = pfn.find_last_of('.'); + if (lastPoint != std::string::npos) + { + if (!res.isOk) + { + res.name = pfn; + res.isOk = true; + } + res.ext = pfn.substr(lastPoint + 1); + replaceString(res.name, "." + res.ext, ""); + } + } + + return res; +} + +inline void AppendToBuffer(char* vBuffer, size_t vBufferLen, std::string vStr) +{ + std::string st = vStr; + size_t len = vBufferLen - 1u; + size_t slen = strlen(vBuffer); + + if (st != "" && st != "\n") + { + replaceString(st, "\n", ""); + replaceString(st, "\r", ""); + } + vBuffer[slen] = '\0'; + std::string str = std::string(vBuffer); + if (str.size() > 0) str += "\n"; + str += vStr; + if (len > str.size()) len = str.size(); +#ifdef MSVC + strncpy_s(vBuffer, vBufferLen, str.c_str(), len); +#else + strncpy(vBuffer, str.c_str(), len); +#endif + vBuffer[len] = '\0'; +} + +inline void ResetBuffer(char* vBuffer) +{ + vBuffer[0] = '\0'; +} + +char FileDialog::FileNameBuffer[MAX_FILE_DIALOG_NAME_BUFFER] = ""; +char FileDialog::DirectoryNameBuffer[MAX_FILE_DIALOG_NAME_BUFFER] = ""; +char FileDialog::SearchBuffer[MAX_FILE_DIALOG_NAME_BUFFER] = ""; +int FileDialog::FilterIndex = 0; + +FileDialog::FileDialog() +{ + m_AnyWindowsHovered = false; + IsOk = false; + m_ShowDialog = false; + m_ShowDrives = false; + m_CreateDirectoryMode = false; + dlg_optionsPane = 0; + dlg_optionsPaneWidth = 250; + dlg_filters = ""; +} + +FileDialog::~FileDialog() +{ + +} + +/* Alphabetical sorting */ +/*#ifdef WIN32 +static int alphaSort(const void *a, const void *b) +{ + return strcoll(((dirent*)a)->d_name, ((dirent*)b)->d_name); +} +#elif defined(LINUX) or defined(APPLE)*/ +static int alphaSort(const struct dirent **a, const struct dirent **b) +{ + return strcoll((*a)->d_name, (*b)->d_name); +} +//#endif + +static bool stringComparator(const FileInfoStruct& a, const FileInfoStruct& b) +{ + bool res; + if (a.type != b.type) res = (a.type < b.type); + else res = (a.fileName < b.fileName); + return res; +} + +void FileDialog::ScanDir(const std::string& vPath) +{ + struct dirent **files = NULL; + int i = 0; + int n = 0; + std::string path = vPath; + +#if defined(LINUX) or defined(APPLE) + if (path.size()>0) + { + if (path[0] != PATH_SEP) + { + //path = PATH_SEP + path; + } + } +#endif + + if (0u == m_CurrentPath_Decomposition.size()) + { + SetCurrentDir(path); + } + + if (0u != m_CurrentPath_Decomposition.size()) + { +#ifdef WIN32 + if (path == s_fs_root) + { + path += PATH_SEP; + } +#endif + n = scandir(path.c_str(), &files, NULL, alphaSort); + if (n > 0) + { + m_FileList.clear(); + + for (i = 0; i < n; i++) + { + struct dirent *ent = files[i]; + + FileInfoStruct infos; + + infos.fileName = ent->d_name; + if (("." != infos.fileName)/* && (".." != infos.fileName)*/) + { + switch (ent->d_type) + { + case DT_REG: infos.type = 'f'; break; + case DT_DIR: infos.type = 'd'; break; + case DT_LNK: infos.type = 'l'; break; + } + + if (infos.type == 'f') + { + size_t lpt = infos.fileName.find_last_of('.'); + if (lpt != std::string::npos) + { + infos.ext = infos.fileName.substr(lpt); + } + } + + bool is_hidden = false; + #ifdef OSWIN + std::string dir = path + std::string(ent->d_name); + // IF system file skip it... + if (FILE_ATTRIBUTE_SYSTEM & GetFileAttributesA(dir.c_str())) + continue; + if (FILE_ATTRIBUTE_HIDDEN & GetFileAttributesA(dir.c_str())) + is_hidden = true; + #else + if(infos.fileName[0] == '.') + is_hidden = true; + #endif // OSWIN + + if (!is_hidden) + m_FileList.push_back(infos); + } + } + + for (i = 0; i < n; i++) + { + free(files[i]); + } + free(files); + } + + std::sort(m_FileList.begin(), m_FileList.end(), stringComparator); + } +} + +void FileDialog::SetCurrentDir(const std::string& vPath) +{ + std::string path = vPath; +#ifdef WIN32 + if (s_fs_root == path) + path += PATH_SEP; +#endif + DIR *dir = opendir(path.c_str()); + char real_path[PATH_MAX]; + + if (NULL == dir) + { + path = "."; + dir = opendir(path.c_str()); + } + + if (NULL != dir) + { +#ifdef WIN32 + size_t numchar = GetFullPathName(path.c_str(), PATH_MAX-1, real_path, 0); +#elif defined(LINUX) or defined(APPLE) + char *numchar = realpath(path.c_str(), real_path); +#endif + if (numchar != 0) + { + m_CurrentPath = real_path; + if (m_CurrentPath[m_CurrentPath.size()-1] == PATH_SEP) + { + m_CurrentPath = m_CurrentPath.substr(0, m_CurrentPath.size() - 1); + } + m_CurrentPath_Decomposition = splitStringToVector(m_CurrentPath, PATH_SEP, false); +#if defined(LINUX) or defined(APPLE) + m_CurrentPath_Decomposition.insert(m_CurrentPath_Decomposition.begin(), std::string(1u, PATH_SEP)); +#endif + if (m_CurrentPath_Decomposition.size()>0) + { +#ifdef WIN32 + s_fs_root = m_CurrentPath_Decomposition[0]; +#endif + } + } + + closedir(dir); + } +} + +bool FileDialog::CreateDir(const std::string& vPath) +{ + bool res = false; + + if (vPath.size()) + { + std::string path = m_CurrentPath + PATH_SEP + vPath; + + res = CreateDirectoryIfNotExist(path); + } + + return res; +} + +void FileDialog::ComposeNewPath(std::vector::iterator vIter) +{ + m_CurrentPath = ""; + + while (true) + { + if (!m_CurrentPath.empty()) + { +#ifdef WIN32 + m_CurrentPath = *vIter + PATH_SEP + m_CurrentPath; +#elif defined(LINUX) or defined(APPLE) + if (*vIter == s_fs_root) + { + m_CurrentPath = *vIter + m_CurrentPath; + } + else + { + m_CurrentPath = *vIter + PATH_SEP + m_CurrentPath; + } +#endif + } + else + { + m_CurrentPath = *vIter; + } + + if (vIter == m_CurrentPath_Decomposition.begin()) + { +#if defined(LINUX) or defined(APPLE) + if (m_CurrentPath[0] != PATH_SEP) + m_CurrentPath = PATH_SEP + m_CurrentPath; +#endif + break; + } + + vIter--; + } +} + +void FileDialog::GetDrives() +{ + auto res = GetDrivesList(); + if (res.size() > 0) + { + m_CurrentPath = ""; + m_CurrentPath_Decomposition.clear(); + m_FileList.clear(); + for (auto it = res.begin(); it != res.end(); ++it) + { + FileInfoStruct infos; + infos.fileName = *it; + infos.type = 'd'; + + if (infos.fileName.size() > 0) + { + m_FileList.push_back(infos); + } + } + m_ShowDrives = true; + } +} + +void FileDialog::OpenDialog(const std::string& vKey, const char* vName, const char* vFilters, + const std::string& vPath, const std::string& vDefaultFileName, + std::function vOptionsPane, size_t vOptionsPaneWidth, const std::string& vUserString) +{ + if (m_ShowDialog) // si deja ouvert on ne fou pas la merde en voulant en ecrire une autre + return; + + dlg_key = vKey; + dlg_name = std::string(vName); + dlg_filters = vFilters; + dlg_path = vPath; + dlg_defaultFileName = vDefaultFileName; + dlg_optionsPane = vOptionsPane; + dlg_userString = vUserString; + dlg_optionsPaneWidth = vOptionsPaneWidth; + + dlg_defaultExt = ""; + + m_ShowDialog = true; +} + +void FileDialog::OpenDialog(const std::string& vKey, const char* vName, const char* vFilters, + const std::string& vFilePathName, + std::function vOptionsPane, size_t vOptionsPaneWidth, const std::string& vUserString) +{ + if (m_ShowDialog) // si deja ouvert on ne fou pas la merde en voulant en ecrire une autre + return; + + dlg_key = vKey; + dlg_name = std::string(vName); + dlg_filters = vFilters; + + auto ps = ParsePathFileName(vFilePathName); + if (ps.isOk) + { + dlg_path = ps.path; + dlg_defaultFileName = vFilePathName; + dlg_defaultExt = "." + ps.ext; + } + else + { + dlg_path = "."; + dlg_defaultFileName = ""; + dlg_defaultExt = ""; + } + + dlg_optionsPane = vOptionsPane; + dlg_userString = vUserString; + dlg_optionsPaneWidth = vOptionsPaneWidth; + + m_ShowDialog = true; +} + +void FileDialog::OpenDialog(const std::string& vKey, const char* vName, const char* vFilters, + const std::string& vFilePathName, const std::string& vUserString) +{ + if (m_ShowDialog) // si deja ouvert on ne fou pas la merde en voulant en ecrire une autre + return; + + dlg_key = vKey; + dlg_name = std::string(vName); + dlg_filters = vFilters; + + auto ps = ParsePathFileName(vFilePathName); + if (ps.isOk) + { + dlg_path = ps.path; + dlg_defaultFileName = vFilePathName; + dlg_defaultExt = "." + ps.ext; + } + else + { + dlg_path = "."; + dlg_defaultFileName = ""; + dlg_defaultExt = ""; + } + + dlg_optionsPane = 0; + dlg_userString = vUserString; + dlg_optionsPaneWidth = 0; + + m_ShowDialog = true; +} + +void FileDialog::OpenDialog(const std::string& vKey, const char* vName, const char* vFilters, + const std::string& vPath, const std::string& vDefaultFileName, const std::string& vUserString) +{ + if (m_ShowDialog) // si deja ouvert on ne fou pas la merde en voulant en ecrire une autre + return; + + dlg_key = vKey; + dlg_name = std::string(vName); + dlg_filters = vFilters; + dlg_path = vPath; + dlg_defaultFileName = vDefaultFileName; + dlg_optionsPane = 0; + dlg_userString = vUserString; + dlg_optionsPaneWidth = 0; + + dlg_defaultExt = ""; + + m_ShowDialog = true; +} + +void FileDialog::CloseDialog(const std::string& vKey) +{ + if (dlg_key == vKey) + { + dlg_key.clear(); + m_ShowDialog = false; + } +} + +void FileDialog::SetPath(const std::string& vPath) +{ + m_ShowDrives = false; + m_CurrentPath = vPath; + m_FileList.clear(); + m_CurrentPath_Decomposition.clear(); + ScanDir(m_CurrentPath); +} + +bool FileDialog::Render(const std::string& vKey, ImVec2 geometry) +{ + std::string name = dlg_name + "##" + dlg_key; + + if (m_ShowDialog) { + ImGui::OpenPopup(name.c_str()); + // m_ShowDialog = false; + } + + if (dlg_key == vKey) + { + bool res = false; + + if (m_Name != name) + { + m_FileList.clear(); + m_CurrentPath_Decomposition.clear(); + } + + IsOk = false; + + if (ImGui::BeginPopupModal(name.c_str(), NULL, ImGuiWindowFlags_AlwaysAutoResize)) + { + + m_Name = name; + + m_AnyWindowsHovered |= ImGui::IsWindowHovered(); + + if (dlg_path.size() == 0) dlg_path = "."; + + if (m_FileList.size() == 0 && !m_ShowDrives) + { + replaceString(dlg_defaultFileName, dlg_path, ""); // local path + + if (dlg_defaultFileName.size() > 0) + { + ResetBuffer(FileNameBuffer); + AppendToBuffer(FileNameBuffer, MAX_FILE_DIALOG_NAME_BUFFER, dlg_defaultFileName); + m_SelectedFileName = dlg_defaultFileName; + + if (dlg_defaultExt.size() > 0) + { + m_SelectedExt = dlg_defaultExt; + + FileDialog::FilterIndex = 0; + size_t size = 0; + const char* p = dlg_filters; // FIXME-OPT: Avoid computing this, or at least only when combo is open + while (*p) + { + size += strlen(p) + 1; + p += size; + } + int idx = 0; + auto arr = splitStringToVector(std::string(dlg_filters, size), '\0', false); + for (auto it = arr.begin(); it != arr.end(); ++it) + { + if (m_SelectedExt == *it) + { + FileDialog::FilterIndex = idx; + break; + } + idx++; + } + } + } + + ScanDir(dlg_path); + } + + if (ImGuiToolkit::ButtonIcon(3, 8)) + // if (ImGui::Button("+")) // new Folder + { + if (!m_CreateDirectoryMode) + { + m_CreateDirectoryMode = true; + ResetBuffer(DirectoryNameBuffer); + } + } + + if (m_CreateDirectoryMode) + { + ImGui::SameLine(); + + ImGui::PushItemWidth(100.0f); + ImGui::InputText("##DirectoryFileName", DirectoryNameBuffer, MAX_FILE_DIALOG_NAME_BUFFER); + ImGui::PopItemWidth(); + + ImGui::SameLine(); + + if (ImGui::Button("OK")) + { + std::string newDir = std::string(DirectoryNameBuffer); + if (CreateDir(newDir)) + { + SetPath(m_CurrentPath + PATH_SEP + newDir); + } + + m_CreateDirectoryMode = false; + } + + ImGui::SameLine(); + + if (ImGui::Button("Cancel")) + { + m_CreateDirectoryMode = false; + } + } + + ImGui::SameLine(); + + ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); + + ImGui::SameLine(); + + // if (ImGui::Button("R")) // HOME + if (ImGuiToolkit::ButtonIcon(2,10)) + { + SetPath("."); // Go Home + } + + bool drivesClick = false; + +#ifdef WIN32 + ImGui::SameLine(); + + if (ImGui::Button("Drives")) + { + drivesClick = true; + } +#endif + + ImGui::SameLine(); + + ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); + + // show current path + bool pathClick = false; + if (m_CurrentPath_Decomposition.size() > 0) + { + ImGui::SameLine(); + for (std::vector::iterator itPathDecomp = m_CurrentPath_Decomposition.begin(); + itPathDecomp != m_CurrentPath_Decomposition.end(); ++itPathDecomp) + { + if (itPathDecomp != m_CurrentPath_Decomposition.begin()) + ImGui::SameLine(); + if (ImGui::Button((*itPathDecomp).c_str())) + { + ComposeNewPath(itPathDecomp); + pathClick = true; + break; + } + } + } + + + // search field + ImGuiToolkit::Icon(14, 12); + ImGui::SameLine(); + if (ImGui::InputText("##ImGuiFileDialogSearchFiled", SearchBuffer, MAX_FILE_DIALOG_NAME_BUFFER)) + { + searchTag = SearchBuffer; + } + // reset search + ImGui::SameLine(); + if (ImGuiToolkit::ButtonIcon(13, 2)) + { + ResetBuffer(SearchBuffer); + searchTag.clear(); + } + + + ImGuiToolkit::PushFont(ImGuiToolkit::FONT_MONO); + ImVec2 dsize = geometry - ImVec2((float)dlg_optionsPaneWidth, 180.0f); + ImGui::BeginChild("##FileDialog_FileList", dsize); + + for (std::vector::iterator it = m_FileList.begin(); it != m_FileList.end(); ++it) + { + const FileInfoStruct& infos = *it; + + bool show = true; + + std::string str; + if (infos.type == 'd') str = "[Dir] " + infos.fileName; + if (infos.type == 'l') str = "[Link] " + infos.fileName; + if (infos.type == 'f') str = "[File] " + infos.fileName; + if (infos.type == 'f' && m_SelectedExt.size() > 0 && (infos.ext != m_SelectedExt && m_SelectedExt != ".*")) + { + show = false; + } + if (searchTag.size() > 0 && infos.fileName.find(searchTag) == std::string::npos) + { + show = false; + } + if (show == true) + { + ImVec4 c; + bool showColor = false; + if (infos.type == 'd') { ImGuiToolkit::Icon(5, 8); showColor=true; c = ImVec4(1.0, 1.0, 0.0, 1.0); }; + if (infos.type == 'l') { ImGuiToolkit::Icon(18, 13); showColor=true; c = ImVec4(1.0, 1.0, 1.0, 0.6); }; + if (infos.type == 'f') { + showColor = GetFilterColor(infos.ext, &c); + if (showColor) ImGuiToolkit::Icon(14, 7); else ImGuiToolkit::Icon(8, 8); + } + + if (showColor) + ImGui::PushStyleColor(ImGuiCol_Text, c); + + ImGui::SameLine(); + + if (ImGui::Selectable(infos.fileName.c_str(), (infos.fileName == m_SelectedFileName))) + { + if (infos.type == 'd') + { + if ((*it).fileName == "..") + { + if (m_CurrentPath_Decomposition.size() > 1) + { + ComposeNewPath(m_CurrentPath_Decomposition.end() - 2); + pathClick = true; + } + } + else + { + std::string newPath; + + if (m_ShowDrives) + { + newPath = infos.fileName + PATH_SEP; + } + else + { +#ifdef LINUX + if (s_fs_root == m_CurrentPath) + { + newPath = m_CurrentPath + infos.fileName; + } + else + { +#endif + newPath = m_CurrentPath + PATH_SEP + infos.fileName; +#ifdef LINUX + } +#endif + } + + if (IsDirectoryExist(newPath)) + { + if (m_ShowDrives) + { + m_CurrentPath = infos.fileName; + s_fs_root = m_CurrentPath; + } + else + { + m_CurrentPath = newPath; + } + pathClick = true; + } + } + } + else + { + m_SelectedFileName = infos.fileName; + ResetBuffer(FileNameBuffer); + AppendToBuffer(FileNameBuffer, MAX_FILE_DIALOG_NAME_BUFFER, m_SelectedFileName); + } + if (showColor) + ImGui::PopStyleColor(); + break; + } + + if (showColor) + ImGui::PopStyleColor(); + } + } + + // changement de repertoire + if (pathClick == true) + { + SetPath(m_CurrentPath); + } + + if (drivesClick == true) + { + GetDrives(); + } + + ImGui::EndChild(); + ImGui::PopFont(); + + bool _CanWeContinue = true; + + if (dlg_optionsPane) + { + ImGui::SameLine(); + + dsize.x = (float)dlg_optionsPaneWidth; + + ImGui::BeginChild("##FileTypes", dsize); + + dlg_optionsPane(m_SelectedExt, &_CanWeContinue); + + ImGui::EndChild(); + } + + ImGui::Text("File Name : "); + + ImGui::SameLine(); + + float width = ImGui::GetContentRegionAvail().x; + if (dlg_filters) width -= 120.0f; + ImGui::PushItemWidth(width); + ImGui::InputText("##FileName", FileNameBuffer, MAX_FILE_DIALOG_NAME_BUFFER); + ImGui::PopItemWidth(); + + if (dlg_filters) + { + ImGui::SameLine(); + + ImGui::PushItemWidth(100.0f); + bool comboClick = ImGui::Combo("##Filters", &FilterIndex, dlg_filters) || m_SelectedExt.size() == 0; + ImGui::PopItemWidth(); + if (comboClick == true) + { + int itemIdx = 0; + const char* p = dlg_filters; + while (*p) + { + if (FilterIndex == itemIdx) + { + m_SelectedExt = std::string(p); + break; + } + p += strlen(p) + 1; + itemIdx++; + } + } + } + + //width = ImGui::GetContentRegionAvail().x; + float button_width = 200.f; + if (ImGui::Button(" Cancel ", ImVec2(button_width, 0))) + { + IsOk = false; + res = true; + } + + if (_CanWeContinue) + { + ImGui::SameLine(); + float w = ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.x; + ImGui::Dummy(ImVec2(w - button_width, 0)); ImGui::SameLine(); // right align + if (ImGui::Button(" Ok ", ImVec2(button_width, 0))) + { + if ('\0' != FileNameBuffer[0]) + { + IsOk = true; + res = true; + } + } + ImGui::SetItemDefaultFocus(); + + } + + if(res) { + ImGui::CloseCurrentPopup(); + m_ShowDialog = false; + } + + ImGui::EndPopup(); + + } + + // ImGui::End(); + + if (res == true) + { + m_FileList.clear(); + } + + return res; + } + + return false; +} + +std::string FileDialog::GetFilepathName() +{ + std::string result = m_CurrentPath; + + if (s_fs_root != result) + { + result += PATH_SEP; + } + + result += GetCurrentFileName(); + + return result; +} + +std::string FileDialog::GetCurrentPath() +{ + return m_CurrentPath; +} + +std::string FileDialog::GetCurrentFileName() +{ + std::string result = FileNameBuffer; + + // size_t lastPoint = result.find_last_of('.'); + // if (lastPoint != std::string::npos) + // { + // result = result.substr(0, lastPoint); + // } + + // result += m_SelectedExt; + + return result; +} + +std::string FileDialog::GetCurrentFilter() +{ + return m_SelectedExt; +} + +std::string FileDialog::GetUserString() +{ + return dlg_userString; +} + +void FileDialog::SetFilterColor(std::string vFilter, ImVec4 vColor) +{ + m_FilterColor[vFilter] = vColor; +} + +bool FileDialog::GetFilterColor(std::string vFilter, ImVec4 *vColor) +{ + if (vColor) + { + if (m_FilterColor.find(vFilter) != m_FilterColor.end()) // found + { + *vColor = m_FilterColor[vFilter]; + return true; + } + } + return false;; +} + +void FileDialog::ClearFilterColor() +{ + m_FilterColor.clear(); +} diff --git a/FileDialog.h b/FileDialog.h new file mode 100644 index 0000000..68981c1 --- /dev/null +++ b/FileDialog.h @@ -0,0 +1,110 @@ +#ifndef __IMGUI_FILE_DIALOG_H_ +#define __IMGUI_FILE_DIALOG_H_ + +#include "imgui.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 m_FileList; + std::map m_FilterColor; + std::string m_SelectedFileName; + std::string m_SelectedExt; + std::string m_CurrentPath; + std::vector 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 dlg_optionsPane; + size_t dlg_optionsPaneWidth; + std::string searchTag; + std::string dlg_userString; + +public: + static FileDialog* Instance() + { + static FileDialog *_instance = new FileDialog(); + return _instance; + } + +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 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 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::iterator vIter); + void GetDrives(); +}; + + +#endif // __IMGUI_FILE_DIALOG_H_ \ No newline at end of file diff --git a/GstToolkit.cpp b/GstToolkit.cpp new file mode 100644 index 0000000..b9618d4 --- /dev/null +++ b/GstToolkit.cpp @@ -0,0 +1,27 @@ + +#include +#include + +#include + +#include "GstToolkit.h" + + +string GstToolkit::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; + + std::ostringstream oss; + if (s / 3600) + oss << std::setw(2) << std::setfill('0') << s / 3600 << ':'; + if ((s % 3600) / 60) + oss << std::setw(2) << std::setfill('0') << (s % 3600) / 60 << ':'; + oss << std::setw(2) << std::setfill('0') << (s % 3600) % 60 << '.'; + oss << std::setw(2) << std::setfill('0') << (ms % 1000) / 10; + + return oss.str(); +} diff --git a/GstToolkit.h b/GstToolkit.h new file mode 100644 index 0000000..040898d --- /dev/null +++ b/GstToolkit.h @@ -0,0 +1,15 @@ +#ifndef __GSTGUI_TOOLKIT_H_ +#define __GSTGUI_TOOLKIT_H_ + +#include +using namespace std; + + +namespace GstToolkit +{ + + string to_string(guint64 t); + +}; + +#endif // __GSTGUI_TOOLKIT_H_ \ No newline at end of file diff --git a/SettingsManager.h b/SettingsManager.h new file mode 100644 index 0000000..6d0d859 --- /dev/null +++ b/SettingsManager.h @@ -0,0 +1,52 @@ +#ifndef vlmixer_app_settings +#define vlmixer_app_settings + +#include +#include +using namespace std; + +class WindowSettings +{ +public: + int x,y,w,h; + string name; + bool fullscreen; + + WindowSettings() : x(0), y(0), w(100), h(100), name("Untitled"), fullscreen(false) + { + } + + WindowSettings(int x, int y, int w, int h, const string& name) + { + this->x=x; + this->y=y; + this->w=w; + this->h=h; + this->name=name; + this->fullscreen=false; + } +}; + +class AppSettings +{ +public: + string name; + string filename; + list windows; + float scale; + int color; + + AppSettings(const string& name); +}; + +class Settings +{ +public: + static AppSettings application; + + static void Save(); + static void Load(); + static void Check(); +}; + +#endif /* vlmixer_app_settings */ diff --git a/ShaderManager.cpp b/ShaderManager.cpp new file mode 100644 index 0000000..f2dd084 --- /dev/null +++ b/ShaderManager.cpp @@ -0,0 +1,123 @@ +#include "ShaderManager.h" +#include "ResourceManager.h" + +#include +#include +#include + +#include +#include +#include +#include +#define GLM_ENABLE_EXPERIMENTAL +#include + +Shader::Shader() { +} + +void Shader::load(const std::string& vertex_file, const std::string& fragment_file) { + + init(Resource::getText(vertex_file), Resource::getText(fragment_file)); +} + +void Shader::init(const std::string& vertex_code, const std::string& fragment_code) { + vertex_code_ = vertex_code; + fragment_code_ = fragment_code; + compile(); + link(); +} + +void Shader::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 Shader::link() { + id_ = glCreateProgram(); + glAttachShader(id_, vertex_id_); + glAttachShader(id_, fragment_id_); + glLinkProgram(id_); + checkLinkingErr(); + glDeleteShader(vertex_id_); + glDeleteShader(fragment_id_); +} + +void Shader::use() { + glUseProgram(id_); +} + +void Shader::enduse() { + glUseProgram(0); +} + +template<> +void Shader::setUniform(const std::string& name, int val) { + glUniform1i(glGetUniformLocation(id_, name.c_str()), val); +} + +template<> +void Shader::setUniform(const std::string& name, bool val) { + glUniform1i(glGetUniformLocation(id_, name.c_str()), val); +} + +template<> +void Shader::setUniform(const std::string& name, float val) { + glUniform1f(glGetUniformLocation(id_, name.c_str()), val); +} + +template<> +void Shader::setUniform(const std::string& name, glm::mat4 val) { + glm::mat4 m(val); + // std::cout << glm::to_string(m) << std::endl; + glUniformMatrix4fv(glGetUniformLocation(id_, name.c_str()), 1, GL_FALSE, glm::value_ptr(m)); +} + +template<> +void Shader::setUniform(const std::string& name, float val1, float val2) { + glUniform2f(glGetUniformLocation(id_, name.c_str()), val1, val2); +} + +template<> +void Shader::setUniform(const std::string& name, float val1, float val2, float val3) { + glUniform3f(glGetUniformLocation(id_, name.c_str()), val1, val2, val3); +} + +// template<> +// void Shader::setUniform(const std::string& name, float* val) { +// glUniformMatrix4fv(glGetUniformLocation(id_, name.c_str()), 1, GL_FALSE, val); +// } + +void Shader::checkCompileErr() { + int success; + char infoLog[1024]; + glGetShaderiv(vertex_id_, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(vertex_id_, 1024, NULL, infoLog); + std::cout << "Error compiling Vertex Shader:\n" << infoLog << std::endl; + std::cout << vertex_code_ << std::endl; + } + glGetShaderiv(fragment_id_, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(fragment_id_, 1024, NULL, infoLog); + std::cout << "Error compiling Fragment Shader:\n" << infoLog << std::endl; + std::cout << fragment_code_ << std::endl; + } +} + +void Shader::checkLinkingErr() { + int success; + char infoLog[1024]; + glGetProgramiv(id_, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(id_, 1024, NULL, infoLog); + std::cout << "Error Linking Shader Program:\n" << infoLog << std::endl; + } +} diff --git a/ShaderManager.h b/ShaderManager.h new file mode 100644 index 0000000..141c091 --- /dev/null +++ b/ShaderManager.h @@ -0,0 +1,31 @@ +#ifndef vlmixer_shader +#define vlmixer_shader + +#include +#include + +class Shader +{ +public: + Shader(); + void load(const std::string& vertex_rsc, const std::string& fragment_rsc); + void init(const std::string& vertex_code, const std::string& fragment_code); + void use(); + template void setUniform(const std::string& name, T val); + template void setUniform(const std::string& name, T val1, T val2); + template 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_; + +}; + +#endif /* vlmixer_shader */ diff --git a/defines.h b/defines.h new file mode 100644 index 0000000..0b36ea9 --- /dev/null +++ b/defines.h @@ -0,0 +1,59 @@ +#ifndef VMIX_DEFINES_H +#define VMIX_DEFINES_H + +#define APP_NAME "vmix" +#define APP_TITLE "v-mix -- Video Live Mixer" +#define APP_VERSION "0.0.1" + +#define MINI(a, b) (((a) < (b)) ? (a) : (b)) +#define MAXI(a, b) (((a) > (b)) ? (a) : (b)) +#define ABS(a) (((a) < 0) ? -(a) : (a)) +#define SIGN(a) (((a) < 0) ? -1.0 : 1.0) +#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) +#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 SOURCE_UNIT 10.0 +#define CIRCLE_SQUARE_DIST(x,y) ( (x*x + y*y) / (SOURCE_UNIT * SOURCE_UNIT * CIRCLE_SIZE * CIRCLE_SIZE) ) + +#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 MIN_SCALE 0.1 +#define MAX_SCALE 200.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_BGROUND 52, 52, 52 +#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 210, 30, 210 +#define COLOR_FRAME_MOVE 230, 30, 230 +#define COLOR_CURSOR 10, 100, 255 + +#define XML_PREFERENCE_FILE "vlmixer.xml" + +#endif // VMIX_DEFINES_H