diff --git a/CMakeLists.txt b/CMakeLists.txt index 405660c..94e6fd6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,9 @@ add_executable( linux-wallpaperengine main.cpp + src/Steam/FileSystem/FileSystem.h + src/Steam/FileSystem/FileSystem.cpp + src/WallpaperEngine/Logging/CLog.cpp src/WallpaperEngine/Logging/CLog.h @@ -83,6 +86,10 @@ add_executable( src/WallpaperEngine/Render/Shaders/Compiler.h src/WallpaperEngine/Render/Shaders/Compiler.cpp + src/WallpaperEngine/Render/Drivers/COpenGLDriver.h + src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp + src/WallpaperEngine/Render/Drivers/CVideoDriver.h + src/WallpaperEngine/Render/Drivers/CVideoDriver.cpp src/WallpaperEngine/Render/CRenderContext.h src/WallpaperEngine/Render/CRenderContext.cpp src/WallpaperEngine/Render/CTextureCache.h diff --git a/main.cpp b/main.cpp index 7b1765b..7b1f50f 100644 --- a/main.cpp +++ b/main.cpp @@ -1,15 +1,16 @@ -#include -#include -#include -#include -#include -#include #include -#include #include -#include #include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include "WallpaperEngine/Core/CProject.h" #include "WallpaperEngine/Render/CRenderContext.h" @@ -22,25 +23,18 @@ #include "WallpaperEngine/Assets/CCombinedContainer.h" #include "WallpaperEngine/Assets/CPackageLoadException.h" +#include "WallpaperEngine/Render/Drivers/COpenGLDriver.h" +#include "Steam/FileSystem/FileSystem.h" #include "common.h" +#define WORKSHOP_APP_ID 431960 +#define APP_DIRECTORY "wallpaper_engine" + float g_Time; float g_TimeLast; bool g_KeepRunning = true; int g_AudioVolume = 15; -const char* assets_default_paths [] = { - ".steam/steam/steamapps/common/wallpaper_engine/assets", - ".local/share/Steam/steamapps/common/wallpaper_engine/assets", - nullptr -}; - -const char* backgrounds_default_paths [] = { - ".local/share/Steam/steamapps/workshop/content/431960", - ".steam/steam/steamapps/workshop/content/431960", - nullptr -}; - void print_help (const char* route) { sLog.out ("Usage: ", route, " [options] background_path/background_id"); @@ -81,86 +75,11 @@ void signalhandler(int sig) g_KeepRunning = false; } -int handleValidatePath (const char* path, std::string& final) -{ - char finalPath [PATH_MAX]; - char* pointer = realpath (path, finalPath); - - if (pointer == nullptr) - return errno; - - // ensure the path points to a folder - struct stat pathinfo; - - if (stat (finalPath, &pathinfo) != 0) - return errno; - - if (!S_ISDIR (pathinfo.st_mode)) - return ENOTDIR; - - final = finalPath; - - return 0; -} - -void validatePath(const char* path, std::string& final) -{ - int error = handleValidatePath (path, final); - - switch (error) - { - case ENOTDIR: - sLog.exception ("Invalid directory, ", path, " is not a folder"); - break; - case ENAMETOOLONG: - sLog.exception ("Path ", path, " too long"); - break; - case 0: - return; - default: - sLog.exception ("Cannot find the specified folder"); - break; - } -} - -std::string getHomePath () -{ - char* home = getenv ("HOME"); - - if (home == nullptr) - sLog.exception ("Cannot find home directory for the current user"); - - std::string homepath; - - validatePath (home, homepath); - - return homepath; -} - -void initGLFW () -{ - // first of all, initialize the window - if (glfwInit () == GLFW_FALSE) - sLog.exception ("Failed to initialize GLFW"); - - // initialize freeimage - FreeImage_Initialise (TRUE); - - // set some window hints (opengl version to be used) - glfwWindowHint (GLFW_SAMPLES, 4); - glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - - if (DEBUG) - glfwWindowHint (GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); -} - -void addPkg (CCombinedContainer* containers, const std::string& path, std::string pkgfile) +void addPkg (CCombinedContainer* containers, const std::filesystem::path& path, std::string pkgfile) { try { - std::string scene_path = path + pkgfile; + auto scene_path = std::filesystem::path (path) / pkgfile; // add the package to the list containers->add (new WallpaperEngine::Assets::CPackage (scene_path)); @@ -278,7 +197,7 @@ CVirtualContainer* buildVirtualContainer () return container; } -void takeScreenshot (WallpaperEngine::Render::CWallpaper* wp, const std::string& filename, FREE_IMAGE_FORMAT format) +void takeScreenshot (WallpaperEngine::Render::CWallpaper* wp, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format) { GLint width, height; @@ -344,8 +263,8 @@ int main (int argc, char* argv[]) bool shouldListPropertiesAndStop = false; FREE_IMAGE_FORMAT screenshotFormat = FIF_UNKNOWN; std::string path; - std::string assetsDir; - std::string screenshotPath; + std::filesystem::path assetsPath; + std::filesystem::path screenshotPath; static struct option long_options [] = { {"screen-root", required_argument, 0, 'r'}, @@ -413,8 +332,7 @@ int main (int argc, char* argv[]) maximumFPS = atoi (optarg); break; - case 'a': - assetsDir = optarg; + case 'a': assetsPath = optarg; break; case 'v': @@ -444,103 +362,60 @@ int main (int argc, char* argv[]) // validate screenshot file just to make sure if (shouldTakeScreenshot == true) { - // ensure the file is one of the supported formats - std::string extension = screenshotPath.substr (screenshotPath.find_last_of (".") + 1); + if (screenshotPath.has_extension () == false) + sLog.exception ("Cannot determine screenshot format"); - if (extension == "bmp") + std::string extension = screenshotPath.extension (); + + if (extension == ".bmp") screenshotFormat = FIF_BMP; - else if (extension == "png") + else if (extension == ".png") screenshotFormat = FIF_PNG; - else if (extension == "jpg" || extension == "jpeg") + else if (extension == ".jpg" || extension == ".jpeg") screenshotFormat = FIF_JPEG; else - sLog.exception ("Unsupported screenshot format ", extension); + sLog.exception ("Cannot determine screenshot format, unknown extension ", extension); } - std::string homepath = getHomePath (); - auto containers = new WallpaperEngine::Assets::CCombinedContainer (); - // check if the background might be an ID and try to find the right path in the steam installation folder if (path.find ('/') == std::string::npos) - { - for (const char** current = backgrounds_default_paths; *current != nullptr; current ++) - { - std::string tmppath = homepath + "/" + *current + "/" + path; - - int error = handleValidatePath (tmppath.c_str (), tmppath); - - if (error != 0) - continue; - - path = tmppath; - } - } - - validatePath (path.c_str (), path); - - // add a trailing slash to the path so the right file can be found - path += "/"; + path = Steam::FileSystem::workshopDirectory (WORKSHOP_APP_ID, path); + WallpaperEngine::Assets::CCombinedContainer containers; // the background's path is required to load project.json regardless of the type of background we're using - containers->add (new WallpaperEngine::Assets::CDirectory (path)); + containers.add (new WallpaperEngine::Assets::CDirectory (path)); // add the virtual container for mocked up files - containers->add (buildVirtualContainer ()); + containers.add (buildVirtualContainer ()); // try to add the common packages - addPkg (containers, path, "scene.pkg"); - addPkg (containers, path, "gifscene.pkg"); + addPkg (&containers, path, "scene.pkg"); + addPkg (&containers, path, "gifscene.pkg"); - if (assetsDir.empty () == true) + if (assetsPath.empty () == true) { - for (const char** current = assets_default_paths; *current != nullptr; current ++) + try { - std::string tmppath = homepath + "/" + *current; - - int error = handleValidatePath (tmppath.c_str (), tmppath); - - if (error != 0) - continue; - - assetsDir = tmppath; - sLog.out ("Found wallpaper engine's assets at ", assetsDir); - break; + assetsPath = Steam::FileSystem::appDirectory (APP_DIRECTORY, "assets"); } - - if (assetsDir.empty () == true) + catch (std::runtime_error) { - unsigned long len = strlen (argv [0]) + 1; - char* copy = new char[len]; - - strncpy (copy, argv [0], len); - - // path still not found, try one last thing on the current binary's folder - std::string exepath = dirname (copy); - exepath += "/assets"; - - int error = handleValidatePath (exepath.c_str (), exepath); - - if (error == 0) - { - assetsDir = exepath; - sLog.out ("Found assets folder alongside the binary: ", assetsDir); - } - - delete[] copy; + // set current path as assets' folder + std::filesystem::path directory = std::filesystem::canonical ("/proc/self/exe") + .parent_path () / "assets"; } } else { - validatePath (assetsDir.c_str (), assetsDir); - sLog.out ("Found wallpaper engine's assets at ", assetsDir, " based on --assets-dir parameter"); + sLog.out ("Found wallpaper engine's assets at ", assetsPath, " based on --assets-dir parameter"); } - if (assetsDir.empty () == true) + if (assetsPath.empty () == true) sLog.exception ("Cannot determine a valid path for the wallpaper engine assets"); // add containers to the list - containers->add (new WallpaperEngine::Assets::CDirectory (assetsDir + "/")); + containers.add (new WallpaperEngine::Assets::CDirectory (assetsPath)); // parse the project.json file - auto project = WallpaperEngine::Core::CProject::fromFile ("project.json", containers); + auto project = WallpaperEngine::Core::CProject::fromFile ("project.json", &containers); // go to the right folder so the videos will play if (project->getWallpaper ()->is () == true) chdir (path.c_str ()); @@ -570,98 +445,49 @@ int main (int argc, char* argv[]) std::signal(SIGINT, signalhandler); std::signal(SIGTERM, signalhandler); - // initialize glfw - initGLFW (); - - // auto projection = project->getWallpaper ()->as ()->getOrthogonalProjection (); - // create the window! - // TODO: DO WE NEED TO PASS MONITOR HERE OR ANYTHING? - // TODO: FIGURE OUT HOW TO PUT THIS WINDOW IN THE BACKGROUND - GLFWwindow* window = glfwCreateWindow (1920, 1080, "WallpaperEngine", NULL, NULL); - - if (window == nullptr) - { - sLog.error ("GLFW", "Failed to open a GLFW window"); - glfwTerminate (); - return 2; - } - - glfwMakeContextCurrent (window); - - // TODO: FIGURE THESE OUT BASED ON THE SCREEN - int windowWidth = 1920; - int windowHeight = 1080; - - // get the real framebuffer size - glfwGetFramebufferSize (window, &windowWidth, &windowHeight); - - GLenum glewInitResult = glewInit (); - // initialize glew - if (glewInitResult != GLEW_OK) - { - sLog.error ("GLEW", "Failed to initialize GLEW: ", glewGetErrorString (glewInitResult)); - glfwTerminate (); - return 3; - } - if (shouldEnableAudio == true && SDL_Init (SDL_INIT_AUDIO) < 0) { - sLog.error ("SDL", "Cannot initialize SDL audio system, SDL_GetError: ", SDL_GetError()); - sLog.error ("SDL", "Continuing without audio support"); + sLog.error ("Cannot initialize SDL audio system, SDL_GetError: ", SDL_GetError()); + sLog.error ("Continuing without audio support"); } + // initialize OpenGL driver + WallpaperEngine::Render::Drivers::COpenGLDriver videoDriver ("Wallpaper Engine"); // initialize custom context class - WallpaperEngine::Render::CRenderContext* context = new WallpaperEngine::Render::CRenderContext (screens, window, containers); + WallpaperEngine::Render::CRenderContext context (screens, videoDriver, &containers); // initialize mouse support - context->setMouse (new CMouseInput (window)); - // set the default viewport - context->setDefaultViewport ({0, 0, windowWidth, windowHeight}); + context.setMouse (new CMouseInput (videoDriver.getWindow ())); // ensure the context knows what wallpaper to render - context->setWallpaper ( - WallpaperEngine::Render::CWallpaper::fromWallpaper (project->getWallpaper (), context) + context.setWallpaper ( + WallpaperEngine::Render::CWallpaper::fromWallpaper (project->getWallpaper (), &context) ); // update maximum FPS if it's a video - if (context->getWallpaper ()->is () == true) - maximumFPS = context->getWallpaper ()->as ()->getFPS (); + if (context.getWallpaper ()->is () == true) + maximumFPS = context.getWallpaper ()->as ()->getFPS (); - // TODO: FIGURE OUT THE REQUIRED INPUT MODE, AS SOME WALLPAPERS USE THINGS LIKE MOUSE POSITION - // glfwSetInputMode (window, GLFW_STICKY_KEYS, GL_TRUE); + float startTime, endTime, minimumTime = 1.0f / maximumFPS; - double startTime, endTime, minimumTime = 1.0 / maximumFPS; - - uint32_t frameCounter = 0; - - while (glfwWindowShouldClose (window) == 0 && g_KeepRunning == true) + while (videoDriver.closeRequested () == false && g_KeepRunning == true) { - // get the real framebuffer size - glfwGetFramebufferSize (window, &windowWidth, &windowHeight); - // set the default viewport - context->setDefaultViewport ({0, 0, windowWidth, windowHeight}); // keep track of the previous frame's time g_TimeLast = g_Time; // calculate the current time value - g_Time = (float) glfwGetTime (); + g_Time = videoDriver.getRenderTime (); // get the start time of the frame - startTime = glfwGetTime (); + startTime = g_Time; // render the scene - context->render (); - // do buffer swapping - glfwSwapBuffers (window); - // poll for events (like closing the window) - glfwPollEvents (); + context.render (); // get the end time of the frame - endTime = glfwGetTime (); + endTime = videoDriver.getRenderTime (); // ensure the frame time is correct to not overrun FPS if ((endTime - startTime) < minimumTime) usleep ((minimumTime - (endTime - startTime)) * CLOCKS_PER_SEC); - frameCounter ++; - - if (frameCounter == 5 && shouldTakeScreenshot == true) + if (shouldTakeScreenshot == true && videoDriver.getFrameCounter () == 5) { - takeScreenshot (context->getWallpaper (), screenshotPath, screenshotFormat); + takeScreenshot (context.getWallpaper (), screenshotPath, screenshotFormat); // disable screenshot just in case the counter overflows shouldTakeScreenshot = false; } @@ -672,16 +498,9 @@ int main (int argc, char* argv[]) sLog.out ("Stop requested"); - // terminate gl - glfwTerminate (); - // terminate free image - FreeImage_DeInitialise (); // terminate SDL SDL_QuitSubSystem(SDL_INIT_AUDIO); SDL_Quit (); - // free context - delete context; - return 0; } \ No newline at end of file diff --git a/src/Steam/FileSystem/FileSystem.cpp b/src/Steam/FileSystem/FileSystem.cpp new file mode 100644 index 0000000..9a1463f --- /dev/null +++ b/src/Steam/FileSystem/FileSystem.cpp @@ -0,0 +1,68 @@ +#include "FileSystem.h" +#include "WallpaperEngine/Logging/CLog.h" +#include +#include +#include +#include +#include + +const char* assets_default_paths [] = { + ".steam/steam/steamapps/common", + ".local/share/Steam/steamapps/common", + nullptr +}; + +const char* workshop_content_default_paths [] = { + ".local/share/Steam/steamapps/workshop/content", + ".steam/steam/steamapps/workshop/content", + nullptr +}; + +std::filesystem::path detectHomepath () +{ + char* home = getenv ("HOME"); + + if (home == nullptr) + sLog.exception ("Cannot find home directory for the current user"); + + std::filesystem::path path = home; + + if (std::filesystem::is_directory (path) == false) + sLog.exception ("Cannot find home directory for current user, ", home, " is not a directory"); + + return home; +} + +std::filesystem::path Steam::FileSystem::workshopDirectory (int appID, const std::string& contentID) +{ + auto homepath = detectHomepath (); + + for (const char** current = workshop_content_default_paths; *current != nullptr; current ++) + { + auto currentpath = std::filesystem::path (homepath) / *current / std::to_string (appID) / contentID; + + if (std::filesystem::exists (currentpath) == false || std::filesystem::is_directory (currentpath) == false) + continue; + + return currentpath; + } + + sLog.exception ("Cannot find workshop directory for steam app ", appID, " and content ", contentID); +} + +std::filesystem::path Steam::FileSystem::appDirectory (const std::string& appDirectory, const std::string& path) +{ + auto homepath = detectHomepath (); + + for (const char** current = assets_default_paths; *current != nullptr; current ++) + { + auto currentpath = std::filesystem::path (homepath) / *current / appDirectory / path; + + if (std::filesystem::exists (currentpath) == false || std::filesystem::is_directory (currentpath) == false) + continue; + + return currentpath; + } + + sLog.exception ("Cannot find directory for steam app ", appDirectory, ": ", path); +} \ No newline at end of file diff --git a/src/Steam/FileSystem/FileSystem.h b/src/Steam/FileSystem/FileSystem.h new file mode 100644 index 0000000..5f39cd0 --- /dev/null +++ b/src/Steam/FileSystem/FileSystem.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include +namespace Steam::FileSystem +{ + std::filesystem::path workshopDirectory (int appID, const std::string& contentID); + std::filesystem::path appDirectory (const std::string& appDirectory, const std::string& path); +} \ No newline at end of file diff --git a/src/WallpaperEngine/Assets/CCombinedContainer.cpp b/src/WallpaperEngine/Assets/CCombinedContainer.cpp index 2670d12..2664bc5 100644 --- a/src/WallpaperEngine/Assets/CCombinedContainer.cpp +++ b/src/WallpaperEngine/Assets/CCombinedContainer.cpp @@ -10,16 +10,13 @@ void CCombinedContainer::add (CContainer* container) const void* CCombinedContainer::readFile (std::string filename, uint32_t* length) const { - auto cur = this->m_containers.begin (); - auto end = this->m_containers.end (); - - for (; cur != end; cur ++) + for (auto cur : this->m_containers) { try { // try to read the file on the current container, if the file doesn't exists // an exception will be thrown - return (*cur)->readFile (filename, length); + return cur->readFile (filename, length); } catch (CAssetLoadException& ex) { diff --git a/src/WallpaperEngine/Assets/CCombinedContainer.h b/src/WallpaperEngine/Assets/CCombinedContainer.h index 282a820..ffe9125 100644 --- a/src/WallpaperEngine/Assets/CCombinedContainer.h +++ b/src/WallpaperEngine/Assets/CCombinedContainer.h @@ -14,9 +14,6 @@ namespace WallpaperEngine::Assets class CCombinedContainer : public CContainer { public: - CCombinedContainer () {} - ~CCombinedContainer () {} - /** * Adds a container to the list * diff --git a/src/WallpaperEngine/Assets/CDirectory.cpp b/src/WallpaperEngine/Assets/CDirectory.cpp index cecb022..dcf81dc 100644 --- a/src/WallpaperEngine/Assets/CDirectory.cpp +++ b/src/WallpaperEngine/Assets/CDirectory.cpp @@ -1,13 +1,15 @@ #include "common.h" #include +#include + #include "CDirectory.h" #include "CAssetLoadException.h" using namespace WallpaperEngine::Assets; -CDirectory::CDirectory (std::string basepath) : - m_basepath (std::move (basepath)) +CDirectory::CDirectory (std::filesystem::path basepath) : + m_basepath (std::move(basepath)) { // ensure the specified path exists struct stat buffer; @@ -26,7 +28,7 @@ CDirectory::~CDirectory () const void* CDirectory::readFile (std::string filename, uint32_t* length) const { - std::string final = this->m_basepath + filename; + std::filesystem::path final = std::filesystem::path (this->m_basepath) / filename; // first check the cache, if the file is there already just return the data in there auto it = this->m_cache.find (final); diff --git a/src/WallpaperEngine/Assets/CDirectory.h b/src/WallpaperEngine/Assets/CDirectory.h index 34366eb..caa8218 100644 --- a/src/WallpaperEngine/Assets/CDirectory.h +++ b/src/WallpaperEngine/Assets/CDirectory.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "CContainer.h" #include "CFileEntry.h" @@ -12,12 +13,12 @@ namespace WallpaperEngine::Assets class CDirectory : public CContainer { public: - CDirectory (std::string basepath); + CDirectory (std::filesystem::path basepath); ~CDirectory (); const void* readFile (std::string filename, uint32_t* length) const override; private: - std::string m_basepath; + std::filesystem::path m_basepath; std::map m_cache; }; }; \ No newline at end of file diff --git a/src/WallpaperEngine/Assets/CPackage.cpp b/src/WallpaperEngine/Assets/CPackage.cpp index 4b9fdb3..3a5f869 100644 --- a/src/WallpaperEngine/Assets/CPackage.cpp +++ b/src/WallpaperEngine/Assets/CPackage.cpp @@ -21,8 +21,8 @@ public: uint32_t length; }; -CPackage::CPackage (const std::string& path) : - m_path (path), +CPackage::CPackage (std::filesystem::path path) : + m_path (std::move(path)), m_contents () { this->init (); @@ -150,32 +150,25 @@ void CPackage::loadFiles (FILE* fp) // get current baseOffset, this is where the files start long baseOffset = ftell (fp); - // read file contents now - auto cur = list.begin (); - auto end = list.end (); - - for (; cur != end; cur ++) + for (const auto& cur : list) { - long offset = (*cur).offset + baseOffset; + long offset = cur.offset + baseOffset; // with all the data we can jump to the offset and read the content if (fseek (fp, offset, SEEK_SET) != 0) - sLog.exception ("Cannot find file ", (*cur).filename, " from package ", this->m_path); + sLog.exception ("Cannot find file ", cur.filename, " from package ", this->m_path); // allocate memory for the file's contents and read it from the file - char* fileContents = new char [(*cur).length]; + char* fileContents = new char [cur.length]; - if (fread (fileContents, (*cur).length, 1, fp) != 1) + if (fread (fileContents, cur.length, 1, fp) != 1) { delete[] fileContents; - sLog.exception ("Cannot read file ", (*cur).filename, " contents from package ", this->m_path); + sLog.exception ("Cannot read file ", cur.filename, " contents from package ", this->m_path); } // add the file to the map - this->m_contents.insert (std::make_pair ( - std::move((*cur).filename), - CFileEntry (fileContents, (*cur).length)) - ); + this->m_contents.insert_or_assign (cur.filename, CFileEntry (fileContents, cur.length)); } } \ No newline at end of file diff --git a/src/WallpaperEngine/Assets/CPackage.h b/src/WallpaperEngine/Assets/CPackage.h index c84c2e1..bef2f45 100644 --- a/src/WallpaperEngine/Assets/CPackage.h +++ b/src/WallpaperEngine/Assets/CPackage.h @@ -1,7 +1,3 @@ -// -// Created by almamu on 8/8/21. -// - #pragma once #include @@ -10,6 +6,7 @@ #include #include #include +#include #include "CContainer.h" #include "CFileEntry.h" @@ -19,7 +16,7 @@ namespace WallpaperEngine::Assets class CPackage : public CContainer { public: - CPackage (const std::string& path); + CPackage (std::filesystem::path path); ~CPackage (); const void* readFile (std::string filename, uint32_t* length) const override; @@ -62,7 +59,7 @@ namespace WallpaperEngine::Assets uint32_t readInteger (FILE* fp); private: - std::string m_path; + std::filesystem::path m_path; std::map m_contents; }; } diff --git a/src/WallpaperEngine/Assets/CTexture.cpp b/src/WallpaperEngine/Assets/CTexture.cpp index 51256a7..52011e3 100644 --- a/src/WallpaperEngine/Assets/CTexture.cpp +++ b/src/WallpaperEngine/Assets/CTexture.cpp @@ -322,16 +322,10 @@ CTexture::TextureHeader::TextureHeader () CTexture::TextureHeader::~TextureHeader () { - auto imgCur = this->images.begin (); - auto imgEnd = this->images.end (); - - for (; imgCur != imgEnd; imgCur ++) + for (const auto& imgCur : this->images) { - auto cur = (*imgCur).second.begin (); - auto end = (*imgCur).second.end (); - - for (; cur != end; cur ++) - delete *cur; + for (auto cur : imgCur.second) + delete cur; } } diff --git a/src/WallpaperEngine/Core/CObject.cpp b/src/WallpaperEngine/Core/CObject.cpp index 23e3af2..fe57b36 100644 --- a/src/WallpaperEngine/Core/CObject.cpp +++ b/src/WallpaperEngine/Core/CObject.cpp @@ -121,28 +121,20 @@ CObject* CObject::fromJSON (json data, CScene* scene, const CContainer* containe if (effects_it != data.end () && (*effects_it).is_array () == true) { - auto cur = (*effects_it).begin (); - auto end = (*effects_it).end (); - - for (; cur != end; cur ++) + for (const auto& cur : *effects_it) { auto effectVisible = jsonFindUserConfig (data, "visible", true); object->insertEffect ( - Objects::CEffect::fromJSON (*cur, effectVisible, object, container) + Objects::CEffect::fromJSON (cur, effectVisible, object, container) ); } } if (dependencies_it != data.end () && (*dependencies_it).is_array () == true) { - auto cur = (*dependencies_it).begin (); - auto end = (*dependencies_it).end (); - - for (; cur != end; cur ++) - { - object->insertDependency (*cur); - } + for (const auto& cur : *dependencies_it) + object->insertDependency (cur); } return object; diff --git a/src/WallpaperEngine/Core/CProject.cpp b/src/WallpaperEngine/Core/CProject.cpp index d111ef1..c48d7db 100644 --- a/src/WallpaperEngine/Core/CProject.cpp +++ b/src/WallpaperEngine/Core/CProject.cpp @@ -56,12 +56,9 @@ CProject* CProject::fromFile (const std::string& filename, CContainer* container if (properties != (*general).end ()) { - auto cur = (*properties).begin (); - auto end = (*properties).end (); - - for (; cur != end; cur ++) + for (const auto& cur : (*properties).items ()) { - Projects::CProperty* property = Projects::CProperty::fromJSON (*cur, cur.key ()); + Projects::CProperty* property = Projects::CProperty::fromJSON (cur.value (), cur.key ()); if (property != nullptr) project->insertProperty (property); diff --git a/src/WallpaperEngine/Core/CScene.cpp b/src/WallpaperEngine/Core/CScene.cpp index b353b05..ae19710 100644 --- a/src/WallpaperEngine/Core/CScene.cpp +++ b/src/WallpaperEngine/Core/CScene.cpp @@ -101,15 +101,8 @@ CScene* CScene::fromFile (const std::string& filename, CContainer* container) WallpaperEngine::Core::aToColorf(skylightcolor) ); - auto cur = (*objects_it).begin (); - auto end = (*objects_it).end (); - - for (; cur != end; cur ++) - { - scene->insertObject ( - CObject::fromJSON (*cur, scene, container) - ); - } + for (const auto& cur : *objects_it) + scene->insertObject (CObject::fromJSON (cur, scene, container)); return scene; } diff --git a/src/WallpaperEngine/Core/Objects/CEffect.cpp b/src/WallpaperEngine/Core/Objects/CEffect.cpp index 4894024..277f7b4 100644 --- a/src/WallpaperEngine/Core/Objects/CEffect.cpp +++ b/src/WallpaperEngine/Core/Objects/CEffect.cpp @@ -84,21 +84,17 @@ CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, Core::CObje Images::CMaterial* material = effect->getMaterials ().at (passNumber); - auto passCur = material->getPasses ().begin (); - auto passEnd = material->getPasses ().end (); - - for (; passCur != passEnd; passCur ++) + for (const auto& passCur : material->getPasses ()) { if (textures_it != (*cur).end ()) { - auto texturesCur = (*textures_it).begin (); - auto texturesEnd = (*textures_it).end (); + int textureNumber = 0; - for (int textureNumber = 0; texturesCur != texturesEnd; texturesCur ++) + for (const auto& texturesCur : (*textures_it)) { std::string texture; - if ((*texturesCur).is_null () == true) + if (texturesCur.is_null () == true) { if (textureNumber == 0) { @@ -113,15 +109,15 @@ CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, Core::CObje } else { - texture = *texturesCur; + texture = texturesCur; } - std::vector passTextures = (*passCur)->getTextures (); + std::vector passTextures = passCur->getTextures (); if (textureNumber < passTextures.size ()) - (*passCur)->setTexture (textureNumber, texture); + passCur->setTexture (textureNumber, texture); else - (*passCur)->insertTexture (texture); + passCur->insertTexture (texture); textureNumber ++; } @@ -129,12 +125,12 @@ CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, Core::CObje if (combos_it != (*cur).end ()) { - CEffect::combosFromJSON (combos_it, *passCur); + CEffect::combosFromJSON (combos_it, passCur); } if (constants_it != (*cur).end ()) { - CEffect::constantsFromJSON (constants_it, *passCur); + CEffect::constantsFromJSON (constants_it, passCur); } } } @@ -145,23 +141,15 @@ CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, Core::CObje void CEffect::combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass) { - auto cur = (*combos_it).begin (); - auto end = (*combos_it).end (); - - for (; cur != end; cur ++) - { - pass->insertCombo (cur.key (), *cur); - } + for (const auto& cur : (*combos_it).items ()) + pass->insertCombo (cur.key (), cur.value ()); } void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPass* pass) { - auto cur = (*constants_it).begin (); - auto end = (*constants_it).end (); - - for (; cur != end; cur ++) + for (auto& cur : (*constants_it).items ()) { - json::const_iterator val = cur; + auto val = cur.value (); Effects::Constants::CShaderConstant* constant = nullptr; @@ -169,33 +157,35 @@ void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Object // for the UI, take the value, which is what we need // TODO: SUPPORT USER SETTINGS HERE - if ((*cur).is_object () == true) + if (cur.value ().is_object () == true) { - val = (*cur).find ("value"); + auto it = cur.value ().find ("value"); - if (val == (*cur).end ()) + if (it == cur.value ().end ()) { sLog.error ("Found object for shader constant without \"value\" member"); continue; } + + val = it.value (); } - if ((*val).is_number_float () == true) + if (val.is_number_float () == true) { - constant = new Effects::Constants::CShaderConstantFloat ((*val).get ()); + constant = new Effects::Constants::CShaderConstantFloat (val.get ()); } - else if ((*val).is_number_integer () == true) + else if (val.is_number_integer () == true) { - constant = new Effects::Constants::CShaderConstantInteger ((*val).get ()); + constant = new Effects::Constants::CShaderConstantInteger (val.get ()); } - else if ((*val).is_string () == true) + else if (val.is_string () == true) { // try a vector 4 first, then a vector3 and then a vector 2 - constant = new Effects::Constants::CShaderConstantVector4 (WallpaperEngine::Core::aToVector4 (*val)); + constant = new Effects::Constants::CShaderConstantVector4 (WallpaperEngine::Core::aToVector4 (val)); } else { - sLog.exception ("unknown shader constant type ", *val); + sLog.exception ("unknown shader constant type ", val); } pass->insertConstant (cur.key (), constant); @@ -204,64 +194,38 @@ void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Object void CEffect::fbosFromJSON (json::const_iterator fbos_it, CEffect* effect) { - auto cur = (*fbos_it).begin (); - auto end = (*fbos_it).end (); - - for (; cur != end; cur ++) - { - effect->insertFBO ( - Effects::CFBO::fromJSON (*cur) - ); - } + for (const auto& cur : (*fbos_it)) + effect->insertFBO (Effects::CFBO::fromJSON (cur)); } void CEffect::dependencyFromJSON (json::const_iterator dependencies_it, CEffect* effect) { - auto cur = (*dependencies_it).begin (); - auto end = (*dependencies_it).end (); - - for (; cur != end; cur ++) - { - effect->insertDependency (*cur); - } + for (const auto& cur : (*dependencies_it)) + effect->insertDependency (cur); } void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect, const CContainer* container) { - auto cur = (*passes_it).begin (); - auto end = (*passes_it).end (); - - for (; cur != end; cur ++) + for (const auto& cur : (*passes_it)) { - auto materialfile = (*cur).find ("material"); - auto target = (*cur).find ("target"); - auto bind = (*cur).find ("bind"); + auto materialfile = cur.find ("material"); + auto target = cur.find ("target"); + auto bind = cur.find ("bind"); - if (materialfile == (*cur).end ()) + if (materialfile == cur.end ()) sLog.exception ("Found an effect ", effect->m_name, " without material"); Images::CMaterial* material = nullptr; - if (target == (*cur).end ()) - { + if (target == cur.end ()) material = Images::CMaterial::fromFile ((*materialfile).get (), container); - } else - { material = Images::CMaterial::fromFile ((*materialfile).get (), *target, container); - } - if (bind != (*cur).end ()) + if (bind != cur.end ()) { - auto bindCur = (*bind).begin (); - auto bindEnd = (*bind).end (); - - for (; bindCur != bindEnd; bindCur ++) - { - material->insertTextureBind ( - Effects::CBind::fromJSON (*bindCur) - ); - } + for (const auto& bindCur : (*bind)) + material->insertTextureBind (Effects::CBind::fromJSON (bindCur)); } effect->insertMaterial (material); @@ -290,16 +254,9 @@ bool CEffect::isVisible () const Effects::CFBO* CEffect::findFBO (const std::string& name) { - auto cur = this->m_fbos.begin (); - auto end = this->m_fbos.end (); - - for (; cur != end; cur ++) - { - if ((*cur)->getName () == name) - { - return (*cur); - } - } + for (const auto& cur : this->m_fbos) + if (cur->getName () == name) + return cur; sLog.exception ("cannot find fbo ", name); } diff --git a/src/WallpaperEngine/Core/Objects/CParticle.cpp b/src/WallpaperEngine/Core/Objects/CParticle.cpp index b4f175d..635ac49 100644 --- a/src/WallpaperEngine/Core/Objects/CParticle.cpp +++ b/src/WallpaperEngine/Core/Objects/CParticle.cpp @@ -33,36 +33,14 @@ CParticle* CParticle::fromFile ( if (controlpoint_it != data.end ()) { - auto cur = (*controlpoint_it).begin (); - auto end = (*controlpoint_it).end (); - - for (; cur != end; cur ++) - { - particle->insertControlPoint ( - Particles::CControlPoint::fromJSON (*cur) - ); - } + for (const auto& cur : (*controlpoint_it)) + particle->insertControlPoint (Particles::CControlPoint::fromJSON (cur)); } - auto cur = (*emitter_it).begin (); - auto end = (*emitter_it).end (); - - for (; cur != end; cur ++) - { - particle->insertEmitter ( - Particles::CEmitter::fromJSON (*cur) - ); - } - - cur = (*initializer_it).begin (); - end = (*initializer_it).end (); - - for (; cur != end; cur ++) - { - particle->insertInitializer ( - Particles::CInitializer::fromJSON (*cur) - ); - } + for (const auto& cur : (*emitter_it)) + particle->insertEmitter (Particles::CEmitter::fromJSON (cur)); + for (const auto&cur : (*initializer_it)) + particle->insertInitializer (Particles::CInitializer::fromJSON (cur)); return particle; } diff --git a/src/WallpaperEngine/Core/Objects/CSound.cpp b/src/WallpaperEngine/Core/Objects/CSound.cpp index 245da50..31b05cc 100644 --- a/src/WallpaperEngine/Core/Objects/CSound.cpp +++ b/src/WallpaperEngine/Core/Objects/CSound.cpp @@ -42,13 +42,8 @@ WallpaperEngine::Core::CObject* CSound::fromJSON ( angles ); - auto cur = (*sound_it).begin (); - auto end = (*sound_it).end (); - - for (; cur != end; cur ++) - { - sound->insertSound (*cur); - } + for (const auto& cur : (*sound_it)) + sound->insertSound (cur); return sound; } diff --git a/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp b/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp index 36ddd62..43d6daf 100644 --- a/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp +++ b/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp @@ -43,15 +43,8 @@ CMaterial* CMaterial::fromJSON (const std::string& name, json data) CMaterial* material = new CMaterial (name); - auto cur = (*passes_it).begin (); - auto end = (*passes_it).end (); - - for (; cur != end; cur ++) - { - material->insertPass ( - Materials::CPass::fromJSON (*cur) - ); - } + for (const auto& cur : (*passes_it)) + material->insertPass (Materials::CPass::fromJSON (cur)); return material; } diff --git a/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp b/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp index 01e57a1..db55dda 100644 --- a/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp +++ b/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp @@ -41,39 +41,29 @@ CPass* CPass::fromJSON (json data) if (textures_it != data.end ()) { - auto cur = (*textures_it).begin (); - auto end = (*textures_it).end (); - - for (;cur != end; cur ++) + for (const auto& cur : (*textures_it)) { - if ((*cur).is_null () == true) + if (cur.is_null () == true) { pass->insertTexture (""); } else { - pass->insertTexture (*cur); + pass->insertTexture (cur); } } } if (combos_it != data.end ()) { - auto cur = (*combos_it).begin (); - auto end = (*combos_it).end (); - - for (; cur != end; cur ++) + for (const auto& cur : (*combos_it).items ()) { std::string name = cur.key (); - if ((*cur).is_number_integer () == true) - { - pass->insertCombo (name, *cur); - } + if (cur.value ().is_number_integer () == true) + pass->insertCombo (name, cur.value ()); else - { sLog.exception ("unexpected non-integer combo on pass"); - } } } diff --git a/src/WallpaperEngine/Core/Projects/CPropertyCombo.cpp b/src/WallpaperEngine/Core/Projects/CPropertyCombo.cpp index 03e23b8..c32dfa0 100644 --- a/src/WallpaperEngine/Core/Projects/CPropertyCombo.cpp +++ b/src/WallpaperEngine/Core/Projects/CPropertyCombo.cpp @@ -23,20 +23,15 @@ CPropertyCombo* CPropertyCombo::fromJSON (json data, const std::string& name) if (options->is_array () == false) sLog.exception ("Property combo options should be an array"); - auto cur = (*options).begin (); - auto end = (*options).end (); - - for (; cur != end; cur ++) + for (auto& cur : (*options)) { - if ((*cur).is_object () == false) - { - // TODO: PROPERLY REPORT THESE ISSUES + // TODO: PROPERLY REPORT THESE ISSUES + if (cur.is_object () == false) continue; - } // check for label and value to ensure they're there - auto label = jsonFindRequired (*cur, "label", "Label is required for a property combo option"); - auto value = jsonFindRequired (*cur, "value", "Value is required for a property combo option"); + auto label = jsonFindRequired (cur, "label", "Label is required for a property combo option"); + auto value = jsonFindRequired (cur, "value", "Value is required for a property combo option"); combo->addValue (*label, *value); } diff --git a/src/WallpaperEngine/Render/CRenderContext.cpp b/src/WallpaperEngine/Render/CRenderContext.cpp index 660a18e..0cd76b7 100644 --- a/src/WallpaperEngine/Render/CRenderContext.cpp +++ b/src/WallpaperEngine/Render/CRenderContext.cpp @@ -12,6 +12,9 @@ #include "CRenderContext.h" #include "CVideo.h" +#define DEFAULT_WINDOW_WIDTH 1280 +#define DEFAULT_WINDOW_HEIGHT 720 + using namespace WallpaperEngine::Render; XErrorHandler originalErrorHandler; @@ -25,7 +28,7 @@ void CustomXIOErrorExitHandler (Display* dsp, void* userdata) #endif /* DEBUG */ // refetch all the resources - context->initializeViewports (); + context->initialize (); } int CustomXErrorHandler (Display* dpy, XErrorEvent* event) @@ -49,24 +52,32 @@ int CustomXIOErrorHandler (Display* dsp) return 0; } -CRenderContext::CRenderContext (std::vector screens, GLFWwindow* window, CContainer* container) : +CRenderContext::CRenderContext (std::vector screens, CVideoDriver& driver, CContainer* container) : m_wallpaper (nullptr), m_screens (std::move (screens)), - m_isRootWindow (m_screens.empty () == false), - m_defaultViewport ({0, 0, 1920, 1080}), - m_window (window), + m_driver (driver), m_container (container), m_textureCache (new CTextureCache (this)) { - this->initializeViewports (); + this->initialize (); } -void CRenderContext::initializeViewports () +void CRenderContext::initialize () { - if (this->m_isRootWindow == false || this->m_screens.empty () == true) - return; + if (this->m_screens.empty () == true) + this->setupWindow (); + else + this->setupScreens (); +} - // clear the viewports we're drawing to +void CRenderContext::setupWindow () +{ + this->m_driver.showWindow (); + this->m_driver.resizeWindow ({DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT}); +} + +void CRenderContext::setupScreens () +{ this->m_viewports.clear (); this->m_display = XOpenDisplay (nullptr); @@ -86,9 +97,6 @@ void CRenderContext::initializeViewports () return; } - // hide the glfw window if the viewports are to be detected - glfwHideWindow (this->m_window); - Window root = DefaultRootWindow (this->m_display); int fullWidth = DisplayWidth (this->m_display, DefaultScreen (this->m_display)); int fullHeight = DisplayHeight (this->m_display, DefaultScreen (this->m_display)); @@ -109,28 +117,21 @@ void CRenderContext::initializeViewports () XRROutputInfo* info = XRRGetOutputInfo (this->m_display, screenResources, screenResources->outputs [i]); // there are some situations where xrandr returns null (like screen not using the extension) - if (info == nullptr) + if (info == nullptr || info->connection != RR_Connected) continue; - auto cur = this->m_screens.begin (); - auto end = this->m_screens.end (); - - for (; cur != end; cur ++) + for (const auto& cur : this->m_screens) { - if (info->connection == RR_Connected && strcmp (info->name, (*cur).c_str ()) == 0) - { - XRRCrtcInfo* crtc = XRRGetCrtcInfo (this->m_display, screenResources, info->crtc); + if (strcmp (info->name, cur.c_str ()) != 0) + continue; - sLog.out ("Found requested screen: ", info->name, " -> ", crtc->x, "x", crtc->y, ":", crtc->width, "x", crtc->height); + XRRCrtcInfo* crtc = XRRGetCrtcInfo (this->m_display, screenResources, info->crtc); - glm::ivec4 viewport = { - crtc->x, crtc->y, crtc->width, crtc->height - }; + sLog.out ("Found requested screen: ", info->name, " -> ", crtc->x, "x", crtc->y, ":", crtc->width, "x", crtc->height); - this->m_viewports.push_back ({viewport, *cur}); + this->m_viewports.push_back ({{crtc->x, crtc->y, crtc->width, crtc->height}, cur}); - XRRFreeCrtcInfo (crtc); - } + XRRFreeCrtcInfo (crtc); } XRRFreeOutputInfo (info); @@ -169,6 +170,58 @@ CRenderContext::~CRenderContext () } } +void CRenderContext::renderScreens () +{ + bool firstFrame = true; + bool renderFrame = true; + int fullWidth = DisplayWidth (this->m_display, DefaultScreen (this->m_display)); + int fullHeight = DisplayHeight (this->m_display, DefaultScreen (this->m_display)); + Window root = DefaultRootWindow (this->m_display); + + for (const auto& cur : this->m_viewports) + { + if (DEBUG) + { + std::string str = "Rendering to screen " + cur.name; + + glPushDebugGroup (GL_DEBUG_SOURCE_APPLICATION, 0, -1, str.c_str ()); + } + + // render the background + this->m_wallpaper->render (cur.viewport, false, renderFrame, firstFrame); + // scenes need to render a new frame for each viewport as they produce different results + // but videos should only be rendered once per group of viewports + firstFrame = false; + renderFrame = !this->m_wallpaper->is (); + + if (DEBUG) + glPopDebugGroup (); + } + + // read the full texture into the image + glReadPixels (0, 0, fullWidth, fullHeight, GL_BGRA, GL_UNSIGNED_BYTE, (void*) this->m_imageData); + + // put the image back into the screen + XPutImage (this->m_display, this->m_pixmap, this->m_gc, this->m_image, 0, 0, 0, 0, fullWidth, fullHeight); + + // _XROOTPMAP_ID & ESETROOT_PMAP_ID allow other programs (compositors) to + // edit the background. Without these, other programs will clear the screen. + // it also forces the compositor to refresh the background (tested with picom) + Atom prop_root = XInternAtom(this->m_display, "_XROOTPMAP_ID", False); + Atom prop_esetroot = XInternAtom(this->m_display, "ESETROOT_PMAP_ID", False); + XChangeProperty(this->m_display, root, prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &this->m_pixmap, 1); + XChangeProperty(this->m_display, root, prop_esetroot, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &this->m_pixmap, 1); + + XClearWindow(this->m_display, root); + XFlush(this->m_display); +} + +void CRenderContext::renderWindow () +{ + // render the background to the window directly + this->m_wallpaper->render ({0, 0, this->m_driver.getFramebufferSize ()}, true); +} + void CRenderContext::render () { if (this->m_wallpaper == nullptr) @@ -178,54 +231,11 @@ void CRenderContext::render () this->m_mouse->update (); if (this->m_viewports.empty () == false) - { - bool firstFrame = true; - bool renderFrame = true; - auto cur = this->m_viewports.begin (); - auto end = this->m_viewports.end (); - int fullWidth = DisplayWidth (this->m_display, DefaultScreen (this->m_display)); - int fullHeight = DisplayHeight (this->m_display, DefaultScreen (this->m_display)); - Window root = DefaultRootWindow (this->m_display); - - for (; cur != end; cur ++) - { - if (DEBUG) - { - std::string str = "Rendering to screen " + (*cur).name; - - glPushDebugGroup (GL_DEBUG_SOURCE_APPLICATION, 0, -1, str.c_str ()); - } - - // render the background - this->m_wallpaper->render ((*cur).viewport, false, renderFrame, firstFrame); - // scenes need to render a new frame for each viewport as they produce different results - // but videos should only be rendered once per group of viewports - firstFrame = false; - renderFrame = !this->m_wallpaper->is (); - - if (DEBUG) - glPopDebugGroup (); - } - - // read the full texture into the image - glReadPixels (0, 0, fullWidth, fullHeight, GL_BGRA, GL_UNSIGNED_BYTE, (void*) this->m_imageData); - - // put the image back into the screen - XPutImage (this->m_display, this->m_pixmap, this->m_gc, this->m_image, 0, 0, 0, 0, fullWidth, fullHeight); - - // _XROOTPMAP_ID & ESETROOT_PMAP_ID allow other programs (compositors) to - // edit the background. Without these, other programs will clear the screen. - // it also forces the compositor to refresh the background (tested with picom) - Atom prop_root = XInternAtom(this->m_display, "_XROOTPMAP_ID", False); - Atom prop_esetroot = XInternAtom(this->m_display, "ESETROOT_PMAP_ID", False); - XChangeProperty(this->m_display, root, prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &this->m_pixmap, 1); - XChangeProperty(this->m_display, root, prop_esetroot, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &this->m_pixmap, 1); - - XClearWindow(this->m_display, root); - XFlush(this->m_display); - } + this->renderScreens (); else - this->m_wallpaper->render (this->m_defaultViewport, true); + this->renderWindow (); + + this->m_driver.swapBuffers (); } void CRenderContext::setWallpaper (CWallpaper* wallpaper) @@ -249,11 +259,6 @@ void CRenderContext::setWallpaper (CWallpaper* wallpaper) } } -void CRenderContext::setDefaultViewport (glm::vec4 defaultViewport) -{ - this->m_defaultViewport = defaultViewport; -} - CMouseInput* CRenderContext::getMouse () const { return this->m_mouse; diff --git a/src/WallpaperEngine/Render/CRenderContext.h b/src/WallpaperEngine/Render/CRenderContext.h index ff4072e..ad962d4 100644 --- a/src/WallpaperEngine/Render/CRenderContext.h +++ b/src/WallpaperEngine/Render/CRenderContext.h @@ -4,11 +4,19 @@ #include #include "WallpaperEngine/Input/CMouseInput.h" +#include "WallpaperEngine/Render/Drivers/CVideoDriver.h" #include "CTextureCache.h" #include "CWallpaper.h" #include +using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Input; +using namespace WallpaperEngine::Render::Drivers; + +namespace WallpaperEngine::Render::Drivers +{ + class CVideoDriver; +} namespace WallpaperEngine::Render { @@ -18,13 +26,12 @@ namespace WallpaperEngine::Render class CRenderContext { public: - CRenderContext (std::vector screens, GLFWwindow* window, CContainer* container); + CRenderContext (std::vector screens, CVideoDriver& driver, CContainer* container); ~CRenderContext (); - void initializeViewports (); + void initialize (); void render (); void setWallpaper (CWallpaper* wallpaper); - void setDefaultViewport (glm::vec4 defaultViewport); CMouseInput* getMouse () const; void setMouse (CMouseInput* mouse); CWallpaper* getWallpaper () const; @@ -32,6 +39,12 @@ namespace WallpaperEngine::Render const ITexture* resolveTexture (const std::string& name); private: + void setupScreens (); + void setupWindow (); + + void renderScreens (); + void renderWindow (); + struct viewport { glm::ivec4 viewport; @@ -42,15 +55,13 @@ namespace WallpaperEngine::Render Pixmap m_pixmap; GC m_gc; XImage* m_image; - GLFWwindow* m_window; + CVideoDriver& m_driver; char* m_imageData; CFBO* m_fbo; std::vector m_screens; std::vector m_viewports; - glm::vec4 m_defaultViewport; CWallpaper* m_wallpaper; CMouseInput* m_mouse; - bool m_isRootWindow; CContainer* m_container; CTextureCache* m_textureCache; }; diff --git a/src/WallpaperEngine/Render/CScene.cpp b/src/WallpaperEngine/Render/CScene.cpp index 674cb52..338e743 100644 --- a/src/WallpaperEngine/Render/CScene.cpp +++ b/src/WallpaperEngine/Render/CScene.cpp @@ -24,15 +24,12 @@ CScene::CScene (Core::CScene* scene, CRenderContext* context) : if (scene->getOrthogonalProjection ()->isAuto () == true) { // calculate the size of the projection based on the size of everything - auto cur = scene->getObjects ().begin (); - auto end = scene->getObjects ().end (); - - for (; cur != end; cur ++) + for (const auto& cur : scene->getObjects ()) { - if ((*cur).second->is () == false) + if (cur.second->is () == false) continue; - glm::vec2 size = (*cur).second->as ()->getSize (); + glm::vec2 size = cur.second->as ()->getSize (); scene->getOrthogonalProjection ()->setWidth (size.x); scene->getOrthogonalProjection ()->setHeight (size.y); @@ -55,21 +52,13 @@ CScene::CScene (Core::CScene* scene, CRenderContext* context) : this->setupFramebuffers (); // create all objects based off their dependencies + for (const auto& cur : scene->getObjects ()) + this->createObject (cur.second); + + // copy over objects by render order + for (const auto& cur : scene->getObjectsByRenderOrder ()) { - auto cur = scene->getObjects ().begin (); - auto end = scene->getObjects ().end (); - - for (; cur != end; cur++) - this->createObject ((*cur).second); - } - - // now setup the render order - auto cur = scene->getObjectsByRenderOrder ().begin (); - auto end = scene->getObjectsByRenderOrder ().end (); - - for (; cur != end; cur ++) - { - auto obj = this->m_objects.find ((*cur)->getId ()); + auto obj = this->m_objects.find (cur->getId ()); // ignores not created objects like particle systems if (obj == this->m_objects.end ()) @@ -183,16 +172,13 @@ Render::CObject* CScene::createObject (Core::CObject* object) return (*current).second; // check dependencies too! - auto depCur = object->getDependencies ().begin (); - auto depEnd = object->getDependencies ().end (); - - for (; depCur != depEnd; depCur ++) + for (const auto& cur : object->getDependencies ()) { // self-dependency is a possibility... - if ((*depCur) == object->getId ()) + if (cur == object->getId ()) continue; - auto dep = this->getScene ()->getObjects ().find (*depCur); + auto dep = this->getScene ()->getObjects ().find (cur); if (dep != this->getScene ()->getObjects ().end ()) this->createObject ((*dep).second); @@ -232,10 +218,6 @@ CCamera* CScene::getCamera () const void CScene::renderFrame (glm::ivec4 viewport) { - auto projection = this->getScene ()->getOrthogonalProjection (); - auto cur = this->m_objectsByRenderOrder.begin (); - auto end = this->m_objectsByRenderOrder.end (); - // ensure the virtual mouse position is up to date this->updateMouse (viewport); @@ -256,8 +238,8 @@ void CScene::renderFrame (glm::ivec4 viewport) glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - for (; cur != end; cur ++) - (*cur)->render (); + for (const auto& cur : this->m_objectsByRenderOrder) + cur->render (); } void CScene::updateMouse (glm::ivec4 viewport) diff --git a/src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp b/src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp new file mode 100644 index 0000000..4aad06d --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp @@ -0,0 +1,101 @@ +#include "COpenGLDriver.h" +#include "common.h" +#include + +using namespace WallpaperEngine::Render::Drivers; + +COpenGLDriver::COpenGLDriver (const char* windowTitle) : + m_frameCounter (0) +{ + // initialize glfw + if (glfwInit () == GLFW_FALSE) + sLog.exception ("Failed to initialize glfw"); + + // set some window hints (opengl version to be used) + glfwWindowHint (GLFW_SAMPLES, 4); + glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint (GLFW_VISIBLE, GLFW_FALSE); + + if (DEBUG) + glfwWindowHint (GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); + + // create window, size doesn't matter as long as we don't show it + this->m_window = glfwCreateWindow (640, 480, windowTitle, nullptr, nullptr); + + if (this->m_window == nullptr) + sLog.exception ("Cannot create window"); + + // make context current, required for glew initialization + glfwMakeContextCurrent (this->m_window); + + // initialize glew for rendering + GLenum result = glewInit (); + + if (result != GLEW_OK) + sLog.error("Failed to initialize GLEW: ", glewGetErrorString (result)); + + // initialize free image + FreeImage_Initialise (TRUE); +} + +COpenGLDriver::~COpenGLDriver () +{ + glfwTerminate (); + FreeImage_DeInitialise(); +} + +float COpenGLDriver::getRenderTime () +{ + return (float) glfwGetTime (); +} + +bool COpenGLDriver::closeRequested () +{ + return glfwWindowShouldClose (this->m_window); +} + +void COpenGLDriver::resizeWindow (glm::ivec2 size) +{ + glfwSetWindowSize (this->m_window, size.x, size.y); +} + +void COpenGLDriver::showWindow () +{ + glfwShowWindow (this->m_window); +} + +void COpenGLDriver::hideWindow () +{ + glfwHideWindow (this->m_window); +} + +glm::ivec2 COpenGLDriver::getFramebufferSize () +{ + glm::ivec2 size; + + glfwGetFramebufferSize (this->m_window, &size.x, &size.y); + + return size; +} + +void COpenGLDriver::swapBuffers () +{ + // do buffer swapping first + glfwSwapBuffers (this->m_window); + // poll for events + glfwPollEvents (); + // increase frame counter + this->m_frameCounter ++; +} + +uint32_t COpenGLDriver::getFrameCounter () +{ + return this->m_frameCounter; +} + +GLFWwindow* COpenGLDriver::getWindow () +{ + return this->m_window; +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Drivers/COpenGLDriver.h b/src/WallpaperEngine/Render/Drivers/COpenGLDriver.h new file mode 100644 index 0000000..1e3af0a --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/COpenGLDriver.h @@ -0,0 +1,29 @@ +#pragma once + +#include "WallpaperEngine/Render/Drivers/CVideoDriver.h" +#include +#include + +namespace WallpaperEngine::Render::Drivers +{ + class COpenGLDriver : public CVideoDriver + { + public: + COpenGLDriver (const char* windowTitle); + ~COpenGLDriver(); + + float getRenderTime () override; + bool closeRequested () override; + void resizeWindow (glm::ivec2 size) override; + void showWindow () override; + void hideWindow () override; + glm::ivec2 getFramebufferSize () override; + void swapBuffers () override; + uint32_t getFrameCounter () override; + + GLFWwindow* getWindow (); + private: + GLFWwindow* m_window; + uint32_t m_frameCounter; + }; +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Drivers/CVideoDriver.cpp b/src/WallpaperEngine/Render/Drivers/CVideoDriver.cpp new file mode 100644 index 0000000..36d8178 --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/CVideoDriver.cpp @@ -0,0 +1,3 @@ +#include "CVideoDriver.h" + +using namespace WallpaperEngine::Render::Drivers; diff --git a/src/WallpaperEngine/Render/Drivers/CVideoDriver.h b/src/WallpaperEngine/Render/Drivers/CVideoDriver.h new file mode 100644 index 0000000..5da1d4d --- /dev/null +++ b/src/WallpaperEngine/Render/Drivers/CVideoDriver.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace WallpaperEngine::Render::Drivers +{ + class CVideoDriver + { + public: + virtual float getRenderTime () = 0; + virtual bool closeRequested () = 0; + virtual void resizeWindow (glm::ivec2 size) = 0; + virtual void showWindow () = 0; + virtual void hideWindow () = 0; + virtual glm::ivec2 getFramebufferSize () = 0; + virtual void swapBuffers () = 0; + virtual uint32_t getFrameCounter () = 0; + }; +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Objects/CEffect.cpp b/src/WallpaperEngine/Render/Objects/CEffect.cpp index b41d8fc..c565eaa 100644 --- a/src/WallpaperEngine/Render/Objects/CEffect.cpp +++ b/src/WallpaperEngine/Render/Objects/CEffect.cpp @@ -23,46 +23,33 @@ const std::vector& CEffect::getMaterials () const const CFBO* CEffect::findFBO (const std::string& name) const { - auto cur = this->m_fbos.begin (); - auto end = this->m_fbos.end (); - - for (; cur != end; cur ++) - { - if ((*cur)->getName () == name) - { - return *cur; - } - } + for (const auto& cur : this->m_fbos) + if (cur->getName () == name) + return cur; return nullptr; } void CEffect::generatePasses () { - auto cur = this->m_effect->getMaterials ().begin (); - auto end = this->m_effect->getMaterials ().end (); - - for (; cur != end; cur ++) - this->m_materials.emplace_back (new Effects::CMaterial (this, *cur)); + for (const auto& cur : this->m_effect->getMaterials ()) + this->m_materials.emplace_back (new Effects::CMaterial (this, cur)); } void CEffect::generateFBOs () { - auto cur = this->m_effect->getFbos ().begin (); - auto end = this->m_effect->getFbos ().end (); - - for (; cur != end; cur ++) + for (const auto& cur : this->m_effect->getFbos ()) { this->m_fbos.push_back ( new CFBO ( - (*cur)->getName (), + cur->getName (), ITexture::TextureFormat::ARGB8888, // TODO: CHANGE this->m_image->getTexture ()->getFlags (), // TODO: CHANGE - (*cur)->getScale (), - this->m_image->getSize ().x / (*cur)->getScale (), - this->m_image->getSize ().y / (*cur)->getScale (), - this->m_image->getSize ().x / (*cur)->getScale (), - this->m_image->getSize ().y / (*cur)->getScale () + cur->getScale (), + this->m_image->getSize ().x / cur->getScale (), + this->m_image->getSize ().y / cur->getScale (), + this->m_image->getSize ().x / cur->getScale (), + this->m_image->getSize ().y / cur->getScale () ) ); } diff --git a/src/WallpaperEngine/Render/Objects/CImage.cpp b/src/WallpaperEngine/Render/Objects/CImage.cpp index b7f95a0..8e338aa 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.cpp +++ b/src/WallpaperEngine/Render/Objects/CImage.cpp @@ -242,34 +242,21 @@ void CImage::setup () ); // add blendmode to the combos - auto cur = this->m_material->getPasses ().begin (); - auto end = this->m_material->getPasses ().end (); - - for (; cur != end; cur ++) - this->m_passes.push_back (*cur); + for (const auto& cur : this->m_material->getPasses ()) + this->m_passes.push_back (cur); } // prepare the passes list if (this->getImage ()->getEffects ().empty () == false) { // generate the effects used by this material - auto cur = this->getImage ()->getEffects ().begin (); - auto end = this->getImage ()->getEffects ().end (); - - for (; cur != end; cur ++) + for (const auto& cur : this->getImage ()->getEffects ()) { - auto effect = new CEffect (this, *cur); - auto materialCur = effect->getMaterials ().begin (); - auto materialEnd = effect->getMaterials ().end (); + auto effect = new CEffect (this, cur); - for (; materialCur != materialEnd; materialCur ++) - { - auto passCur = (*materialCur)->getPasses ().begin (); - auto passEnd = (*materialCur)->getPasses ().end (); - - for (; passCur != passEnd; passCur ++) - this->m_passes.push_back (*passCur); - } + for (const auto& material : effect->getMaterials ()) + for (const auto& pass : material->getPasses ()) + this->m_passes.push_back (pass); this->m_effects.push_back (effect); } @@ -289,11 +276,8 @@ void CImage::setup () ); // add blendmode to the combos - auto cur = this->m_colorBlendMaterial->getPasses ().begin (); - auto end = this->m_colorBlendMaterial->getPasses ().end (); - - for (; cur != end; cur ++) - this->m_passes.push_back (*cur); + for (const auto& cur : this->m_colorBlendMaterial->getPasses ()) + this->m_passes.push_back (cur); } // if there's more than one pass the blendmode has to be moved from the beginning to the end @@ -306,16 +290,11 @@ void CImage::setup () (*first)->getPass ()->setBlendingMode ("normal"); } - { - // calculate full animation time (if any) - this->m_animationTime = 0.0f; + // calculate full animation time (if any) + this->m_animationTime = 0.0f; - auto cur = this->getTexture ()->getFrames ().begin (); - auto end = this->getTexture ()->getFrames ().end (); - - for (; cur != end; cur++) - this->m_animationTime += (*cur)->frametime; - } + for (const auto& cur : this->getTexture ()->getFrames ()) + this->m_animationTime += cur->frametime; this->setupPasses (); this->m_initialized = true; diff --git a/src/WallpaperEngine/Render/Objects/CSound.cpp b/src/WallpaperEngine/Render/Objects/CSound.cpp index b7d12c1..f8b06d0 100644 --- a/src/WallpaperEngine/Render/Objects/CSound.cpp +++ b/src/WallpaperEngine/Render/Objects/CSound.cpp @@ -13,13 +13,10 @@ CSound::CSound (CScene* scene, Core::Objects::CSound* sound) : void CSound::load () { - auto cur = this->m_sound->getSounds ().begin (); - auto end = this->m_sound->getSounds ().end (); - - for (; cur != end; cur ++) + for (const auto& cur : this->m_sound->getSounds ()) { uint32_t filesize = 0; - const void* filebuffer = this->getContainer ()->readFile ((*cur), &filesize); + const void* filebuffer = this->getContainer ()->readFile (cur, &filesize); this->m_audioStreams.push_back (new Audio::CAudioStream (filebuffer, filesize)); this->m_soundBuffer.push_back (filebuffer); diff --git a/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp index 5ff60e8..9522603 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp +++ b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp @@ -23,12 +23,9 @@ CImage* CMaterial::getImage () const void CMaterial::generatePasses () { - auto cur = this->m_material->getPasses ().begin (); - auto end = this->m_material->getPasses ().end (); - // these are simple now, just create the entries and done - for (; cur != end; cur ++) - this->m_passes.emplace_back (new CPass (this, *cur)); + for (const auto& cur : this->m_material->getPasses ()) + this->m_passes.emplace_back (new CPass (this, cur)); } const Core::Objects::Images::CMaterial* CMaterial::getMaterial () const diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp index 27a7821..2751601 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp @@ -136,26 +136,22 @@ void CPass::render () // calculate current texture and frame double currentRenderTime = fmod (static_cast (g_Time), this->m_material->getImage ()->getAnimationTime ()); - // find the right frame now - auto frameCur = texture->getFrames ().begin (); - auto frameEnd = texture->getFrames ().end (); - - for (; frameCur != frameEnd; frameCur ++) + for (const auto& frameCur : texture->getFrames ()) { - currentRenderTime -= (*frameCur)->frametime; + currentRenderTime -= frameCur->frametime; if (currentRenderTime <= 0.0f) { // frame found, store coordinates and done - currentTexture = (*frameCur)->frameNumber; + currentTexture = frameCur->frameNumber; - translation.x = (*frameCur)->x / texture->getTextureWidth (currentTexture); - translation.y = (*frameCur)->y / texture->getTextureHeight (currentTexture); + translation.x = frameCur->x / texture->getTextureWidth (currentTexture); + translation.y = frameCur->y / texture->getTextureHeight (currentTexture); - rotation.x = (*frameCur)->width1 / static_cast (texture->getTextureWidth (currentTexture)); - rotation.y = (*frameCur)->width2 / static_cast (texture->getTextureWidth(currentTexture)); - rotation.z = (*frameCur)->height2 / static_cast (texture->getTextureHeight (currentTexture)); - rotation.w = (*frameCur)->height1 / static_cast (texture->getTextureHeight (currentTexture)); + rotation.x = frameCur->width1 / static_cast (texture->getTextureWidth (currentTexture)); + rotation.y = frameCur->width2 / static_cast (texture->getTextureWidth(currentTexture)); + rotation.z = frameCur->height2 / static_cast (texture->getTextureHeight (currentTexture)); + rotation.w = frameCur->height1 / static_cast (texture->getTextureHeight (currentTexture)); break; } } @@ -168,118 +164,97 @@ void CPass::render () // continue on the map from the second texture if (this->m_finalTextures.empty () == false) { - auto cur = this->m_finalTextures.begin (); - auto end = this->m_finalTextures.end (); - - for (; cur != end; cur ++) + for (const auto& cur : this->m_finalTextures) { - texture = this->resolveTexture ((*cur).second, (*cur).first, this->m_input); + texture = this->resolveTexture (cur.second, cur.first, this->m_input); - glActiveTexture (GL_TEXTURE0 + (*cur).first); + glActiveTexture (GL_TEXTURE0 + cur.first); glBindTexture (GL_TEXTURE_2D, texture->getTextureID (0)); } } // add uniforms + for (const auto& cur : this->m_uniforms) { - auto cur = this->m_uniforms.begin (); - auto end = this->m_uniforms.end (); + UniformEntry* entry = cur.second; - for (; cur != end; cur ++) + switch (entry->type) { - UniformEntry* entry = (*cur).second; - - switch (entry->type) - { - case Double: - glUniform1d (entry->id, *reinterpret_cast (entry->value)); - break; - case Float: - glUniform1f (entry->id, *reinterpret_cast (entry->value)); - break; - case Integer: - glUniform1i (entry->id, *reinterpret_cast (entry->value)); - break; - case Vector4: - glUniform4fv (entry->id, 1, glm::value_ptr (*reinterpret_cast (entry->value))); - break; - case Vector3: - glUniform3fv (entry->id, 1, glm::value_ptr (*reinterpret_cast (entry->value))); - break; - case Vector2: - glUniform2fv (entry->id, 1, glm::value_ptr (*reinterpret_cast (entry->value))); - break; - case Matrix4: - glUniformMatrix4fv (entry->id, 1, GL_FALSE, glm::value_ptr (*reinterpret_cast (entry->value))); - break; - } + case Double: + glUniform1d (entry->id, *reinterpret_cast (entry->value)); + break; + case Float: + glUniform1f (entry->id, *reinterpret_cast (entry->value)); + break; + case Integer: + glUniform1i (entry->id, *reinterpret_cast (entry->value)); + break; + case Vector4: + glUniform4fv (entry->id, 1, glm::value_ptr (*reinterpret_cast (entry->value))); + break; + case Vector3: + glUniform3fv (entry->id, 1, glm::value_ptr (*reinterpret_cast (entry->value))); + break; + case Vector2: + glUniform2fv (entry->id, 1, glm::value_ptr (*reinterpret_cast (entry->value))); + break; + case Matrix4: + glUniformMatrix4fv (entry->id, 1, GL_FALSE, glm::value_ptr (*reinterpret_cast (entry->value))); + break; } } // add reference uniforms + for (const auto& cur : this->m_referenceUniforms) { - auto cur = this->m_referenceUniforms.begin (); - auto end = this->m_referenceUniforms.end (); + ReferenceUniformEntry* entry = cur.second; - for (; cur != end; cur ++) + switch (entry->type) { - ReferenceUniformEntry* entry = (*cur).second; - - switch (entry->type) - { - case Double: - glUniform1d (entry->id, *reinterpret_cast (*entry->value)); - break; - case Float: - glUniform1f (entry->id, *reinterpret_cast (*entry->value)); - break; - case Integer: - glUniform1i (entry->id, *reinterpret_cast (*entry->value)); - break; - case Vector4: - glUniform4fv (entry->id, 1, glm::value_ptr (*reinterpret_cast (*entry->value))); - break; - case Vector3: - glUniform3fv (entry->id, 1, glm::value_ptr (*reinterpret_cast (*entry->value))); - break; - case Vector2: - glUniform2fv (entry->id, 1, glm::value_ptr (*reinterpret_cast (*entry->value))); - break; - case Matrix4: - glUniformMatrix4fv (entry->id, 1, GL_FALSE, glm::value_ptr (*reinterpret_cast (*entry->value))); - break; - } + case Double: + glUniform1d (entry->id, *reinterpret_cast (*entry->value)); + break; + case Float: + glUniform1f (entry->id, *reinterpret_cast (*entry->value)); + break; + case Integer: + glUniform1i (entry->id, *reinterpret_cast (*entry->value)); + break; + case Vector4: + glUniform4fv (entry->id, 1, glm::value_ptr (*reinterpret_cast (*entry->value))); + break; + case Vector3: + glUniform3fv (entry->id, 1, glm::value_ptr (*reinterpret_cast (*entry->value))); + break; + case Vector2: + glUniform2fv (entry->id, 1, glm::value_ptr (*reinterpret_cast (*entry->value))); + break; + case Matrix4: + glUniformMatrix4fv (entry->id, 1, GL_FALSE, glm::value_ptr (*reinterpret_cast (*entry->value))); + break; } } + // used in animations when one of the frames is vertical instead of horizontal + // rotation with translation = origin and end of the image to display if (this->g_Texture0Rotation != -1) - { - // used in animations when one of the frames is vertical instead of horizontal - // rotation with translation = origin and end of the image to display glUniform4f (this->g_Texture0Rotation, rotation.x, rotation.y, rotation.z, rotation.w); - } + // this actually picks the origin point of the image from the atlast if (this->g_Texture0Translation != -1) - { - // this actually picks the origin point of the image from the atlast glUniform2f (this->g_Texture0Translation, translation.x, translation.y); - } + + for (const auto& cur : this->m_attribs) { - auto cur = this->m_attribs.begin (); - auto end = this->m_attribs.end (); + glEnableVertexAttribArray (cur->id); + glBindBuffer (GL_ARRAY_BUFFER, *cur->value); + glVertexAttribPointer (cur->id, cur->elements, cur->type, GL_FALSE, 0, nullptr); - for (; cur != end; cur ++) - { - glEnableVertexAttribArray ((*cur)->id); - glBindBuffer (GL_ARRAY_BUFFER, *(*cur)->value); - glVertexAttribPointer ((*cur)->id, (*cur)->elements, (*cur)->type, GL_FALSE, 0, nullptr); - - if (DEBUG) - glObjectLabel (GL_BUFFER, *(*cur)->value, -1, ( - "Image " + std::to_string (this->getMaterial ()->getImage ()->getId ()) + - " Pass " + this->m_pass->getShader() + - " " + (*cur)->name - ).c_str () - ); - } + if (DEBUG) + glObjectLabel (GL_BUFFER, *cur->value, -1, ( + "Image " + std::to_string (this->getMaterial ()->getImage ()->getId ()) + + " Pass " + this->m_pass->getShader() + + " " + cur->name + ).c_str () + ); } // start actual rendering now @@ -287,13 +262,8 @@ void CPass::render () glDrawArrays (GL_TRIANGLES, 0, 6); // disable vertex attribs array and textures - { - auto cur = this->m_attribs.begin (); - auto end = this->m_attribs.end (); - - for (; cur != end; cur ++) - glDisableVertexAttribArray ((*cur)->id); - } + for (const auto& cur : this->m_attribs) + glDisableVertexAttribArray (cur->id); // unbind all the used textures glActiveTexture (GL_TEXTURE0); @@ -302,12 +272,9 @@ void CPass::render () // continue on the map from the second texture if (this->m_finalTextures.empty () == false) { - auto cur = this->m_finalTextures.begin (); - auto end = this->m_finalTextures.end (); - - for (; cur != end; cur ++) + for (const auto& cur : this->m_finalTextures) { - glActiveTexture (GL_TEXTURE0 + (*cur).first); + glActiveTexture (GL_TEXTURE0 + cur.first); glBindTexture (GL_TEXTURE_2D, 0); } } @@ -600,19 +567,14 @@ void CPass::setupUniforms () } } + for (const auto& cur : this->m_finalTextures) { - auto cur = this->m_finalTextures.begin (); - auto end = this->m_finalTextures.end (); + std::ostringstream namestream; - for (; cur != end; cur ++) - { - std::ostringstream namestream; + namestream << "g_Texture" << cur.first << "Resolution"; - namestream << "g_Texture" << (*cur).first << "Resolution"; - - texture = this->resolveTexture ((*cur).second, (*cur).first, texture); - this->addUniform (namestream.str (), texture->getResolution ()); - } + texture = this->resolveTexture (cur.second, cur.first, texture); + this->addUniform (namestream.str (), texture->getResolution ()); } auto projection = this->getMaterial ()->getImage ()->getScene ()->getScene ()->getOrthogonalProjection (); @@ -744,128 +706,113 @@ void CPass::setupTextures () void CPass::setupShaderVariables () { + // find variables in the shaders and set the value with the constants if possible + for (const auto& cur : this->m_pass->getConstants ()) { - // find variables in the shaders and set the value with the constants if possible - auto cur = this->m_pass->getConstants ().begin (); - auto end = this->m_pass->getConstants ().end (); + CShaderVariable* vertexVar = this->m_vertShader->findParameter (cur.first); + CShaderVariable* pixelVar = this->m_fragShader->findParameter (cur.first); - for (; cur != end; cur ++) + // variable not found, can be ignored + if (vertexVar == nullptr && pixelVar == nullptr) + continue; + + // if both can be found, ensure they're the correct type + /*if (vertexVar != nullptr && pixelVar != nullptr) { - CShaderVariable* vertexVar = this->m_vertShader->findParameter ((*cur).first); - CShaderVariable* pixelVar = this->m_fragShader->findParameter ((*cur).first); + if (vertexVar->getType () != pixelVar->getType ()) + throw std::runtime_error ("Pixel and vertex shader variable types do not match"); + }*/ - // variable not found, can be ignored - if (vertexVar == nullptr && pixelVar == nullptr) - continue; + // get one instance of it + CShaderVariable* var = vertexVar == nullptr ? pixelVar : vertexVar; - // if both can be found, ensure they're the correct type - /*if (vertexVar != nullptr && pixelVar != nullptr) + // ensure the shader's and the constant are of the same type + if (cur.second->getType () != var->getType ()) + { + // there's situations where this type mismatch is actually expected + // integers and floats are equivalent, this could be detected at load time + // but that'd mean to compile the shader in the load, and not on the render stage + // so take into account these conversions here + + if (cur.second->is () == true && var->is () == true) { - if (vertexVar->getType () != pixelVar->getType ()) - throw std::runtime_error ("Pixel and vertex shader variable types do not match"); - }*/ - - // get one instance of it - CShaderVariable* var = vertexVar == nullptr ? pixelVar : vertexVar; - - // ensure the shader's and the constant are of the same type - if ((*cur).second->getType () != var->getType ()) + // create an integer value from a float + this->addUniform (var->getName (), static_cast (*cur.second->as ()->getValue ())); + } + else if (cur.second->is () == true && var->is () == true) { - // there's situations where this type mismatch is actually expected - // integers and floats are equivalent, this could be detected at load time - // but that'd mean to compile the shader in the load, and not on the render stage - // so take into account these conversions here + // create a float value from an integer + this->addUniform (var->getName (), static_cast (*cur.second->as ()->getValue ())); + } + else if (cur.second->is () == true && var->is () == true) + { + CShaderConstantVector4* val = cur.second->as (); - if ((*cur).second->is () == true && var->is () == true) - { - // create an integer value from a float - this->addUniform (var->getName (), static_cast (*(*cur).second->as ()->getValue ())); - } - else if ((*cur).second->is () == true && var->is () == true) - { - // create a float value from an integer - this->addUniform (var->getName (), static_cast (*(*cur).second->as ()->getValue ())); - } - else if ((*cur).second->is () == true && var->is () == true) - { - CShaderConstantVector4* val = (*cur).second->as (); + // create a new vector2 with the first two values + this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y}); + } + else if (cur.second->is () == true && var->is () == true) + { + CShaderConstantVector4* val = cur.second->as (); - // create a new vector2 with the first two values - this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y}); - } - else if ((*cur).second->is () == true && var->is () == true) - { - CShaderConstantVector4* val = (*cur).second->as (); - - this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y, val->getValue ()->z}); - } - else - { - sLog.exception ( - "Constant ", - (*cur).first, - " type does not match pixel/vertex shader variable and cannot be converted (", - (*cur).second->getType (), - " to ", - var->getType () - ); - } + this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y, val->getValue ()->z}); } else { - // now determine the constant's type and register the correct uniform for it - if ((*cur).second->is ()) - this->addUniform (var->getName (), (*cur).second->as ()->getValue ()); - else if ((*cur).second->is ()) - this->addUniform (var->getName (), (*cur).second->as ()->getValue ()); - else if ((*cur).second->is ()) - this->addUniform (var->getName (), (*cur).second->as ()->getValue ()); + sLog.exception ( + "Constant ", + cur.first, + " type does not match pixel/vertex shader variable and cannot be converted (", + cur.second->getType (), + " to ", + var->getType () + ); } } - } - - { - auto cur = this->m_vertShader->getParameters ().begin (); - auto end = this->m_vertShader->getParameters ().end (); - - for (; cur != end; cur ++) + else { - if (this->m_uniforms.find ((*cur)->getName ()) != this->m_uniforms.end ()) - continue; - - if ((*cur)->is ()) - this->addUniform ((*cur)->getName (), const_cast (reinterpret_cast ((*cur)->as ()->getValue ()))); - else if ((*cur)->is ()) - this->addUniform ((*cur)->getName (), const_cast (reinterpret_cast ((*cur)->as ()->getValue ()))); - else if ((*cur)->is ()) - this->addUniform ((*cur)->getName (), const_cast (reinterpret_cast ((*cur)->as ()->getValue ()))); - else if ((*cur)->is ()) - this->addUniform ((*cur)->getName (), const_cast (reinterpret_cast ((*cur)->as ()->getValue ()))); - else if ((*cur)->is ()) - this->addUniform ((*cur)->getName (), const_cast (reinterpret_cast ((*cur)->as ()->getValue ()))); + // now determine the constant's type and register the correct uniform for it + if (cur.second->is ()) + this->addUniform (var->getName (), cur.second->as ()->getValue ()); + else if (cur.second->is ()) + this->addUniform (var->getName (), cur.second->as ()->getValue ()); + else if (cur.second->is ()) + this->addUniform (var->getName (), cur.second->as ()->getValue ()); } } + for (const auto& cur : this->m_vertShader->getParameters ()) { - auto cur = this->m_fragShader->getParameters ().begin (); - auto end = this->m_fragShader->getParameters ().end (); + if (this->m_uniforms.find (cur->getName ()) != this->m_uniforms.end ()) + continue; - for (; cur != end; cur ++) - { - if (this->m_uniforms.find ((*cur)->getName ()) != this->m_uniforms.end ()) - continue; + if (cur->is ()) + this->addUniform (cur->getName (), const_cast (reinterpret_cast (cur->as ()->getValue ()))); + else if (cur->is ()) + this->addUniform (cur->getName (), const_cast (reinterpret_cast (cur->as ()->getValue ()))); + else if (cur->is ()) + this->addUniform (cur->getName (), const_cast (reinterpret_cast (cur->as ()->getValue ()))); + else if (cur->is ()) + this->addUniform (cur->getName (), const_cast (reinterpret_cast (cur->as ()->getValue ()))); + else if (cur->is ()) + this->addUniform (cur->getName (), const_cast (reinterpret_cast (cur->as ()->getValue ()))); + } - if ((*cur)->is ()) - this->addUniform ((*cur)->getName (), const_cast (reinterpret_cast ((*cur)->as ()->getValue ()))); - else if ((*cur)->is ()) - this->addUniform ((*cur)->getName (), const_cast (reinterpret_cast ((*cur)->as ()->getValue ()))); - else if ((*cur)->is ()) - this->addUniform ((*cur)->getName (), const_cast (reinterpret_cast ((*cur)->as ()->getValue ()))); - else if ((*cur)->is ()) - this->addUniform ((*cur)->getName (), const_cast (reinterpret_cast ((*cur)->as ()->getValue ()))); - else if ((*cur)->is ()) - this->addUniform ((*cur)->getName (), const_cast (reinterpret_cast ((*cur)->as ()->getValue ()))); - } + for (const auto& cur : this->m_fragShader->getParameters ()) + { + if (this->m_uniforms.find (cur->getName ()) != this->m_uniforms.end ()) + continue; + + if (cur->is ()) + this->addUniform (cur->getName (), const_cast (reinterpret_cast (cur->as ()->getValue ()))); + else if (cur->is ()) + this->addUniform (cur->getName (), const_cast (reinterpret_cast (cur->as ()->getValue ()))); + else if (cur->is ()) + this->addUniform (cur->getName (), const_cast (reinterpret_cast (cur->as ()->getValue ()))); + else if (cur->is ()) + this->addUniform (cur->getName (), const_cast (reinterpret_cast (cur->as ()->getValue ()))); + else if (cur->is ()) + this->addUniform (cur->getName (), const_cast (reinterpret_cast (cur->as ()->getValue ()))); } } diff --git a/src/WallpaperEngine/Render/Shaders/Compiler.cpp b/src/WallpaperEngine/Render/Shaders/Compiler.cpp index 6331b70..4e582ee 100644 --- a/src/WallpaperEngine/Render/Shaders/Compiler.cpp +++ b/src/WallpaperEngine/Render/Shaders/Compiler.cpp @@ -55,11 +55,8 @@ namespace WallpaperEngine::Render::Shaders this->m_content = this->m_container->readIncludeShader (this->m_file); // clone the combos into the baseCombos to keep track of values that must be embedded no matter what - auto cur = this->m_combos->begin (); - auto end = this->m_combos->end (); - - for (; cur != end; cur ++) - this->m_baseCombos.insert (std::make_pair ((*cur).first, (*cur).second)); + for (const auto& cur : *this->m_combos) + this->m_baseCombos.insert (std::make_pair (cur.first, cur.second)); } bool Compiler::peekString(std::string str, std::string::const_iterator& it) @@ -526,36 +523,26 @@ namespace WallpaperEngine::Render::Shaders "// Shader combo parameter definitions\n" "// ======================================================\n"; + // add combo values + for (const auto& cur : *this->m_foundCombos) { - // add combo values - auto cur = this->m_foundCombos->begin (); - auto end = this->m_foundCombos->end (); + // find the right value for the combo in the combos map + auto combo = this->m_combos->find (cur.first); - for (; cur != end; cur++) - { - // find the right value for the combo in the combos map - auto combo = this->m_combos->find ((*cur).first); + if (combo == this->m_combos->end ()) + continue; - if (combo == this->m_combos->end ()) - continue; - - finalCode += "#define " + (*cur).first + " " + std::to_string ((*combo).second) + "\n"; - } + finalCode += "#define " + cur.first + " " + std::to_string ((*combo).second) + "\n"; } // add base combos that come from the pass change that MUST be added + for (const auto& cur : this->m_baseCombos) { - auto cur = this->m_baseCombos.begin (); - auto end = this->m_baseCombos.end (); + auto alreadyFound = this->m_foundCombos->find (cur.first); - for (; cur != end; cur ++) - { - auto alreadyFound = this->m_foundCombos->find ((*cur).first); + if (alreadyFound != this->m_foundCombos->end ()) + continue; - if (alreadyFound != this->m_foundCombos->end ()) - continue; - - finalCode += "#define " + (*cur).first + " " + std::to_string ((*cur).second) + "\n"; - } + finalCode += "#define " + cur.first + " " + std::to_string (cur.second) + "\n"; } } @@ -737,16 +724,9 @@ namespace WallpaperEngine::Render::Shaders Variables::CShaderVariable* Compiler::findParameter (const std::string& identifier) { - auto cur = this->m_parameters.begin (); - auto end = this->m_parameters.end (); - - for (; cur != end; cur ++) - { - if ((*cur)->getIdentifierName () == identifier) - { - return (*cur); - } - } + for (const auto& cur : this->m_parameters) + if (cur->getIdentifierName () == identifier) + return cur; return nullptr; }