mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-07-14 13:22:23 +08:00
Added support for running multiple X11 backgrounds off the same instance
Window mode now has extra settings for setting the position and size Fixed audio not muting when --silent was used Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
parent
e2d80a074c
commit
b69ce8ba57
@ -105,6 +105,12 @@ add_executable(
|
|||||||
src/WallpaperEngine/Render/Shaders/Compiler.h
|
src/WallpaperEngine/Render/Shaders/Compiler.h
|
||||||
src/WallpaperEngine/Render/Shaders/Compiler.cpp
|
src/WallpaperEngine/Render/Shaders/Compiler.cpp
|
||||||
|
|
||||||
|
src/WallpaperEngine/Render/Drivers/Output/COutput.cpp
|
||||||
|
src/WallpaperEngine/Render/Drivers/Output/COutput.h
|
||||||
|
src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp
|
||||||
|
src/WallpaperEngine/Render/Drivers/Output/CX11Output.h
|
||||||
|
src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.cpp
|
||||||
|
src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.h
|
||||||
src/WallpaperEngine/Render/Drivers/COpenGLDriver.h
|
src/WallpaperEngine/Render/Drivers/COpenGLDriver.h
|
||||||
src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp
|
src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp
|
||||||
src/WallpaperEngine/Render/Drivers/CVideoDriver.h
|
src/WallpaperEngine/Render/Drivers/CVideoDriver.h
|
||||||
|
@ -14,6 +14,8 @@ using namespace WallpaperEngine::Application;
|
|||||||
|
|
||||||
struct option long_options [] = {
|
struct option long_options [] = {
|
||||||
{"screen-root", required_argument, nullptr, 'r'},
|
{"screen-root", required_argument, nullptr, 'r'},
|
||||||
|
{"bg", required_argument, nullptr, 'b'},
|
||||||
|
{"window", optional_argument, nullptr, 'w'},
|
||||||
{"pkg", required_argument, nullptr, 'p'},
|
{"pkg", required_argument, nullptr, 'p'},
|
||||||
{"dir", required_argument, nullptr, 'd'},
|
{"dir", required_argument, nullptr, 'd'},
|
||||||
{"silent", no_argument, nullptr, 's'},
|
{"silent", no_argument, nullptr, 's'},
|
||||||
@ -52,10 +54,21 @@ CApplicationContext::CApplicationContext (int argc, char* argv[]) :
|
|||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
while ((c = getopt_long (argc, argv, "r:p:d:shf:a:", long_options, nullptr)) != -1)
|
std::string lastScreen;
|
||||||
|
|
||||||
|
while ((c = getopt_long (argc, argv, "b:r:p:d:shf:a:w::", long_options, nullptr)) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
|
case 'b':
|
||||||
|
if (lastScreen.empty ())
|
||||||
|
sLog.exception ("--bg has to go after a --screen-root argument");
|
||||||
|
|
||||||
|
// no need to check for previous screen being in the list, as it's the only way for this variable
|
||||||
|
// to have any value
|
||||||
|
this->screenSettings.insert_or_assign (lastScreen, this->validatePath (optarg));
|
||||||
|
break;
|
||||||
|
|
||||||
case 'o':
|
case 'o':
|
||||||
{
|
{
|
||||||
std::string value = optarg;
|
std::string value = optarg;
|
||||||
@ -77,13 +90,41 @@ CApplicationContext::CApplicationContext (int argc, char* argv[]) :
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
screens.emplace_back (optarg);
|
if (this->screenSettings.find (optarg) != this->screenSettings.end ())
|
||||||
|
sLog.exception ("Cannot specify the same screen more than once: ", optarg);
|
||||||
|
if (this->windowMode == EXPLICIT_WINDOW)
|
||||||
|
sLog.exception ("Cannot run in both background and window mode");
|
||||||
|
|
||||||
|
this->windowMode = X11_BACKGROUND;
|
||||||
|
lastScreen = optarg;
|
||||||
|
this->screenSettings.insert_or_assign (lastScreen, "");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'w':
|
||||||
|
if (this->windowMode == X11_BACKGROUND)
|
||||||
|
sLog.exception ("Cannot run in both background and window mode");
|
||||||
|
|
||||||
|
if (optarg != nullptr)
|
||||||
|
{
|
||||||
|
this->windowMode = EXPLICIT_WINDOW;
|
||||||
|
// read window geometry
|
||||||
|
char* pos = optarg;
|
||||||
|
|
||||||
|
if (pos != nullptr)
|
||||||
|
this->windowGeometry.x = atoi (pos);
|
||||||
|
if ((pos = strchr (pos, '.')) != nullptr)
|
||||||
|
this->windowGeometry.y = atoi (pos + 1);
|
||||||
|
if ((pos = strchr (pos + 1, '.')) != nullptr)
|
||||||
|
this->windowGeometry.z = atoi (pos + 1);
|
||||||
|
if ((pos = strchr (pos + 1, '.')) != nullptr)
|
||||||
|
this->windowGeometry.w = atoi (pos + 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
case 'd':
|
case 'd':
|
||||||
sLog.error ("--dir/--pkg is deprecated and not used anymore");
|
sLog.error ("--dir/--pkg is deprecated and not used anymore");
|
||||||
this->background = stringPathFixes (optarg);
|
this->background = this->validatePath (stringPathFixes (optarg));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
@ -110,6 +151,10 @@ CApplicationContext::CApplicationContext (int argc, char* argv[]) :
|
|||||||
this->takeScreenshot = true;
|
this->takeScreenshot = true;
|
||||||
this->screenshot = stringPathFixes (optarg);
|
this->screenshot = stringPathFixes (optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
sLog.out ("Default on path parsing: ", optarg);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +162,7 @@ CApplicationContext::CApplicationContext (int argc, char* argv[]) :
|
|||||||
{
|
{
|
||||||
if (optind < argc && strlen (argv [optind]) > 0)
|
if (optind < argc && strlen (argv [optind]) > 0)
|
||||||
{
|
{
|
||||||
this->background = argv [optind];
|
this->background = this->validatePath (argv [optind]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -126,17 +171,16 @@ CApplicationContext::CApplicationContext (int argc, char* argv[]) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
// perform some extra validation on the inputs
|
// perform some extra validation on the inputs
|
||||||
this->validatePath ();
|
|
||||||
this->validateAssets ();
|
this->validateAssets ();
|
||||||
this->validateScreenshot ();
|
this->validateScreenshot ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CApplicationContext::validatePath ()
|
std::string CApplicationContext::validatePath (const std::string& path)
|
||||||
{
|
{
|
||||||
if (this->background.find ('/') != std::string::npos)
|
if (path.find ('/') == std::string::npos)
|
||||||
return;
|
return Steam::FileSystem::workshopDirectory (WORKSHOP_APP_ID, path);
|
||||||
|
|
||||||
this->background = Steam::FileSystem::workshopDirectory (WORKSHOP_APP_ID, this->background);
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CApplicationContext::validateAssets ()
|
void CApplicationContext::validateAssets ()
|
||||||
@ -191,6 +235,7 @@ void CApplicationContext::printHelp (const char* route)
|
|||||||
sLog.out ("\t--silent\t\t\t\t\tMutes all the sound the wallpaper might produce");
|
sLog.out ("\t--silent\t\t\t\t\tMutes all the sound the wallpaper might produce");
|
||||||
sLog.out ("\t--volume <amount>\t\t\tSets the volume for all the sounds in the background");
|
sLog.out ("\t--volume <amount>\t\t\tSets the volume for all the sounds in the background");
|
||||||
sLog.out ("\t--screen-root <screen name>\tDisplay as screen's background");
|
sLog.out ("\t--screen-root <screen name>\tDisplay as screen's background");
|
||||||
|
sLog.out ("\t--window <geometry>\tRuns in window mode, geometry has to be XxYxWxH");
|
||||||
sLog.out ("\t--fps <maximum-fps>\t\t\tLimits the FPS to the given number, useful to keep battery consumption low");
|
sLog.out ("\t--fps <maximum-fps>\t\t\tLimits the FPS to the given number, useful to keep battery consumption low");
|
||||||
sLog.out ("\t--assets-dir <path>\t\t\tFolder where the assets are stored");
|
sLog.out ("\t--assets-dir <path>\t\t\tFolder where the assets are stored");
|
||||||
sLog.out ("\t--screenshot\t\t\t\tTakes a screenshot of the background");
|
sLog.out ("\t--screenshot\t\t\t\tTakes a screenshot of the background");
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <glm/vec4.hpp>
|
||||||
|
|
||||||
namespace WallpaperEngine::Application
|
namespace WallpaperEngine::Application
|
||||||
{
|
{
|
||||||
class CApplicationContext
|
class CApplicationContext
|
||||||
@ -13,7 +15,15 @@ namespace WallpaperEngine::Application
|
|||||||
public:
|
public:
|
||||||
CApplicationContext (int argc, char* argv[]);
|
CApplicationContext (int argc, char* argv[]);
|
||||||
|
|
||||||
std::vector <std::string> screens;
|
enum WINDOW_MODE
|
||||||
|
{
|
||||||
|
NORMAL_WINDOW = 0,
|
||||||
|
X11_BACKGROUND = 1,
|
||||||
|
EXPLICIT_WINDOW = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
glm::ivec4 windowGeometry;
|
||||||
|
std::map <std::string, std::string> screenSettings;
|
||||||
std::map <std::string, std::string> properties;
|
std::map <std::string, std::string> properties;
|
||||||
std::string background;
|
std::string background;
|
||||||
std::filesystem::path assets;
|
std::filesystem::path assets;
|
||||||
@ -24,9 +34,10 @@ namespace WallpaperEngine::Application
|
|||||||
bool audioEnabled;
|
bool audioEnabled;
|
||||||
bool onlyListProperties;
|
bool onlyListProperties;
|
||||||
FREE_IMAGE_FORMAT screenshotFormat;
|
FREE_IMAGE_FORMAT screenshotFormat;
|
||||||
|
WINDOW_MODE windowMode;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void validatePath ();
|
std::string validatePath (const std::string& path);
|
||||||
void validateAssets ();
|
void validateAssets ();
|
||||||
void validateScreenshot ();
|
void validateScreenshot ();
|
||||||
static void printHelp (const char* route);
|
static void printHelp (const char* route);
|
||||||
|
@ -5,9 +5,13 @@
|
|||||||
#include "WallpaperEngine/Core/CVideo.h"
|
#include "WallpaperEngine/Core/CVideo.h"
|
||||||
#include "WallpaperEngine/Logging/CLog.h"
|
#include "WallpaperEngine/Logging/CLog.h"
|
||||||
#include "WallpaperEngine/Render/CRenderContext.h"
|
#include "WallpaperEngine/Render/CRenderContext.h"
|
||||||
|
#include "WallpaperEngine/Render/Drivers/Output/CX11Output.h"
|
||||||
|
#include "WallpaperEngine/Render/Drivers/Output/CWindowOutput.h"
|
||||||
|
#include "Steam/FileSystem/FileSystem.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
float g_Time;
|
float g_Time;
|
||||||
float g_TimeLast;
|
float g_TimeLast;
|
||||||
bool g_KeepRunning = true;
|
bool g_KeepRunning = true;
|
||||||
@ -18,30 +22,32 @@ using namespace WallpaperEngine::Application;
|
|||||||
using namespace WallpaperEngine::Core;
|
using namespace WallpaperEngine::Core;
|
||||||
|
|
||||||
CWallpaperApplication::CWallpaperApplication (CApplicationContext& context) :
|
CWallpaperApplication::CWallpaperApplication (CApplicationContext& context) :
|
||||||
m_context (context)
|
m_context (context),
|
||||||
|
m_defaultProject (nullptr)
|
||||||
{
|
{
|
||||||
// copy state to global variables for now
|
// copy state to global variables for now
|
||||||
g_AudioVolume = context.audioVolume;
|
g_AudioVolume = context.audioVolume;
|
||||||
g_AudioEnabled = context.audioEnabled;
|
g_AudioEnabled = context.audioEnabled;
|
||||||
this->setupContainer ();
|
this->loadProjects ();
|
||||||
this->loadProject ();
|
|
||||||
this->setupProperties ();
|
this->setupProperties ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallpaperApplication::setupContainer ()
|
void CWallpaperApplication::setupContainer (CCombinedContainer& container, const std::string& bg) const
|
||||||
{
|
{
|
||||||
this->m_vfs.add (new CDirectory (this->m_context.background));
|
std::filesystem::path basepath = bg;
|
||||||
this->m_vfs.addPkg (std::filesystem::path (this->m_context.background) / "scene.pkg");
|
|
||||||
this->m_vfs.addPkg (std::filesystem::path (this->m_context.background) / "gifscene.pkg");
|
container.add (new CDirectory (basepath));
|
||||||
this->m_vfs.add (new CDirectory (this->m_context.assets));
|
container.addPkg (basepath / "scene.pkg");
|
||||||
|
container.addPkg (basepath / "gifscene.pkg");
|
||||||
|
container.add (new CDirectory (this->m_context.assets));
|
||||||
#if !NDEBUG
|
#if !NDEBUG
|
||||||
this->m_vfs.add (new CDirectory ("../share/"));
|
container.add (new CDirectory ("../share/"));
|
||||||
#else
|
#else
|
||||||
this->m_vfs.add (new CDirectory (DATADIR));
|
this->m_vfs.add (new CDirectory (DATADIR));
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
// TODO: move this somewhere else?
|
// TODO: move this somewhere else?
|
||||||
CVirtualContainer* container = new CVirtualContainer ();
|
CVirtualContainer* virtualContainer = new CVirtualContainer ();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Had to get a little creative with the effects to achieve the same bloom effect without any custom code
|
// Had to get a little creative with the effects to achieve the same bloom effect without any custom code
|
||||||
@ -50,7 +56,7 @@ void CWallpaperApplication::setupContainer ()
|
|||||||
//
|
//
|
||||||
|
|
||||||
// add the effect file for screen bloom
|
// add the effect file for screen bloom
|
||||||
container->add (
|
virtualContainer->add (
|
||||||
"effects/wpenginelinux/bloomeffect.json",
|
"effects/wpenginelinux/bloomeffect.json",
|
||||||
"{"
|
"{"
|
||||||
"\t\"name\":\"camerabloom_wpengine_linux\","
|
"\t\"name\":\"camerabloom_wpengine_linux\","
|
||||||
@ -111,7 +117,7 @@ void CWallpaperApplication::setupContainer ()
|
|||||||
);
|
);
|
||||||
|
|
||||||
// add some model for the image element even if it's going to waste rendering cycles
|
// add some model for the image element even if it's going to waste rendering cycles
|
||||||
container->add (
|
virtualContainer->add (
|
||||||
"models/wpenginelinux.json",
|
"models/wpenginelinux.json",
|
||||||
"{"
|
"{"
|
||||||
"\t\"material\":\"materials/wpenginelinux.json\""
|
"\t\"material\":\"materials/wpenginelinux.json\""
|
||||||
@ -119,7 +125,7 @@ void CWallpaperApplication::setupContainer ()
|
|||||||
);
|
);
|
||||||
|
|
||||||
// models require materials, so add that too
|
// models require materials, so add that too
|
||||||
container->add (
|
virtualContainer->add (
|
||||||
"materials/wpenginelinux.json",
|
"materials/wpenginelinux.json",
|
||||||
"{"
|
"{"
|
||||||
"\t\"passes\":"
|
"\t\"passes\":"
|
||||||
@ -136,47 +142,74 @@ void CWallpaperApplication::setupContainer ()
|
|||||||
"}"
|
"}"
|
||||||
);
|
);
|
||||||
|
|
||||||
this->m_vfs.add (container);
|
container.add (virtualContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallpaperApplication::loadProject ()
|
void CWallpaperApplication::loadProjects ()
|
||||||
{
|
{
|
||||||
this->m_project = CProject::fromFile ("project.json", this->m_vfs);
|
for (const auto& it : this->m_context.screenSettings)
|
||||||
// go to the right folder so the videos will play
|
{
|
||||||
// TODO: stop doing chdir and use full path
|
// ignore the screen settings if there was no background specified
|
||||||
if (this->m_project->getWallpaper ()->is <WallpaperEngine::Core::CVideo> ())
|
// the default will be used
|
||||||
chdir (this->m_context.background.c_str ());
|
if (it.second.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
this->m_projects.insert_or_assign (
|
||||||
|
it.first,
|
||||||
|
this->loadProject (it.second)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the default project if required
|
||||||
|
if (!this->m_context.background.empty ())
|
||||||
|
this->m_defaultProject = this->loadProject (this->m_context.background);
|
||||||
|
}
|
||||||
|
|
||||||
|
CProject* CWallpaperApplication::loadProject (const std::string& bg)
|
||||||
|
{
|
||||||
|
CCombinedContainer* container = new CCombinedContainer ();
|
||||||
|
|
||||||
|
this->setupContainer (*container, bg);
|
||||||
|
|
||||||
|
// TODO: Change this to pointer instead of reference
|
||||||
|
return CProject::fromFile ("project.json", container);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWallpaperApplication::setupPropertiesForProject (CProject* project)
|
||||||
|
{
|
||||||
|
// show properties if required
|
||||||
|
for (auto cur : project->getProperties ())
|
||||||
|
{
|
||||||
|
// update the value of the property
|
||||||
|
auto override = this->m_context.properties.find (cur->getName ());
|
||||||
|
|
||||||
|
if (override != this->m_context.properties.end ())
|
||||||
|
{
|
||||||
|
sLog.out ("Applying override value for ", cur->getName ());
|
||||||
|
|
||||||
|
cur->update (override->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->m_context.onlyListProperties)
|
||||||
|
sLog.out (cur->dump ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallpaperApplication::setupProperties ()
|
void CWallpaperApplication::setupProperties ()
|
||||||
{
|
{
|
||||||
// show properties if required
|
for (const auto& it : this->m_projects)
|
||||||
for (auto cur : this->m_project->getProperties ())
|
this->setupPropertiesForProject (it.second);
|
||||||
{
|
|
||||||
// update the value of the property
|
|
||||||
auto override = this->m_context.properties.find (cur->getName ());
|
|
||||||
|
|
||||||
if (override != this->m_context.properties.end ())
|
if (this->m_defaultProject != nullptr)
|
||||||
{
|
this->setupPropertiesForProject (this->m_defaultProject);
|
||||||
sLog.out ("Applying override value for ", cur->getName ());
|
|
||||||
|
|
||||||
cur->update (override->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->m_context.onlyListProperties)
|
|
||||||
sLog.out (cur->dump ());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallpaperApplication::takeScreenshot (WallpaperEngine::Render::CWallpaper* wp, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format)
|
void CWallpaperApplication::takeScreenshot (const Render::CRenderContext& context, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format)
|
||||||
{
|
{
|
||||||
GLint width, height;
|
// this should be getting called at the end of the frame, so the right thing should be bound already
|
||||||
|
|
||||||
// bind texture and get the size
|
int width = context.getOutput ()->getFullWidth ();
|
||||||
glBindFramebuffer (GL_FRAMEBUFFER, wp->getWallpaperFramebuffer ());
|
int height = context.getOutput ()->getFullHeight ();
|
||||||
glBindTexture (GL_TEXTURE_2D, wp->getWallpaperTexture ());
|
|
||||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
|
|
||||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
|
|
||||||
|
|
||||||
// make room for storing the pixel data
|
// make room for storing the pixel data
|
||||||
uint8_t* buffer = new uint8_t [width * height * sizeof (uint8_t) * 3];
|
uint8_t* buffer = new uint8_t [width * height * sizeof (uint8_t) * 3];
|
||||||
@ -222,15 +255,42 @@ void CWallpaperApplication::show ()
|
|||||||
// initialize audio context
|
// initialize audio context
|
||||||
WallpaperEngine::Audio::CAudioContext audioContext (audioDriver);
|
WallpaperEngine::Audio::CAudioContext audioContext (audioDriver);
|
||||||
// initialize OpenGL driver
|
// initialize OpenGL driver
|
||||||
WallpaperEngine::Render::Drivers::COpenGLDriver videoDriver (this->m_project->getTitle ().c_str ());
|
WallpaperEngine::Render::Drivers::COpenGLDriver videoDriver ("wallpaperengine");
|
||||||
// initialize the input subsystem
|
// initialize the input subsystem
|
||||||
WallpaperEngine::Input::CInputContext inputContext (videoDriver);
|
WallpaperEngine::Input::CInputContext inputContext (videoDriver);
|
||||||
|
// output requested
|
||||||
|
WallpaperEngine::Render::Drivers::Output::COutput* output;
|
||||||
|
|
||||||
|
// initialize the requested output
|
||||||
|
switch (this->m_context.windowMode)
|
||||||
|
{
|
||||||
|
case CApplicationContext::EXPLICIT_WINDOW:
|
||||||
|
case CApplicationContext::NORMAL_WINDOW:
|
||||||
|
output = new WallpaperEngine::Render::Drivers::Output::CWindowOutput (this->m_context, videoDriver);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CApplicationContext::X11_BACKGROUND:
|
||||||
|
output = new WallpaperEngine::Render::Drivers::Output::CX11Output (this->m_context, videoDriver);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// initialize render context
|
// initialize render context
|
||||||
WallpaperEngine::Render::CRenderContext context (this->m_context.screens, videoDriver, inputContext, this->m_vfs, *this);
|
WallpaperEngine::Render::CRenderContext context (output, videoDriver, inputContext, *this);
|
||||||
// ensure the context knows what wallpaper to render
|
|
||||||
context.setWallpaper (
|
// set all the specific wallpapers required
|
||||||
WallpaperEngine::Render::CWallpaper::fromWallpaper (this->m_project->getWallpaper (), context, audioContext)
|
for (const auto& it : this->m_projects)
|
||||||
);
|
{
|
||||||
|
context.setWallpaper (
|
||||||
|
it.first,
|
||||||
|
WallpaperEngine::Render::CWallpaper::fromWallpaper (it.second->getWallpaper (), context, audioContext)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the default rendering wallpaper if available
|
||||||
|
if (this->m_defaultProject != nullptr)
|
||||||
|
context.setDefaultWallpaper (
|
||||||
|
WallpaperEngine::Render::CWallpaper::fromWallpaper (this->m_defaultProject->getWallpaper (), context, audioContext)
|
||||||
|
);
|
||||||
|
|
||||||
float startTime, endTime, minimumTime = 1.0f / this->m_context.maximumFPS;
|
float startTime, endTime, minimumTime = 1.0f / this->m_context.maximumFPS;
|
||||||
|
|
||||||
@ -255,7 +315,7 @@ void CWallpaperApplication::show ()
|
|||||||
|
|
||||||
if (this->m_context.takeScreenshot && videoDriver.getFrameCounter () == 5)
|
if (this->m_context.takeScreenshot && videoDriver.getFrameCounter () == 5)
|
||||||
{
|
{
|
||||||
this->takeScreenshot (context.getWallpaper (), this->m_context.screenshot, this->m_context.screenshotFormat);
|
this->takeScreenshot (context, this->m_context.screenshot, this->m_context.screenshotFormat);
|
||||||
// disable screenshot just in case the counter overflows
|
// disable screenshot just in case the counter overflows
|
||||||
this->m_context.takeScreenshot = false;
|
this->m_context.takeScreenshot = false;
|
||||||
}
|
}
|
||||||
@ -272,4 +332,14 @@ void CWallpaperApplication::show ()
|
|||||||
void CWallpaperApplication::signal (int signal)
|
void CWallpaperApplication::signal (int signal)
|
||||||
{
|
{
|
||||||
g_KeepRunning = false;
|
g_KeepRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::map <std::string, CProject*>& CWallpaperApplication::getProjects () const
|
||||||
|
{
|
||||||
|
return this->m_projects;
|
||||||
|
}
|
||||||
|
|
||||||
|
CProject* CWallpaperApplication::getDefaultProject () const
|
||||||
|
{
|
||||||
|
return this->m_defaultProject;
|
||||||
}
|
}
|
@ -5,10 +5,12 @@
|
|||||||
#include "WallpaperEngine/Assets/CCombinedContainer.h"
|
#include "WallpaperEngine/Assets/CCombinedContainer.h"
|
||||||
#include "WallpaperEngine/Core/CProject.h"
|
#include "WallpaperEngine/Core/CProject.h"
|
||||||
#include "WallpaperEngine/Render/CWallpaper.h"
|
#include "WallpaperEngine/Render/CWallpaper.h"
|
||||||
|
#include "WallpaperEngine/Render/CRenderContext.h"
|
||||||
|
|
||||||
namespace WallpaperEngine::Render
|
namespace WallpaperEngine::Render
|
||||||
{
|
{
|
||||||
class CWallpaper;
|
class CWallpaper;
|
||||||
|
class CRenderContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace WallpaperEngine::Application
|
namespace WallpaperEngine::Application
|
||||||
@ -22,15 +24,19 @@ namespace WallpaperEngine::Application
|
|||||||
|
|
||||||
void show ();
|
void show ();
|
||||||
void signal (int signal);
|
void signal (int signal);
|
||||||
|
const std::map <std::string, Core::CProject*>& getProjects () const;
|
||||||
|
Core::CProject* getDefaultProject () const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupContainer ();
|
void setupContainer (CCombinedContainer& container, const std::string& bg) const;
|
||||||
void loadProject ();
|
void loadProjects ();
|
||||||
|
Core::CProject* loadProject (const std::string& bg);
|
||||||
void setupProperties ();
|
void setupProperties ();
|
||||||
void takeScreenshot (WallpaperEngine::Render::CWallpaper* wp, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format);
|
void setupPropertiesForProject (Core::CProject* project);
|
||||||
|
void takeScreenshot (const Render::CRenderContext& context, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format);
|
||||||
|
|
||||||
Core::CProject* m_project;
|
Core::CProject* m_defaultProject;
|
||||||
CApplicationContext& m_context;
|
CApplicationContext& m_context;
|
||||||
CCombinedContainer m_vfs;
|
std::map <std::string, Core::CProject*> m_projects;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,27 @@ void CCombinedContainer::addPkg (const std::filesystem::path& path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::filesystem::path CCombinedContainer::resolveRealFile (std::string filename) const
|
||||||
|
{
|
||||||
|
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->resolveRealFile (filename);
|
||||||
|
}
|
||||||
|
catch (CAssetLoadException& ex)
|
||||||
|
{
|
||||||
|
// not found in this container, next try
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no container was able to load the file, abort!
|
||||||
|
throw CAssetLoadException (filename, "Cannot resolve file in any of the containers");
|
||||||
|
}
|
||||||
|
|
||||||
const void* CCombinedContainer::readFile (std::string filename, uint32_t* length) const
|
const void* CCombinedContainer::readFile (std::string filename, uint32_t* length) const
|
||||||
{
|
{
|
||||||
for (auto cur : this->m_containers)
|
for (auto cur : this->m_containers)
|
||||||
|
@ -21,6 +21,7 @@ namespace WallpaperEngine::Assets
|
|||||||
void add (CContainer* container);
|
void add (CContainer* container);
|
||||||
void addPkg (const std::filesystem::path& path);
|
void addPkg (const std::filesystem::path& path);
|
||||||
|
|
||||||
|
std::filesystem::path resolveRealFile (std::string filename) const override;
|
||||||
const void* readFile (std::string filename, uint32_t* length = nullptr) const override;
|
const void* readFile (std::string filename, uint32_t* length = nullptr) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -9,6 +9,11 @@
|
|||||||
|
|
||||||
using namespace WallpaperEngine::Assets;
|
using namespace WallpaperEngine::Assets;
|
||||||
|
|
||||||
|
std::filesystem::path CContainer::resolveRealFile (std::string filename) const
|
||||||
|
{
|
||||||
|
throw CAssetLoadException (filename, "Cannot resolve physical file in this container");
|
||||||
|
}
|
||||||
|
|
||||||
const ITexture* CContainer::readTexture (std::string filename) const
|
const ITexture* CContainer::readTexture (std::string filename) const
|
||||||
{
|
{
|
||||||
// get the texture's filename (usually .tex)
|
// get the texture's filename (usually .tex)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "WallpaperEngine/Assets/ITexture.h"
|
#include "WallpaperEngine/Assets/ITexture.h"
|
||||||
|
|
||||||
@ -8,6 +9,14 @@ namespace WallpaperEngine::Assets
|
|||||||
class CContainer
|
class CContainer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Resolves the full path to the specified file in the filesystem
|
||||||
|
*
|
||||||
|
* @param filename
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual std::filesystem::path resolveRealFile (std::string filename) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the given file from the container and returns it's data
|
* Reads the given file from the container and returns it's data
|
||||||
* Additionally sets a length parameter to return back the file's length
|
* Additionally sets a length parameter to return back the file's length
|
||||||
|
@ -24,6 +24,11 @@ CDirectory::CDirectory (std::filesystem::path basepath) :
|
|||||||
CDirectory::~CDirectory ()
|
CDirectory::~CDirectory ()
|
||||||
= default;
|
= default;
|
||||||
|
|
||||||
|
std::filesystem::path CDirectory::resolveRealFile (std::string filename) const
|
||||||
|
{
|
||||||
|
return std::filesystem::path (this->m_basepath) / filename;
|
||||||
|
}
|
||||||
|
|
||||||
const void* CDirectory::readFile (std::string filename, uint32_t* length) const
|
const void* CDirectory::readFile (std::string filename, uint32_t* length) const
|
||||||
{
|
{
|
||||||
std::filesystem::path final = std::filesystem::path (this->m_basepath) / filename;
|
std::filesystem::path final = std::filesystem::path (this->m_basepath) / filename;
|
||||||
|
@ -16,6 +16,7 @@ namespace WallpaperEngine::Assets
|
|||||||
explicit CDirectory (std::filesystem::path basepath);
|
explicit CDirectory (std::filesystem::path basepath);
|
||||||
~CDirectory ();
|
~CDirectory ();
|
||||||
|
|
||||||
|
std::filesystem::path resolveRealFile (std::string filename) const override;
|
||||||
const void* readFile (std::string filename, uint32_t* length) const override;
|
const void* readFile (std::string filename, uint32_t* length) const override;
|
||||||
private:
|
private:
|
||||||
std::filesystem::path m_basepath;
|
std::filesystem::path m_basepath;
|
||||||
|
@ -7,7 +7,6 @@ using namespace WallpaperEngine::Audio::Drivers;
|
|||||||
CAudioContext::CAudioContext (CAudioDriver& driver) :
|
CAudioContext::CAudioContext (CAudioDriver& driver) :
|
||||||
m_driver (driver)
|
m_driver (driver)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAudioContext::addStream (CAudioStream* stream)
|
void CAudioContext::addStream (CAudioStream* stream)
|
||||||
|
@ -35,7 +35,7 @@ CObject::CObject (
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CObject* CObject::fromJSON (json data, CScene* scene, const CContainer& container)
|
CObject* CObject::fromJSON (json data, CScene* scene, CContainer* container)
|
||||||
{
|
{
|
||||||
std::string json = data.dump ();
|
std::string json = data.dump ();
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ namespace WallpaperEngine::Core
|
|||||||
{
|
{
|
||||||
friend class CScene;
|
friend class CScene;
|
||||||
public:
|
public:
|
||||||
static CObject* fromJSON (json data, CScene* scene, const CContainer& container);
|
static CObject* fromJSON (json data, CScene* scene, CContainer* container);
|
||||||
|
|
||||||
template<class T> const T* as () const { assert (is <T> ()); return (const T*) this; }
|
template<class T> const T* as () const { assert (is <T> ()); return (const T*) this; }
|
||||||
template<class T> T* as () { assert (is <T> ()); return (T*) this; }
|
template<class T> T* as () { assert (is <T> ()); return (T*) this; }
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
using namespace WallpaperEngine::Core;
|
using namespace WallpaperEngine::Core;
|
||||||
using namespace WallpaperEngine::Assets;
|
using namespace WallpaperEngine::Assets;
|
||||||
|
|
||||||
CProject::CProject (std::string title, std::string type, CContainer& container) :
|
CProject::CProject (std::string title, std::string type, CContainer* container) :
|
||||||
m_title (std::move (title)),
|
m_title (std::move (title)),
|
||||||
m_type (std::move (type)),
|
m_type (std::move (type)),
|
||||||
m_container (container)
|
m_container (container)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CProject* CProject::fromFile (const std::string& filename, CContainer& container)
|
CProject* CProject::fromFile (const std::string& filename, CContainer* container)
|
||||||
{
|
{
|
||||||
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container));
|
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container));
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ const std::vector<Projects::CProperty*>& CProject::getProperties () const
|
|||||||
return this->m_properties;
|
return this->m_properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
CContainer& CProject::getContainer ()
|
CContainer* CProject::getContainer ()
|
||||||
{
|
{
|
||||||
return this->m_container;
|
return this->m_container;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ namespace WallpaperEngine::Core
|
|||||||
class CProject
|
class CProject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static CProject* fromFile (const std::string& filename, CContainer& container);
|
static CProject* fromFile (const std::string& filename, CContainer* container);
|
||||||
|
|
||||||
CWallpaper* getWallpaper () const;
|
CWallpaper* getWallpaper () const;
|
||||||
|
|
||||||
@ -24,10 +24,10 @@ namespace WallpaperEngine::Core
|
|||||||
const std::string& getType () const;
|
const std::string& getType () const;
|
||||||
const std::vector<Projects::CProperty*>& getProperties () const;
|
const std::vector<Projects::CProperty*>& getProperties () const;
|
||||||
|
|
||||||
CContainer& getContainer ();
|
CContainer* getContainer ();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CProject (std::string title, std::string type, CContainer& container);
|
CProject (std::string title, std::string type, CContainer* container);
|
||||||
|
|
||||||
void setWallpaper (CWallpaper* wallpaper);
|
void setWallpaper (CWallpaper* wallpaper);
|
||||||
void insertProperty (Projects::CProperty* property);
|
void insertProperty (Projects::CProperty* property);
|
||||||
@ -37,6 +37,6 @@ namespace WallpaperEngine::Core
|
|||||||
std::string m_title;
|
std::string m_title;
|
||||||
std::string m_type;
|
std::string m_type;
|
||||||
CWallpaper* m_wallpaper;
|
CWallpaper* m_wallpaper;
|
||||||
CContainer& m_container;
|
CContainer* m_container;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ using namespace WallpaperEngine::Core;
|
|||||||
|
|
||||||
CScene::CScene (
|
CScene::CScene (
|
||||||
CProject& project,
|
CProject& project,
|
||||||
CContainer& container,
|
CContainer* container,
|
||||||
Scenes::CCamera* camera,
|
Scenes::CCamera* camera,
|
||||||
glm::vec3 ambientColor,
|
glm::vec3 ambientColor,
|
||||||
CUserSettingBoolean* bloom,
|
CUserSettingBoolean* bloom,
|
||||||
@ -52,7 +52,7 @@ CScene::CScene (
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CScene* CScene::fromFile (const std::string& filename, CProject& project, CContainer& container)
|
CScene* CScene::fromFile (const std::string& filename, CProject& project, CContainer* container)
|
||||||
{
|
{
|
||||||
std::string stringContent = WallpaperEngine::FileSystem::loadFullFile (filename, container);
|
std::string stringContent = WallpaperEngine::FileSystem::loadFullFile (filename, container);
|
||||||
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container));
|
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container));
|
||||||
@ -128,7 +128,7 @@ void CScene::insertObject (CObject* object)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CContainer& CScene::getContainer ()
|
CContainer* CScene::getContainer ()
|
||||||
{
|
{
|
||||||
return this->m_container;
|
return this->m_container;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ namespace WallpaperEngine::Core
|
|||||||
class CScene : public CWallpaper
|
class CScene : public CWallpaper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static CScene* fromFile (const std::string& filename, CProject& project, CContainer& container);
|
static CScene* fromFile (const std::string& filename, CProject& project, CContainer* container);
|
||||||
|
|
||||||
const std::map<uint32_t, CObject*>& getObjects () const;
|
const std::map<uint32_t, CObject*>& getObjects () const;
|
||||||
const std::vector<CObject*>& getObjectsByRenderOrder () const;
|
const std::vector<CObject*>& getObjectsByRenderOrder () const;
|
||||||
@ -46,7 +46,7 @@ namespace WallpaperEngine::Core
|
|||||||
|
|
||||||
CScene (
|
CScene (
|
||||||
CProject& project,
|
CProject& project,
|
||||||
CContainer& container,
|
CContainer* container,
|
||||||
Scenes::CCamera* camera,
|
Scenes::CCamera* camera,
|
||||||
glm::vec3 ambientColor,
|
glm::vec3 ambientColor,
|
||||||
CUserSettingBoolean* bloom,
|
CUserSettingBoolean* bloom,
|
||||||
@ -71,9 +71,9 @@ namespace WallpaperEngine::Core
|
|||||||
|
|
||||||
void insertObject (CObject* object);
|
void insertObject (CObject* object);
|
||||||
|
|
||||||
CContainer& getContainer ();
|
CContainer* getContainer ();
|
||||||
private:
|
private:
|
||||||
CContainer& m_container;
|
CContainer* m_container;
|
||||||
Scenes::CCamera* m_camera;
|
Scenes::CCamera* m_camera;
|
||||||
|
|
||||||
// data from general section on the json
|
// data from general section on the json
|
||||||
|
@ -36,7 +36,7 @@ CEffect::CEffect (
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, Core::CObject* object, const CContainer& container)
|
CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, Core::CObject* object, CContainer* container)
|
||||||
{
|
{
|
||||||
auto file_it = jsonFindRequired (data, "file", "Object effect must have a file");
|
auto file_it = jsonFindRequired (data, "file", "Object effect must have a file");
|
||||||
auto effectpasses_it = data.find ("passes");
|
auto effectpasses_it = data.find ("passes");
|
||||||
@ -202,7 +202,7 @@ void CEffect::dependencyFromJSON (json::const_iterator dependencies_it, CEffect*
|
|||||||
effect->insertDependency (cur);
|
effect->insertDependency (cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect, const CContainer& container)
|
void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect, CContainer* container)
|
||||||
{
|
{
|
||||||
for (const auto& cur : (*passes_it))
|
for (const auto& cur : (*passes_it))
|
||||||
{
|
{
|
||||||
|
@ -35,7 +35,7 @@ namespace WallpaperEngine::Core::Objects
|
|||||||
CUserSettingBoolean* visible
|
CUserSettingBoolean* visible
|
||||||
);
|
);
|
||||||
|
|
||||||
static CEffect* fromJSON (json data, CUserSettingBoolean* visible, Core::CObject* object, const CContainer& container);
|
static CEffect* fromJSON (json data, CUserSettingBoolean* visible, Core::CObject* object, CContainer* container);
|
||||||
|
|
||||||
const std::vector<std::string>& getDependencies () const;
|
const std::vector<std::string>& getDependencies () const;
|
||||||
const std::vector<Images::CMaterial*>& getMaterials () const;
|
const std::vector<Images::CMaterial*>& getMaterials () const;
|
||||||
@ -48,7 +48,7 @@ namespace WallpaperEngine::Core::Objects
|
|||||||
static void combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass);
|
static void combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass);
|
||||||
static void fbosFromJSON (json::const_iterator fbos_it, CEffect* effect);
|
static void fbosFromJSON (json::const_iterator fbos_it, CEffect* effect);
|
||||||
static void dependencyFromJSON (json::const_iterator dependencies_it, CEffect* effect);
|
static void dependencyFromJSON (json::const_iterator dependencies_it, CEffect* effect);
|
||||||
static void materialsFromJSON (json::const_iterator passes_it, CEffect* effect, const CContainer& container);
|
static void materialsFromJSON (json::const_iterator passes_it, CEffect* effect, CContainer* container);
|
||||||
|
|
||||||
void insertDependency (const std::string& dep);
|
void insertDependency (const std::string& dep);
|
||||||
void insertMaterial (Images::CMaterial* material);
|
void insertMaterial (Images::CMaterial* material);
|
||||||
|
@ -44,7 +44,7 @@ CImage::CImage (
|
|||||||
WallpaperEngine::Core::CObject* CImage::fromJSON (
|
WallpaperEngine::Core::CObject* CImage::fromJSON (
|
||||||
CScene* scene,
|
CScene* scene,
|
||||||
json data,
|
json data,
|
||||||
const CContainer& container,
|
CContainer* container,
|
||||||
CUserSettingBoolean* visible,
|
CUserSettingBoolean* visible,
|
||||||
uint32_t id,
|
uint32_t id,
|
||||||
std::string name,
|
std::string name,
|
||||||
|
@ -29,7 +29,7 @@ namespace WallpaperEngine::Core::Objects
|
|||||||
static CObject* fromJSON (
|
static CObject* fromJSON (
|
||||||
CScene* scene,
|
CScene* scene,
|
||||||
json data,
|
json data,
|
||||||
const CContainer& container,
|
CContainer* container,
|
||||||
CUserSettingBoolean* visible,
|
CUserSettingBoolean* visible,
|
||||||
uint32_t id,
|
uint32_t id,
|
||||||
std::string name,
|
std::string name,
|
||||||
|
@ -8,7 +8,7 @@ using namespace WallpaperEngine::Core::Objects;
|
|||||||
CParticle* CParticle::fromFile (
|
CParticle* CParticle::fromFile (
|
||||||
CScene* scene,
|
CScene* scene,
|
||||||
const std::string& filename,
|
const std::string& filename,
|
||||||
const CContainer& container,
|
CContainer* container,
|
||||||
CUserSettingBoolean* visible,
|
CUserSettingBoolean* visible,
|
||||||
uint32_t id,
|
uint32_t id,
|
||||||
std::string name,
|
std::string name,
|
||||||
@ -34,10 +34,8 @@ CParticle* CParticle::fromFile (
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (controlpoint_it != data.end ())
|
if (controlpoint_it != data.end ())
|
||||||
{
|
|
||||||
for (const auto& cur : (*controlpoint_it))
|
for (const auto& cur : (*controlpoint_it))
|
||||||
particle->insertControlPoint (Particles::CControlPoint::fromJSON (cur));
|
particle->insertControlPoint (Particles::CControlPoint::fromJSON (cur));
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& cur : (*emitter_it))
|
for (const auto& cur : (*emitter_it))
|
||||||
particle->insertEmitter (Particles::CEmitter::fromJSON (cur));
|
particle->insertEmitter (Particles::CEmitter::fromJSON (cur));
|
||||||
|
@ -19,7 +19,7 @@ namespace WallpaperEngine::Core::Objects
|
|||||||
static CParticle* fromFile (
|
static CParticle* fromFile (
|
||||||
CScene* scene,
|
CScene* scene,
|
||||||
const std::string& filename,
|
const std::string& filename,
|
||||||
const CContainer& container,
|
CContainer* container,
|
||||||
CUserSettingBoolean* visible,
|
CUserSettingBoolean* visible,
|
||||||
uint32_t id,
|
uint32_t id,
|
||||||
std::string name,
|
std::string name,
|
||||||
|
@ -16,13 +16,13 @@ CMaterial::CMaterial (std::string name) :
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CMaterial* CMaterial::fromFile (const std::string& filename, const CContainer& container)
|
CMaterial* CMaterial::fromFile (const std::string& filename, CContainer* container)
|
||||||
{
|
{
|
||||||
return fromJSON (
|
return fromJSON (
|
||||||
filename, json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container))
|
filename, json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
CMaterial* CMaterial::fromFile (const std::string& filename, const std::string& target, const CContainer& container)
|
CMaterial* CMaterial::fromFile (const std::string& filename, const std::string& target, CContainer* container)
|
||||||
{
|
{
|
||||||
return fromJSON (
|
return fromJSON (
|
||||||
filename, json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)), target
|
filename, json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)), target
|
||||||
|
@ -14,9 +14,9 @@ namespace WallpaperEngine::Core::Objects::Images
|
|||||||
class CMaterial
|
class CMaterial
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static CMaterial* fromFile (const std::string& filename, const CContainer& container);
|
static CMaterial* fromFile (const std::string& filename, CContainer* container);
|
||||||
static CMaterial* fromJSON (const std::string& name, json data);
|
static CMaterial* fromJSON (const std::string& name, json data);
|
||||||
static CMaterial* fromFile (const std::string& filename, const std::string& target, const CContainer& container);
|
static CMaterial* fromFile (const std::string& filename, const std::string& target, CContainer* container);
|
||||||
static CMaterial* fromJSON (const std::string& name, json data, const std::string& target);
|
static CMaterial* fromJSON (const std::string& name, json data, const std::string& target);
|
||||||
|
|
||||||
void insertPass (Materials::CPass* mass);
|
void insertPass (Materials::CPass* mass);
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
using namespace WallpaperEngine;
|
using namespace WallpaperEngine;
|
||||||
|
|
||||||
std::string FileSystem::loadFullFile (const std::string& file, const WallpaperEngine::Assets::CContainer& containers)
|
std::string FileSystem::loadFullFile (const std::string& file, WallpaperEngine::Assets::CContainer* containers)
|
||||||
{
|
{
|
||||||
uint32_t length = 0;
|
uint32_t length = 0;
|
||||||
const void* contents = containers.readFile (file, &length);
|
const void* contents = containers->readFile (file, &length);
|
||||||
|
|
||||||
// build a new buffer that can fit in the string
|
// build a new buffer that can fit in the string
|
||||||
char* filedata = new char [length + 1];
|
char* filedata = new char [length + 1];
|
||||||
|
@ -17,5 +17,5 @@ namespace WallpaperEngine::FileSystem
|
|||||||
* @param file
|
* @param file
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
std::string loadFullFile (const std::string& file, const WallpaperEngine::Assets::CContainer& containers);
|
std::string loadFullFile (const std::string& file, WallpaperEngine::Assets::CContainer* containers);
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ namespace WallpaperEngine::Render
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CFBO (std::string name, ITexture::TextureFormat format, ITexture::TextureFlags flags, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight);
|
CFBO (std::string name, ITexture::TextureFormat format, ITexture::TextureFlags flags, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight);
|
||||||
|
// TODO: ADD DESTRUCTOR TO FREE RESOURCES
|
||||||
|
|
||||||
const std::string& getName () const;
|
const std::string& getName () const;
|
||||||
const float& getScale () const;
|
const float& getScale () const;
|
||||||
|
@ -20,7 +20,7 @@ CScene* CObject::getScene () const
|
|||||||
return this->m_scene;
|
return this->m_scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CContainer& CObject::getContainer () const
|
CContainer* CObject::getContainer () const
|
||||||
{
|
{
|
||||||
return this->getScene ()->getContainer ();
|
return this->getScene ()->getContainer ();
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ namespace WallpaperEngine::Render
|
|||||||
virtual void render () = 0;
|
virtual void render () = 0;
|
||||||
|
|
||||||
CScene* getScene () const;
|
CScene* getScene () const;
|
||||||
const CContainer& getContainer () const;
|
CContainer* getContainer () const;
|
||||||
int getId () const;
|
int getId () const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -12,190 +12,39 @@
|
|||||||
#include "CRenderContext.h"
|
#include "CRenderContext.h"
|
||||||
#include "CVideo.h"
|
#include "CVideo.h"
|
||||||
|
|
||||||
#define DEFAULT_WINDOW_WIDTH 1280
|
|
||||||
#define DEFAULT_WINDOW_HEIGHT 720
|
|
||||||
|
|
||||||
using namespace WallpaperEngine::Render;
|
using namespace WallpaperEngine::Render;
|
||||||
|
|
||||||
XErrorHandler originalErrorHandler;
|
CRenderContext::CRenderContext (const COutput* output, CVideoDriver& driver, CInputContext& input, CWallpaperApplication& app) :
|
||||||
|
m_defaultWallpaper (nullptr),
|
||||||
void CustomXIOErrorExitHandler (Display* dsp, void* userdata)
|
m_output (output),
|
||||||
|
m_driver (driver),
|
||||||
|
m_app (app),
|
||||||
|
m_input (input),
|
||||||
|
m_textureCache (new CTextureCache (*this))
|
||||||
{
|
{
|
||||||
auto context = static_cast <CRenderContext*> (userdata);
|
|
||||||
|
|
||||||
#if !NDEBUG
|
|
||||||
sLog.debugerror ("Critical XServer error detected. Attempting to recover...");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
// refetch all the resources
|
|
||||||
context->initialize ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CustomXErrorHandler (Display* dpy, XErrorEvent* event)
|
void CRenderContext::render ()
|
||||||
{
|
{
|
||||||
#if !NDEBUG
|
bool firstFrame = true;
|
||||||
sLog.debugerror ("Detected X error");
|
bool renderFrame = true;
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
// call the original handler so we can keep some information reporting
|
for (const auto& cur : this->m_output->getViewports ())
|
||||||
originalErrorHandler (dpy, event);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CustomXIOErrorHandler (Display* dsp)
|
|
||||||
{
|
|
||||||
#if !NDEBUG
|
|
||||||
sLog.debugerror ("Detected X error");
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CRenderContext::CRenderContext (std::vector <std::string> screens, CVideoDriver& driver, CInputContext& input, CContainer& container, CWallpaperApplication& app) :
|
|
||||||
m_wallpaper (nullptr),
|
|
||||||
m_screens (std::move (screens)),
|
|
||||||
m_driver (driver),
|
|
||||||
m_container (container),
|
|
||||||
m_app (app),
|
|
||||||
m_input (input),
|
|
||||||
m_textureCache (new CTextureCache (*this)),
|
|
||||||
m_display (nullptr),
|
|
||||||
m_pixmap (0),
|
|
||||||
m_gc (nullptr),
|
|
||||||
m_image (nullptr),
|
|
||||||
m_imageData (nullptr),
|
|
||||||
m_fbo (nullptr)
|
|
||||||
{
|
|
||||||
this->initialize ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CRenderContext::initialize ()
|
|
||||||
{
|
|
||||||
if (this->m_screens.empty ())
|
|
||||||
this->setupWindow ();
|
|
||||||
else
|
|
||||||
this->setupScreens ();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// set the error handling to try and recover from X disconnections
|
|
||||||
#ifdef HAVE_XSETIOERROREXITHANDLER
|
|
||||||
XSetIOErrorExitHandler (this->m_display, CustomXIOErrorExitHandler, this);
|
|
||||||
#endif /* HAVE_XSETIOERROREXITHANDLER */
|
|
||||||
originalErrorHandler = XSetErrorHandler (CustomXErrorHandler);
|
|
||||||
XSetIOErrorHandler (CustomXIOErrorHandler);
|
|
||||||
|
|
||||||
int xrandr_result, xrandr_error;
|
|
||||||
|
|
||||||
if (!XRRQueryExtension (this->m_display, &xrandr_result, &xrandr_error))
|
|
||||||
{
|
|
||||||
sLog.error ("XRandr is not present, cannot detect specified screens, running in window mode");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
XRRScreenResources* screenResources = XRRGetScreenResources (this->m_display, DefaultRootWindow (this->m_display));
|
|
||||||
|
|
||||||
// there are some situations where xrandr returns null (like screen not using the extension)
|
|
||||||
if (screenResources == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// create the pixmap and gc used for this display, most situations only have one "display"
|
|
||||||
this->m_pixmap = XCreatePixmap (this->m_display, DefaultRootWindow (this->m_display), fullWidth, fullHeight, 24);
|
|
||||||
this->m_gc = XCreateGC (this->m_display, this->m_pixmap, 0, nullptr);
|
|
||||||
// fill the whole pixmap with black for now
|
|
||||||
XFillRectangle (this->m_display, this->m_pixmap, this->m_gc, 0, 0, fullWidth, fullHeight);
|
|
||||||
|
|
||||||
for (int i = 0; i < screenResources->noutput; i ++)
|
|
||||||
{
|
|
||||||
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 || info->connection != RR_Connected)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (const auto& cur : this->m_screens)
|
|
||||||
{
|
|
||||||
if (strcmp (info->name, cur.c_str ()) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
XRRCrtcInfo* crtc = XRRGetCrtcInfo (this->m_display, screenResources, info->crtc);
|
|
||||||
|
|
||||||
sLog.out ("Found requested screen: ", info->name, " -> ", crtc->x, "x", crtc->y, ":", crtc->width, "x", crtc->height);
|
|
||||||
|
|
||||||
this->m_viewports.push_back ({{crtc->x, crtc->y, crtc->width, crtc->height}, cur});
|
|
||||||
|
|
||||||
XRRFreeCrtcInfo (crtc);
|
|
||||||
}
|
|
||||||
|
|
||||||
XRRFreeOutputInfo (info);
|
|
||||||
}
|
|
||||||
|
|
||||||
XRRFreeScreenResources (screenResources);
|
|
||||||
|
|
||||||
// create the fbo that will handle the screen
|
|
||||||
this->m_fbo = new CFBO(
|
|
||||||
"_sc_FullFrameBuffer",
|
|
||||||
ITexture::TextureFormat::ARGB8888,
|
|
||||||
ITexture::TextureFlags::NoFlags,
|
|
||||||
1.0,
|
|
||||||
fullWidth, fullHeight,
|
|
||||||
fullWidth, fullHeight
|
|
||||||
);
|
|
||||||
|
|
||||||
// set the window background so the pixmap is drawn
|
|
||||||
XSetWindowBackgroundPixmap(this->m_display, root, this->m_pixmap);
|
|
||||||
|
|
||||||
this->m_imageData = new char [fullWidth * fullHeight * 4];
|
|
||||||
|
|
||||||
// create the image for X11 to be able to copy it over
|
|
||||||
this->m_image = XCreateImage (this->m_display, CopyFromParent, 24, ZPixmap, 0, this->m_imageData, fullWidth, fullHeight, 32, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
CRenderContext::~CRenderContext ()
|
|
||||||
{
|
|
||||||
if (!this->m_screens.empty ())
|
|
||||||
{
|
|
||||||
// free any used resource
|
|
||||||
XDestroyImage (this->m_image);
|
|
||||||
XFreeGC (this->m_display, this->m_gc);
|
|
||||||
XFreePixmap (this->m_display, this->m_pixmap);
|
|
||||||
XCloseDisplay (this->m_display);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 !NDEBUG
|
#if !NDEBUG
|
||||||
std::string str = "Rendering to screen " + cur.name;
|
std::string str = "Rendering to output " + cur.first;
|
||||||
|
|
||||||
glPushDebugGroup (GL_DEBUG_SOURCE_APPLICATION, 0, -1, str.c_str ());
|
glPushDebugGroup (GL_DEBUG_SOURCE_APPLICATION, 0, -1, str.c_str ());
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
// render the background
|
// search the background in the viewport selection
|
||||||
this->m_wallpaper->render (cur.viewport, false, renderFrame, firstFrame);
|
auto ref = this->m_wallpapers.find (cur.first);
|
||||||
|
|
||||||
|
// render the background
|
||||||
|
if (ref != this->m_wallpapers.end ())
|
||||||
|
ref->second->render (cur.second.viewport, this->m_output->renderVFlip (), renderFrame, firstFrame);
|
||||||
|
else
|
||||||
|
this->m_defaultWallpaper->render (cur.second.viewport, this->m_output->renderVFlip (), renderFrame, firstFrame);
|
||||||
// scenes need to render a new frame for each viewport as they produce different results
|
// 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
|
// but videos should only be rendered once per group of viewports
|
||||||
firstFrame = false;
|
firstFrame = false;
|
||||||
@ -205,61 +54,27 @@ void CRenderContext::renderScreens ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// read the full texture into the image
|
// read the full texture into the image
|
||||||
glReadPixels (0, 0, fullWidth, fullHeight, GL_BGRA, GL_UNSIGNED_BYTE, (void*) this->m_imageData);
|
if (this->m_output->haveImageBuffer ())
|
||||||
|
glReadPixels (
|
||||||
// put the image back into the screen
|
0, 0, this->m_output->getFullWidth (), this->m_output->getFullHeight (),
|
||||||
XPutImage (this->m_display, this->m_pixmap, this->m_gc, this->m_image, 0, 0, 0, 0, fullWidth, fullHeight);
|
GL_BGRA, GL_UNSIGNED_BYTE,
|
||||||
|
this->m_output->getImageBuffer ()
|
||||||
// _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)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (this->m_viewports.empty ())
|
|
||||||
this->renderWindow ();
|
|
||||||
else
|
|
||||||
this->renderScreens ();
|
|
||||||
|
|
||||||
|
// update the output with the given image
|
||||||
|
this->m_output->updateRender ();
|
||||||
|
// finally swap buffers
|
||||||
this->m_driver.swapBuffers ();
|
this->m_driver.swapBuffers ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderContext::setWallpaper (CWallpaper* wallpaper)
|
void CRenderContext::setDefaultWallpaper (CWallpaper* wallpaper)
|
||||||
{
|
{
|
||||||
this->m_wallpaper = wallpaper;
|
this->m_defaultWallpaper = wallpaper;
|
||||||
|
}
|
||||||
|
|
||||||
// update the wallpaper's texcoords based on the mode we're running
|
void CRenderContext::setWallpaper (const std::string& display, CWallpaper* wallpaper)
|
||||||
if (!this->m_screens.empty ())
|
{
|
||||||
{
|
this->m_wallpapers.insert_or_assign (display, wallpaper);
|
||||||
GLfloat texCoords [] = {
|
|
||||||
0.0f, 1.0f,
|
|
||||||
1.0f, 1.0f,
|
|
||||||
0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f,
|
|
||||||
1.0f, 1.0f,
|
|
||||||
1.0f, 0.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
this->m_wallpaper->updateTexCoord (texCoords, sizeof (texCoords));
|
|
||||||
this->m_wallpaper->setDestinationFramebuffer (this->m_fbo->getFramebuffer ());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CInputContext& CRenderContext::getInputContext () const
|
CInputContext& CRenderContext::getInputContext () const
|
||||||
@ -267,21 +82,16 @@ CInputContext& CRenderContext::getInputContext () const
|
|||||||
return this->m_input;
|
return this->m_input;
|
||||||
}
|
}
|
||||||
|
|
||||||
CWallpaper* CRenderContext::getWallpaper () const
|
|
||||||
{
|
|
||||||
return this->m_wallpaper;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CContainer& CRenderContext::getContainer () const
|
|
||||||
{
|
|
||||||
return this->m_container;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CWallpaperApplication& CRenderContext::getApp () const
|
const CWallpaperApplication& CRenderContext::getApp () const
|
||||||
{
|
{
|
||||||
return this->m_app;
|
return this->m_app;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const COutput* CRenderContext::getOutput () const
|
||||||
|
{
|
||||||
|
return this->m_output;
|
||||||
|
}
|
||||||
|
|
||||||
const ITexture* CRenderContext::resolveTexture (const std::string& name)
|
const ITexture* CRenderContext::resolveTexture (const std::string& name)
|
||||||
{
|
{
|
||||||
return this->m_textureCache->resolve (name);
|
return this->m_textureCache->resolve (name);
|
||||||
|
@ -9,12 +9,19 @@
|
|||||||
#include "WallpaperEngine/Input/CInputContext.h"
|
#include "WallpaperEngine/Input/CInputContext.h"
|
||||||
#include "WallpaperEngine/Input/CMouseInput.h"
|
#include "WallpaperEngine/Input/CMouseInput.h"
|
||||||
#include "WallpaperEngine/Render/Drivers/CVideoDriver.h"
|
#include "WallpaperEngine/Render/Drivers/CVideoDriver.h"
|
||||||
|
#include "WallpaperEngine/Render/Drivers/Output/COutput.h"
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
using namespace WallpaperEngine::Application;
|
using namespace WallpaperEngine::Application;
|
||||||
using namespace WallpaperEngine::Assets;
|
using namespace WallpaperEngine::Assets;
|
||||||
using namespace WallpaperEngine::Input;
|
using namespace WallpaperEngine::Input;
|
||||||
using namespace WallpaperEngine::Render::Drivers;
|
using namespace WallpaperEngine::Render::Drivers;
|
||||||
|
using namespace WallpaperEngine::Render::Drivers::Output;
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Render::Drivers::Output
|
||||||
|
{
|
||||||
|
class COutput;
|
||||||
|
}
|
||||||
|
|
||||||
namespace WallpaperEngine::Render::Drivers
|
namespace WallpaperEngine::Render::Drivers
|
||||||
{
|
{
|
||||||
@ -34,45 +41,23 @@ namespace WallpaperEngine::Render
|
|||||||
class CRenderContext
|
class CRenderContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CRenderContext (std::vector <std::string> screens, CVideoDriver& driver, CInputContext& input, CContainer& container, CWallpaperApplication& app);
|
CRenderContext (const COutput* output, CVideoDriver& driver, CInputContext& input, CWallpaperApplication& app);
|
||||||
~CRenderContext ();
|
|
||||||
|
|
||||||
void initialize ();
|
|
||||||
void render ();
|
void render ();
|
||||||
void setWallpaper (CWallpaper* wallpaper);
|
void setDefaultWallpaper (CWallpaper* wallpaper);
|
||||||
|
void setWallpaper (const std::string& display, CWallpaper* wallpaper);
|
||||||
CInputContext& getInputContext () const;
|
CInputContext& getInputContext () const;
|
||||||
void setMouse (CMouseInput* mouse);
|
|
||||||
CWallpaper* getWallpaper () const;
|
|
||||||
const CContainer& getContainer () const;
|
|
||||||
const CWallpaperApplication& getApp () const;
|
const CWallpaperApplication& getApp () const;
|
||||||
|
const COutput* getOutput () const;
|
||||||
const ITexture* resolveTexture (const std::string& name);
|
const ITexture* resolveTexture (const std::string& name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupScreens ();
|
|
||||||
void setupWindow ();
|
|
||||||
|
|
||||||
void renderScreens ();
|
|
||||||
void renderWindow ();
|
|
||||||
|
|
||||||
struct viewport
|
|
||||||
{
|
|
||||||
glm::ivec4 viewport;
|
|
||||||
std::string name;
|
|
||||||
};
|
|
||||||
|
|
||||||
Display* m_display;
|
|
||||||
Pixmap m_pixmap;
|
|
||||||
GC m_gc;
|
|
||||||
XImage* m_image;
|
|
||||||
CVideoDriver& m_driver;
|
CVideoDriver& m_driver;
|
||||||
char* m_imageData;
|
std::map <std::string, CWallpaper*> m_wallpapers;
|
||||||
CFBO* m_fbo;
|
CWallpaper* m_defaultWallpaper;
|
||||||
std::vector <std::string> m_screens;
|
|
||||||
std::vector <viewport> m_viewports;
|
|
||||||
CWallpaper* m_wallpaper;
|
|
||||||
CInputContext& m_input;
|
CInputContext& m_input;
|
||||||
CContainer& m_container;
|
|
||||||
CWallpaperApplication& m_app;
|
CWallpaperApplication& m_app;
|
||||||
CTextureCache* m_textureCache;
|
CTextureCache* m_textureCache;
|
||||||
|
const COutput* m_output;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -1,6 +1,9 @@
|
|||||||
#include "CTextureCache.h"
|
#include "CTextureCache.h"
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Assets/CAssetLoadException.h"
|
||||||
|
|
||||||
using namespace WallpaperEngine::Render;
|
using namespace WallpaperEngine::Render;
|
||||||
|
using namespace WallpaperEngine::Assets;
|
||||||
|
|
||||||
CTextureCache::CTextureCache (CRenderContext& context) :
|
CTextureCache::CTextureCache (CRenderContext& context) :
|
||||||
m_context (context)
|
m_context (context)
|
||||||
@ -17,11 +20,26 @@ const ITexture* CTextureCache::resolve (const std::string& filename)
|
|||||||
if (found != this->m_textureCache.end ())
|
if (found != this->m_textureCache.end ())
|
||||||
return (*found).second;
|
return (*found).second;
|
||||||
|
|
||||||
const ITexture* texture = this->m_context.getContainer ().readTexture (filename);
|
// search for the texture in all the different containers just in case
|
||||||
|
for (auto it : this->m_context.getApp ().getProjects ())
|
||||||
|
{
|
||||||
|
const ITexture* texture = it.second->getContainer ()->readTexture (filename);
|
||||||
|
|
||||||
this->store (filename, texture);
|
this->store (filename, texture);
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->m_context.getApp ().getDefaultProject () != nullptr)
|
||||||
|
{
|
||||||
|
const ITexture* texture = this->m_context.getApp ().getDefaultProject ()->getContainer ()->readTexture (filename);
|
||||||
|
|
||||||
|
this->store (filename, texture);
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw CAssetLoadException (filename, "Cannot find file");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTextureCache::store (std::string name, const ITexture* texture)
|
void CTextureCache::store (std::string name, const ITexture* texture)
|
||||||
|
@ -54,8 +54,11 @@ CVideo::CVideo (Core::CVideo* video, CRenderContext& context, CAudioContext& aud
|
|||||||
if (mpv_render_context_create (&this->m_mpvGl, this->m_mpv, params) < 0)
|
if (mpv_render_context_create (&this->m_mpvGl, this->m_mpv, params) < 0)
|
||||||
sLog.exception ("Failed to initialize MPV's GL context");
|
sLog.exception ("Failed to initialize MPV's GL context");
|
||||||
|
|
||||||
|
std::filesystem::path videopath = this->getVideo ()->getProject ().getContainer ()->resolveRealFile (this->getVideo ()->getFilename ());
|
||||||
|
|
||||||
|
// build the path to the video file
|
||||||
const char* command [] = {
|
const char* command [] = {
|
||||||
"loadfile", this->getVideo ()->getFilename ().c_str (), nullptr
|
"loadfile", videopath.c_str (), nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mpv_command (this->m_mpv, command) < 0)
|
if (mpv_command (this->m_mpv, command) < 0)
|
||||||
|
@ -61,9 +61,9 @@ CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRend
|
|||||||
CWallpaper::~CWallpaper ()
|
CWallpaper::~CWallpaper ()
|
||||||
= default;
|
= default;
|
||||||
|
|
||||||
const CContainer& CWallpaper::getContainer () const
|
CContainer* CWallpaper::getContainer () const
|
||||||
{
|
{
|
||||||
return this->m_context.getContainer ();
|
return this->m_wallpaperData->getProject ().getContainer ();
|
||||||
}
|
}
|
||||||
|
|
||||||
WallpaperEngine::Core::CWallpaper* CWallpaper::getWallpaperData () const
|
WallpaperEngine::Core::CWallpaper* CWallpaper::getWallpaperData () const
|
||||||
|
@ -38,7 +38,7 @@ namespace WallpaperEngine::Render
|
|||||||
/**
|
/**
|
||||||
* @return The container to resolve files for this wallpaper
|
* @return The container to resolve files for this wallpaper
|
||||||
*/
|
*/
|
||||||
const CContainer& getContainer () const;
|
CContainer* getContainer () const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The current context rendering this wallpaper
|
* @return The current context rendering this wallpaper
|
||||||
|
@ -62,6 +62,12 @@ void COpenGLDriver::resizeWindow (glm::ivec2 size)
|
|||||||
glfwSetWindowSize (this->m_window, size.x, size.y);
|
glfwSetWindowSize (this->m_window, size.x, size.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void COpenGLDriver::resizeWindow (glm::ivec4 sizeandpos)
|
||||||
|
{
|
||||||
|
glfwSetWindowPos (this->m_window, sizeandpos.x, sizeandpos.y);
|
||||||
|
glfwSetWindowSize (this->m_window, sizeandpos.z, sizeandpos.w);
|
||||||
|
}
|
||||||
|
|
||||||
void COpenGLDriver::showWindow ()
|
void COpenGLDriver::showWindow ()
|
||||||
{
|
{
|
||||||
glfwShowWindow (this->m_window);
|
glfwShowWindow (this->m_window);
|
||||||
|
@ -3,9 +3,17 @@
|
|||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include "WallpaperEngine/Render/Drivers/CVideoDriver.h"
|
#include "WallpaperEngine/Render/Drivers/CVideoDriver.h"
|
||||||
|
#include "WallpaperEngine/Application/CApplicationContext.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Application
|
||||||
|
{
|
||||||
|
class CApplicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
namespace WallpaperEngine::Render::Drivers
|
namespace WallpaperEngine::Render::Drivers
|
||||||
{
|
{
|
||||||
|
using namespace WallpaperEngine::Application;
|
||||||
|
|
||||||
class COpenGLDriver : public CVideoDriver
|
class COpenGLDriver : public CVideoDriver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -15,6 +23,7 @@ namespace WallpaperEngine::Render::Drivers
|
|||||||
float getRenderTime () override;
|
float getRenderTime () override;
|
||||||
bool closeRequested () override;
|
bool closeRequested () override;
|
||||||
void resizeWindow (glm::ivec2 size) override;
|
void resizeWindow (glm::ivec2 size) override;
|
||||||
|
void resizeWindow (glm::ivec4 sizeandpos) override;
|
||||||
void showWindow () override;
|
void showWindow () override;
|
||||||
void hideWindow () override;
|
void hideWindow () override;
|
||||||
glm::ivec2 getFramebufferSize () override;
|
glm::ivec2 getFramebufferSize () override;
|
||||||
@ -22,6 +31,7 @@ namespace WallpaperEngine::Render::Drivers
|
|||||||
uint32_t getFrameCounter () override;
|
uint32_t getFrameCounter () override;
|
||||||
|
|
||||||
GLFWwindow* getWindow ();
|
GLFWwindow* getWindow ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLFWwindow* m_window;
|
GLFWwindow* m_window;
|
||||||
uint32_t m_frameCounter;
|
uint32_t m_frameCounter;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/vec4.hpp>
|
||||||
#include <glm/vec2.hpp>
|
#include <glm/vec2.hpp>
|
||||||
|
|
||||||
namespace WallpaperEngine::Render::Drivers
|
namespace WallpaperEngine::Render::Drivers
|
||||||
@ -10,6 +11,7 @@ namespace WallpaperEngine::Render::Drivers
|
|||||||
virtual float getRenderTime () = 0;
|
virtual float getRenderTime () = 0;
|
||||||
virtual bool closeRequested () = 0;
|
virtual bool closeRequested () = 0;
|
||||||
virtual void resizeWindow (glm::ivec2 size) = 0;
|
virtual void resizeWindow (glm::ivec2 size) = 0;
|
||||||
|
virtual void resizeWindow (glm::ivec4 size) = 0;
|
||||||
virtual void showWindow () = 0;
|
virtual void showWindow () = 0;
|
||||||
virtual void hideWindow () = 0;
|
virtual void hideWindow () = 0;
|
||||||
virtual glm::ivec2 getFramebufferSize () = 0;
|
virtual glm::ivec2 getFramebufferSize () = 0;
|
||||||
|
23
src/WallpaperEngine/Render/Drivers/Output/COutput.cpp
Normal file
23
src/WallpaperEngine/Render/Drivers/Output/COutput.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include "COutput.h"
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Render::Drivers::Output;
|
||||||
|
|
||||||
|
COutput::COutput (CApplicationContext& context) :
|
||||||
|
m_context (context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::map <std::string, COutput::ScreenInfo>& COutput::getViewports () const
|
||||||
|
{
|
||||||
|
return this->m_viewports;
|
||||||
|
}
|
||||||
|
|
||||||
|
int COutput::getFullWidth () const
|
||||||
|
{
|
||||||
|
return this->m_fullWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
int COutput::getFullHeight () const
|
||||||
|
{
|
||||||
|
return this->m_fullHeight;
|
||||||
|
}
|
47
src/WallpaperEngine/Render/Drivers/Output/COutput.h
Normal file
47
src/WallpaperEngine/Render/Drivers/Output/COutput.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <glm/vec4.hpp>
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Application/CApplicationContext.h"
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Application;
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Application
|
||||||
|
{
|
||||||
|
class CApplicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Render::Drivers::Output
|
||||||
|
{
|
||||||
|
class COutput
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
COutput (CApplicationContext& context);
|
||||||
|
|
||||||
|
virtual void reset () = 0;
|
||||||
|
|
||||||
|
int getFullWidth () const;
|
||||||
|
int getFullHeight () const;
|
||||||
|
|
||||||
|
struct ScreenInfo
|
||||||
|
{
|
||||||
|
glm::ivec4 viewport;
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual bool renderVFlip () const = 0;
|
||||||
|
virtual bool renderMultiple () const = 0;
|
||||||
|
virtual bool haveImageBuffer () const = 0;
|
||||||
|
const std::map <std::string, ScreenInfo>& getViewports () const;
|
||||||
|
virtual void* getImageBuffer () const = 0;
|
||||||
|
virtual void updateRender () const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
mutable int m_fullWidth;
|
||||||
|
mutable int m_fullHeight;
|
||||||
|
mutable std::map <std::string, ScreenInfo> m_viewports;
|
||||||
|
CApplicationContext& m_context;
|
||||||
|
};
|
||||||
|
}
|
77
src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.cpp
Normal file
77
src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#include "CWindowOutput.h"
|
||||||
|
#include "WallpaperEngine/Logging/CLog.h"
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Render::Drivers::Output;
|
||||||
|
|
||||||
|
CWindowOutput::CWindowOutput (CApplicationContext& context, CVideoDriver& driver) :
|
||||||
|
COutput (context),
|
||||||
|
m_driver (driver)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
this->m_context.windowMode != Application::CApplicationContext::NORMAL_WINDOW &&
|
||||||
|
this->m_context.windowMode != Application::CApplicationContext::EXPLICIT_WINDOW)
|
||||||
|
sLog.exception ("Inititalizing window output when not in output mode, how did you get here?!");
|
||||||
|
|
||||||
|
// window should be visible
|
||||||
|
driver.showWindow ();
|
||||||
|
|
||||||
|
if (this->m_context.windowMode == Application::CApplicationContext::EXPLICIT_WINDOW)
|
||||||
|
{
|
||||||
|
this->m_fullWidth = this->m_context.windowGeometry.z;
|
||||||
|
this->m_fullHeight = this->m_context.windowGeometry.w;
|
||||||
|
this->repositionWindow ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// take the size from the driver (default window size)
|
||||||
|
this->m_fullWidth = this->m_driver.getFramebufferSize ().x;
|
||||||
|
this->m_fullHeight = this->m_driver.getFramebufferSize ().y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// register the default viewport
|
||||||
|
this->m_viewports ["default"] = {{0, 0, this->m_fullWidth, this->m_fullHeight}, "default"};
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWindowOutput::repositionWindow ()
|
||||||
|
{
|
||||||
|
// reposition the window
|
||||||
|
this->m_driver.resizeWindow (this->m_context.windowGeometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWindowOutput::reset ()
|
||||||
|
{
|
||||||
|
if (this->m_context.windowMode == Application::CApplicationContext::EXPLICIT_WINDOW)
|
||||||
|
this->repositionWindow ();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWindowOutput::renderVFlip () const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWindowOutput::renderMultiple () const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWindowOutput::haveImageBuffer () const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* CWindowOutput::getImageBuffer () const
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
void CWindowOutput::updateRender () const
|
||||||
|
{
|
||||||
|
if (this->m_context.windowMode != Application::CApplicationContext::NORMAL_WINDOW)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// take the size from the driver (default window size)
|
||||||
|
this->m_fullWidth = this->m_driver.getFramebufferSize ().x;
|
||||||
|
this->m_fullHeight = this->m_driver.getFramebufferSize ().y;
|
||||||
|
|
||||||
|
// update the default viewport
|
||||||
|
this->m_viewports ["default"] = {{0, 0, this->m_fullWidth, this->m_fullHeight}, "default"};
|
||||||
|
}
|
25
src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.h
Normal file
25
src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Render/Drivers/CVideoDriver.h"
|
||||||
|
#include "COutput.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Render::Drivers::Output
|
||||||
|
{
|
||||||
|
class CWindowOutput : public COutput
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CWindowOutput (CApplicationContext& context, CVideoDriver& driver);
|
||||||
|
|
||||||
|
void reset () override;
|
||||||
|
bool renderVFlip () const override;
|
||||||
|
bool renderMultiple () const override;
|
||||||
|
bool haveImageBuffer () const override;
|
||||||
|
void* getImageBuffer () const override;
|
||||||
|
void updateRender () const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void repositionWindow ();
|
||||||
|
|
||||||
|
CVideoDriver& m_driver;
|
||||||
|
};
|
||||||
|
}
|
183
src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp
Normal file
183
src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "CX11Output.h"
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
#include <X11/extensions/Xrandr.h>
|
||||||
|
|
||||||
|
using namespace WallpaperEngine::Render::Drivers::Output;
|
||||||
|
|
||||||
|
XErrorHandler originalErrorHandler;
|
||||||
|
|
||||||
|
void CustomXIOErrorExitHandler (Display* dsp, void* userdata)
|
||||||
|
{
|
||||||
|
auto context = static_cast <CX11Output*> (userdata);
|
||||||
|
|
||||||
|
#if !NDEBUG
|
||||||
|
sLog.debugerror ("Critical XServer error detected. Attempting to recover...");
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
// refetch all the resources
|
||||||
|
context->reset ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CustomXErrorHandler (Display* dpy, XErrorEvent* event)
|
||||||
|
{
|
||||||
|
#if !NDEBUG
|
||||||
|
sLog.debugerror ("Detected X error");
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
// call the original handler so we can keep some information reporting
|
||||||
|
originalErrorHandler (dpy, event);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CustomXIOErrorHandler (Display* dsp)
|
||||||
|
{
|
||||||
|
#if !NDEBUG
|
||||||
|
sLog.debugerror ("Detected X error");
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CX11Output::CX11Output (CApplicationContext& context, CVideoDriver& driver) :
|
||||||
|
COutput (context),
|
||||||
|
m_driver (driver)
|
||||||
|
{
|
||||||
|
this->m_display = XOpenDisplay (nullptr);
|
||||||
|
this->loadScreenInfo ();
|
||||||
|
}
|
||||||
|
CX11Output::~CX11Output ()
|
||||||
|
{
|
||||||
|
this->free ();
|
||||||
|
XCloseDisplay (this->m_display);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CX11Output::reset ()
|
||||||
|
{
|
||||||
|
// first free whatever we have right now
|
||||||
|
this->free ();
|
||||||
|
// re-load screen info
|
||||||
|
this->loadScreenInfo ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CX11Output::free ()
|
||||||
|
{
|
||||||
|
// free all the resources we've got
|
||||||
|
XDestroyImage (this->m_image);
|
||||||
|
XFreeGC (this->m_display, this->m_gc);
|
||||||
|
XFreePixmap (this->m_display, this->m_pixmap);
|
||||||
|
delete this->m_imageData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* CX11Output::getImageBuffer () const
|
||||||
|
{
|
||||||
|
return this->m_imageData;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CX11Output::renderVFlip () const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CX11Output::renderMultiple () const
|
||||||
|
{
|
||||||
|
return this->m_viewports.size () > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CX11Output::haveImageBuffer () const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CX11Output::loadScreenInfo ()
|
||||||
|
{
|
||||||
|
// reset the viewports
|
||||||
|
this->m_viewports.clear ();
|
||||||
|
|
||||||
|
// set the error handling to try and recover from X disconnections
|
||||||
|
#ifdef HAVE_XSETIOERROREXITHANDLER
|
||||||
|
XSetIOErrorExitHandler (this->m_display, CustomXIOErrorExitHandler, this);
|
||||||
|
#endif /* HAVE_XSETIOERROREXITHANDLER */
|
||||||
|
originalErrorHandler = XSetErrorHandler (CustomXErrorHandler);
|
||||||
|
XSetIOErrorHandler (CustomXIOErrorHandler);
|
||||||
|
|
||||||
|
int xrandr_result, xrandr_error;
|
||||||
|
|
||||||
|
if (!XRRQueryExtension (this->m_display, &xrandr_result, &xrandr_error))
|
||||||
|
{
|
||||||
|
sLog.error ("XRandr is not present, cannot detect specified screens, running in window mode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->m_root = DefaultRootWindow (this->m_display);
|
||||||
|
this->m_fullWidth = DisplayWidth (this->m_display, DefaultScreen (this->m_display));
|
||||||
|
this->m_fullHeight = DisplayHeight (this->m_display, DefaultScreen (this->m_display));
|
||||||
|
XRRScreenResources* screenResources = XRRGetScreenResources (this->m_display, DefaultRootWindow (this->m_display));
|
||||||
|
|
||||||
|
if (screenResources == nullptr)
|
||||||
|
{
|
||||||
|
sLog.error ("Cannot detect screen sizes using xrandr, running in window mode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < screenResources->noutput; i ++)
|
||||||
|
{
|
||||||
|
XRROutputInfo* info = XRRGetOutputInfo (this->m_display, screenResources, screenResources->outputs [i]);
|
||||||
|
|
||||||
|
// screen not in use, ignore it
|
||||||
|
if (info == nullptr || info->connection != RR_Connected)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// only keep info of registered screens
|
||||||
|
if (this->m_context.screenSettings.find (info->name) == this->m_context.screenSettings.end ())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
XRRCrtcInfo* crtc = XRRGetCrtcInfo (this->m_display, screenResources, info->crtc);
|
||||||
|
|
||||||
|
sLog.out ("Found requested screen: ", info->name, " -> ", crtc->x, "x", crtc->y, ":", crtc->width, "x", crtc->height);
|
||||||
|
|
||||||
|
this->m_viewports [info->name] =
|
||||||
|
{
|
||||||
|
{crtc->x, crtc->y, crtc->width, crtc->height},
|
||||||
|
info->name
|
||||||
|
};
|
||||||
|
|
||||||
|
XRRFreeCrtcInfo (crtc);
|
||||||
|
}
|
||||||
|
|
||||||
|
XRRFreeScreenResources (screenResources);
|
||||||
|
|
||||||
|
// create pixmap so we can draw things in there
|
||||||
|
this->m_pixmap = XCreatePixmap (this->m_display, this->m_root, this->m_fullWidth, this->m_fullHeight, 24);
|
||||||
|
this->m_gc = XCreateGC (this->m_display, this->m_pixmap, 0, nullptr);
|
||||||
|
// pre-fill it with black
|
||||||
|
XFillRectangle (this->m_display, this->m_pixmap, this->m_gc, 0, 0, this->m_fullWidth, this->m_fullHeight);
|
||||||
|
// set the window background as our pixmap
|
||||||
|
XSetWindowBackgroundPixmap (this->m_display, this->m_root, this->m_pixmap);
|
||||||
|
// allocate space for the image's data
|
||||||
|
this->m_imageData = new char [this->m_fullWidth * this->m_fullHeight * 4];
|
||||||
|
// create an image so we can copy it over
|
||||||
|
this->m_image = XCreateImage (this->m_display, CopyFromParent, 24, ZPixmap, 0, this->m_imageData, this->m_fullWidth, this->m_fullHeight, 32, 0);
|
||||||
|
// setup driver's render changing the window's size
|
||||||
|
this->m_driver.resizeWindow ({this->m_fullWidth, this->m_fullHeight});
|
||||||
|
}
|
||||||
|
|
||||||
|
void CX11Output::updateRender () const
|
||||||
|
{
|
||||||
|
// put the image back into the screen
|
||||||
|
XPutImage (this->m_display, this->m_pixmap, this->m_gc, this->m_image, 0, 0, 0, 0, this->m_fullWidth, this->m_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, this->m_root, prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &this->m_pixmap, 1);
|
||||||
|
XChangeProperty(this->m_display, this->m_root, prop_esetroot, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &this->m_pixmap, 1);
|
||||||
|
|
||||||
|
XClearWindow(this->m_display, this->m_root);
|
||||||
|
XFlush(this->m_display);
|
||||||
|
}
|
40
src/WallpaperEngine/Render/Drivers/Output/CX11Output.h
Normal file
40
src/WallpaperEngine/Render/Drivers/Output/CX11Output.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <glm/vec4.hpp>
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
#include "WallpaperEngine/Render/Drivers/CVideoDriver.h"
|
||||||
|
#include "COutput.h"
|
||||||
|
|
||||||
|
namespace WallpaperEngine::Render::Drivers::Output
|
||||||
|
{
|
||||||
|
class CX11Output : public COutput
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CX11Output (CApplicationContext& context, CVideoDriver& driver);
|
||||||
|
~CX11Output ();
|
||||||
|
|
||||||
|
void reset () override;
|
||||||
|
|
||||||
|
bool renderVFlip () const override;
|
||||||
|
bool renderMultiple () const override;
|
||||||
|
bool haveImageBuffer () const override;
|
||||||
|
void* getImageBuffer () const override;
|
||||||
|
void updateRender () const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void loadScreenInfo ();
|
||||||
|
void free ();
|
||||||
|
|
||||||
|
Display* m_display;
|
||||||
|
Pixmap m_pixmap;
|
||||||
|
Window m_root;
|
||||||
|
GC m_gc;
|
||||||
|
char* m_imageData;
|
||||||
|
XImage* m_image;
|
||||||
|
CVideoDriver& m_driver;
|
||||||
|
};
|
||||||
|
}
|
@ -2,13 +2,16 @@
|
|||||||
|
|
||||||
#include "CSound.h"
|
#include "CSound.h"
|
||||||
|
|
||||||
|
extern bool g_AudioEnabled;
|
||||||
|
|
||||||
using namespace WallpaperEngine::Render::Objects;
|
using namespace WallpaperEngine::Render::Objects;
|
||||||
|
|
||||||
CSound::CSound (CScene* scene, Core::Objects::CSound* sound) :
|
CSound::CSound (CScene* scene, Core::Objects::CSound* sound) :
|
||||||
CObject (scene, Type, sound),
|
CObject (scene, Type, sound),
|
||||||
m_sound (sound)
|
m_sound (sound)
|
||||||
{
|
{
|
||||||
this->load ();
|
if (g_AudioEnabled)
|
||||||
|
this->load ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSound::load ()
|
void CSound::load ()
|
||||||
@ -16,7 +19,7 @@ void CSound::load ()
|
|||||||
for (const auto& cur : this->m_sound->getSounds ())
|
for (const auto& cur : this->m_sound->getSounds ())
|
||||||
{
|
{
|
||||||
uint32_t filesize = 0;
|
uint32_t filesize = 0;
|
||||||
const void* filebuffer = this->getContainer ().readFile (cur, &filesize);
|
const void* filebuffer = this->getContainer ()->readFile (cur, &filesize);
|
||||||
|
|
||||||
auto stream = new Audio::CAudioStream (this->getScene ()->getAudioContext (), filebuffer, filesize);
|
auto stream = new Audio::CAudioStream (this->getScene ()->getAudioContext (), filebuffer, filesize);
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ using namespace WallpaperEngine::Assets;
|
|||||||
namespace WallpaperEngine::Render::Shaders
|
namespace WallpaperEngine::Render::Shaders
|
||||||
{
|
{
|
||||||
Compiler::Compiler (
|
Compiler::Compiler (
|
||||||
const CContainer& container,
|
CContainer* container,
|
||||||
std::string filename,
|
std::string filename,
|
||||||
Type type,
|
Type type,
|
||||||
std::map <std::string, int>* combos,
|
std::map <std::string, int>* combos,
|
||||||
@ -50,11 +50,11 @@ namespace WallpaperEngine::Render::Shaders
|
|||||||
m_baseCombos ()
|
m_baseCombos ()
|
||||||
{
|
{
|
||||||
if (type == Type_Vertex)
|
if (type == Type_Vertex)
|
||||||
this->m_content = this->m_container.readVertexShader (this->m_file);
|
this->m_content = this->m_container->readVertexShader (this->m_file);
|
||||||
else if (type == Type_Pixel)
|
else if (type == Type_Pixel)
|
||||||
this->m_content = this->m_container.readFragmentShader (this->m_file);
|
this->m_content = this->m_container->readFragmentShader (this->m_file);
|
||||||
else if (type == Type_Include)
|
else if (type == Type_Include)
|
||||||
this->m_content = this->m_container.readIncludeShader (this->m_file);
|
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
|
// clone the combos into the baseCombos to keep track of values that must be embedded no matter what
|
||||||
for (const auto& cur : *this->m_combos)
|
for (const auto& cur : *this->m_combos)
|
||||||
@ -650,7 +650,7 @@ namespace WallpaperEngine::Render::Shaders
|
|||||||
file += ".json";
|
file += ".json";
|
||||||
|
|
||||||
std::string tmp = file;
|
std::string tmp = file;
|
||||||
std::string patchContents = this->m_container.readFileAsString (file);
|
std::string patchContents = this->m_container->readFileAsString (file);
|
||||||
|
|
||||||
json data = json::parse (patchContents);
|
json data = json::parse (patchContents);
|
||||||
auto patches = data.find ("patches");
|
auto patches = data.find ("patches");
|
||||||
|
@ -51,7 +51,7 @@ namespace WallpaperEngine::Render::Shaders
|
|||||||
* @param recursive Whether the compiler should add base definitions or not
|
* @param recursive Whether the compiler should add base definitions or not
|
||||||
*/
|
*/
|
||||||
Compiler (
|
Compiler (
|
||||||
const CContainer& container,
|
CContainer* container,
|
||||||
std::string filename,
|
std::string filename,
|
||||||
Type type,
|
Type type,
|
||||||
std::map<std::string, int>* combos,
|
std::map<std::string, int>* combos,
|
||||||
@ -264,7 +264,7 @@ namespace WallpaperEngine::Render::Shaders
|
|||||||
/**
|
/**
|
||||||
* The container to load files from
|
* The container to load files from
|
||||||
*/
|
*/
|
||||||
const CContainer& m_container;
|
CContainer* m_container;
|
||||||
/**
|
/**
|
||||||
* List of textures that the shader expects (inferred from sampler2D and it's JSON data)
|
* List of textures that the shader expects (inferred from sampler2D and it's JSON data)
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user