Fixed identation problems

Added comments all over the codebase to explain things a bit better
Improved CApplicationContext to be a bit more self-explanatory
Abstracted CRenderContext access away into a helper that every render class should use

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
Alexis Maiquez 2023-03-23 01:42:01 +01:00
parent 92fa11b0a6
commit f499454957
111 changed files with 2897 additions and 1795 deletions

View File

@ -105,12 +105,15 @@ 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/Helpers/CContextAware.cpp
src/WallpaperEngine/Render/Helpers/CContextAware.h
src/WallpaperEngine/Render/Drivers/Output/COutput.cpp src/WallpaperEngine/Render/Drivers/Output/COutput.cpp
src/WallpaperEngine/Render/Drivers/Output/COutput.h src/WallpaperEngine/Render/Drivers/Output/COutput.h
src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp src/WallpaperEngine/Render/Drivers/Output/CX11Output.cpp
src/WallpaperEngine/Render/Drivers/Output/CX11Output.h src/WallpaperEngine/Render/Drivers/Output/CX11Output.h
src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.cpp src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.cpp
src/WallpaperEngine/Render/Drivers/Output/CWindowOutput.h src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.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
@ -120,6 +123,9 @@ add_executable(
src/WallpaperEngine/Render/CTextureCache.h src/WallpaperEngine/Render/CTextureCache.h
src/WallpaperEngine/Render/CTextureCache.cpp src/WallpaperEngine/Render/CTextureCache.cpp
src/WallpaperEngine/Render/Helpers/CContextAware.cpp
src/WallpaperEngine/Render/Helpers/CContextAware.h
src/WallpaperEngine/Render/CWallpaper.h src/WallpaperEngine/Render/CWallpaper.h
src/WallpaperEngine/Render/CWallpaper.cpp src/WallpaperEngine/Render/CWallpaper.cpp
src/WallpaperEngine/Render/CScene.h src/WallpaperEngine/Render/CScene.h

View File

@ -29,7 +29,7 @@ int main (int argc, char* argv[])
WallpaperEngine::Application::CWallpaperApplication app (appContext); WallpaperEngine::Application::CWallpaperApplication app (appContext);
// halt if the list-properties option was specified // halt if the list-properties option was specified
if (appContext.onlyListProperties) if (appContext.general.onlyListProperties)
return 0; return 0;
appPointer = &app; appPointer = &app;

View File

@ -4,7 +4,6 @@
#include "WallpaperEngine/Logging/CLog.h" #include "WallpaperEngine/Logging/CLog.h"
#include <cstring> #include <cstring>
#include <string>
#include <getopt.h> #include <getopt.h>
#define WORKSHOP_APP_ID 431960 #define WORKSHOP_APP_ID 431960
@ -12,24 +11,24 @@
using namespace WallpaperEngine::Application; 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'}, { "bg", required_argument, nullptr, 'b' },
{"window", required_argument, nullptr, 'w'}, { "window", required_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' },
{"volume", required_argument, nullptr, 'v'}, { "volume", required_argument, nullptr, 'v' },
{"help", no_argument, nullptr, 'h'}, { "help", no_argument, nullptr, 'h' },
{"fps", required_argument, nullptr, 'f'}, { "fps", required_argument, nullptr, 'f' },
{"assets-dir", required_argument, nullptr, 'a'}, { "assets-dir", required_argument, nullptr, 'a' },
{"screenshot", required_argument, nullptr, 'c'}, { "screenshot", required_argument, nullptr, 'c' },
{"list-properties", no_argument, nullptr, 'l'}, { "list-properties", no_argument, nullptr, 'l' },
{"set-property", required_argument, nullptr, 'o'}, { "set-property", required_argument, nullptr, 'o' },
{nullptr, 0, nullptr, 0} { nullptr, 0, nullptr, 0 }
}; };
std::string stringPathFixes(const std::string& s) std::string stringPathFixes (const std::string& s)
{ {
if (s.empty ()) if (s.empty ())
return s; return s;
@ -37,136 +36,155 @@ std::string stringPathFixes(const std::string& s)
std::string str (s); std::string str (s);
// remove single-quotes from the arguments // remove single-quotes from the arguments
if (str [0] == '\'' && str [str.size() - 1] == '\'') if (str[0] == '\'' && str[str.size () - 1] == '\'')
str str
.erase (str.size() - 1, 1) .erase (str.size () - 1, 1)
.erase (0, 1); .erase (0, 1);
return std::move (str); return std::move (str);
} }
CApplicationContext::CApplicationContext (int argc, char* argv[]) : CApplicationContext::CApplicationContext (int argc, char* argv[])
takeScreenshot (false),
maximumFPS (30),
audioVolume (128),
audioEnabled (true),
onlyListProperties (false)
{ {
// setup structs with sane default values for now
this->general =
{
.onlyListProperties = false,
.assets = "",
.defaultBackground = "",
.screenBackgrounds = {},
.properties = {},
};
this->render =
{
.mode = NORMAL_WINDOW,
.maximumFPS = 30,
.window = { .geometry = {}},
};
this->audio =
{
.enabled = true,
.volume = 127,
};
this->screenshot =
{
.take = false,
.path = "",
.format = FIF_UNKNOWN,
};
int c; int c;
std::string lastScreen; std::string lastScreen;
while ((c = getopt_long (argc, argv, "b:r:p:d:shf:a:w:", long_options, nullptr)) != -1) while ((c = getopt_long (argc, argv, "b:r:p:d:shf:a:w:", long_options, nullptr)) != -1)
{ {
switch (c) switch (c)
{ {
case 'b': case 'b':
if (lastScreen.empty ()) if (lastScreen.empty ())
sLog.exception ("--bg has to go after a --screen-root argument"); 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 // no need to check for previous screen being in the list, as it's the only way for this variable
// to have any value // to have any value
this->screenSettings.insert_or_assign (lastScreen, this->validatePath (optarg)); this->general.screenBackgrounds[lastScreen] = translateBackground (optarg);
break; break;
case 'o': case 'o':
{ {
std::string value = optarg; std::string value = optarg;
std::string::size_type equals = value.find ('='); std::string::size_type equals = value.find ('=');
// properties without value are treated as booleans for now // properties without value are treated as booleans for now
if (equals == std::string::npos) if (equals == std::string::npos)
this->properties.insert_or_assign (value, "1"); this->general.properties[value] = "1";
else else
this->properties.insert_or_assign ( this->general.properties[value.substr (0, equals)] = value.substr (equals + 1);
value.substr (0, equals), }
value.substr (equals + 1) break;
);
}
break;
case 'l': case 'l':
this->onlyListProperties = true; this->general.onlyListProperties = true;
break; break;
case 'r': case 'r':
if (this->screenSettings.find (optarg) != this->screenSettings.end ()) if (this->general.screenBackgrounds.find (optarg) != this->general.screenBackgrounds.end ())
sLog.exception ("Cannot specify the same screen more than once: ", optarg); sLog.exception ("Cannot specify the same screen more than once: ", optarg);
if (this->windowMode == EXPLICIT_WINDOW) if (this->render.mode == EXPLICIT_WINDOW)
sLog.exception ("Cannot run in both background and window mode"); sLog.exception ("Cannot run in both background and window mode");
this->windowMode = X11_BACKGROUND; this->render.mode = X11_BACKGROUND;
lastScreen = optarg; lastScreen = optarg;
this->screenSettings.insert_or_assign (lastScreen, ""); this->general.screenBackgrounds[lastScreen] = "";
break; break;
case 'w': case 'w':
if (this->windowMode == X11_BACKGROUND) if (this->render.mode == X11_BACKGROUND)
sLog.exception ("Cannot run in both background and window mode"); sLog.exception ("Cannot run in both background and window mode");
if (optarg != nullptr) if (optarg != nullptr)
{ {
this->windowMode = EXPLICIT_WINDOW; this->render.mode = EXPLICIT_WINDOW;
// read window geometry // read window geometry
char* pos = optarg; char* pos = optarg;
if (pos != nullptr) if (pos != nullptr)
this->windowGeometry.x = atoi (pos); this->render.window.geometry.x = atoi (pos);
if ((pos = strchr (pos, '.')) != nullptr) if ((pos = strchr (pos, '.')) != nullptr)
this->windowGeometry.y = atoi (pos + 1); this->render.window.geometry.y = atoi (pos + 1);
if ((pos = strchr (pos + 1, '.')) != nullptr) if ((pos = strchr (pos + 1, '.')) != nullptr)
this->windowGeometry.z = atoi (pos + 1); this->render.window.geometry.z = atoi (pos + 1);
if ((pos = strchr (pos + 1, '.')) != nullptr) if ((pos = strchr (pos + 1, '.')) != nullptr)
this->windowGeometry.w = atoi (pos + 1); this->render.window.geometry.w = atoi (pos + 1);
} }
break; 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 = this->validatePath (stringPathFixes (optarg)); this->general.defaultBackground = translateBackground (stringPathFixes (optarg));
break; break;
case 's': case 's':
this->audioEnabled = false; this->audio.enabled = false;
break; break;
case 'h': case 'h':
this->printHelp (argv [0]); printHelp (argv[0]);
break; break;
case 'f': case 'f':
maximumFPS = atoi (optarg); this->render.maximumFPS = atoi (optarg);
break; break;
case 'a': case 'a':
this->assets = stringPathFixes (optarg); this->general.assets = stringPathFixes (optarg);
break; break;
case 'v': case 'v':
this->audioVolume = std::max (atoi (optarg), 128); this->audio.volume = std::max (atoi (optarg), 128);
break; break;
case 'c': case 'c':
this->takeScreenshot = true; this->screenshot.take = true;
this->screenshot = stringPathFixes (optarg); this->screenshot.path = stringPathFixes (optarg);
break; break;
default: default:
sLog.out ("Default on path parsing: ", optarg); sLog.out ("Default on path parsing: ", optarg);
break; break;
} }
} }
if (this->background.empty ()) if (this->general.defaultBackground.empty ())
{ {
if (optind < argc && strlen (argv [optind]) > 0) if (optind < argc && strlen (argv[optind]) > 0)
{ {
this->background = this->validatePath (argv [optind]); this->general.defaultBackground = translateBackground (argv[optind]);
} }
else else
{ {
printHelp (argv [0]); printHelp (argv[0]);
} }
} }
@ -175,50 +193,49 @@ CApplicationContext::CApplicationContext (int argc, char* argv[]) :
this->validateScreenshot (); this->validateScreenshot ();
} }
std::string CApplicationContext::validatePath (const std::string& path) std::filesystem::path CApplicationContext::translateBackground (const std::string& bgIdOrPath)
{ {
if (path.find ('/') == std::string::npos) if (bgIdOrPath.find ('/') == std::string::npos)
return Steam::FileSystem::workshopDirectory (WORKSHOP_APP_ID, path); return Steam::FileSystem::workshopDirectory (WORKSHOP_APP_ID, bgIdOrPath);
return path; return bgIdOrPath;
} }
void CApplicationContext::validateAssets () void CApplicationContext::validateAssets ()
{ {
if (!this->assets.empty ()) if (!this->general.assets.empty ())
{ {
sLog.out ("Using wallpaper engine's assets at ", this->assets, " based on --assets-dir parameter"); sLog.out ("Using wallpaper engine's assets at ", this->general.assets, " based on --assets-dir parameter");
return; return;
} }
try try
{ {
this->assets = Steam::FileSystem::appDirectory (APP_DIRECTORY, "assets"); this->general.assets = Steam::FileSystem::appDirectory (APP_DIRECTORY, "assets");
} }
catch (std::runtime_error&) catch (std::runtime_error&)
{ {
// set current path as assets' folder // set current path as assets' folder
std::filesystem::path directory = std::filesystem::canonical ("/proc/self/exe") std::filesystem::path directory = std::filesystem::canonical ("/proc/self/exe").parent_path () / "assets";
.parent_path () / "assets";
} }
} }
void CApplicationContext::validateScreenshot () void CApplicationContext::validateScreenshot ()
{ {
if (!this->takeScreenshot) if (!this->screenshot.take)
return; return;
if (!this->screenshot.has_extension ()) if (!this->screenshot.path.has_extension ())
sLog.exception ("Cannot determine screenshot format"); sLog.exception ("Cannot determine screenshot format");
std::string extension = this->screenshot.extension (); std::string extension = this->screenshot.path.extension ();
if (extension == ".bmp") if (extension == ".bmp")
this->screenshotFormat = FIF_BMP; this->screenshot.format = FIF_BMP;
else if (extension == ".png") else if (extension == ".png")
this->screenshotFormat = FIF_PNG; this->screenshot.format = FIF_PNG;
else if (extension == ".jpg" || extension == ".jpeg") else if (extension == ".jpg" || extension == ".jpeg")
this->screenshotFormat = FIF_JPEG; this->screenshot.format = FIF_JPEG;
else else
sLog.exception ("Cannot determine screenshot format, unknown extension ", extension); sLog.exception ("Cannot determine screenshot format, unknown extension ", extension);
} }
@ -235,7 +252,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 and sets the position and size of the window"); sLog.out ("\t--window <geometry>\tRuns in window mode, geometry has to be XxYxWxH and sets the position and size of the window");
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");

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <FreeImage.h>
#include <filesystem> #include <filesystem>
#include <map> #include <map>
#include <string> #include <string>
@ -8,38 +7,141 @@
#include <glm/vec4.hpp> #include <glm/vec4.hpp>
#include <FreeImage.h>
namespace WallpaperEngine::Application namespace WallpaperEngine::Application
{ {
class CApplicationContext /**
{ * Application information as parsed off the command line arguments
public: */
CApplicationContext (int argc, char* argv[]); class CApplicationContext
{
public:
CApplicationContext (int argc, char* argv[]);
enum WINDOW_MODE enum WINDOW_MODE
{ {
/**
* Default window mode
*/
NORMAL_WINDOW = 0, NORMAL_WINDOW = 0,
/**
* Draw to X11 background
*/
X11_BACKGROUND = 1, X11_BACKGROUND = 1,
/**
* Explicit window mode with specified geometry
*/
EXPLICIT_WINDOW = 2, EXPLICIT_WINDOW = 2,
}; };
glm::ivec4 windowGeometry; /**
std::map <std::string, std::string> screenSettings; * General settings
std::map <std::string, std::string> properties; */
std::string background; struct
std::filesystem::path assets; {
std::filesystem::path screenshot; /**
bool takeScreenshot; * If the user requested a list of properties for the given background
int maximumFPS; */
int audioVolume; bool onlyListProperties;
bool audioEnabled;
bool onlyListProperties;
FREE_IMAGE_FORMAT screenshotFormat;
WINDOW_MODE windowMode;
private: /**
std::string validatePath (const std::string& path); * The path to the assets folder
void validateAssets (); */
void validateScreenshot (); std::filesystem::path assets;
static void printHelp (const char* route); /**
}; * Background to load (provided as the final argument) as fallback for multi-screen setups
*/
std::filesystem::path defaultBackground;
/**
* The backgrounds specified for different screens
*/
std::map <std::string, std::filesystem::path> screenBackgrounds;
/**
* Properties to change values for
*/
std::map <std::string, std::string> properties;
} general;
/**
* Render settings
*/
struct
{
/**
* The mode to run the background in
*/
WINDOW_MODE mode;
/**
* Maximum FPS
*/
int maximumFPS;
struct
{
/**
* The window size used in explicit window
*/
glm::ivec4 geometry;
} window;
} render;
/**
* Audio settings
*/
struct
{
/**
* If the audio system is enabled
*/
bool enabled;
/**
* Sound volume (0-128)
*/
int volume;
} audio;
/**
* Screenshot settings
*/
struct
{
/**
* If an screenshot should be taken
*/
bool take;
/**
* The path to where the screenshot must be saved
*/
std::filesystem::path path;
/**
* The image format
*/
FREE_IMAGE_FORMAT format;
} screenshot;
private:
/**
* Validates the assets folder and ensures a valid one is present
*/
void validateAssets ();
/**
* Validates the screenshot settings
*/
void validateScreenshot ();
/**
* Validates a background parameter and returns the real bgIdOrPath to it
*
* @param bgIdOrPath
* @return
*/
static std::filesystem::path translateBackground (const std::string& bgIdOrPath);
/**
* Prints the normal help message
*/
static void printHelp (const char* route);
};
} }

View File

@ -1,366 +1,366 @@
#include "CWallpaperApplication.h" #include "CWallpaperApplication.h"
#include "Steam/FileSystem/FileSystem.h"
#include "WallpaperEngine/Assets/CDirectory.h" #include "WallpaperEngine/Assets/CDirectory.h"
#include "WallpaperEngine/Assets/CVirtualContainer.h" #include "WallpaperEngine/Assets/CVirtualContainer.h"
#include "WallpaperEngine/Audio/Drivers/CSDLAudioDriver.h" #include "WallpaperEngine/Audio/Drivers/CSDLAudioDriver.h"
#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/CGLFWWindowOutput.h"
#include "WallpaperEngine/Render/Drivers/Output/CX11Output.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;
bool g_AudioEnabled = true; bool g_AudioEnabled = true;
int g_AudioVolume = 128; int g_AudioVolume = 128;
using namespace WallpaperEngine::Application; namespace WallpaperEngine::Application
using namespace WallpaperEngine::Core;
CWallpaperApplication::CWallpaperApplication (CApplicationContext& context) :
m_context (context),
m_defaultProject (nullptr)
{ {
// copy state to global variables for now CWallpaperApplication::CWallpaperApplication (CApplicationContext& context) :
g_AudioVolume = context.audioVolume; m_context (context),
g_AudioEnabled = context.audioEnabled; m_defaultBackground (nullptr)
this->loadProjects ();
this->setupProperties ();
}
void CWallpaperApplication::setupContainer (CCombinedContainer& container, const std::string& bg) const
{
std::filesystem::path basepath = bg;
container.add (new CDirectory (basepath));
container.addPkg (basepath / "scene.pkg");
container.addPkg (basepath / "gifscene.pkg");
container.add (new CDirectory (this->m_context.assets));
// add two possible patches directories to the container
// hopefully one sticks
bool relative = true;
bool absolute = true;
try
{
container.add (new CDirectory ("../share/"));
}
catch (std::runtime_error& ex)
{
relative = false;
}
try
{
container.add (new CDirectory (DATADIR));
}
catch (std::runtime_error& ex)
{
absolute = false;
}
if (!relative && !absolute)
sLog.error ("WARNING: Shader patches directory cannot be found, this might make some backgrounds not work properly");
// TODO: move this somewhere else?
CVirtualContainer* virtualContainer = new CVirtualContainer ();
//
// Had to get a little creative with the effects to achieve the same bloom effect without any custom code
// these virtual files are loaded by an image in the scene that takes current _rt_FullFrameBuffer and
// applies the bloom effect to render it out to the screen
//
// add the effect file for screen bloom
virtualContainer->add (
"effects/wpenginelinux/bloomeffect.json",
"{"
"\t\"name\":\"camerabloom_wpengine_linux\","
"\t\"group\":\"wpengine_linux_camera\","
"\t\"dependencies\":[],"
"\t\"passes\":"
"\t["
"\t\t{"
"\t\t\t\"material\": \"materials/util/downsample_quarter_bloom.json\","
"\t\t\t\"target\": \"_rt_4FrameBuffer\","
"\t\t\t\"bind\":"
"\t\t\t["
"\t\t\t\t{"
"\t\t\t\t\t\"name\": \"_rt_FullFrameBuffer\","
"\t\t\t\t\t\"index\": 0"
"\t\t\t\t}"
"\t\t\t]"
"\t\t},"
"\t\t{"
"\t\t\t\"material\": \"materials/util/downsample_eighth_blur_v.json\","
"\t\t\t\"target\": \"_rt_8FrameBuffer\","
"\t\t\t\"bind\":"
"\t\t\t["
"\t\t\t\t{"
"\t\t\t\t\t\"name\": \"_rt_4FrameBuffer\","
"\t\t\t\t\t\"index\": 0"
"\t\t\t\t}"
"\t\t\t]"
"\t\t},"
"\t\t{"
"\t\t\t\"material\": \"materials/util/blur_h_bloom.json\","
"\t\t\t\"target\": \"_rt_Bloom\","
"\t\t\t\"bind\":"
"\t\t\t["
"\t\t\t\t{"
"\t\t\t\t\t\"name\": \"_rt_8FrameBuffer\","
"\t\t\t\t\t\"index\": 0"
"\t\t\t\t}"
"\t\t\t]"
"\t\t},"
"\t\t{"
"\t\t\t\"material\": \"materials/util/combine.json\","
"\t\t\t\"target\": \"_rt_FullFrameBuffer\","
"\t\t\t\"bind\":"
"\t\t\t["
"\t\t\t\t{"
"\t\t\t\t\t\"name\": \"_rt_imageLayerComposite_-1_a\","
"\t\t\t\t\t\"index\": 0"
"\t\t\t\t},"
"\t\t\t\t{"
"\t\t\t\t\t\"name\": \"_rt_Bloom\","
"\t\t\t\t\t\"index\": 1"
"\t\t\t\t}"
"\t\t\t]"
"\t\t}"
"\t]"
"}"
);
// add some model for the image element even if it's going to waste rendering cycles
virtualContainer->add (
"models/wpenginelinux.json",
"{"
"\t\"material\":\"materials/wpenginelinux.json\""
"}"
);
// models require materials, so add that too
virtualContainer->add (
"materials/wpenginelinux.json",
"{"
"\t\"passes\":"
"\t\t["
"\t\t\t{"
"\t\t\t\t\"blending\": \"normal\","
"\t\t\t\t\"cullmode\": \"nocull\","
"\t\t\t\t\"depthtest\": \"disabled\","
"\t\t\t\t\"depthwrite\": \"disabled\","
"\t\t\t\t\"shader\": \"genericimage2\","
"\t\t\t\t\"textures\": [\"_rt_FullFrameBuffer\"]"
"\t\t\t}"
"\t\t]"
"}"
);
container.add (virtualContainer);
}
void CWallpaperApplication::loadProjects ()
{
for (const auto& it : this->m_context.screenSettings)
{
// ignore the screen settings if there was no background specified
// the default will be used
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 ()
{
for (const auto& it : this->m_projects)
this->setupPropertiesForProject (it.second);
if (this->m_defaultProject != nullptr)
this->setupPropertiesForProject (this->m_defaultProject);
}
void CWallpaperApplication::takeScreenshot (const Render::CRenderContext& context, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format)
{
// this should be getting called at the end of the frame, so the right thing should be bound already
int width = context.getOutput ()->getFullWidth ();
int height = context.getOutput ()->getFullHeight ();
// make room for storing the pixel data
uint8_t* buffer = new uint8_t [width * height * sizeof (uint8_t) * 3];
uint8_t* pixel = buffer;
// read the image into the buffer
glReadPixels (0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer);
// build the output file with FreeImage
FIBITMAP* bitmap = FreeImage_Allocate (width, height, 24);
RGBQUAD color;
// now get access to the pixels
for (int y = height; y > 0; y --)
{ {
for (int x = 0; x < width; x ++) // copy state to global variables for now
{ g_AudioVolume = context.audio.volume;
color.rgbRed = *pixel ++; g_AudioEnabled = context.audio.enabled;
color.rgbGreen = *pixel ++; this->loadBackgrounds ();
color.rgbBlue = *pixel ++; this->setupProperties ();
}
// set the pixel in the destination void CWallpaperApplication::setupContainer (CCombinedContainer& container, const std::string& bg) const
FreeImage_SetPixelColor (bitmap, x, y, &color); {
std::filesystem::path basepath = bg;
container.add (new CDirectory (basepath));
container.addPkg (basepath / "scene.pkg");
container.addPkg (basepath / "gifscene.pkg");
container.add (new CDirectory (this->m_context.general.assets));
// add two possible patches directories to the container
// hopefully one sticks
bool relative = true;
bool absolute = true;
try
{
container.add (new CDirectory ("../share/"));
}
catch (std::runtime_error& ex)
{
relative = false;
}
try
{
container.add (new CDirectory (DATADIR));
}
catch (std::runtime_error& ex)
{
absolute = false;
}
if (!relative && !absolute)
sLog.error (
"WARNING: Shader patches directory cannot be found, this might make some backgrounds not work "
"properly"
);
// TODO: move this somewhere else?
CVirtualContainer* virtualContainer = new CVirtualContainer ();
//
// Had to get a little creative with the effects to achieve the same bloom effect without any custom code
// these virtual files are loaded by an image in the scene that takes current _rt_FullFrameBuffer and
// applies the bloom effect to render it out to the screen
//
// add the effect file for screen bloom
// add some model for the image element even if it's going to waste rendering cycles
virtualContainer->add (
"effects/wpenginelinux/bloomeffect.json",
"{"
"\t\"name\":\"camerabloom_wpengine_linux\","
"\t\"group\":\"wpengine_linux_camera\","
"\t\"dependencies\":[],"
"\t\"passes\":"
"\t["
"\t\t{"
"\t\t\t\"material\": \"materials/util/downsample_quarter_bloom.json\","
"\t\t\t\"target\": \"_rt_4FrameBuffer\","
"\t\t\t\"bind\":"
"\t\t\t["
"\t\t\t\t{"
"\t\t\t\t\t\"name\": \"_rt_FullFrameBuffer\","
"\t\t\t\t\t\"index\": 0"
"\t\t\t\t}"
"\t\t\t]"
"\t\t},"
"\t\t{"
"\t\t\t\"material\": \"materials/util/downsample_eighth_blur_v.json\","
"\t\t\t\"target\": \"_rt_8FrameBuffer\","
"\t\t\t\"bind\":"
"\t\t\t["
"\t\t\t\t{"
"\t\t\t\t\t\"name\": \"_rt_4FrameBuffer\","
"\t\t\t\t\t\"index\": 0"
"\t\t\t\t}"
"\t\t\t]"
"\t\t},"
"\t\t{"
"\t\t\t\"material\": \"materials/util/blur_h_bloom.json\","
"\t\t\t\"target\": \"_rt_Bloom\","
"\t\t\t\"bind\":"
"\t\t\t["
"\t\t\t\t{"
"\t\t\t\t\t\"name\": \"_rt_8FrameBuffer\","
"\t\t\t\t\t\"index\": 0"
"\t\t\t\t}"
"\t\t\t]"
"\t\t},"
"\t\t{"
"\t\t\t\"material\": \"materials/util/combine.json\","
"\t\t\t\"target\": \"_rt_FullFrameBuffer\","
"\t\t\t\"bind\":"
"\t\t\t["
"\t\t\t\t{"
"\t\t\t\t\t\"name\": \"_rt_imageLayerComposite_-1_a\","
"\t\t\t\t\t\"index\": 0"
"\t\t\t\t},"
"\t\t\t\t{"
"\t\t\t\t\t\"name\": \"_rt_Bloom\","
"\t\t\t\t\t\"index\": 1"
"\t\t\t\t}"
"\t\t\t]"
"\t\t}"
"\t]"
"}"
);
virtualContainer->add (
"models/wpenginelinux.json",
"{"
"\t\"material\":\"materials/wpenginelinux.json\""
"}"
);
// models require materials, so add that too
virtualContainer->add (
"materials/wpenginelinux.json",
"{"
"\t\"passes\":"
"\t\t["
"\t\t\t{"
"\t\t\t\t\"blending\": \"normal\","
"\t\t\t\t\"cullmode\": \"nocull\","
"\t\t\t\t\"depthtest\": \"disabled\","
"\t\t\t\t\"depthwrite\": \"disabled\","
"\t\t\t\t\"shader\": \"genericimage2\","
"\t\t\t\t\"textures\": [\"_rt_FullFrameBuffer\"]"
"\t\t\t}"
"\t\t]"
"}"
);
container.add (virtualContainer);
}
void CWallpaperApplication::loadBackgrounds ()
{
for (const auto& it : this->m_context.general.screenBackgrounds)
{
// ignore the screen settings if there was no background specified
// the default will be used
if (it.second.empty ())
continue;
this->m_backgrounds[it.first] = this->loadBackground (it.second);
}
// load the default project if required
if (!this->m_context.general.defaultBackground.empty ())
this->m_defaultBackground = this->loadBackground (this->m_context.general.defaultBackground);
}
Core::CProject* CWallpaperApplication::loadBackground (const std::string& bg)
{
CCombinedContainer* container = new CCombinedContainer ();
this->setupContainer (*container, bg);
return Core::CProject::fromFile ("project.json", container);
}
void CWallpaperApplication::setupPropertiesForProject (Core::CProject* project)
{
// show properties if required
for (auto cur : project->getProperties ())
{
// update the value of the property
auto override = this->m_context.general.properties.find (cur->getName ());
if (override != this->m_context.general.properties.end ())
{
sLog.out ("Applying override value for ", cur->getName ());
cur->update (override->second);
}
if (this->m_context.general.onlyListProperties)
sLog.out (cur->dump ());
} }
} }
// finally save the file void CWallpaperApplication::setupProperties ()
FreeImage_Save (format, bitmap, filename.c_str (), 0);
// free all the used memory
delete[] buffer;
FreeImage_Unload (bitmap);
// unbind the textures
glBindTexture (GL_TEXTURE_2D, GL_NONE);
}
void CWallpaperApplication::show ()
{
// initialize sdl audio driver
WallpaperEngine::Audio::Drivers::CSDLAudioDriver audioDriver;
// initialize audio context
WallpaperEngine::Audio::CAudioContext audioContext (audioDriver);
// initialize OpenGL driver
WallpaperEngine::Render::Drivers::COpenGLDriver videoDriver ("wallpaperengine");
// initialize the input subsystem
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
WallpaperEngine::Render::CRenderContext context (output, videoDriver, inputContext, *this);
// set all the specific wallpapers required
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;
while (!videoDriver.closeRequested () && g_KeepRunning)
{ {
// update input information for (const auto& it : this->m_backgrounds)
inputContext.update (); this->setupPropertiesForProject (it.second);
// keep track of the previous frame's time
g_TimeLast = g_Time;
// calculate the current time value
g_Time = videoDriver.getRenderTime ();
// get the start time of the frame
startTime = g_Time;
// render the scene
context.render ();
// get the end time of the frame
endTime = videoDriver.getRenderTime ();
// ensure the frame time is correct to not overrun FPS if (this->m_defaultBackground != nullptr)
if ((endTime - startTime) < minimumTime) this->setupPropertiesForProject (this->m_defaultBackground);
usleep ((minimumTime - (endTime - startTime)) * CLOCKS_PER_SEC); }
if (this->m_context.takeScreenshot && videoDriver.getFrameCounter () == 5) void CWallpaperApplication::takeScreenshot (
const Render::CRenderContext& context, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format
)
{
// this should be getting called at the end of the frame, so the right thing should be bound already
int width = context.getOutput ()->getFullWidth ();
int height = context.getOutput ()->getFullHeight ();
// make room for storing the pixel data
uint8_t* buffer = new uint8_t[width * height * sizeof (uint8_t) * 3];
uint8_t* pixel = buffer;
// read the image into the buffer
glReadPixels (0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer);
// build the output file with FreeImage
FIBITMAP* bitmap = FreeImage_Allocate (width, height, 24);
RGBQUAD color;
// now get access to the pixels
for (int y = height; y > 0; y--)
{ {
this->takeScreenshot (context, this->m_context.screenshot, this->m_context.screenshotFormat); for (int x = 0; x < width; x++)
{
color.rgbRed = *pixel++;
color.rgbGreen = *pixel++;
color.rgbBlue = *pixel++;
// set the pixel in the destination
FreeImage_SetPixelColor (bitmap, x, y, &color);
}
}
// finally save the file
FreeImage_Save (format, bitmap, filename.c_str (), 0);
// free all the used memory
delete[] buffer;
FreeImage_Unload (bitmap);
// unbind the textures
glBindTexture (GL_TEXTURE_2D, GL_NONE);
}
void CWallpaperApplication::show ()
{
// initialize sdl audio driver
WallpaperEngine::Audio::Drivers::CSDLAudioDriver audioDriver;
// initialize audio context
WallpaperEngine::Audio::CAudioContext audioContext (audioDriver);
// initialize OpenGL driver
WallpaperEngine::Render::Drivers::COpenGLDriver videoDriver ("wallpaperengine");
// initialize the input subsystem
WallpaperEngine::Input::CInputContext inputContext (videoDriver);
// output requested
WallpaperEngine::Render::Drivers::Output::COutput* output;
// initialize the requested output
switch (this->m_context.render.mode)
{
case CApplicationContext::EXPLICIT_WINDOW:
case CApplicationContext::NORMAL_WINDOW:
output = new WallpaperEngine::Render::Drivers::Output::CGLFWWindowOutput (this->m_context, videoDriver);
break;
case CApplicationContext::X11_BACKGROUND:
output = new WallpaperEngine::Render::Drivers::Output::CX11Output (this->m_context, videoDriver);
break;
}
// initialize render context
WallpaperEngine::Render::CRenderContext context (output, videoDriver, inputContext, *this);
// set all the specific wallpapers required
for (const auto& it : this->m_backgrounds)
context.setWallpaper (
it.first,
WallpaperEngine::Render::CWallpaper::fromWallpaper (it.second->getWallpaper (), context, audioContext)
);
// set the default rendering wallpaper if available
if (this->m_defaultBackground != nullptr)
context.setDefaultWallpaper (WallpaperEngine::Render::CWallpaper::fromWallpaper (
this->m_defaultBackground->getWallpaper (), context, audioContext
));
float startTime, endTime, minimumTime = 1.0f / this->m_context.render.maximumFPS;
while (!videoDriver.closeRequested () && g_KeepRunning)
{
// update input information
inputContext.update ();
// keep track of the previous frame's time
g_TimeLast = g_Time;
// calculate the current time value
g_Time = videoDriver.getRenderTime ();
// get the start time of the frame
startTime = g_Time;
// render the scene
context.render ();
// get the end time of the frame
endTime = videoDriver.getRenderTime ();
// ensure the frame time is correct to not overrun FPS
if ((endTime - startTime) < minimumTime)
usleep ((minimumTime - (endTime - startTime)) * CLOCKS_PER_SEC);
if (!this->m_context.screenshot.take || videoDriver.getFrameCounter () != 5)
continue;
this->takeScreenshot (context, this->m_context.screenshot.path, this->m_context.screenshot.format);
// disable screenshot just in case the counter overflows // disable screenshot just in case the counter overflows
this->m_context.takeScreenshot = false; this->m_context.screenshot.take = false;
} }
// ensure this is updated as sometimes it might not come from a signal
g_KeepRunning = false;
sLog.out ("Stop requested");
SDL_Quit ();
} }
// ensure this is updated as sometimes it might not come from a signal void CWallpaperApplication::signal (int signal)
g_KeepRunning = false; {
g_KeepRunning = false;
}
sLog.out ("Stop requested"); const std::map<std::string, Core::CProject*>& CWallpaperApplication::getBackgrounds () const
{
return this->m_backgrounds;
}
SDL_Quit (); Core::CProject* CWallpaperApplication::getDefaultBackground () const
} {
return this->m_defaultBackground;
void CWallpaperApplication::signal (int signal) }
{
g_KeepRunning = false;
}
const std::map <std::string, CProject*>& CWallpaperApplication::getProjects () const
{
return this->m_projects;
}
CProject* CWallpaperApplication::getDefaultProject () const
{
return this->m_defaultProject;
} }

View File

@ -1,42 +1,95 @@
#pragma once #pragma once
#include "CApplicationContext.h" #include "WallpaperEngine/Application/CApplicationContext.h"
#include "WallpaperEngine/Render/Drivers/COpenGLDriver.h"
#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" #include "WallpaperEngine/Render/CRenderContext.h"
#include "WallpaperEngine/Render/Drivers/COpenGLDriver.h"
namespace WallpaperEngine::Render
{
class CWallpaper;
class CRenderContext;
}
namespace WallpaperEngine::Application namespace WallpaperEngine::Application
{ {
using namespace WallpaperEngine::Assets; /**
* Small wrapper class over the actual wallpaper's main application skeleton
*
* @author Alexis Maiquez <almamu@almamu.com>
*/
class CWallpaperApplication class CWallpaperApplication
{ {
public: public:
CWallpaperApplication (CApplicationContext& context); explicit CWallpaperApplication (CApplicationContext& context);
/**
* Shows the application until it's closed
*/
void show (); void show ();
/**
* Handles a OS signal sent to this PID
*
* @param signal
*/
void signal (int signal); void signal (int signal);
const std::map <std::string, Core::CProject*>& getProjects () const; /**
Core::CProject* getDefaultProject () const; * @return Maps screens to loaded backgrounds
*/
[[nodiscard]] const std::map <std::string, Core::CProject*>& getBackgrounds () const;
/**
* @return The default background to use if no specific project is loaded
*/
[[nodiscard]] Core::CProject* getDefaultBackground () const;
private: private:
/**
* Sets up a combined container for the given background, adding default files and directories to the list
*
* @param container
* @param bg
*/
void setupContainer (CCombinedContainer& container, const std::string& bg) const; void setupContainer (CCombinedContainer& container, const std::string& bg) const;
void loadProjects (); /**
Core::CProject* loadProject (const std::string& bg); * Loads projects based off the settings
*/
void loadBackgrounds ();
/**
* Loads the given project
*
* @param bg
* @return
*/
Core::CProject* loadBackground (const std::string& bg);
/**
* Prepares all background's values and updates their properties if required
*/
void setupProperties (); void setupProperties ();
void setupPropertiesForProject (Core::CProject* project); /**
void takeScreenshot (const Render::CRenderContext& context, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format); * Updates the properties for the given background based on the current context
*
* @param project
*/
void setupPropertiesForProject (Core::CProject* project);
/**
* Takes an screenshot of the background and saves it to the specified path
*
* @param context
* @param filename
* @param format
*/
static void takeScreenshot (const Render::CRenderContext& context, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format);
Core::CProject* m_defaultProject; /**
* The default background to display if no specific background was loaded
*/
Core::CProject* m_defaultBackground;
/**
* The application context that contains the current app settings
*/
CApplicationContext& m_context; CApplicationContext& m_context;
std::map <std::string, Core::CProject*> m_projects; /**
* Maps screens to backgrounds
*/
std::map <std::string, Core::CProject*> m_backgrounds;
}; };
} }

View File

@ -5,7 +5,6 @@ using namespace WallpaperEngine::Assets;
CAssetLoadException::CAssetLoadException(const std::string& filename, const std::string& extrainfo) CAssetLoadException::CAssetLoadException(const std::string& filename, const std::string& extrainfo)
: m_message("Cannot find file " + filename + ": " + extrainfo) : m_message("Cannot find file " + filename + ": " + extrainfo)
{ {
} }
const char *CAssetLoadException::what() const noexcept const char *CAssetLoadException::what() const noexcept

View File

@ -8,8 +8,8 @@ namespace WallpaperEngine::Assets
class CAssetLoadException : public std::exception class CAssetLoadException : public std::exception
{ {
public: public:
CAssetLoadException(const std::string& filename, const std::string& extrainfo = ""); explicit CAssetLoadException (const std::string& filename, const std::string& extrainfo = "");
const char* what() const noexcept override; [[nodiscard]] const char* what () const noexcept override;
private: private:
std::string m_message; std::string m_message;

View File

@ -7,8 +7,8 @@
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
CCombinedContainer::CCombinedContainer () : CCombinedContainer::CCombinedContainer () :
CContainer (), CContainer (),
m_containers () m_containers ()
{ {
} }
@ -38,7 +38,7 @@ void CCombinedContainer::addPkg (const std::filesystem::path& path)
} }
std::filesystem::path CCombinedContainer::resolveRealFile (std::string filename) const std::filesystem::path CCombinedContainer::resolveRealFile (const std::string& filename) const
{ {
for (auto cur : this->m_containers) for (auto cur : this->m_containers)
{ {
@ -58,7 +58,7 @@ std::filesystem::path CCombinedContainer::resolveRealFile (std::string filename)
throw CAssetLoadException (filename, "Cannot resolve file in any of the containers"); 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 (const std::string& filename, uint32_t* length) const
{ {
for (auto cur : this->m_containers) for (auto cur : this->m_containers)
{ {

View File

@ -1,17 +1,20 @@
#pragma once #pragma once
#include <vector>
#include <stdexcept>
#include <filesystem>
#include "CContainer.h" #include "CContainer.h"
#include <filesystem>
#include <stdexcept>
#include <vector>
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets
{ {
/**
* A meta-container that allows backgrounds to have files spread across different containers
*/
class CCombinedContainer : public CContainer class CCombinedContainer : public CContainer
{ {
public: public:
CCombinedContainer (); CCombinedContainer ();
/** /**
* Adds a container to the list * Adds a container to the list
@ -19,12 +22,20 @@ namespace WallpaperEngine::Assets
* @param container * @param container
*/ */
void add (CContainer* container); void add (CContainer* container);
/**
* Adds the given package to the list
*
* @param path
*/
void addPkg (const std::filesystem::path& path); void addPkg (const std::filesystem::path& path);
std::filesystem::path resolveRealFile (std::string filename) const override; /** @inheritdoc */
const void* readFile (std::string filename, uint32_t* length = nullptr) const override; [[nodiscard]] std::filesystem::path resolveRealFile (const std::string& filename) const override;
/** @inheritdoc */
[[nodiscard]] const void* readFile (const std::string& filename, uint32_t* length) const override;
private: private:
/** The list of containers to search files off from */
std::vector<CContainer*> m_containers; std::vector<CContainer*> m_containers;
}; };
}; };

View File

@ -9,58 +9,58 @@
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
std::filesystem::path CContainer::resolveRealFile (std::string filename) const std::filesystem::path CContainer::resolveRealFile (const std::string& filename) const
{ {
throw CAssetLoadException (filename, "Cannot resolve physical file in this container"); throw CAssetLoadException (filename, "Cannot resolve physical file in this container");
} }
const ITexture* CContainer::readTexture (std::string filename) const const ITexture* CContainer::readTexture (const std::string& filename) const
{ {
// get the texture's filename (usually .tex) // get the texture's filename (usually .tex)
filename = "materials/" + filename + ".tex"; std::string texture = "materials/" + filename + ".tex";
const void* textureContents = this->readFile (filename, nullptr); const void* textureContents = this->readFile (texture, nullptr);
ITexture* result = new CTexture (textureContents); ITexture* result = new CTexture (textureContents);
#if !NDEBUG #if !NDEBUG
glObjectLabel (GL_TEXTURE, result->getTextureID (), -1, filename.c_str ()); glObjectLabel (GL_TEXTURE, result->getTextureID (), -1, texture.c_str ());
#endif /* NDEBUG */ #endif /* NDEBUG */
return result; return result;
} }
std::string CContainer::readShader (const std::string& filename) const std::string CContainer::readShader (const std::string& filename) const
{ {
std::filesystem::path shader = filename; std::filesystem::path shader = filename;
auto it = shader.begin (); auto it = shader.begin ();
// detect workshop shaders and check if there's a // detect workshop shaders and check if there's a
if (*it++ == "workshop") if (*it++ == "workshop")
{ {
std::filesystem::path workshopId = *it++; std::filesystem::path workshopId = *it++;
if (++it != shader.end ()) if (++it != shader.end ())
{ {
std::filesystem::path shaderfile = *it; std::filesystem::path shaderfile = *it;
try try
{ {
shader = std::filesystem::path ("zcompat") / "scene" / "shaders" / workshopId / shaderfile; shader = std::filesystem::path ("zcompat") / "scene" / "shaders" / workshopId / shaderfile;
// replace the old path with the new one // replace the old path with the new one
std::string contents = this->readFileAsString (shader); std::string contents = this->readFileAsString (shader);
sLog.out ("Replaced ", filename, " with compat ", shader); sLog.out ("Replaced ", filename, " with compat ", shader);
return contents; return contents;
} }
catch (CAssetLoadException&) catch (CAssetLoadException&)
{ {
} }
} }
} }
return this->readFileAsString ("shaders/" + filename); return this->readFileAsString ("shaders/" + filename);
} }
std::string CContainer::readVertexShader (const std::string& filename) const std::string CContainer::readVertexShader (const std::string& filename) const
@ -78,7 +78,7 @@ std::string CContainer::readIncludeShader (const std::string& filename) const
return this->readFileAsString ("shaders/" + filename); return this->readFileAsString ("shaders/" + filename);
} }
std::string CContainer::readFileAsString (std::string filename) const std::string CContainer::readFileAsString (const std::string& filename) const
{ {
uint32_t length = 0; uint32_t length = 0;

View File

@ -1,21 +1,25 @@
#pragma once #pragma once
#include "WallpaperEngine/Assets/ITexture.h"
#include <filesystem> #include <filesystem>
#include <string> #include <string>
#include "WallpaperEngine/Assets/ITexture.h"
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets
{ {
/**
* File container, provides access to files for backgrounds
*/
class CContainer class CContainer
{ {
public: public:
/** /**
* Resolves the full path to the specified file in the filesystem * Resolves the full path to the specified file in the filesystem
* *
* @param filename * @param filename
* @return * @return
*/ */
virtual std::filesystem::path resolveRealFile (std::string filename) const; [[nodiscard]] virtual std::filesystem::path resolveRealFile (const 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
@ -26,7 +30,7 @@ namespace WallpaperEngine::Assets
* *
* @return * @return
*/ */
virtual const void* readFile (std::string filename, uint32_t* length = nullptr) const = 0; [[nodiscard]] virtual const void* readFile (const std::string& filename, uint32_t* length) const = 0;
/** /**
* Wrapper for readFile, appends the texture extension at the end of the filename * Wrapper for readFile, appends the texture extension at the end of the filename
@ -35,16 +39,16 @@ namespace WallpaperEngine::Assets
* *
* @return * @return
*/ */
const ITexture* readTexture (std::string filename) const; [[nodiscard]] const ITexture* readTexture (const std::string& filename) const;
/** /**
* Wrapper for readFile, checks for compat versions of the given shader file * Wrapper for readFile, checks for compat versions of the given shader file
* *
* @param filename * @param filename
* *
* @return The shader code as an string to be used * @return The shader code as an string to be used
*/ */
std::string readShader (const std::string& filename) const; [[nodiscard]] std::string readShader (const std::string& filename) const;
/** /**
* Wrapper for readFile, appends the .vert extension at the end and opens the given shader file * Wrapper for readFile, appends the .vert extension at the end and opens the given shader file
@ -53,7 +57,7 @@ namespace WallpaperEngine::Assets
* *
* @return The shader code as an string to be used * @return The shader code as an string to be used
*/ */
std::string readVertexShader (const std::string& filename) const; [[nodiscard]] std::string readVertexShader (const std::string& filename) const;
/** /**
* Wrapper for readFile, appends the .frag extension at the end and opens the given shader file * Wrapper for readFile, appends the .frag extension at the end and opens the given shader file
@ -62,7 +66,7 @@ namespace WallpaperEngine::Assets
* *
* @return The shader code as an string to be used * @return The shader code as an string to be used
*/ */
std::string readFragmentShader (const std::string& filename) const; [[nodiscard]] std::string readFragmentShader (const std::string& filename) const;
/** /**
* Wrapper for readFile, appends the .h extension at the end and opens the given shader file * Wrapper for readFile, appends the .h extension at the end and opens the given shader file
@ -71,7 +75,7 @@ namespace WallpaperEngine::Assets
* *
* @return The shader code as an string to be used * @return The shader code as an string to be used
*/ */
std::string readIncludeShader (const std::string& filename) const; [[nodiscard]] std::string readIncludeShader (const std::string& filename) const;
/** /**
* Reads a file as string * Reads a file as string
@ -80,6 +84,6 @@ namespace WallpaperEngine::Assets
* *
* @return The file's contents as string * @return The file's contents as string
*/ */
std::string readFileAsString (std::string filename) const; [[nodiscard]] std::string readFileAsString (const std::string& filename) const;
}; };
} }

View File

@ -24,12 +24,12 @@ CDirectory::CDirectory (std::filesystem::path basepath) :
CDirectory::~CDirectory () CDirectory::~CDirectory ()
= default; = default;
std::filesystem::path CDirectory::resolveRealFile (std::string filename) const std::filesystem::path CDirectory::resolveRealFile (const std::string& filename) const
{ {
return std::filesystem::path (this->m_basepath) / filename; return std::filesystem::path (this->m_basepath) / filename;
} }
const void* CDirectory::readFile (std::string filename, uint32_t* length) const const void* CDirectory::readFile (const 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;

View File

@ -10,16 +10,24 @@
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets
{ {
/**
* Directory container implementation, provides access to background files under a specific directory
*/
class CDirectory : public CContainer class CDirectory : public CContainer
{ {
public: public:
explicit CDirectory (std::filesystem::path basepath); explicit CDirectory (std::filesystem::path basepath);
~CDirectory (); ~CDirectory ();
std::filesystem::path resolveRealFile (std::string filename) const override; /** @inheritdoc */
const void* readFile (std::string filename, uint32_t* length) const override; [[nodiscard]] std::filesystem::path resolveRealFile (const std::string& filename) const override;
/** @inheritdoc */
[[nodiscard]] const void* readFile (const std::string& filename, uint32_t* length) const override;
private: private:
/** The basepath for the directory */
std::filesystem::path m_basepath; std::filesystem::path m_basepath;
/** File cache to simplify access to data */
std::map <std::string, CFileEntry> m_cache; std::map <std::string, CFileEntry> m_cache;
}; };
} }

View File

@ -1,11 +1,10 @@
//
// Created by almamu on 8/8/21.
//
#pragma once #pragma once
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets
{ {
/**
* File cache entry to prevent hit the disk when loading the same file multiple times
*/
class CFileEntry class CFileEntry
{ {
public: public:
@ -13,7 +12,9 @@ namespace WallpaperEngine::Assets
address (address), address (address),
length (length) { } length (length) { }
/** File contents */
const void* address; const void* address;
/** File length */
uint32_t length; uint32_t length;
}; };
} }

View File

@ -32,7 +32,7 @@ CPackage::~CPackage()
= default; = default;
const void* CPackage::readFile (std::string filename, uint32_t* length) const const void* CPackage::readFile (const std::string& filename, uint32_t* length) const
{ {
auto it = this->m_contents.find (filename); auto it = this->m_contents.find (filename);

View File

@ -13,13 +13,17 @@
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets
{ {
/**
* Package container implementation, provides access to background files that are stored
* inside the WallpaperEngine's pkg format
*/
class CPackage : public CContainer class CPackage : public CContainer
{ {
public: public:
explicit CPackage (std::filesystem::path path); explicit CPackage (std::filesystem::path path);
~CPackage (); ~CPackage ();
const void* readFile (std::string filename, uint32_t* length) const override; [[nodiscard]] const void* readFile (const std::string& filename, uint32_t* length) const override;
protected: protected:
/** /**
@ -59,7 +63,9 @@ namespace WallpaperEngine::Assets
uint32_t readInteger (FILE* fp); uint32_t readInteger (FILE* fp);
private: private:
/** The path to the package file */
std::filesystem::path m_path; std::filesystem::path m_path;
/** Contents of the package file */
std::map <std::string, CFileEntry> m_contents; std::map <std::string, CFileEntry> m_contents;
}; };
} }

View File

@ -2,12 +2,12 @@
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
CPackageLoadException::CPackageLoadException(const std::string& filename, const std::string& extrainfo) CPackageLoadException::CPackageLoadException (const std::string& filename, const std::string& extrainfo) :
: m_message("Cannot load package " + filename + ": " + extrainfo) m_message ("Cannot load package " + filename + ": " + extrainfo)
{ {
} }
const char *CPackageLoadException::what() const noexcept const char *CPackageLoadException::what () const noexcept
{ {
return this->m_message.c_str (); return this->m_message.c_str ();
} }

View File

@ -8,8 +8,8 @@ namespace WallpaperEngine::Assets
class CPackageLoadException : public std::exception class CPackageLoadException : public std::exception
{ {
public: public:
explicit CPackageLoadException(const std::string& message, const std::string& extrainfo = ""); explicit CPackageLoadException (const std::string& message, const std::string& extrainfo = "");
const char* what() const noexcept override; [[nodiscard]] const char* what () const noexcept override;
private: private:
std::string m_message; std::string m_message;

View File

@ -8,7 +8,7 @@
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
CTexture::CTexture (const void* fileData) : CTexture::CTexture (const void* fileData) :
m_resolution () m_resolution ()
{ {
// ensure the header is parsed // ensure the header is parsed
this->m_header = parseHeader (static_cast <const char*> (fileData)); this->m_header = parseHeader (static_cast <const char*> (fileData));
@ -62,27 +62,27 @@ CTexture::CTexture (const void* fileData) :
// detect the image format and hand it to openGL to be used // detect the image format and hand it to openGL to be used
switch (this->m_header->format) switch (this->m_header->format)
{ {
case TextureFormat::DXT5: case TextureFormat::DXT5:
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
break; break;
case TextureFormat::DXT3: case TextureFormat::DXT3:
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
break; break;
case TextureFormat::DXT1: case TextureFormat::DXT1:
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
break; break;
case TextureFormat::ARGB8888: case TextureFormat::ARGB8888:
internalFormat = GL_RGBA8; internalFormat = GL_RGBA8;
break; break;
case TextureFormat::R8: case TextureFormat::R8:
internalFormat = GL_R8; internalFormat = GL_R8;
break; break;
case TextureFormat::RG88: case TextureFormat::RG88:
internalFormat = GL_RG8; internalFormat = GL_RG8;
break; break;
default: default:
delete this->m_header; delete this->m_header;
sLog.exception ("Cannot determine texture format"); sLog.exception ("Cannot determine texture format");
} }
} }
@ -161,39 +161,39 @@ CTexture::CTexture (const void* fileData) :
} }
else else
{ {
if (this->m_header->format == TextureFormat::R8) if (this->m_header->format == TextureFormat::R8)
{ {
// red textures are 1-byte-per-pixel, so it's alignment has to be set manually // red textures are 1-byte-per-pixel, so it's alignment has to be set manually
glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
textureFormat = GL_RED; textureFormat = GL_RED;
} }
else if (this->m_header->format == TextureFormat::RG88) else if (this->m_header->format == TextureFormat::RG88)
textureFormat = GL_RG; textureFormat = GL_RG;
} }
switch (internalFormat) switch (internalFormat)
{ {
case GL_RGBA8: case GL_RGBA8:
case GL_RG8: case GL_RG8:
case GL_R8: case GL_R8:
glTexImage2D ( glTexImage2D (
GL_TEXTURE_2D, level, internalFormat, GL_TEXTURE_2D, level, internalFormat,
width, height, 0, width, height, 0,
textureFormat, GL_UNSIGNED_BYTE, textureFormat, GL_UNSIGNED_BYTE,
dataptr dataptr
); );
break; break;
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
glCompressedTexImage2D ( glCompressedTexImage2D (
GL_TEXTURE_2D, level, internalFormat, GL_TEXTURE_2D, level, internalFormat,
width, height, 0, width, height, 0,
bufferSize, dataptr bufferSize, dataptr
); );
break; break;
default: default:
sLog.exception ("Cannot load texture, unknown format", this->m_header->format); sLog.exception ("Cannot load texture, unknown format", this->m_header->format);
} }
// freeimage buffer won't be used anymore, so free memory // freeimage buffer won't be used anymore, so free memory
@ -309,14 +309,14 @@ void CTexture::TextureMipmap::decompressData ()
} }
CTexture::TextureFrame::TextureFrame () : CTexture::TextureFrame::TextureFrame () :
frameNumber (0), frameNumber (0),
frametime (0.0f), frametime (0.0f),
x (0), x (0),
y (0), y (0),
width1 (0), width1 (0),
width2 (0), width2 (0),
height1 (0), height1 (0),
height2 (0) height2 (0)
{ {
} }
@ -324,16 +324,16 @@ CTexture::TextureFrame::~TextureFrame ()
= default; = default;
CTexture::TextureHeader::TextureHeader () : CTexture::TextureHeader::TextureHeader () :
flags (NoFlags), flags (NoFlags),
width (0), width (0),
height (0), height (0),
textureWidth (0), textureWidth (0),
textureHeight (0), textureHeight (0),
gifWidth (0), gifWidth (0),
gifHeight (0), gifHeight (0),
format (TextureFormat::UNKNOWN), format (TextureFormat::UNKNOWN),
imageCount (0), imageCount (0),
mipmapCount (0) mipmapCount (0)
{ {
} }

View File

@ -1,40 +1,26 @@
#pragma once #pragma once
#include <string> #include "ITexture.h"
#include <vector>
#include <stdexcept>
#include <GL/glew.h>
#include <glm/vec4.hpp>
#include <FreeImage.h> #include <FreeImage.h>
#include <GL/glew.h>
#include <glm/vec4.hpp>
#include <map> #include <map>
#include "ITexture.h" #include <stdexcept>
#include <string>
#include <vector>
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets
{ {
/**
* A normal texture file in WallpaperEngine's format
*/
class CTexture : public ITexture class CTexture : public ITexture
{ {
struct TextureHeader;
public:
explicit CTexture (const void* fileData);
~CTexture ();
const GLuint getTextureID (uint32_t imageIndex = 0) const override;
const uint32_t getTextureWidth (uint32_t imageIndex = 0) const override;
const uint32_t getTextureHeight (uint32_t imageIndex = 0) const override;
const uint32_t getRealWidth () const override;
const uint32_t getRealHeight () const override;
const TextureFormat getFormat () const override;
const TextureFlags getFlags () const override;
const glm::vec4* getResolution () const override;
const std::vector<TextureFrame*>& getFrames () const override;
const bool isAnimated () const override;
private: private:
const TextureHeader* getHeader () const; /**
* Different texture container versions supported
*/
enum ContainerVersion : int enum ContainerVersion : int
{ {
UNKNOWN = -1, UNKNOWN = -1,
@ -43,6 +29,9 @@ namespace WallpaperEngine::Assets
TEXB0001 = 1 TEXB0001 = 1
}; };
/**
* Different texture animation versions supported
*/
enum AnimatedVersion : int enum AnimatedVersion : int
{ {
TEXSUNKN = -1, TEXSUNKN = -1,
@ -50,6 +39,9 @@ namespace WallpaperEngine::Assets
TEXS0003 = 1, TEXS0003 = 1,
}; };
/**
* Texture mipmap data
*/
class TextureMipmap class TextureMipmap
{ {
public: public:
@ -76,13 +68,16 @@ namespace WallpaperEngine::Assets
void decompressData (); void decompressData ();
}; };
/**
* Texture header data
*/
class TextureHeader class TextureHeader
{ {
public: public:
TextureHeader (); TextureHeader ();
~TextureHeader (); ~TextureHeader ();
bool isAnimated () const; [[nodiscard]] bool isAnimated () const;
/** The version of the texture container */ /** The version of the texture container */
ContainerVersion containerVersion = ContainerVersion::UNKNOWN; ContainerVersion containerVersion = ContainerVersion::UNKNOWN;
@ -111,17 +106,70 @@ namespace WallpaperEngine::Assets
/** Number of mipmap levels on the texture */ /** Number of mipmap levels on the texture */
uint32_t mipmapCount; uint32_t mipmapCount;
/** List of mipmaps */ /** List of mipmaps */
std::map <uint32_t, std::vector <TextureMipmap*>> images; std::map<uint32_t, std::vector<TextureMipmap*>> images;
/** List of animation frames */ /** List of animation frames */
std::vector <TextureFrame*> frames; std::vector<TextureFrame*> frames;
}; };
public:
explicit CTexture (const void* fileData);
~CTexture ();
/** @inheritdoc */
[[nodiscard]] const GLuint getTextureID (uint32_t imageIndex = 0) const override;
/** @inheritdoc */
[[nodiscard]] const uint32_t getTextureWidth (uint32_t imageIndex = 0) const override;
/** @inheritdoc */
[[nodiscard]] const uint32_t getTextureHeight (uint32_t imageIndex = 0) const override;
/** @inheritdoc */
[[nodiscard]] const uint32_t getRealWidth () const override;
/** @inheritdoc */
[[nodiscard]] const uint32_t getRealHeight () const override;
/** @inheritdoc */
[[nodiscard]] const TextureFormat getFormat () const override;
/** @inheritdoc */
[[nodiscard]] const TextureFlags getFlags () const override;
/** @inheritdoc */
[[nodiscard]] const glm::vec4* getResolution () const override;
/** @inheritdoc */
[[nodiscard]] const std::vector<TextureFrame*>& getFrames () const override;
/** @inheritdoc */
[[nodiscard]] const bool isAnimated () const override;
private: private:
/**
* @return The texture header
*/
[[nodiscard]] const TextureHeader* getHeader () const;
/**
* Tries to parse a header off the given data pointer
*
* @param fileData The point at which to start reading data off from
* @return
*/
static TextureHeader* parseHeader (const char* fileData); static TextureHeader* parseHeader (const char* fileData);
/**
* Tries to parse an animation frame off the given data pointer
*
* @param originalFileData The point at which to start reading data off from
* @return
*/
static TextureFrame* parseAnimation (const char** originalFileData); static TextureFrame* parseAnimation (const char** originalFileData);
/**
* Tries to parse mipmap information off the given data pointer
*
* @param header The file header
* @param fileData The point at which to start reading data off from
* @return
*/
static TextureMipmap* parseMipmap (TextureHeader* header, const char** fileData); static TextureMipmap* parseMipmap (TextureHeader* header, const char** fileData);
/** The texture header */
TextureHeader* m_header; TextureHeader* m_header;
/** OpenGL's texture ID */
GLuint* m_textureID; GLuint* m_textureID;
/** Resolution vector of the texture */
glm::vec4 m_resolution; glm::vec4 m_resolution;
}; };
} }

View File

@ -23,7 +23,7 @@ void CVirtualContainer::add (const std::string& filename, const std::string& con
this->add (filename, copy, contents.length () + 1); this->add (filename, copy, contents.length () + 1);
} }
const void* CVirtualContainer::readFile (std::string filename, uint32_t* length) const const void* CVirtualContainer::readFile (const std::string& filename, uint32_t* length) const
{ {
auto cur = this->m_virtualFiles.find (filename); auto cur = this->m_virtualFiles.find (filename);

View File

@ -8,6 +8,9 @@
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets
{ {
/**
* Virtual container implementation, provides virtual files for the backgrounds to use
*/
class CVirtualContainer : public CContainer class CVirtualContainer : public CContainer
{ {
public: public:
@ -30,10 +33,11 @@ namespace WallpaperEngine::Assets
* @param contents * @param contents
*/ */
void add (const std::string& filename, const std::string& contents); void add (const std::string& filename, const std::string& contents);
/** @inheritdoc */
const void* readFile (std::string filename, uint32_t* length) const override; const void* readFile (const std::string& filename, uint32_t* length) const override;
private: private:
/** The recorded files in this virtual container */
std::map <std::string, CFileEntry> m_virtualFiles; std::map <std::string, CFileEntry> m_virtualFiles;
}; };
} }

View File

@ -6,9 +6,16 @@
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets
{ {
/**
* Base interface that describes the minimum information required for a texture
* to be displayed by the engine
*/
class ITexture class ITexture
{ {
public: public:
/**
* Texture frame information for animated textures
*/
class TextureFrame class TextureFrame
{ {
public: public:
@ -32,11 +39,11 @@ namespace WallpaperEngine::Assets
}; };
/** /**
* Configures the data format for the texture * Data formats for textures in memory
*/ */
enum TextureFormat : uint32_t enum TextureFormat : uint32_t
{ {
UNKNOWN = 0xFFFFFFFF, UNKNOWN = 0xFFFFFFFF,
ARGB8888 = 0, ARGB8888 = 0,
RGB888 = 1, RGB888 = 1,
RGB565 = 2, RGB565 = 2,
@ -54,7 +61,7 @@ namespace WallpaperEngine::Assets
}; };
/** /**
* Configures how the texture will be handled by the background * Different settings of the textures
*/ */
enum TextureFlags : uint32_t enum TextureFlags : uint32_t
{ {
@ -64,15 +71,48 @@ namespace WallpaperEngine::Assets
IsGif = 4, IsGif = 4,
}; };
virtual const GLuint getTextureID (uint32_t imageIndex = 0) const = 0; /**
virtual const uint32_t getTextureWidth (uint32_t imageIndex = 0) const = 0; * @param imageIndex For animated textures, the frame to get the ID of
virtual const uint32_t getTextureHeight (uint32_t imageIndex = 0) const = 0; * @return The OpenGL texture to use when rendering
virtual const uint32_t getRealWidth () const = 0; */
virtual const uint32_t getRealHeight () const = 0; [[nodiscard]] virtual const GLuint getTextureID (uint32_t imageIndex = 0) const = 0;
virtual const TextureFormat getFormat () const = 0; /**
virtual const TextureFlags getFlags () const = 0; * @param imageIndex For animated textures, the frame to get the ID of
virtual const std::vector<TextureFrame*>& getFrames () const = 0; * @return The texture's width
virtual const glm::vec4* getResolution () const = 0; */
virtual const bool isAnimated () const = 0; [[nodiscard]] virtual const uint32_t getTextureWidth (uint32_t imageIndex = 0) const = 0;
/**
* @param imageIndex For animated textures, the frame to get the ID of
* @return The texture's height
*/
[[nodiscard]] virtual const uint32_t getTextureHeight (uint32_t imageIndex = 0) const = 0;
/**
* @return The textures real width
*/
[[nodiscard]] virtual const uint32_t getRealWidth () const = 0;
/**
* @return The textures real height
*/
[[nodiscard]] virtual const uint32_t getRealHeight () const = 0;
/**
* @return The texture's memory format
*/
[[nodiscard]] virtual const TextureFormat getFormat () const = 0;
/**
* @return The texture's settings
*/
[[nodiscard]] virtual const TextureFlags getFlags () const = 0;
/**
* @return The list of frames this texture has
*/
[[nodiscard]] virtual const std::vector<TextureFrame*>& getFrames () const = 0;
/**
* @return The texture's resolution vector
*/
[[nodiscard]] virtual const glm::vec4* getResolution () const = 0;
/**
* @return If the texture is animated or not
*/
[[nodiscard]] virtual const bool isAnimated () const = 0;
}; };
} }

View File

@ -17,12 +17,30 @@ namespace WallpaperEngine::Audio
public: public:
explicit CAudioContext (Drivers::CAudioDriver& driver); explicit CAudioContext (Drivers::CAudioDriver& driver);
/**
* Registers the given stream in the driver for playing
*
* @param stream
*/
void addStream (CAudioStream* stream); void addStream (CAudioStream* stream);
AVSampleFormat getFormat () const; /**
int getSampleRate () const; * TODO: MAYBE THIS SHOULD BE OUR OWN DEFINITIONS INSTEAD OF LIBRARY SPECIFIC ONES?
int getChannels () const; *
* @return The audio format the driver supports
*/
[[nodiscard]] AVSampleFormat getFormat () const;
/**
* @return The sample rate the driver supports
*/
[[nodiscard]] int getSampleRate () const;
/**
* @return The channels the driver supports
*/
[[nodiscard]] int getChannels () const;
private: private:
/** The audio driver in use */
Drivers::CAudioDriver& m_driver; Drivers::CAudioDriver& m_driver;
}; };
} }

View File

@ -28,8 +28,8 @@ int audio_read_thread (void* arg)
// give the cpu some time to play the queued frames if there's enough info there // give the cpu some time to play the queued frames if there's enough info there
if ( if (
stream->getQueueSize () >= MAX_QUEUE_SIZE || stream->getQueueSize () >= MAX_QUEUE_SIZE ||
(stream->getQueuePacketCount () > MIN_FRAMES && (stream->getQueuePacketCount () > MIN_FRAMES &&
(av_q2d (stream->getTimeBase ()) * stream->getQueueDuration () > 1.0)) (av_q2d (stream->getTimeBase ()) * stream->getQueueDuration () > 1.0))
) )
{ {
SDL_LockMutex (waitMutex); SDL_LockMutex (waitMutex);
@ -328,7 +328,7 @@ void CAudioStream::dequeuePacket (AVPacket* output)
#if FF_API_FIFO_OLD_API #if FF_API_FIFO_OLD_API
int ret = av_fifo_read (this->m_queue->packetList, &entry, 1); int ret = av_fifo_read (this->m_queue->packetList, &entry, 1);
#else #else
int ret = -1; int ret = -1;
if (av_fifo_size (this->m_queue->packetList) >= sizeof (entry)) if (av_fifo_size (this->m_queue->packetList) >= sizeof (entry))
ret = av_fifo_generic_read (this->m_queue->packetList, &entry, sizeof (entry), nullptr); ret = av_fifo_generic_read (this->m_queue->packetList, &entry, sizeof (entry), nullptr);
@ -450,7 +450,7 @@ void CAudioStream::stop ()
int CAudioStream::resampleAudio (AVFrame * decoded_audio_frame, uint8_t * out_buf) int CAudioStream::resampleAudio (AVFrame * decoded_audio_frame, uint8_t * out_buf)
{ {
int out_linesize = 0; int out_linesize = 0;
int ret; int ret;
int out_nb_channels; int out_nb_channels;
int in_nb_samples; int in_nb_samples;
@ -515,7 +515,7 @@ int CAudioStream::resampleAudio (AVFrame * decoded_audio_frame, uint8_t * out_bu
// retrieve output samples number taking into account the progressive delay // retrieve output samples number taking into account the progressive delay
out_nb_samples = av_rescale_rnd( out_nb_samples = av_rescale_rnd(
swr_get_delay(this->m_swrctx, this->getContext ()->sample_rate) + in_nb_samples, swr_get_delay(this->m_swrctx, this->getContext ()->sample_rate) + in_nb_samples,
this->m_audioContext.getSampleRate (), this->m_audioContext.getSampleRate (),
this->getContext ()->sample_rate, this->getContext ()->sample_rate,
AV_ROUND_UP AV_ROUND_UP
); );
@ -634,7 +634,7 @@ int CAudioStream::decodeFrame (uint8_t* audioBuffer, int bufferSize)
if (ret < 0 && ret != AVERROR (EAGAIN)) if (ret < 0 && ret != AVERROR (EAGAIN))
return -1; return -1;
len1 = pkt->size; len1 = pkt->size;
if (len1 < 0) if (len1 < 0)
{ {

View File

@ -4,12 +4,12 @@
extern "C" extern "C"
{ {
#include <libavutil/fifo.h> #include <libavutil/fifo.h>
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
#include <libswscale/swscale.h> #include <libswscale/swscale.h>
#include <libswresample/swresample.h> #include <libswresample/swresample.h>
#include <libavutil/opt.h> #include <libavutil/opt.h>
} }
#include <SDL.h> #include <SDL.h>
@ -19,6 +19,11 @@ extern "C"
namespace WallpaperEngine::Audio namespace WallpaperEngine::Audio
{ {
class CAudioContext;
/**
* Represents a playable audio stream for the audio driver
*/
class CAudioStream class CAudioStream
{ {
public: public:
@ -38,66 +43,165 @@ namespace WallpaperEngine::Audio
*/ */
void dequeuePacket (AVPacket* output); void dequeuePacket (AVPacket* output);
/**
* @return to the codec context, which provides information on the audio stream's format
*/
AVCodecContext* getContext (); AVCodecContext* getContext ();
/**
* @returns the format context, which controls how data is read off the audio stream
*/
AVFormatContext* getFormatContext (); AVFormatContext* getFormatContext ();
/**
* @return The audio stream index of the given file
*/
int getAudioStream (); int getAudioStream ();
/**
* @return If the audio stream can be played or not
*/
bool isInitialized (); bool isInitialized ();
/**
* @param newRepeat true = repeat, false = no repeat
*/
void setRepeat (bool newRepeat = true); void setRepeat (bool newRepeat = true);
/**
* @return If the stream is to be repeated at the end or not
*/
bool isRepeat (); bool isRepeat ();
/**
* Stops decoding and playbak of the stream
*/
void stop (); void stop ();
/**
* @return The file data buffer
*/
const void* getBuffer (); const void* getBuffer ();
/**
* @return The length of the file data buffer
*/
int getLength (); int getLength ();
/**
* @return The read position of the data buffer
*/
int getPosition (); int getPosition ();
/**
* Updates the read position of the data buffer
*
* @param current
*/
void setPosition (int current); void setPosition (int current);
/**
* @return The SDL_cond used to signal waiting for data
*/
SDL_cond* getWaitCondition (); SDL_cond* getWaitCondition ();
/**
* @return The data queue size
*/
int getQueueSize (); int getQueueSize ();
/**
* @return The amount of packets ready to be converted and played
*/
int getQueuePacketCount (); int getQueuePacketCount ();
/**
* @return The duration (in seconds) of the queued data to be played
*/
int64_t getQueueDuration (); int64_t getQueueDuration ();
/**
* @return Time unit used for packet playback
*/
AVRational getTimeBase (); AVRational getTimeBase ();
/**
* @return If the data queue is empty or not
*/
bool isQueueEmpty (); bool isQueueEmpty ();
/**
* @return The SDL_mutex used for thread synchronization
*/
SDL_mutex* getMutex (); SDL_mutex* getMutex ();
/**
* Reads a frame from the audio stream, resamples it to the driver's settings
* and returns the data ready to be played
*
* @param audioBuffer
* @param bufferSize
*
* @return The amount of bytes available or < 0 for error
*/
int decodeFrame (uint8_t* audioBuffer, int bufferSize); int decodeFrame (uint8_t* audioBuffer, int bufferSize);
private: private:
/**
* Initializes ffmpeg to read the given file
*
* @param filename
*/
void loadCustomContent (const char* filename = nullptr); void loadCustomContent (const char* filename = nullptr);
int resampleAudio (AVFrame * decoded_audio_frame, uint8_t* out_buf); /**
* Converts the audio frame from the original format to one supported by the audio driver
*
* @param decoded_audio_frame
* @param out_buf
* @return
*/
int resampleAudio (AVFrame* decoded_audio_frame, uint8_t* out_buf);
/**
* Queues a packet into the play queue
*
* @param pkt
* @return
*/
bool doQueue (AVPacket* pkt); bool doQueue (AVPacket* pkt);
/**
* Initializes queues and ffmpeg resampling
*/
void initialize (); void initialize ();
#if FF_API_OLD_CHANNEL_LAYOUT #if FF_API_OLD_CHANNEL_LAYOUT
/** Chanel layout needed for old FFMPEG versions */
AVChannelLayout m_out_channel_layout; AVChannelLayout m_out_channel_layout;
#endif #endif
/** The SwrContext that handles resampling */
SwrContext* m_swrctx; SwrContext* m_swrctx;
/** The audio context this stream will be played under */
CAudioContext& m_audioContext; CAudioContext& m_audioContext;
/** If this stream was properly initialized or not */
bool m_initialized; bool m_initialized;
/** Repeat enabled? */
bool m_repeat; bool m_repeat;
/** The codec context that contains the original audio format information */
AVCodecContext* m_context = nullptr; AVCodecContext* m_context = nullptr;
/** The format context that controls how data is read off the file */
AVFormatContext* m_formatContext = nullptr; AVFormatContext* m_formatContext = nullptr;
/** The stream index for the audio being played */
int m_audioStream = -1; int m_audioStream = -1;
/** File data pointer */
const void* m_buffer; const void* m_buffer;
/** The length of the file data pointer */
int m_length; int m_length;
/** The read position on the file data pointer */
int m_position = 0; int m_position = 0;
struct MyAVPacketList struct MyAVPacketList
{ {
AVPacket *packet; AVPacket* packet;
}; };
/**
* Packet queue information
*/
struct PacketQueue struct PacketQueue
{ {
#if FF_API_FIFO_OLD_API #if FF_API_FIFO_OLD_API
AVFifo* packetList; AVFifo* packetList;
#else #else
AVFifoBuffer* packetList; AVFifoBuffer* packetList;
#endif #endif
int nb_packets; int nb_packets;
int size; int size;
int64_t duration; int64_t duration;
SDL_mutex *mutex; SDL_mutex* mutex;
SDL_cond *wait; SDL_cond* wait;
SDL_cond *cond; SDL_cond* cond;
} *m_queue; }* m_queue;
}; };
} }

View File

@ -11,14 +11,32 @@ namespace WallpaperEngine::Audio
namespace WallpaperEngine::Audio::Drivers namespace WallpaperEngine::Audio::Drivers
{ {
/**
* Base class for audio driver implementations
*/
class CAudioDriver class CAudioDriver
{ {
public: public:
/**
* Registers the given stream in the driver for playing
*
* @param stream
*/
virtual void addStream (CAudioStream* stream) = 0; virtual void addStream (CAudioStream* stream) = 0;
virtual AVSampleFormat getFormat () const = 0; /**
virtual int getSampleRate () const = 0; * TODO: MAYBE THIS SHOULD BE OUR OWN DEFINITIONS INSTEAD OF LIBRARY SPECIFIC ONES?
virtual int getChannels () const = 0; *
private: * @return The audio format the driver supports
*/
[[nodiscard]] virtual AVSampleFormat getFormat () const = 0;
/**
* @return The sample rate the driver supports
*/
[[nodiscard]] virtual int getSampleRate () const = 0;
/**
* @return The channels the driver supports
*/
[[nodiscard]] virtual int getChannels () const = 0;
}; };
} }

View File

@ -75,7 +75,7 @@ void audio_callback (void* userdata, uint8_t* streamData, int length)
CSDLAudioDriver::CSDLAudioDriver () : CSDLAudioDriver::CSDLAudioDriver () :
m_initialized (false), m_initialized (false),
m_audioSpec () m_audioSpec ()
{ {
if (SDL_InitSubSystem (SDL_INIT_AUDIO) < 0) if (SDL_InitSubSystem (SDL_INIT_AUDIO) < 0)
{ {
@ -122,6 +122,7 @@ void CSDLAudioDriver::addStream (CAudioStream* stream)
{ {
this->m_streams.push_back (new CSDLAudioBuffer { stream }); this->m_streams.push_back (new CSDLAudioBuffer { stream });
} }
const std::vector <CSDLAudioBuffer*>& CSDLAudioDriver::getStreams () const std::vector <CSDLAudioBuffer*>& CSDLAudioDriver::getStreams ()
{ {
return this->m_streams; return this->m_streams;

View File

@ -12,31 +12,52 @@
namespace WallpaperEngine::Audio::Drivers namespace WallpaperEngine::Audio::Drivers
{ {
/**
* Audio output buffers for streams being played under SDL
*/
struct CSDLAudioBuffer struct CSDLAudioBuffer
{ {
CAudioStream* stream; CAudioStream* stream;
uint8_t audio_buf[(MAX_AUDIO_FRAME_SIZE * 3) / 2]; uint8_t audio_buf[(MAX_AUDIO_FRAME_SIZE * 3) / 2] = {0};
unsigned int audio_buf_size = 0; unsigned int audio_buf_size = 0;
unsigned int audio_buf_index = 0; unsigned int audio_buf_index = 0;
}; };
/**
* SDL's audio driver implementation
*/
class CSDLAudioDriver : public CAudioDriver class CSDLAudioDriver : public CAudioDriver
{ {
public: public:
CSDLAudioDriver (); CSDLAudioDriver ();
~CSDLAudioDriver (); ~CSDLAudioDriver ();
/** @inheritdoc */
void addStream (CAudioStream* stream) override; void addStream (CAudioStream* stream) override;
/**
* @return All the registered audio streams
*/
const std::vector <CSDLAudioBuffer*>& getStreams (); const std::vector <CSDLAudioBuffer*>& getStreams ();
AVSampleFormat getFormat () const override; /** @inheritdoc */
int getSampleRate () const override; [[nodiscard]] AVSampleFormat getFormat () const override;
int getChannels () const override; /** @inheritdoc */
const SDL_AudioSpec& getSpec () const; [[nodiscard]] int getSampleRate () const override;
/** @inheritdoc */
[[nodiscard]] int getChannels () const override;
/**
* @return The SDL's audio driver settings
*/
[[nodiscard]] const SDL_AudioSpec& getSpec () const;
private: private:
/** The device's ID */
SDL_AudioDeviceID m_deviceID; SDL_AudioDeviceID m_deviceID;
/** If the driver is initialized or not */
bool m_initialized; bool m_initialized;
/** The sound output configuration */
SDL_AudioSpec m_audioSpec; SDL_AudioSpec m_audioSpec;
/** All the playable steams */
std::vector <CSDLAudioBuffer*> m_streams; std::vector <CSDLAudioBuffer*> m_streams;
}; };
} }

View File

@ -39,7 +39,7 @@ CProject* CProject::fromFile (const std::string& filename, CContainer* container
else else
sLog.exception ("Unsupported wallpaper type: ", type); sLog.exception ("Unsupported wallpaper type: ", type);
project->setWallpaper (wallpaper); project->setWallpaper (wallpaper);
if (general != content.end ()) if (general != content.end ())
{ {
@ -62,7 +62,7 @@ CProject* CProject::fromFile (const std::string& filename, CContainer* container
void CProject::setWallpaper (CWallpaper* wallpaper) void CProject::setWallpaper (CWallpaper* wallpaper)
{ {
this->m_wallpaper = wallpaper; this->m_wallpaper = wallpaper;
} }
CWallpaper* CProject::getWallpaper () const CWallpaper* CProject::getWallpaper () const

View File

@ -29,7 +29,7 @@ namespace WallpaperEngine::Core
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);
private: private:
std::vector<Projects::CProperty*> m_properties; std::vector<Projects::CProperty*> m_properties;

View File

@ -9,26 +9,26 @@
using namespace WallpaperEngine::Core; 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,
CUserSettingFloat* bloomStrength, CUserSettingFloat* bloomStrength,
CUserSettingFloat* bloomThreshold, CUserSettingFloat* bloomThreshold,
bool cameraFade, bool cameraFade,
bool cameraParallax, bool cameraParallax,
double cameraParallaxAmount, double cameraParallaxAmount,
double cameraParallaxDelay, double cameraParallaxDelay,
double cameraParallaxMouseInfluence, double cameraParallaxMouseInfluence,
bool cameraPreview, bool cameraPreview,
bool cameraShake, bool cameraShake,
double cameraShakeAmplitude, double cameraShakeAmplitude,
double cameraShakeRoughness, double cameraShakeRoughness,
double cameraShakeSpeed, double cameraShakeSpeed,
CUserSettingVector3* clearColor, CUserSettingVector3* clearColor,
Scenes::CProjection* orthogonalProjection, Scenes::CProjection* orthogonalProjection,
glm::vec3 skylightColor) : glm::vec3 skylightColor) :
CWallpaper (Type, project), CWallpaper (Type, project),
m_container (container), m_container (container),
m_camera (camera), m_camera (camera),
@ -81,26 +81,26 @@ CScene* CScene::fromFile (const std::string& filename, CProject& project, CConta
auto skylightcolor = jsonFindDefault <std::string> (*general_it, "skylightcolor", "0 0 0"); auto skylightcolor = jsonFindDefault <std::string> (*general_it, "skylightcolor", "0 0 0");
CScene* scene = new CScene ( CScene* scene = new CScene (
project, project,
container, container,
Scenes::CCamera::fromJSON (*camera_it), Scenes::CCamera::fromJSON (*camera_it),
WallpaperEngine::Core::aToColorf(ambientcolor), WallpaperEngine::Core::aToColorf(ambientcolor),
bloom, bloom,
bloomstrength, bloomstrength,
bloomthreshold, bloomthreshold,
camerafade, camerafade,
cameraparallax, cameraparallax,
cameraparallaxamount, cameraparallaxamount,
cameraparallaxdelay, cameraparallaxdelay,
cameraparallaxmouseinfluence, cameraparallaxmouseinfluence,
camerapreview, camerapreview,
camerashake, camerashake,
camerashakeamplitude, camerashakeamplitude,
camerashakeroughness, camerashakeroughness,
camerashakespeed, camerashakespeed,
clearcolor, clearcolor,
Scenes::CProjection::fromJSON (*orthogonalprojection_it), Scenes::CProjection::fromJSON (*orthogonalprojection_it),
WallpaperEngine::Core::aToColorf(skylightcolor) WallpaperEngine::Core::aToColorf(skylightcolor)
); );
for (const auto& cur : *objects_it) for (const auto& cur : *objects_it)

View File

@ -45,26 +45,26 @@ namespace WallpaperEngine::Core
friend class CWallpaper; friend class CWallpaper;
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,
CUserSettingFloat* bloomStrength, CUserSettingFloat* bloomStrength,
CUserSettingFloat* bloomThreshold, CUserSettingFloat* bloomThreshold,
bool cameraFade, bool cameraFade,
bool cameraParallax, bool cameraParallax,
double cameraParallaxAmount, double cameraParallaxAmount,
double cameraParallaxDelay, double cameraParallaxDelay,
double cameraParallaxMouseInfluence, double cameraParallaxMouseInfluence,
bool cameraPreview, bool cameraPreview,
bool cameraShake, bool cameraShake,
double cameraShakeAmplitude, double cameraShakeAmplitude,
double cameraShakeRoughness, double cameraShakeRoughness,
double cameraShakeSpeed, double cameraShakeSpeed,
CUserSettingVector3* clearColor, CUserSettingVector3* clearColor,
Scenes::CProjection* orthogonalProjection, Scenes::CProjection* orthogonalProjection,
glm::vec3 skylightColor glm::vec3 skylightColor
); );
static const std::string Type; static const std::string Type;

View File

@ -5,8 +5,8 @@
using namespace WallpaperEngine::Core; using namespace WallpaperEngine::Core;
CVideo::CVideo (std::string filename, CProject& project) : CVideo::CVideo (std::string filename, CProject& project) :
CWallpaper (Type, project), CWallpaper (Type, project),
m_filename (std::move(filename)) m_filename (std::move(filename))
{ {
} }

View File

@ -5,10 +5,10 @@
extern "C" extern "C"
{ {
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
#include <libavutil/imgutils.h> #include <libavutil/imgutils.h>
#include <libswscale/swscale.h> #include <libswscale/swscale.h>
} }
namespace WallpaperEngine::Core namespace WallpaperEngine::Core

View File

@ -6,7 +6,7 @@ using namespace WallpaperEngine::Core;
CWallpaper::CWallpaper (std::string type, CProject& project) : CWallpaper::CWallpaper (std::string type, CProject& project) :
m_type (std::move(type)), m_type (std::move(type)),
m_project (project) m_project (project)
{ {
} }

View File

@ -21,12 +21,12 @@ using namespace WallpaperEngine::Core::Objects;
using namespace WallpaperEngine::Core::UserSettings; using namespace WallpaperEngine::Core::UserSettings;
CEffect::CEffect ( CEffect::CEffect (
std::string name, std::string name,
std::string description, std::string description,
std::string group, std::string group,
std::string preview, std::string preview,
Core::CObject* object, CObject* object,
CUserSettingBoolean* visible): CUserSettingBoolean* visible):
m_name (std::move(name)), m_name (std::move(name)),
m_description (std::move(description)), m_description (std::move(description)),
m_group (std::move(group)), m_group (std::move(group)),
@ -36,7 +36,7 @@ CEffect::CEffect (
{ {
} }
CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, Core::CObject* object, CContainer* container) CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, 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");

View File

@ -23,6 +23,9 @@ namespace WallpaperEngine::Core::Objects
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
using namespace WallpaperEngine::Core::UserSettings; using namespace WallpaperEngine::Core::UserSettings;
/**
* Represents an effect applied to background objects
*/
class CEffect class CEffect
{ {
public: public:
@ -31,17 +34,35 @@ namespace WallpaperEngine::Core::Objects
std::string description, std::string description,
std::string group, std::string group,
std::string preview, std::string preview,
Core::CObject* object, CObject* object,
CUserSettingBoolean* visible CUserSettingBoolean* visible
); );
static CEffect* fromJSON (json data, CUserSettingBoolean* visible, Core::CObject* object, CContainer* container); static CEffect* fromJSON (json data, UserSettings::CUserSettingBoolean* visible, CObject* object, CContainer* container);
const std::vector<std::string>& getDependencies () const;
const std::vector<Images::CMaterial*>& getMaterials () const;
const std::vector<Effects::CFBO*>& getFbos () const;
bool isVisible () const;
/**
* @return List of dependencies for the effect to work
*/
[[nodiscard]] const std::vector<std::string>& getDependencies () const;
/**
* @return List of materials the effect applies
*/
[[nodiscard]] const std::vector<Images::CMaterial*>& getMaterials () const;
/**
* @return The list of FBOs to be used for this effect
*/
[[nodiscard]] const std::vector<Effects::CFBO*>& getFbos () const;
/**
* @return If the effect is visible or not
*/
[[nodiscard]] bool isVisible () const;
/**
* Searches the FBOs list for the given FBO
*
* @param name The FBO to search for
*
* @return
*/
Effects::CFBO* findFBO (const std::string& name); Effects::CFBO* findFBO (const std::string& name);
protected: protected:
static void constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPass* pass); static void constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPass* pass);
@ -55,15 +76,24 @@ namespace WallpaperEngine::Core::Objects
void insertFBO (Effects::CFBO* fbo); void insertFBO (Effects::CFBO* fbo);
private: private:
/** Effect's name */
std::string m_name; std::string m_name;
/** Effect's description used in the UI */
std::string m_description; std::string m_description;
/** Effect's group used in the UI */
std::string m_group; std::string m_group;
/** A project that previews the given effect, used in the UI */
std::string m_preview; std::string m_preview;
Core::CObject* m_object; /** The object the effect applies to */
CUserSettingBoolean* m_visible; CObject* m_object;
/** If the effect is visible or not */
UserSettings::CUserSettingBoolean* m_visible;
/** List of dependencies for the effect */
std::vector<std::string> m_dependencies; std::vector<std::string> m_dependencies;
/** List of materials the effect applies */
std::vector<Images::CMaterial*> m_materials; std::vector<Images::CMaterial*> m_materials;
/** List of FBOs required for this effect */
std::vector<Effects::CFBO*> m_fbos; std::vector<Effects::CFBO*> m_fbos;
}; };
} }

View File

@ -23,7 +23,7 @@ CImage::CImage (
const glm::vec3& angles, const glm::vec3& angles,
const glm::vec2& size, const glm::vec2& size,
std::string alignment, std::string alignment,
CUserSettingVector3* color, CUserSettingVector3* color,
CUserSettingFloat* alpha, CUserSettingFloat* alpha,
float brightness, float brightness,
uint32_t colorBlendMode, uint32_t colorBlendMode,

View File

@ -22,60 +22,80 @@ namespace WallpaperEngine::Core::Objects
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
using namespace WallpaperEngine::Core::UserSettings; using namespace WallpaperEngine::Core::UserSettings;
/**
* Represents an image in a background
*/
class CImage : public CObject class CImage : public CObject
{ {
friend class CObject; friend class CObject;
public: public:
static CObject* fromJSON ( static CObject* fromJSON (
CScene* scene, CScene* scene, json data, CContainer* container, CUserSettingBoolean* visible, uint32_t id,
json data, std::string name, CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles
CContainer* container,
CUserSettingBoolean* visible,
uint32_t id,
std::string name,
CUserSettingVector3* origin,
CUserSettingVector3* scale,
const glm::vec3& angles
); );
const Images::CMaterial* getMaterial () const; /**
const glm::vec2& getSize () const; * @return The base material to use for the image
const std::string& getAlignment () const; */
float getAlpha () const; [[nodiscard]] const Images::CMaterial* getMaterial () const;
glm::vec3 getColor () const; /**
float getBrightness () const; * @return The size of the image
uint32_t getColorBlendMode () const; */
const glm::vec2& getParallaxDepth () const; [[nodiscard]] const glm::vec2& getSize () const;
/**
* @return The type of alignment to use for image positioning
*/
[[nodiscard]] const std::string& getAlignment () const;
/**
* @return The alpha value for the image's rendering
*/
[[nodiscard]] float getAlpha () const;
/**
* @return The color to use for the image
*/
[[nodiscard]] glm::vec3 getColor () const;
/**
* @return The brightness to use for the image
*/
[[nodiscard]] float getBrightness () const;
/**
* @return The color blending mode to be used, special value for shaders
*/
[[nodiscard]] uint32_t getColorBlendMode () const;
/**
* @return Parallax depth of the image
*/
[[nodiscard]] const glm::vec2& getParallaxDepth () const;
protected: protected:
CImage ( CImage (
CScene* scene, CScene* scene, Images::CMaterial* material, CUserSettingBoolean* visible, uint32_t id, std::string name,
Images::CMaterial* material, CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles, const glm::vec2& size,
CUserSettingBoolean* visible, std::string alignment, CUserSettingVector3* color, CUserSettingFloat* alpha, float brightness,
uint32_t id, uint32_t colorBlendMode, const glm::vec2& parallaxDepth
std::string name,
CUserSettingVector3* origin,
CUserSettingVector3* scale,
const glm::vec3& angles,
const glm::vec2& size,
std::string alignment,
CUserSettingVector3* color,
CUserSettingFloat* alpha,
float brightness,
uint32_t colorBlendMode,
const glm::vec2& parallaxDepth
); );
/**
* Type value used to differentiate the different types of objects in a background
*/
static const std::string Type; static const std::string Type;
private: private:
/** The image's size */
glm::vec2 m_size; glm::vec2 m_size;
/** Parallax depth */
const glm::vec2 m_parallaxDepth; const glm::vec2 m_parallaxDepth;
/** Base material for the image */
Images::CMaterial* m_material; Images::CMaterial* m_material;
/** What type of alignment to use for the image's position */
std::string m_alignment; std::string m_alignment;
/** The alpha value for the image */
CUserSettingFloat* m_alpha; CUserSettingFloat* m_alpha;
/** The brightness for the image */
float m_brightness; float m_brightness;
/** The color to use for the image */
CUserSettingVector3* m_color; CUserSettingVector3* m_color;
/** The color blending mode used for the image, special value for shaders */
uint32_t m_colorBlendMode; uint32_t m_colorBlendMode;
}; };
} }

View File

@ -46,17 +46,17 @@ CParticle* CParticle::fromFile (
} }
CParticle::CParticle ( CParticle::CParticle (
CScene* scene, CScene* scene,
uint32_t starttime, uint32_t starttime,
uint32_t maxcount, uint32_t maxcount,
CUserSettingBoolean* visible, CUserSettingBoolean* visible,
uint32_t id, uint32_t id,
std::string name, std::string name,
CUserSettingVector3* origin, CUserSettingVector3* origin,
CUserSettingVector3* scale): CUserSettingVector3* scale):
CObject (scene, visible, id, std::move(name), Type, origin, scale, glm::vec3 ()), CObject (scene, visible, id, std::move(name), Type, origin, scale, glm::vec3 ()),
m_starttime (starttime), m_starttime (starttime),
m_maxcount (maxcount) m_maxcount (maxcount)
{ {
} }

View File

@ -11,25 +11,37 @@ namespace WallpaperEngine::Core::Objects
{ {
using json = nlohmann::json; using json = nlohmann::json;
/**
* Represents a particle system in the background
*/
class CParticle : public CObject class CParticle : public CObject
{ {
friend class CObject; friend class CObject;
public: public:
static CParticle* fromFile ( static CParticle* fromFile (
CScene* scene, CScene* scene,
const std::string& filename, const std::string& filename,
CContainer* container, CContainer* container,
CUserSettingBoolean* visible, CUserSettingBoolean* visible,
uint32_t id, uint32_t id,
std::string name, std::string name,
CUserSettingVector3* origin, CUserSettingVector3* origin,
CUserSettingVector3* scale CUserSettingVector3* scale
); );
const std::vector<Particles::CEmitter*>& getEmitters () const; /**
const std::vector<Particles::CControlPoint*>& getControlPoints () const; * @return The list of emitters for the particle system
const std::vector<Particles::CInitializer*>& getInitializers () const; */
[[nodiscard]] const std::vector<Particles::CEmitter*>& getEmitters () const;
/**
* @return The list of control points for the particle system
*/
[[nodiscard]] const std::vector<Particles::CControlPoint*>& getControlPoints () const;
/**
* @return The list of initializers for the particle system
*/
[[nodiscard]] const std::vector<Particles::CInitializer*>& getInitializers () const;
protected: protected:
CParticle ( CParticle (
@ -42,16 +54,35 @@ namespace WallpaperEngine::Core::Objects
CUserSettingVector3* origin, CUserSettingVector3* origin,
CUserSettingVector3* scale CUserSettingVector3* scale
); );
/**
* @param controlpoint The control point to add to the particle system
*/
void insertControlPoint (Particles::CControlPoint* controlpoint); void insertControlPoint (Particles::CControlPoint* controlpoint);
/**
* @param emitter The emitter to add to the particle system
*/
void insertEmitter (Particles::CEmitter* emitter); void insertEmitter (Particles::CEmitter* emitter);
/**
* @param initializer The initializer to add to the particle system
*/
void insertInitializer (Particles::CInitializer* initializer); void insertInitializer (Particles::CInitializer* initializer);
/**
* Type value used to differentiate the different types of objects in a background
*/
static const std::string Type; static const std::string Type;
private: private:
/** The time at which the particle system should start emitting */
uint32_t m_starttime; uint32_t m_starttime;
/** Maximum number of particles at the same time */
uint32_t m_maxcount; uint32_t m_maxcount;
/** List of control points */
std::vector<Particles::CControlPoint*> m_controlpoints; std::vector<Particles::CControlPoint*> m_controlpoints;
/** List of emitters */
std::vector<Particles::CEmitter*> m_emitters; std::vector<Particles::CEmitter*> m_emitters;
/** List of initializers */
std::vector<Particles::CInitializer*> m_initializers; std::vector<Particles::CInitializer*> m_initializers;
}; };
} }

View File

@ -20,14 +20,14 @@ CSound::CSound (
} }
WallpaperEngine::Core::CObject* CSound::fromJSON ( WallpaperEngine::Core::CObject* CSound::fromJSON (
CScene* scene, CScene* scene,
json data, json data,
CUserSettingBoolean* visible, CUserSettingBoolean* visible,
uint32_t id, uint32_t id,
const std::string& name, const std::string& name,
CUserSettingVector3* origin, CUserSettingVector3* origin,
CUserSettingVector3* scale, CUserSettingVector3* scale,
const glm::vec3& angles) const glm::vec3& angles)
{ {
bool repeat = false; bool repeat = false;
// TODO: PARSE AUDIO VOLUME // TODO: PARSE AUDIO VOLUME

View File

@ -9,6 +9,9 @@ namespace WallpaperEngine::Core::Objects
using json = nlohmann::json; using json = nlohmann::json;
using namespace WallpaperEngine::Core::UserSettings; using namespace WallpaperEngine::Core::UserSettings;
/**
* Represents a sound played while the background is working
*/
class CSound : public CObject class CSound : public CObject
{ {
friend class CObject; friend class CObject;
@ -25,9 +28,14 @@ namespace WallpaperEngine::Core::Objects
const glm::vec3& angles const glm::vec3& angles
); );
void insertSound (const std::string& filename); /**
const std::vector<std::string>& getSounds () const; * @return The list of sounds to play
bool isRepeat () const; */
[[nodiscard]] const std::vector<std::string>& getSounds () const;
/**
* @return If the sound should repeat or not
*/
[[nodiscard]] bool isRepeat () const;
protected: protected:
CSound ( CSound (
@ -41,9 +49,20 @@ namespace WallpaperEngine::Core::Objects
bool repeat bool repeat
); );
/**
* @param filename The sound to add
*/
void insertSound (const std::string& filename);
/**
* Type value used to differentiate the different types of objects in a background
*/
static const std::string Type; static const std::string Type;
private: private:
/** If the sounds should repeat or not */
bool m_repeat; bool m_repeat;
/** The list of sounds to play */
std::vector<std::string> m_sounds; std::vector<std::string> m_sounds;
}; };
} }

View File

@ -8,18 +8,37 @@ namespace WallpaperEngine::Core::Objects::Effects
{ {
using json = nlohmann::json; using json = nlohmann::json;
/**
* Material's bind information, describes for passes what textures to bind
* in what positions for shaders. Used to override the textures specified inside
* the object's passes
*/
class CBind class CBind
{ {
public: public:
/**
* Parses bind information off the given json data
*
* @param data
* @return
*/
static CBind* fromJSON (json data); static CBind* fromJSON (json data);
CBind (std::string name, uint32_t index); CBind (std::string name, uint32_t index);
const std::string& getName () const; /**
const uint32_t& getIndex () const; * @return The texture name, previous to use the one already specified by the object's passes
*/
[[nodiscard]] const std::string& getName () const;
/**
* @return The texture index to replace
*/
[[nodiscard]] const uint32_t& getIndex () const;
private: private:
/** The texture's name */
std::string m_name; std::string m_name;
/** The texture index to replace */
uint32_t m_index; uint32_t m_index;
}; };
} }

View File

@ -1,14 +1,19 @@
#pragma once #pragma once
#include <string>
#include "WallpaperEngine/Core/Core.h" #include "WallpaperEngine/Core/Core.h"
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <string>
namespace WallpaperEngine::Core::Objects::Effects namespace WallpaperEngine::Core::Objects::Effects
{ {
using json = nlohmann::json; using json = nlohmann::json;
/**
* FBO = Frame Buffer Object
*
* Represents a framebuffer object used in objects with multiple effects or render passes
*/
class CFBO class CFBO
{ {
public: public:
@ -16,13 +21,25 @@ namespace WallpaperEngine::Core::Objects::Effects
static CFBO* fromJSON (json data); static CFBO* fromJSON (json data);
const std::string& getName () const; /**
const float& getScale () const; * @return The FBO name used to identify it in the background's files
const std::string& getFormat () const; */
[[nodiscard]] const std::string& getName () const;
/**
* @return The scale factor of the FBO
*/
[[nodiscard]] const float& getScale () const;
/**
* @return The FBO's format for the render
*/
[[nodiscard]] const std::string& getFormat () const;
private: private:
/** The name of the FBO */
std::string m_name; std::string m_name;
/** The scale factor of the FBO */
float m_scale; float m_scale;
/** The FBO's format for the render */
std::string m_format; std::string m_format;
}; };
} }

View File

@ -4,6 +4,9 @@
namespace WallpaperEngine::Core::Objects::Effects::Constants namespace WallpaperEngine::Core::Objects::Effects::Constants
{ {
/**
* Shader constants base class
*/
class CShaderConstant class CShaderConstant
{ {
public: public:
@ -13,7 +16,11 @@ namespace WallpaperEngine::Core::Objects::Effects::Constants
template<class T> T* as () { assert (is <T> ()); return (T*) this; } template<class T> T* as () { assert (is <T> ()); return (T*) this; }
template<class T> bool is () { return this->m_type == T::Type; } template<class T> bool is () { return this->m_type == T::Type; }
const std::string& getType () const;
/**
* @return The type name of this constant
*/
[[nodiscard]] const std::string& getType () const;
private: private:
std::string m_type; std::string m_type;

View File

@ -2,7 +2,6 @@
using namespace WallpaperEngine::Core::Objects::Effects::Constants; using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstantFloat::CShaderConstantFloat (float value) : CShaderConstantFloat::CShaderConstantFloat (float value) :
CShaderConstant (Type), CShaderConstant (Type),
m_value (value) m_value (value)

View File

@ -6,15 +6,25 @@
namespace WallpaperEngine::Core::Objects::Effects::Constants namespace WallpaperEngine::Core::Objects::Effects::Constants
{ {
/**
* Shader constant of type float
*/
class CShaderConstantFloat : public CShaderConstant class CShaderConstantFloat : public CShaderConstant
{ {
public: public:
explicit CShaderConstantFloat (float value); explicit CShaderConstantFloat (float value);
/**
* @return A pointer to the actual value of the constant
*/
float* getValue (); float* getValue ();
/**
* Type string indicator
*/
static const std::string Type; static const std::string Type;
protected: protected:
/** The constant's value */
float m_value; float m_value;
}; };
} }

View File

@ -2,7 +2,6 @@
using namespace WallpaperEngine::Core::Objects::Effects::Constants; using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstantInteger::CShaderConstantInteger (int32_t value) : CShaderConstantInteger::CShaderConstantInteger (int32_t value) :
CShaderConstant (Type), CShaderConstant (Type),
m_value (value) m_value (value)

View File

@ -6,15 +6,25 @@
namespace WallpaperEngine::Core::Objects::Effects::Constants namespace WallpaperEngine::Core::Objects::Effects::Constants
{ {
/**
* Shader constant of type integer
*/
class CShaderConstantInteger : public CShaderConstant class CShaderConstantInteger : public CShaderConstant
{ {
public: public:
explicit CShaderConstantInteger (int32_t value); explicit CShaderConstantInteger (int32_t value);
/**
* @return A pointer to the actual value of the constant
*/
int32_t* getValue (); int32_t* getValue ();
/**
* Type string indicator
*/
static const std::string Type; static const std::string Type;
protected: protected:
/** The constant's value */
int32_t m_value; int32_t m_value;
}; };
} }

View File

@ -8,15 +8,25 @@
namespace WallpaperEngine::Core::Objects::Effects::Constants namespace WallpaperEngine::Core::Objects::Effects::Constants
{ {
/**
* Shader constant of vector2 type
*/
class CShaderConstantVector2 : public CShaderConstant class CShaderConstantVector2 : public CShaderConstant
{ {
public: public:
explicit CShaderConstantVector2 (glm::vec2 value); explicit CShaderConstantVector2 (glm::vec2 value);
/**
* @return A pointer to the actual value of the constant
*/
glm::vec2* getValue (); glm::vec2* getValue ();
/**
* Type string indicator
*/
static const std::string Type; static const std::string Type;
protected: protected:
/** The constant's value */
glm::vec2 m_value; glm::vec2 m_value;
}; };
} }

View File

@ -7,15 +7,25 @@
namespace WallpaperEngine::Core::Objects::Effects::Constants namespace WallpaperEngine::Core::Objects::Effects::Constants
{ {
/**
* Shader constant of vector3 type
*/
class CShaderConstantVector3 : public CShaderConstant class CShaderConstantVector3 : public CShaderConstant
{ {
public: public:
explicit CShaderConstantVector3 (glm::vec3 value); explicit CShaderConstantVector3 (glm::vec3 value);
/**
* @return A pointer to the actual value of the constant
*/
glm::vec3* getValue (); glm::vec3* getValue ();
/**
* Type string indicator
*/
static const std::string Type; static const std::string Type;
protected: protected:
/** The constant's value */
glm::vec3 m_value; glm::vec3 m_value;
}; };
} }

View File

@ -7,15 +7,25 @@
namespace WallpaperEngine::Core::Objects::Effects::Constants namespace WallpaperEngine::Core::Objects::Effects::Constants
{ {
/**
* Shader constant of vector4 type
*/
class CShaderConstantVector4 : public CShaderConstant class CShaderConstantVector4 : public CShaderConstant
{ {
public: public:
CShaderConstantVector4 (glm::vec4 value); explicit CShaderConstantVector4 (glm::vec4 value);
/**
* @return A pointer to the actual value of the constant
*/
glm::vec4* getValue (); glm::vec4* getValue ();
/**
* Type string indicator
*/
static const std::string Type; static const std::string Type;
protected: protected:
/** The constant's value */
glm::vec4 m_value; glm::vec4 m_value;
}; };
} }

View File

@ -11,30 +11,64 @@ namespace WallpaperEngine::Core::Objects::Images
using json = nlohmann::json; using json = nlohmann::json;
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
/**
* Represents a material in use in the background
*/
class CMaterial class CMaterial
{ {
public: public:
static CMaterial* fromFile (const std::string& filename, CContainer* container); static CMaterial* fromFile (const std::string& filename, Assets::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, CContainer* container); static CMaterial* fromFile (const std::string& filename, const std::string& target, Assets::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); /**
* @param pass The rendering pass to add to the material
*/
void insertPass (Materials::CPass* pass);
/**
* @param bind Texture bind override for the material
*/
void insertTextureBind (Effects::CBind* bind); void insertTextureBind (Effects::CBind* bind);
const std::vector <Materials::CPass*>& getPasses () const; /**
const std::map <int, Effects::CBind*>& getTextureBinds () const; * @return All the rendering passes that happen for this material
const std::string& getTarget () const; */
bool hasTarget () const; [[nodiscard]] const std::vector <Materials::CPass*>& getPasses () const;
const std::string& getName () const; /**
* @return The textures that have to be bound while rendering the material.
* These act as an override of the textures specified by the parent effect
*/
[[nodiscard]] const std::map <int, Effects::CBind*>& getTextureBinds () const;
/**
* @return The materials destination (fbo) if required
*/
[[nodiscard]] const std::string& getTarget () const;
/**
* @return Indicates if this material has a specific destination (fbo) while rendering
*/
[[nodiscard]] bool hasTarget () const;
/**
* @return The name of the material
*/
[[nodiscard]] const std::string& getName () const;
protected: protected:
explicit CMaterial (std::string name); explicit CMaterial (std::string name);
/**
* @param target The new target while rendering this material
*/
void setTarget (const std::string& target); void setTarget (const std::string& target);
private: private:
/** All the shader passes required to render this material */
std::vector <Materials::CPass*> m_passes; std::vector <Materials::CPass*> m_passes;
/** List of texture bind overrides to use for this material */
std::map <int, Effects::CBind*> m_textureBindings; std::map <int, Effects::CBind*> m_textureBindings;
/** The FBO target to render to (if any) */
std::string m_target; std::string m_target;
/** The material's name */
std::string m_name; std::string m_name;
}; };
} }

View File

@ -43,7 +43,7 @@ CPass* CPass::fromJSON (json data)
if (textures_it != data.end ()) if (textures_it != data.end ())
for (const auto& cur : (*textures_it)) for (const auto& cur : (*textures_it))
pass->insertTexture (cur.is_null () ? "" : cur); pass->insertTexture (cur.is_null () ? "" : cur);
if (combos_it != data.end ()) if (combos_it != data.end ())
{ {

View File

@ -13,40 +13,101 @@ namespace WallpaperEngine::Core::Objects::Images::Materials
{ {
using json = nlohmann::json; using json = nlohmann::json;
/**
* Represents a shader pass of an object
*/
class CPass class CPass
{ {
friend class Core::Objects::CEffect; friend class WallpaperEngine::Core::Objects::CEffect;
public: public:
static CPass* fromJSON (json data); static CPass* fromJSON (json data);
const std::vector<std::string>& getTextures () const; /**
const std::map<std::string, Effects::Constants::CShaderConstant*>& getConstants () const; * @return The list of textures to bind while rendering
*/
std::map<std::string, int>* getCombos (); [[nodiscard]] const std::vector<std::string>& getTextures () const;
const std::string& getShader () const; /**
const std::string& getBlendingMode () const; * @return Shader constants that alter how the shader should behave
const std::string& getCullingMode () const; */
const std::string& getDepthTest () const; [[nodiscard]] const std::map<std::string, Effects::Constants::CShaderConstant*>& getConstants () const;
const std::string& getDepthWrite () const; /**
* @return Shader combos that alter how the shader should behave
*/
[[nodiscard]] std::map<std::string, int>* getCombos ();
/**
* @return Shader to be used while rendering the pass
*/
[[nodiscard]] const std::string& getShader () const;
/**
* @return The blending mode to use while rendering
*/
[[nodiscard]] const std::string& getBlendingMode () const;
/**
* @return The culling mode to use while rendering
*/
[[nodiscard]] const std::string& getCullingMode () const;
/**
* @return If depth testing has to happen while rendering
*/
[[nodiscard]] const std::string& getDepthTest () const;
/**
* @return If depth write has to happen while rendering
*/
[[nodiscard]] const std::string& getDepthWrite () const;
/**
* @param mode The new blending mode to use
*/
void setBlendingMode (const std::string& mode); void setBlendingMode (const std::string& mode);
/**
* Add a shader combo value to the list
*
* @param name The combo name
* @param value It's value
*/
void insertCombo (const std::string& name, int value); void insertCombo (const std::string& name, int value);
/**
* Adds a shader constant to the list
*
* @param name The constant's name
* @param constant It's value
*/
void insertConstant (const std::string& name, Effects::Constants::CShaderConstant* constant); void insertConstant (const std::string& name, Effects::Constants::CShaderConstant* constant);
protected: protected:
CPass (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite, std::string shader); CPass (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite, std::string shader);
/**
* Adds a new texture to the list of textures to bind while rendering
*
* @param texture
*/
void insertTexture (const std::string& texture); void insertTexture (const std::string& texture);
/**
* Updates a texture in the specified index for binding while rendering
*
* @param index
* @param texture
*/
void setTexture (int index, const std::string& texture); void setTexture (int index, const std::string& texture);
private: private:
// TODO: CREATE ENUMERATIONS FOR THESE INSTEAD OF USING STRING VALUES!
/** The blending mode to use */
std::string m_blending; std::string m_blending;
/** The culling mode to use */
std::string m_cullmode; std::string m_cullmode;
/** If depthtesting has to happen while drawing */
std::string m_depthtest; std::string m_depthtest;
/** If depthwrite has to happen while drawing */
std::string m_depthwrite; std::string m_depthwrite;
/** The shader to use */
std::string m_shader; std::string m_shader;
/** The list of textures to use */
std::vector<std::string> m_textures; std::vector<std::string> m_textures;
/** Different combo settings for shader input */
std::map<std::string, int> m_combos; std::map<std::string, int> m_combos;
/** Shader constant values to use for the shaders */
std::map<std::string, Core::Objects::Effects::Constants::CShaderConstant*> m_constants; std::map<std::string, Core::Objects::Effects::Constants::CShaderConstant*> m_constants;
}; };
} }

View File

@ -37,7 +37,7 @@ void CControlPoint::setFlags (uint32_t flags)
} }
uint32_t CControlPoint::getId () const uint32_t CControlPoint::getId () const
{ {
return this->m_id; return this->m_id;
} }
const glm::vec3& CControlPoint::getOffset () const const glm::vec3& CControlPoint::getOffset () const

View File

@ -6,22 +6,45 @@ namespace WallpaperEngine::Core::Objects::Particles
{ {
using json = nlohmann::json; using json = nlohmann::json;
/**
* Control point for particles
*/
class CControlPoint class CControlPoint
{ {
public: public:
static CControlPoint* fromJSON (json data); static CControlPoint* fromJSON (json data);
uint32_t getId () const; /**
const glm::vec3& getOffset () const; * @return The id of the controlpoint used for ordering purposes
uint32_t getFlags () const; */
[[nodiscard]] uint32_t getId () const;
/**
* @return The offset from origin
*/
[[nodiscard]] const glm::vec3& getOffset () const;
/**
* @return Flags for the control point, controls how it should behave
*/
[[nodiscard]] uint32_t getFlags () const;
protected: protected:
explicit CControlPoint (uint32_t id, uint32_t flags = 0); explicit CControlPoint (uint32_t id, uint32_t flags = 0);
/**
* @param offset The new offset
*/
void setOffset (const glm::vec3& offset); void setOffset (const glm::vec3& offset);
/**
* @param flags The new flags
*/
void setFlags (uint32_t flags); void setFlags (uint32_t flags);
private: private:
/** ID used for ordering purposes */
uint32_t m_id; uint32_t m_id;
/** Flags that control how it behaves */
uint32_t m_flags; uint32_t m_flags;
/** The offset from starting position */
glm::vec3 m_offset; glm::vec3 m_offset;
}; };
} }

View File

@ -13,24 +13,24 @@ CEmitter* CEmitter::fromJSON (json data)
auto rate_it = jsonFindRequired (data, "rate", "Particle emitter must have a rate"); auto rate_it = jsonFindRequired (data, "rate", "Particle emitter must have a rate");
return new CEmitter ( return new CEmitter (
WallpaperEngine::Core::aToVector3 (*directions_it), WallpaperEngine::Core::aToVector3 (*directions_it),
*distancemax_it, *distancemax_it,
*distancemin_it, *distancemin_it,
(id_it == data.end () ? 0 : (uint32_t) (*id_it)), (id_it == data.end () ? 0 : (uint32_t) (*id_it)),
*name_it, *name_it,
WallpaperEngine::Core::aToVector3 (*origin_it), WallpaperEngine::Core::aToVector3 (*origin_it),
*rate_it *rate_it
); );
} }
CEmitter::CEmitter ( CEmitter::CEmitter (
const glm::vec3& directions, const glm::vec3& directions,
uint32_t distancemax, uint32_t distancemax,
uint32_t distancemin, uint32_t distancemin,
uint32_t id, uint32_t id,
std::string name, std::string name,
const glm::vec3& origin, const glm::vec3& origin,
double rate): double rate):
m_directions (directions), m_directions (directions),
m_distancemax (distancemax), m_distancemax (distancemax),
m_distancemin (distancemin), m_distancemin (distancemin),
@ -43,7 +43,7 @@ CEmitter::CEmitter (
uint32_t CEmitter::getId () const uint32_t CEmitter::getId () const
{ {
return this->m_id; return this->m_id;
} }
const std::string& CEmitter::getName () const const std::string& CEmitter::getName () const

View File

@ -6,35 +6,63 @@ namespace WallpaperEngine::Core::Objects::Particles
{ {
using json = nlohmann::json; using json = nlohmann::json;
/**
* Particle emitter, controls the area where the particles have to be created
*/
class CEmitter class CEmitter
{ {
public: public:
static CEmitter* fromJSON (json data); static CEmitter* fromJSON (json data);
uint32_t getId () const; /**
const std::string& getName () const; * @return The ID of the emitter
const uint32_t getDistanceMax () const; */
const uint32_t getDistanceMin () const; [[nodiscard]] uint32_t getId () const;
const glm::vec3& getDirections () const; /**
const glm::vec3& getOrigin () const; * @return The name of the emitter, indicates what type of emission to do
const double getRate () const; */
[[nodiscard]] const std::string& getName () const;
/**
* @return The maximum distance a particle can travel before being dead
*/
[[nodiscard]] const uint32_t getDistanceMax () const;
/**
* @return The minimum distance a particle can travel before being dead
*/
[[nodiscard]] const uint32_t getDistanceMin () const;
/**
* @return The direction a particle should move to
*/
[[nodiscard]] const glm::vec3& getDirections () const;
/**
* @return The center of the particle emission
*/
[[nodiscard]] const glm::vec3& getOrigin () const;
/**
* @return The rate of particle emission
*/
[[nodiscard]] const double getRate () const;
protected: protected:
CEmitter ( CEmitter (
const glm::vec3& directions, const glm::vec3& directions, uint32_t distancemax, uint32_t distancemin, uint32_t id, std::string name,
uint32_t distancemax, const glm::vec3& origin, double rate
uint32_t distancemin,
uint32_t id,
std::string name,
const glm::vec3& origin,
double rate
); );
private: private:
/** Direction the particles should move to */
glm::vec3 m_directions; glm::vec3 m_directions;
/** Maximum distance before the particle is dead */
uint32_t m_distancemax; uint32_t m_distancemax;
/** Minimum distance before the particle is dead */
uint32_t m_distancemin; uint32_t m_distancemin;
/** ID of the emitter */
uint32_t m_id; uint32_t m_id;
/** Name of the emitter, indicates the type of emitter */
std::string m_name; std::string m_name;
/** The center of the emitter */
glm::vec3 m_origin; glm::vec3 m_origin;
/** The rate of emission */
double m_rate; double m_rate;
}; };
} }

View File

@ -6,17 +6,31 @@ namespace WallpaperEngine::Core::Objects::Particles
{ {
using json = nlohmann::json; using json = nlohmann::json;
/**
* Initializer for particles, controls the different attributes a particle will have
* on emission
*/
class CInitializer class CInitializer
{ {
public: public:
static CInitializer* fromJSON (json data); static CInitializer* fromJSON (json data);
const std::string& getName () const; /**
uint32_t getId () const; * @return The name of the particle initializer, indicates what type of initialization to do
*/
[[nodiscard]] const std::string& getName () const;
/**
* @return The id of the initializer
*/
[[nodiscard]] uint32_t getId () const;
protected: protected:
CInitializer (uint32_t id, std::string name); CInitializer (uint32_t id, std::string name);
private: private:
/** ID for ordering purposes */
uint32_t m_id; uint32_t m_id;
/** The name of the initializer, indicates what type of initialization to do */
std::string m_name; std::string m_name;
}; };
} }

View File

@ -1,24 +1,36 @@
#pragma once #pragma once
#include "WallpaperEngine/Core/Objects/Particles/CInitializer.h"
#include "WallpaperEngine/Core/Core.h" #include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Core/Objects/Particles/CInitializer.h"
namespace WallpaperEngine::Core::Objects::Particles::Initializers namespace WallpaperEngine::Core::Objects::Particles::Initializers
{ {
class CAlphaRandom : CInitializer /**
{ * Initializer for particles that decides the base alpha for the particles
public: */
double getMinimum () const; class CAlphaRandom : CInitializer
double getMaximum () const; {
protected: public:
friend class CInitializer; /**
* @return The minimum alpha value to be used
*/
[[nodiscard]] double getMinimum () const;
/**
* @return The maximum alpha value to be used
*/
[[nodiscard]] double getMaximum () const;
static CAlphaRandom* fromJSON (json data, uint32_t id); protected:
friend class CInitializer;
CAlphaRandom (uint32_t id, double min, double max); static CAlphaRandom* fromJSON (json data, uint32_t id);
private:
double m_max; CAlphaRandom (uint32_t id, double min, double max);
double m_min;
}; private:
/** Maximum alpha */
double m_max;
/** Minimum alpha */
double m_min;
};
} }

View File

@ -1,24 +1,36 @@
#pragma once #pragma once
#include "WallpaperEngine/Core/Objects/Particles/CInitializer.h"
#include "WallpaperEngine/Core/Core.h" #include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Core/Objects/Particles/CInitializer.h"
namespace WallpaperEngine::Core::Objects::Particles::Initializers namespace WallpaperEngine::Core::Objects::Particles::Initializers
{ {
class CAngularVelocityRandom : CInitializer /**
{ * Initializer for particles that decides the base angular velocity for particles
public: */
const glm::vec3& getMinimum () const; class CAngularVelocityRandom : CInitializer
const glm::vec3& getMaximum () const; {
protected: public:
friend class CInitializer; /**
* @return Minimum angular velocity (direction * speed)
*/
[[nodiscard]] const glm::vec3& getMinimum () const;
/**
* @return Maximum angular velocity (direction * speed)
*/
[[nodiscard]] const glm::vec3& getMaximum () const;
static CAngularVelocityRandom* fromJSON (json data, uint32_t id); protected:
friend class CInitializer;
CAngularVelocityRandom (uint32_t id, glm::vec3 min, glm::vec3 max); static CAngularVelocityRandom* fromJSON (json data, uint32_t id);
private:
glm::vec3 m_max; CAngularVelocityRandom (uint32_t id, glm::vec3 min, glm::vec3 max);
glm::vec3 m_min;
}; private:
/** Maximum velocity (direction * speed) */
glm::vec3 m_max;
/** Minimum velocity (direction * speed) */
glm::vec3 m_min;
};
} }

View File

@ -6,19 +6,32 @@
namespace WallpaperEngine::Core::Objects::Particles::Initializers namespace WallpaperEngine::Core::Objects::Particles::Initializers
{ {
/**
* Initializer for particles that decides the base color
*/
class CColorRandom : CInitializer class CColorRandom : CInitializer
{ {
public: public:
const glm::ivec3& getMinimum () const; /**
const glm::ivec3& getMaximum () const; * @return The minimum color to use (RGB)
*/
[[nodiscard]] const glm::ivec3& getMinimum () const;
/**
* @return The maximum color to use (RGB)
*/
[[nodiscard]] const glm::ivec3& getMaximum () const;
protected: protected:
friend class CInitializer; friend class CInitializer;
static CColorRandom* fromJSON (json data, uint32_t id); static CColorRandom* fromJSON (json data, uint32_t id);
CColorRandom (uint32_t id, glm::ivec3 min, glm::ivec3 max); CColorRandom (uint32_t id, glm::ivec3 min, glm::ivec3 max);
private: private:
/** Maximum color */
glm::ivec3 m_max; glm::ivec3 m_max;
/** Minimum color */
glm::ivec3 m_min; glm::ivec3 m_min;
}; };
} }

View File

@ -12,9 +12,9 @@ CLifeTimeRandom* CLifeTimeRandom::fromJSON (json data, uint32_t id)
CLifeTimeRandom::CLifeTimeRandom (uint32_t id, uint32_t min, uint32_t max) : CLifeTimeRandom::CLifeTimeRandom (uint32_t id, uint32_t min, uint32_t max) :
CInitializer (id, "lifetimerandom"), CInitializer (id, "lifetimerandom"),
m_min (min), m_min (min),
m_max (max) m_max (max)
{ {
} }

View File

@ -6,19 +6,31 @@
namespace WallpaperEngine::Core::Objects::Particles::Initializers namespace WallpaperEngine::Core::Objects::Particles::Initializers
{ {
/**
* Initializer for particles that decides the lifetime of each particle on startup
*/
class CLifeTimeRandom : CInitializer class CLifeTimeRandom : CInitializer
{ {
public: public:
uint32_t getMinimum () const; /**
uint32_t getMaximum () const; * @return The minimum lifetime to be used
*/
[[nodiscard]] uint32_t getMinimum () const;
/**
* @return The maximum lifetime to be used
*/
[[nodiscard]] uint32_t getMaximum () const;
protected: protected:
friend class CInitializer; friend class CInitializer;
static CLifeTimeRandom* fromJSON (json data, uint32_t id); static CLifeTimeRandom* fromJSON (json data, uint32_t id);
CLifeTimeRandom (uint32_t id, uint32_t min, uint32_t max); CLifeTimeRandom (uint32_t id, uint32_t min, uint32_t max);
private: private:
/** Maximum lifetime */
uint32_t m_max; uint32_t m_max;
/** Minimum lifetime */
uint32_t m_min; uint32_t m_min;
}; };
} }

View File

@ -50,13 +50,13 @@ CRotationRandom::CRotationRandom (
double maxNumber, double maxNumber,
bool isMaximumVector bool isMaximumVector
) : ) :
CInitializer (id, "rotationrandom"), CInitializer (id, "rotationrandom"),
m_minVector (minVector), m_minVector (minVector),
m_maxVector (maxVector), m_maxVector (maxVector),
m_minNumber (minNumber), m_minNumber (minNumber),
m_maxNumber (maxNumber), m_maxNumber (maxNumber),
m_isMinimumVector (isMinimumVector), m_isMinimumVector (isMinimumVector),
m_isMaximumVector (isMaximumVector) m_isMaximumVector (isMaximumVector)
{ {
} }

View File

@ -6,18 +6,45 @@
namespace WallpaperEngine::Core::Objects::Particles::Initializers namespace WallpaperEngine::Core::Objects::Particles::Initializers
{ {
/**
* Initializer for particles that decides the base rotation for the particles
*/
class CRotationRandom : CInitializer class CRotationRandom : CInitializer
{ {
public: public:
glm::vec3 getMinimumVector () const; /**
glm::vec3 getMaximumVector () const; * @return The minimum rotation in vector format if available
double getMinimumNumber () const; */
double getMaximumNumber () const; [[nodiscard]] glm::vec3 getMinimumVector () const;
/**
* @return The maximum rotation in vector format if available
*/
[[nodiscard]] glm::vec3 getMaximumVector () const;
/**
* @return The minimum rotation in angle format if available
*/
[[nodiscard]] double getMinimumNumber () const;
/**
* @return The maximum rotation in angle format if available
*/
[[nodiscard]] double getMaximumNumber () const;
bool isMinimumVector () const; /**
bool isMinimumNumber () const; * @return Indicates if the minimum rotation is a vector
bool isMaximumVector () const; */
bool isMaximumNumber () const; [[nodiscard]] bool isMinimumVector () const;
/**
* @return Indicates if the minimum rotation is an angle
*/
[[nodiscard]] bool isMinimumNumber () const;
/**
* @return Indicates if the maximum rotation is a vector
*/
[[nodiscard]] bool isMaximumVector () const;
/**
* @return Indicates if the maximum rotation is an angle
*/
[[nodiscard]] bool isMaximumNumber () const;
protected: protected:
friend class CInitializer; friend class CInitializer;
@ -33,13 +60,20 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
double maxNumber, double maxNumber,
bool isMaximumVector bool isMaximumVector
); );
private:
glm::vec3 m_maxVector;
double m_maxNumber;
glm::vec3 m_minVector;
double m_minNumber;
private:
/** Maximum rotation vector */
glm::vec3 m_maxVector;
/** Maximum rotation angle */
double m_maxNumber;
/** Minimum rotation vector */
glm::vec3 m_minVector;
/** Minimum rotation angle */
double m_minNumber;
/** If minimum is a vector */
bool m_isMinimumVector; bool m_isMinimumVector;
/** If maximum is a vector */
bool m_isMaximumVector; bool m_isMaximumVector;
}; };
} }

View File

@ -11,9 +11,9 @@ CSizeRandom* CSizeRandom::fromJSON (json data, uint32_t id)
} }
CSizeRandom::CSizeRandom (uint32_t id, uint32_t min, uint32_t max) : CSizeRandom::CSizeRandom (uint32_t id, uint32_t min, uint32_t max) :
CInitializer (id, "sizerandom"), CInitializer (id, "sizerandom"),
m_min (min), m_min (min),
m_max (max) m_max (max)
{ {
} }

View File

@ -6,19 +6,32 @@
namespace WallpaperEngine::Core::Objects::Particles::Initializers namespace WallpaperEngine::Core::Objects::Particles::Initializers
{ {
/**
* Initializer for particles that decides the base size for the particles
*/
class CSizeRandom : CInitializer class CSizeRandom : CInitializer
{ {
public: public:
uint32_t getMinimum () const; /**
uint32_t getMaximum () const; * @return The minimum size to be used
*/
[[nodiscard]] uint32_t getMinimum () const;
/**
* @return The maximum size to be used
*/
[[nodiscard]] uint32_t getMaximum () const;
protected: protected:
friend class CInitializer; friend class CInitializer;
static CSizeRandom* fromJSON (json data, uint32_t id); static CSizeRandom* fromJSON (json data, uint32_t id);
CSizeRandom (uint32_t id, uint32_t min, uint32_t max); CSizeRandom (uint32_t id, uint32_t min, uint32_t max);
private: private:
/** Maximum size */
uint32_t m_max; uint32_t m_max;
/** Minimum size */
uint32_t m_min; uint32_t m_min;
}; };
} }

View File

@ -36,13 +36,13 @@ CTurbulentVelocityRandom* CTurbulentVelocityRandom::fromJSON (json data, uint32_
CTurbulentVelocityRandom::CTurbulentVelocityRandom (uint32_t id, CTurbulentVelocityRandom::CTurbulentVelocityRandom (uint32_t id,
double phasemax, double scale, double timescale, uint32_t speedmin, uint32_t speedmax) : double phasemax, double scale, double timescale, uint32_t speedmin, uint32_t speedmax) :
CInitializer (id, "turbulentvelocityrandom"), CInitializer (id, "turbulentvelocityrandom"),
m_phasemax (phasemax), m_phasemax (phasemax),
m_scale (scale), m_scale (scale),
m_timescale (timescale), m_timescale (timescale),
m_speedmin (speedmin), m_speedmin (speedmin),
m_speedmax (speedmax) m_speedmax (speedmax)
{ {
} }

View File

@ -6,13 +6,31 @@
namespace WallpaperEngine::Core::Objects::Particles::Initializers namespace WallpaperEngine::Core::Objects::Particles::Initializers
{ {
/**
* Initializer for particles that decides the turbulent velocity for the particles
*/
class CTurbulentVelocityRandom : CInitializer class CTurbulentVelocityRandom : CInitializer
{ {
public: public:
/**
* @return The phase to use
*/
double getPhaseMax (); double getPhaseMax ();
/**
* @return The scale to use
*/
double getScale (); double getScale ();
/**
* @return How time affects to the scale
*/
double getTimeScale (); double getTimeScale ();
/**
* @return The minimum speed
*/
uint32_t getMinimumSpeed (); uint32_t getMinimumSpeed ();
/**
* @return The maximum speed
*/
uint32_t getMaximumSpeed (); uint32_t getMaximumSpeed ();
protected: protected:
@ -21,12 +39,18 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
static CTurbulentVelocityRandom* fromJSON (json data, uint32_t id); static CTurbulentVelocityRandom* fromJSON (json data, uint32_t id);
CTurbulentVelocityRandom (uint32_t id, CTurbulentVelocityRandom (uint32_t id,
double phasemax, double scale, double timescale, uint32_t speedmin, uint32_t speedmax); double phasemax, double scale, double timescale, uint32_t speedmin, uint32_t speedmax);
private: private:
/** Phase */
double m_phasemax; double m_phasemax;
/** Scale */
double m_scale; double m_scale;
/** Time scale, how the time affects the scale */
double m_timescale; double m_timescale;
/** Minimum speed */
uint32_t m_speedmin; uint32_t m_speedmin;
/** Maximum speed */
uint32_t m_speedmax; uint32_t m_speedmax;
}; };
} }

View File

@ -8,17 +8,17 @@ CVelocityRandom* CVelocityRandom::fromJSON (json data, uint32_t id)
auto max_it = jsonFindRequired (data, "max", "Velocityrandom initializer must have a maximum value"); auto max_it = jsonFindRequired (data, "max", "Velocityrandom initializer must have a maximum value");
return new CVelocityRandom ( return new CVelocityRandom (
id, id,
WallpaperEngine::Core::aToVector3 (*min_it), WallpaperEngine::Core::aToVector3 (*min_it),
WallpaperEngine::Core::aToVector3 (*max_it) WallpaperEngine::Core::aToVector3 (*max_it)
); );
} }
CVelocityRandom::CVelocityRandom (uint32_t id, glm::vec3 min, glm::vec3 max) : CVelocityRandom::CVelocityRandom (uint32_t id, glm::vec3 min, glm::vec3 max) :
CInitializer (id, "velocityrandom"), CInitializer (id, "velocityrandom"),
m_min (min), m_min (min),
m_max (max) m_max (max)
{ {
} }

View File

@ -6,19 +6,32 @@
namespace WallpaperEngine::Core::Objects::Particles::Initializers namespace WallpaperEngine::Core::Objects::Particles::Initializers
{ {
/**
* Initializer for particles that decides the base velocity for the particles
*/
class CVelocityRandom : CInitializer class CVelocityRandom : CInitializer
{ {
public: public:
const glm::vec3& getMinimum () const; /**
const glm::vec3& getMaximum () const; * @return The minimum velocity (direction * speed)
*/
[[nodiscard]] const glm::vec3& getMinimum () const;
/**
* @return The maximum velocity (direction * speed)
*/
[[nodiscard]] const glm::vec3& getMaximum () const;
protected: protected:
friend class CInitializer; friend class CInitializer;
static CVelocityRandom* fromJSON (json data, uint32_t id); static CVelocityRandom* fromJSON (json data, uint32_t id);
CVelocityRandom (uint32_t id, glm::vec3 min, glm::vec3 max); CVelocityRandom (uint32_t id, glm::vec3 min, glm::vec3 max);
private: private:
/** Maximum velocity */
glm::vec3 m_max; glm::vec3 m_max;
/** Minimum velocity */
glm::vec3 m_min; glm::vec3 m_min;
}; };
} }

View File

@ -6,6 +6,12 @@ namespace WallpaperEngine::Core::Projects
{ {
using json = nlohmann::json; using json = nlohmann::json;
/**
* Represents a property in a background
*
* Properties are settings that alter how the background looks or works
* and are configurable by the user so they can customize it to their likings
*/
class CPropertyColor; class CPropertyColor;
class CProperty class CProperty
@ -18,17 +24,38 @@ namespace WallpaperEngine::Core::Projects
template<class T> bool is () { return this->m_type == T::Type; } template<class T> bool is () { return this->m_type == T::Type; }
virtual std::string dump () const = 0; /**
* @return Representation of what the property does and the default values
*/
[[nodiscard]] virtual std::string dump () const = 0;
/**
* Updates the value of the property with the one in the string
*
* @param value New value for the property
*/
virtual void update (const std::string& value) = 0; virtual void update (const std::string& value) = 0;
const std::string& getName () const; /**
const std::string& getType () const; * @return Name of the property
const std::string& getText () const; */
[[nodiscard]] const std::string& getName () const;
/**
* @return Type of the property
*/
[[nodiscard]] const std::string& getType () const;
/**
* @return Text of the property
*/
[[nodiscard]] const std::string& getText () const;
protected: protected:
CProperty (std::string name, std::string type, std::string text); CProperty (std::string name, std::string type, std::string text);
/** Type of property */
std::string m_type; std::string m_type;
/** Name of the property */
std::string m_name; std::string m_name;
/** Description of the property for the user */
std::string m_text; std::string m_text;
}; };
} }

View File

@ -6,13 +6,21 @@ namespace WallpaperEngine::Core::Projects
{ {
using json = nlohmann::json; using json = nlohmann::json;
/**
* Represents a boolean property
*/
class CPropertyBoolean : public CProperty class CPropertyBoolean : public CProperty
{ {
public: public:
static CPropertyBoolean* fromJSON (json data, const std::string& name); static CPropertyBoolean* fromJSON (json data, const std::string& name);
bool getValue () const; /**
std::string dump () const override; * @return The value of the property
*/
[[nodiscard]] bool getValue () const;
/** @inheritdoc */
[[nodiscard]] std::string dump () const override;
/** @inheritdoc */
void update (const std::string& value) override; void update (const std::string& value) override;
static const std::string Type; static const std::string Type;
@ -20,6 +28,7 @@ namespace WallpaperEngine::Core::Projects
private: private:
CPropertyBoolean (bool value, const std::string& name, const std::string& text); CPropertyBoolean (bool value, const std::string& name, const std::string& text);
/** Property's value */
bool m_value; bool m_value;
}; };
} }

View File

@ -8,13 +8,19 @@ namespace WallpaperEngine::Core::Projects
{ {
using json = nlohmann::json; using json = nlohmann::json;
/**
* Represents a color property
*/
class CPropertyColor : public CProperty class CPropertyColor : public CProperty
{ {
public: public:
static CPropertyColor* fromJSON (json data, const std::string& name); static CPropertyColor* fromJSON (json data, const std::string& name);
const glm::vec3& getValue () const; /**
std::string dump () const override; * @return The RGB color value in the 0-1 range
*/
[[nodiscard]] const glm::vec3& getValue () const;
[[nodiscard]] std::string dump () const override;
void update (const std::string& value) override; void update (const std::string& value) override;
static const std::string Type; static const std::string Type;

View File

@ -6,6 +6,9 @@ namespace WallpaperEngine::Core::Projects
{ {
using json = nlohmann::json; using json = nlohmann::json;
/**
* Represents different combo values
*/
class CPropertyComboValue class CPropertyComboValue
{ {
public: public:
@ -13,13 +16,23 @@ namespace WallpaperEngine::Core::Projects
std::string value; std::string value;
}; };
/**
* Represents a combo property
*
* Combos are properties that have different values available and only one can be selected at once
* this limits the user's possibilities, used for things like the amount of samples to use in audioprocessing
* backgrounds
*/
class CPropertyCombo : public CProperty class CPropertyCombo : public CProperty
{ {
public: public:
static CPropertyCombo* fromJSON (json data, const std::string& name); static CPropertyCombo* fromJSON (json data, const std::string& name);
const std::string& getValue () const; /**
std::string dump () const override; * @return The selected value
*/
[[nodiscard]] const std::string& getValue () const;
[[nodiscard]] std::string dump () const override;
void update (const std::string& value) override; void update (const std::string& value) override;
static const std::string Type; static const std::string Type;
@ -27,9 +40,17 @@ namespace WallpaperEngine::Core::Projects
private: private:
CPropertyCombo (const std::string& name, const std::string& text, std::string defaultValue); CPropertyCombo (const std::string& name, const std::string& text, std::string defaultValue);
/**
* Adds a combo value to the list of possible values
*
* @param label
* @param value
*/
void addValue (std::string label, std::string value); void addValue (std::string label, std::string value);
/** List of values available to select */
std::vector <CPropertyComboValue*> m_values; std::vector <CPropertyComboValue*> m_values;
/** The default value */
std::string m_defaultValue; std::string m_defaultValue;
}; };
} }

View File

@ -8,16 +8,31 @@ namespace WallpaperEngine::Core::Projects
{ {
using json = nlohmann::json; using json = nlohmann::json;
/**
* Represents a slider value with a minimum and maximum value
*/
class CPropertySlider : public CProperty class CPropertySlider : public CProperty
{ {
public: public:
static CPropertySlider* fromJSON (json data, const std::string& name); static CPropertySlider* fromJSON (json data, const std::string& name);
const double& getValue () const; /**
const double& getMinValue () const; * @return The slider's value
const double& getMaxValue () const; */
const double& getStep () const; [[nodiscard]] const double& getValue () const;
std::string dump () const override; /**
* @return The slider's minimum value
*/
[[nodiscard]] const double& getMinValue () const;
/**
* @return The slider's maximum value
*/
[[nodiscard]] const double& getMaxValue () const;
/**
* @return The slider's value increment steps, only really used in the UI
*/
[[nodiscard]] const double& getStep () const;
[[nodiscard]] std::string dump () const override;
void update (const std::string& value) override; void update (const std::string& value) override;
static const std::string Type; static const std::string Type;
@ -25,9 +40,13 @@ namespace WallpaperEngine::Core::Projects
private: private:
CPropertySlider (double value, const std::string& name, const std::string& text, double min, double max, double step); CPropertySlider (double value, const std::string& name, const std::string& text, double min, double max, double step);
/** Actual slider value */
double m_value; double m_value;
/** Minimum value */
double m_min; double m_min;
/** Maximum value */
double m_max; double m_max;
/** Increment steps for the slider in the UI */
double m_step; double m_step;
}; };
} }

View File

@ -6,11 +6,14 @@ namespace WallpaperEngine::Core::Projects
{ {
using json = nlohmann::json; using json = nlohmann::json;
/**
* Represents a text property
*/
class CPropertyText : public CProperty class CPropertyText : public CProperty
{ {
public: public:
static CPropertyText* fromJSON (json data, const std::string& name); static CPropertyText* fromJSON (json data, const std::string& name);
std::string dump () const override; [[nodiscard]] std::string dump () const override;
void update (const std::string& value) override; void update (const std::string& value) override;
static const std::string Type; static const std::string Type;

View File

@ -3,7 +3,7 @@
using namespace WallpaperEngine::Core::Scenes; using namespace WallpaperEngine::Core::Scenes;
CProjection::CProjection (uint32_t width, uint32_t height) : CProjection::CProjection (uint32_t width, uint32_t height) :
m_isAuto (false), m_isAuto (false),
m_width (width), m_width (width),
m_height (height) m_height (height)
{ {
@ -11,8 +11,8 @@ CProjection::CProjection (uint32_t width, uint32_t height) :
CProjection::CProjection (bool isAuto) : CProjection::CProjection (bool isAuto) :
m_isAuto (isAuto), m_isAuto (isAuto),
m_width (0), m_width (0),
m_height (0) m_height (0)
{ {
} }

View File

@ -24,8 +24,8 @@ CUserSettingFloat* CUserSettingFloat::fromJSON (nlohmann::json& data)
double defaultValue; double defaultValue;
std::string source; std::string source;
std::string expectedValue; std::string expectedValue;
bool hasCondition = false; bool hasCondition = false;
bool hasSource = false; bool hasSource = false;
if (data.is_object ()) if (data.is_object ())
{ {

View File

@ -1,98 +1,103 @@
#include "common.h" #include "common.h"
#include <iostream> #include <iostream>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/extensions/Xrandr.h>
#include <GL/glew.h> #include <GL/glew.h>
#include <GL/glx.h>
#include "CRenderContext.h" #include "CRenderContext.h"
#include "CVideo.h" #include "CVideo.h"
#include "CWallpaper.h"
using namespace WallpaperEngine::Render; namespace WallpaperEngine::Render
CRenderContext::CRenderContext (const COutput* output, CVideoDriver& driver, CInputContext& input, CWallpaperApplication& app) :
m_defaultWallpaper (nullptr),
m_output (output),
m_driver (driver),
m_app (app),
m_input (input),
m_textureCache (new CTextureCache (*this))
{ {
} CRenderContext::CRenderContext (
const Drivers::Output::COutput* output, Drivers::CVideoDriver& driver, Input::CInputContext& input,
void CRenderContext::render () CWallpaperApplication& app
{ ) :
bool firstFrame = true; m_defaultWallpaper (nullptr),
bool renderFrame = true; m_output (output),
m_driver (driver),
for (const auto& cur : this->m_output->getViewports ()) m_app (app),
m_input (input),
m_textureCache (new CTextureCache (*this))
{ {
#if !NDEBUG
std::string str = "Rendering to output " + cur.first;
glPushDebugGroup (GL_DEBUG_SOURCE_APPLICATION, 0, -1, str.c_str ());
#endif /* DEBUG */
// search the background in the viewport selection
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
// but videos should only be rendered once per group of viewports
firstFrame = false;
#if !NDEBUG
glPopDebugGroup ();
#endif /* DEBUG */
} }
// read the full texture into the image void CRenderContext::render ()
if (this->m_output->haveImageBuffer ()) {
glReadPixels ( bool firstFrame = true;
0, 0, this->m_output->getFullWidth (), this->m_output->getFullHeight (), bool renderFrame = true;
GL_BGRA, GL_UNSIGNED_BYTE,
this->m_output->getImageBuffer ()
);
// update the output with the given image for (const auto& cur : this->m_output->getViewports ())
this->m_output->updateRender (); {
// finally swap buffers #if !NDEBUG
this->m_driver.swapBuffers (); std::string str = "Rendering to output " + cur.first;
}
void CRenderContext::setDefaultWallpaper (CWallpaper* wallpaper) glPushDebugGroup (GL_DEBUG_SOURCE_APPLICATION, 0, -1, str.c_str ());
{ #endif /* DEBUG */
this->m_defaultWallpaper = wallpaper;
}
void CRenderContext::setWallpaper (const std::string& display, CWallpaper* wallpaper) // search the background in the viewport selection
{ auto ref = this->m_wallpapers.find (cur.first);
this->m_wallpapers.insert_or_assign (display, wallpaper);
}
CInputContext& CRenderContext::getInputContext () const // render the background
{ if (ref != this->m_wallpapers.end ())
return this->m_input; 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
// but videos should only be rendered once per group of viewports
firstFrame = false;
#if !NDEBUG
glPopDebugGroup ();
#endif /* DEBUG */
}
const CWallpaperApplication& CRenderContext::getApp () const // read the full texture into the image
{ if (this->m_output->haveImageBuffer ())
return this->m_app; glReadPixels (
} 0, 0, this->m_output->getFullWidth (), this->m_output->getFullHeight (), GL_BGRA, GL_UNSIGNED_BYTE,
this->m_output->getImageBuffer ()
);
const COutput* CRenderContext::getOutput () const // update the output with the given image
{ this->m_output->updateRender ();
return this->m_output; // finally swap buffers
} this->m_driver.swapBuffers ();
}
const ITexture* CRenderContext::resolveTexture (const std::string& name) void CRenderContext::setDefaultWallpaper (CWallpaper* wallpaper)
{ {
return this->m_textureCache->resolve (name); this->m_defaultWallpaper = wallpaper;
}
void CRenderContext::setWallpaper (const std::string& display, CWallpaper* wallpaper)
{
this->m_wallpapers.insert_or_assign (display, wallpaper);
}
Input::CInputContext& CRenderContext::getInputContext () const
{
return this->m_input;
}
const CWallpaperApplication& CRenderContext::getApp () const
{
return this->m_app;
}
const Drivers::CVideoDriver& CRenderContext::getDriver () const
{
return this->m_driver;
}
const Drivers::Output::COutput* CRenderContext::getOutput () const
{
return this->m_output;
}
const ITexture* CRenderContext::resolveTexture (const std::string& name)
{
return this->m_textureCache->resolve (name);
}
} }

View File

@ -4,60 +4,63 @@
#include <glm/vec4.hpp> #include <glm/vec4.hpp>
#include "CTextureCache.h" #include "CTextureCache.h"
#include "CWallpaper.h"
#include "WallpaperEngine/Application/CWallpaperApplication.h" #include "WallpaperEngine/Application/CWallpaperApplication.h"
#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 "WallpaperEngine/Render/Drivers/Output/COutput.h"
#include <X11/Xlib.h>
using namespace WallpaperEngine::Application; namespace WallpaperEngine
using namespace WallpaperEngine::Assets;
using namespace WallpaperEngine::Input;
using namespace WallpaperEngine::Render::Drivers;
using namespace WallpaperEngine::Render::Drivers::Output;
namespace WallpaperEngine::Render::Drivers::Output
{ {
class COutput; namespace Application
}
namespace WallpaperEngine::Render::Drivers
{
class CVideoDriver;
}
namespace WallpaperEngine::Application
{
class CWallpaperApplication;
}
namespace WallpaperEngine::Render
{
class CWallpaper;
class CTextureCache;
class CRenderContext
{ {
public: class CWallpaperApplication;
CRenderContext (const COutput* output, CVideoDriver& driver, CInputContext& input, CWallpaperApplication& app); }
void render (); namespace Render
void setDefaultWallpaper (CWallpaper* wallpaper); {
void setWallpaper (const std::string& display, CWallpaper* wallpaper); namespace Drivers
CInputContext& getInputContext () const; {
const CWallpaperApplication& getApp () const; class CVideoDriver;
const COutput* getOutput () const;
const ITexture* resolveTexture (const std::string& name);
private: namespace Output
CVideoDriver& m_driver; {
std::map <std::string, CWallpaper*> m_wallpapers; class COutput;
CWallpaper* m_defaultWallpaper; }
CInputContext& m_input; }
CWallpaperApplication& m_app;
CTextureCache* m_textureCache; class CWallpaper;
const COutput* m_output; class CTextureCache;
};
class CRenderContext
{
public:
CRenderContext (const Drivers::Output::COutput* output, Drivers::CVideoDriver& driver, Input::CInputContext& input, CWallpaperApplication& app);
void render ();
void setDefaultWallpaper (CWallpaper* wallpaper);
void setWallpaper (const std::string& display, CWallpaper* wallpaper);
[[nodiscard]] Input::CInputContext& getInputContext () const;
[[nodiscard]] const CWallpaperApplication& getApp () const;
[[nodiscard]] const Drivers::CVideoDriver& getDriver () const;
[[nodiscard]] const Drivers::Output::COutput* getOutput () const;
const ITexture* resolveTexture (const std::string& name);
private:
/** Video driver in use */
Drivers::CVideoDriver& m_driver;
/** Maps screen -> wallpaper list */
std::map <std::string, CWallpaper*> m_wallpapers;
/** Default wallpaper to use */
CWallpaper* m_defaultWallpaper;
/** Input context for interactions */
Input::CInputContext& m_input;
/** App that holds the render context */
CWallpaperApplication& m_app;
/** Texture cache for the render */
CTextureCache* m_textureCache;
/** Output driver that describes how the wallpapers are rendered */
const Drivers::Output::COutput* m_output;
};
}
} }

View File

@ -16,9 +16,9 @@ using namespace WallpaperEngine::Render;
CScene::CScene (Core::CScene* scene, CRenderContext& context, CAudioContext& audioContext) : CScene::CScene (Core::CScene* scene, CRenderContext& context, CAudioContext& audioContext) :
CWallpaper (scene, Type, context, audioContext), CWallpaper (scene, Type, context, audioContext),
m_mousePosition (), m_mousePosition (),
m_mousePositionLast (), m_mousePositionLast (),
m_parallaxDisplacement () m_parallaxDisplacement ()
{ {
// setup the scene camera // setup the scene camera
this->m_camera = new CCamera (this, scene->getCamera ()); this->m_camera = new CCamera (this, scene->getCamera ());

View File

@ -1,17 +1,18 @@
#include "CTextureCache.h" #include "CTextureCache.h"
#include "WallpaperEngine/Render/Helpers/CContextAware.h"
#include "WallpaperEngine/Assets/CAssetLoadException.h" #include "WallpaperEngine/Assets/CAssetLoadException.h"
using namespace WallpaperEngine::Render; using namespace WallpaperEngine::Render;
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
CTextureCache::CTextureCache (CRenderContext& context) : CTextureCache::CTextureCache (CRenderContext& context) :
m_context (context) Helpers::CContextAware (context)
{ {
} }
CTextureCache::~CTextureCache () CTextureCache::~CTextureCache ()
= default; = default;
const ITexture* CTextureCache::resolve (const std::string& filename) const ITexture* CTextureCache::resolve (const std::string& filename)
{ {
@ -20,29 +21,30 @@ 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;
// search for the texture in all the different containers just in case // search for the texture in all the different containers just in case
for (auto it : this->m_context.getApp ().getProjects ()) for (auto it : this->getContext ().getApp ().getBackgrounds ())
{ {
const ITexture* texture = it.second->getContainer ()->readTexture (filename); 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) if (this->getContext ().getApp ().getDefaultBackground () != nullptr)
{ {
const ITexture* texture = this->m_context.getApp ().getDefaultProject ()->getContainer ()->readTexture (filename); const ITexture* texture =
this->getContext ().getApp ().getDefaultBackground ()->getContainer ()->readTexture (filename);
this->store (filename, texture); this->store (filename, texture);
return texture; return texture;
} }
throw CAssetLoadException (filename, "Cannot find file"); throw CAssetLoadException (filename, "Cannot find file");
} }
void CTextureCache::store (std::string name, const ITexture* texture) void CTextureCache::store (const std::string& name, const ITexture* texture)
{ {
this->m_textureCache.insert_or_assign (name, texture); this->m_textureCache.insert_or_assign (name, texture);
} }

View File

@ -5,17 +5,23 @@
#include "WallpaperEngine/Assets/ITexture.h" #include "WallpaperEngine/Assets/ITexture.h"
#include "WallpaperEngine/Render/CRenderContext.h" #include "WallpaperEngine/Render/CRenderContext.h"
#include "WallpaperEngine/Render/Helpers/CContextAware.h"
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
namespace WallpaperEngine::Render namespace WallpaperEngine::Render
{ {
namespace Helpers
{
class CContextAware;
}
class CRenderContext; class CRenderContext;
class CTextureCache class CTextureCache : Helpers::CContextAware
{ {
public: public:
CTextureCache (CRenderContext& context); explicit CTextureCache (CRenderContext& context);
~CTextureCache (); ~CTextureCache ();
/** /**
@ -33,10 +39,10 @@ namespace WallpaperEngine::Render
* @param name * @param name
* @param texture * @param texture
*/ */
void store (std::string name, const ITexture* texture); void store (const std::string& name, const ITexture* texture);
private: private:
CRenderContext& m_context; /** Cached textures */
std::map<std::string, const ITexture*> m_textureCache; std::map<std::string, const ITexture*> m_textureCache;
}; };
} }

View File

@ -19,7 +19,7 @@ CVideo::CVideo (Core::CVideo* video, CRenderContext& context, CAudioContext& aud
CWallpaper (video, Type, context, audioContext), CWallpaper (video, Type, context, audioContext),
m_width (16), m_width (16),
m_height (16), m_height (16),
m_mpvGl (nullptr) m_mpvGl (nullptr)
{ {
double volume = g_AudioVolume * 100.0 / 128.0; double volume = g_AudioVolume * 100.0 / 128.0;
@ -54,9 +54,9 @@ 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 ()); std::filesystem::path videopath = this->getVideo ()->getProject ().getContainer ()->resolveRealFile (this->getVideo ()->getFilename ());
// build the path to the video file // build the path to the video file
const char* command [] = { const char* command [] = {
"loadfile", videopath.c_str (), nullptr "loadfile", videopath.c_str (), nullptr
}; };
@ -102,14 +102,14 @@ void CVideo::renderFrame (glm::ivec4 viewport)
break; break;
// we do not care about any of the events // we do not care about any of the events
if (event->event_id == MPV_EVENT_VIDEO_RECONFIG) if (event->event_id == MPV_EVENT_VIDEO_RECONFIG)
{ {
int64_t width, height; int64_t width, height;
if (mpv_get_property (this->m_mpv, "dwidth", MPV_FORMAT_INT64, &width) >= 0 && if (mpv_get_property (this->m_mpv, "dwidth", MPV_FORMAT_INT64, &width) >= 0 &&
mpv_get_property (this->m_mpv, "dheight", MPV_FORMAT_INT64, &height) >= 0) mpv_get_property (this->m_mpv, "dheight", MPV_FORMAT_INT64, &height) >= 0)
this->setSize (width, height); this->setSize (width, height);
} }
} }
// render the next // render the next

View File

@ -10,18 +10,18 @@
using namespace WallpaperEngine::Render; using namespace WallpaperEngine::Render;
CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRenderContext& context, CAudioContext& audioContext) : CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRenderContext& context, CAudioContext& audioContext) :
CContextAware (context),
m_wallpaperData (wallpaperData), m_wallpaperData (wallpaperData),
m_type (std::move(type)), m_type (std::move(type)),
m_context (context),
m_destFramebuffer (GL_NONE), m_destFramebuffer (GL_NONE),
m_sceneFBO (nullptr), m_sceneFBO (nullptr),
m_texCoordBuffer (GL_NONE), m_texCoordBuffer (GL_NONE),
m_positionBuffer (GL_NONE), m_positionBuffer (GL_NONE),
m_shader (GL_NONE), m_shader (GL_NONE),
g_Texture0 (GL_NONE), g_Texture0 (GL_NONE),
a_Position (GL_NONE), a_Position (GL_NONE),
a_TexCoord (GL_NONE), a_TexCoord (GL_NONE),
m_vaoBuffer (GL_NONE), m_vaoBuffer (GL_NONE),
m_audioContext (audioContext) m_audioContext (audioContext)
{ {
// generate the VAO to stop opengl from complaining // generate the VAO to stop opengl from complaining
@ -88,7 +88,7 @@ void CWallpaper::setupShaders ()
// give shader's source code to OpenGL to be compiled // give shader's source code to OpenGL to be compiled
const char* sourcePointer = "#version 330\n" const char* sourcePointer = "#version 330\n"
"precision highp float;\n" "precision highp float;\n"
"in vec3 a_Position;\n" "in vec3 a_Position;\n"
"in vec2 a_TexCoord;\n" "in vec2 a_TexCoord;\n"
"out vec2 v_TexCoord;\n" "out vec2 v_TexCoord;\n"
@ -127,10 +127,10 @@ void CWallpaper::setupShaders ()
// give shader's source code to OpenGL to be compiled // give shader's source code to OpenGL to be compiled
sourcePointer = "#version 330\n" sourcePointer = "#version 330\n"
"precision highp float;\n" "precision highp float;\n"
"uniform sampler2D g_Texture0;\n" "uniform sampler2D g_Texture0;\n"
"in vec2 v_TexCoord;\n" "in vec2 v_TexCoord;\n"
"out vec4 out_FragColor;\n" "out vec4 out_FragColor;\n"
"void main () {\n" "void main () {\n"
"out_FragColor = texture (g_Texture0, v_TexCoord);\n" "out_FragColor = texture (g_Texture0, v_TexCoord);\n"
"}"; "}";
@ -226,7 +226,7 @@ void CWallpaper::render (glm::ivec4 viewport, bool vflip, bool renderFrame, bool
if ( if (
(viewport.w > viewport.z && projectionWidth >= projectionHeight) || (viewport.w > viewport.z && projectionWidth >= projectionHeight) ||
(viewport.z > viewport.w && projectionHeight > projectionWidth) (viewport.z > viewport.w && projectionHeight > projectionWidth)
) )
{ {
if (vflip) if (vflip)
@ -253,7 +253,7 @@ void CWallpaper::render (glm::ivec4 viewport, bool vflip, bool renderFrame, bool
if ( if (
(viewport.z > viewport.w && projectionWidth >= projectionHeight) || (viewport.z > viewport.w && projectionWidth >= projectionHeight) ||
(viewport.w > viewport.z && projectionHeight > projectionWidth) (viewport.w > viewport.z && projectionHeight > projectionWidth)
) )
{ {
ustart = 0.0f; ustart = 0.0f;
@ -335,11 +335,6 @@ void CWallpaper::setupFramebuffers ()
); );
} }
CRenderContext& CWallpaper::getContext ()
{
return this->m_context;
}
CAudioContext& CWallpaper::getAudioContext () CAudioContext& CWallpaper::getAudioContext ()
{ {
return this->m_audioContext; return this->m_audioContext;

View File

@ -3,23 +3,28 @@
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include "WallpaperEngine/Assets/CContainer.h"
#include "WallpaperEngine/Audio/CAudioContext.h"
#include "WallpaperEngine/Core/CWallpaper.h" #include "WallpaperEngine/Core/CWallpaper.h"
#include "WallpaperEngine/Core/CScene.h" #include "WallpaperEngine/Core/CScene.h"
#include "WallpaperEngine/Core/CVideo.h" #include "WallpaperEngine/Core/CVideo.h"
#include "CFBO.h" #include "WallpaperEngine/Render/CRenderContext.h"
#include "CRenderContext.h" #include "WallpaperEngine/Render/CFBO.h"
#include "WallpaperEngine/Assets/CContainer.h" #include "WallpaperEngine/Render/Helpers/CContextAware.h"
#include "WallpaperEngine/Audio/CAudioContext.h"
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
using namespace WallpaperEngine::Audio; using namespace WallpaperEngine::Audio;
namespace WallpaperEngine::Render namespace WallpaperEngine::Render
{ {
class CRenderContext; namespace Helpers
{
class CContextAware;
}
class CWallpaper class CWallpaper : public Helpers::CContextAware
{ {
public: public:
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; }
@ -27,7 +32,6 @@ namespace WallpaperEngine::Render
template<class T> bool is () { return this->m_type == T::Type; } template<class T> bool is () { return this->m_type == T::Type; }
CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRenderContext& context, CAudioContext& audioContext);
~CWallpaper (); ~CWallpaper ();
/** /**
@ -38,12 +42,7 @@ namespace WallpaperEngine::Render
/** /**
* @return The container to resolve files for this wallpaper * @return The container to resolve files for this wallpaper
*/ */
CContainer* getContainer () const; [[nodiscard]] CContainer* getContainer () const;
/**
* @return The current context rendering this wallpaper
*/
CRenderContext& getContext ();
/** /**
* @return The current audio context for this wallpaper * @return The current audio context for this wallpaper
@ -53,11 +52,11 @@ namespace WallpaperEngine::Render
/** /**
* @return The scene's framebuffer * @return The scene's framebuffer
*/ */
virtual GLuint getWallpaperFramebuffer () const; [[nodiscard]] virtual GLuint getWallpaperFramebuffer () const;
/** /**
* @return The scene's texture * @return The scene's texture
*/ */
virtual GLuint getWallpaperTexture () const; [[nodiscard]] virtual GLuint getWallpaperTexture () const;
/** /**
* Creates a new FBO for this wallpaper * Creates a new FBO for this wallpaper
* *
@ -69,19 +68,19 @@ namespace WallpaperEngine::Render
/** /**
* @return The full FBO list to work with * @return The full FBO list to work with
*/ */
const std::map<std::string, CFBO*>& getFBOs () const; [[nodiscard]] const std::map<std::string, CFBO*>& getFBOs () const;
/** /**
* Searches the FBO list for the given FBO * Searches the FBO list for the given FBO
* *
* @param name * @param name
* @return * @return
*/ */
CFBO* findFBO (const std::string& name) const; [[nodiscard]] CFBO* findFBO (const std::string& name) const;
/** /**
* @return The main FBO of this wallpaper * @return The main FBO of this wallpaper
*/ */
CFBO* getFBO () const; [[nodiscard]] CFBO* getFBO () const;
/** /**
* Updates the texcoord used for drawing to the used framebuffer * Updates the texcoord used for drawing to the used framebuffer
@ -98,12 +97,12 @@ namespace WallpaperEngine::Render
/** /**
* @return The width of this wallpaper * @return The width of this wallpaper
*/ */
virtual uint32_t getWidth () const = 0; [[nodiscard]] virtual uint32_t getWidth () const = 0;
/** /**
* @return The height of this wallpaper * @return The height of this wallpaper
*/ */
virtual uint32_t getHeight () const = 0; [[nodiscard]] virtual uint32_t getHeight () const = 0;
/** /**
* Creates a new instance of CWallpaper based on the information provided by the read backgrounds * Creates a new instance of CWallpaper based on the information provided by the read backgrounds
@ -115,6 +114,8 @@ namespace WallpaperEngine::Render
static CWallpaper* fromWallpaper (Core::CWallpaper* wallpaper, CRenderContext& context, CAudioContext& audioContext); static CWallpaper* fromWallpaper (Core::CWallpaper* wallpaper, CRenderContext& context, CAudioContext& audioContext);
protected: protected:
CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRenderContext& context, CAudioContext& audioContext);
/** /**
* Renders a frame of the wallpaper * Renders a frame of the wallpaper
*/ */
@ -127,17 +128,13 @@ namespace WallpaperEngine::Render
Core::CWallpaper* m_wallpaperData; Core::CWallpaper* m_wallpaperData;
Core::CWallpaper* getWallpaperData () const; [[nodiscard]] Core::CWallpaper* getWallpaperData () const;
/** /** The FBO used for scene output */
* The FBO used for scene output
*/
CFBO* m_sceneFBO; CFBO* m_sceneFBO;
private: private:
/** /** The texture used for the scene output */
* The texture used for the scene output
*/
GLuint m_texCoordBuffer; GLuint m_texCoordBuffer;
GLuint m_positionBuffer; GLuint m_positionBuffer;
GLuint m_shader; GLuint m_shader;
@ -146,30 +143,15 @@ namespace WallpaperEngine::Render
GLint a_Position; GLint a_Position;
GLint a_TexCoord; GLint a_TexCoord;
GLuint m_vaoBuffer; GLuint m_vaoBuffer;
/** /** The framebuffer to draw the background to */
* The framebuffer to draw the background to
*/
GLuint m_destFramebuffer; GLuint m_destFramebuffer;
/** /** Setups OpenGL's shaders for this wallpaper backbuffer */
* Setups OpenGL's shaders for this wallpaper backbuffer
*/
void setupShaders (); void setupShaders ();
/** /** The type of background this wallpaper is */
* The type of background this wallpaper is (used
*/
std::string m_type; std::string m_type;
/** List of FBOs registered for this wallpaper */
/**
* List of FBOs registered for this wallpaper
*/
std::map<std::string, CFBO*> m_fbos; std::map<std::string, CFBO*> m_fbos;
/** /** Audio context that is using this wallpaper */
* Context that is using this wallpaper
*/
CRenderContext& m_context;
/*
* Audio context that is using this wallpaper
*/
CAudioContext& m_audioContext; CAudioContext& m_audioContext;
}; };
} }

View File

@ -6,13 +6,13 @@ using namespace WallpaperEngine::Render::Drivers;
void CustomGLFWErrorHandler (int errorCode, const char* reason) void CustomGLFWErrorHandler (int errorCode, const char* reason)
{ {
sLog.error ("GLFW error ", errorCode, ": ", reason); sLog.error ("GLFW error ", errorCode, ": ", reason);
} }
COpenGLDriver::COpenGLDriver (const char* windowTitle) : COpenGLDriver::COpenGLDriver (const char* windowTitle) :
m_frameCounter (0) m_frameCounter (0)
{ {
glfwSetErrorCallback (CustomGLFWErrorHandler); glfwSetErrorCallback (CustomGLFWErrorHandler);
// initialize glfw // initialize glfw
if (glfwInit () == GLFW_FALSE) if (glfwInit () == GLFW_FALSE)
@ -26,7 +26,7 @@ COpenGLDriver::COpenGLDriver (const char* windowTitle) :
glfwWindowHint (GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint (GLFW_VISIBLE, GLFW_FALSE);
#if !NDEBUG #if !NDEBUG
glfwWindowHint (GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); glfwWindowHint (GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
#endif /* DEBUG */ #endif /* DEBUG */
// create window, size doesn't matter as long as we don't show it // create window, size doesn't matter as long as we don't show it
@ -54,7 +54,7 @@ COpenGLDriver::~COpenGLDriver ()
FreeImage_DeInitialise(); FreeImage_DeInitialise();
} }
float COpenGLDriver::getRenderTime () float COpenGLDriver::getRenderTime () const
{ {
return (float) glfwGetTime (); return (float) glfwGetTime ();
} }
@ -71,7 +71,7 @@ void COpenGLDriver::resizeWindow (glm::ivec2 size)
void COpenGLDriver::resizeWindow (glm::ivec4 sizeandpos) void COpenGLDriver::resizeWindow (glm::ivec4 sizeandpos)
{ {
glfwSetWindowPos (this->m_window, sizeandpos.x, sizeandpos.y); glfwSetWindowPos (this->m_window, sizeandpos.x, sizeandpos.y);
glfwSetWindowSize (this->m_window, sizeandpos.z, sizeandpos.w); glfwSetWindowSize (this->m_window, sizeandpos.z, sizeandpos.w);
} }
@ -85,7 +85,7 @@ void COpenGLDriver::hideWindow ()
glfwHideWindow (this->m_window); glfwHideWindow (this->m_window);
} }
glm::ivec2 COpenGLDriver::getFramebufferSize () glm::ivec2 COpenGLDriver::getFramebufferSize () const
{ {
glm::ivec2 size; glm::ivec2 size;
@ -104,7 +104,7 @@ void COpenGLDriver::swapBuffers ()
this->m_frameCounter ++; this->m_frameCounter ++;
} }
uint32_t COpenGLDriver::getFrameCounter () uint32_t COpenGLDriver::getFrameCounter () const
{ {
return this->m_frameCounter; return this->m_frameCounter;
} }
@ -112,4 +112,4 @@ uint32_t COpenGLDriver::getFrameCounter ()
GLFWwindow* COpenGLDriver::getWindow () GLFWwindow* COpenGLDriver::getWindow ()
{ {
return this->m_window; return this->m_window;
} }

View File

@ -7,12 +7,12 @@
namespace WallpaperEngine::Application namespace WallpaperEngine::Application
{ {
class CApplicationContext; class CApplicationContext;
} }
namespace WallpaperEngine::Render::Drivers namespace WallpaperEngine::Render::Drivers
{ {
using namespace WallpaperEngine::Application; using namespace WallpaperEngine::Application;
class COpenGLDriver : public CVideoDriver class COpenGLDriver : public CVideoDriver
{ {
@ -20,15 +20,15 @@ namespace WallpaperEngine::Render::Drivers
explicit COpenGLDriver (const char* windowTitle); explicit COpenGLDriver (const char* windowTitle);
~COpenGLDriver(); ~COpenGLDriver();
float getRenderTime () override; float getRenderTime () const 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 resizeWindow (glm::ivec4 sizeandpos) override;
void showWindow () override; void showWindow () override;
void hideWindow () override; void hideWindow () override;
glm::ivec2 getFramebufferSize () override; glm::ivec2 getFramebufferSize () const override;
void swapBuffers () override; void swapBuffers () override;
uint32_t getFrameCounter () override; uint32_t getFrameCounter () const override;
GLFWwindow* getWindow (); GLFWwindow* getWindow ();

View File

@ -8,14 +8,41 @@ namespace WallpaperEngine::Render::Drivers
class CVideoDriver class CVideoDriver
{ {
public: public:
virtual float getRenderTime () = 0; /**
* @return The time that has passed since the driver started
*/
virtual float getRenderTime () const = 0;
/**
* @return If a close was requested by the OS
*/
virtual bool closeRequested () = 0; virtual bool closeRequested () = 0;
/**
* @param size The new size for the window
*/
virtual void resizeWindow (glm::ivec2 size) = 0; virtual void resizeWindow (glm::ivec2 size) = 0;
virtual void resizeWindow (glm::ivec4 size) = 0; /**
* @param size The new size and position of the window
*/
virtual void resizeWindow (glm::ivec4 positionAndSize) = 0;
/**
* Shows the window created by the driver
*/
virtual void showWindow () = 0; virtual void showWindow () = 0;
/**
* Hides the window created by the driver
*/
virtual void hideWindow () = 0; virtual void hideWindow () = 0;
virtual glm::ivec2 getFramebufferSize () = 0; /**
* @return The size of the framebuffer available for the driver
*/
virtual glm::ivec2 getFramebufferSize () const = 0;
/**
* Performs buffer swapping
*/
virtual void swapBuffers () = 0; virtual void swapBuffers () = 0;
virtual uint32_t getFrameCounter () = 0; /**
* @return The number of rendered frames since the start of the driver
*/
virtual uint32_t getFrameCounter () const = 0;
}; };
} }

View File

@ -0,0 +1,78 @@
#include <GLFW/glfw3.h>
#include "CGLFWWindowOutput.h"
#include "WallpaperEngine/Logging/CLog.h"
using namespace WallpaperEngine::Render::Drivers::Output;
CGLFWWindowOutput::CGLFWWindowOutput (CApplicationContext& context, CVideoDriver& driver) :
COutput (context),
m_driver (driver)
{
if (
this->m_context.render.mode != Application::CApplicationContext::NORMAL_WINDOW &&
this->m_context.render.mode != Application::CApplicationContext::EXPLICIT_WINDOW)
sLog.exception ("Initializing window output when not in output mode, how did you get here?!");
// window should be visible
driver.showWindow ();
if (this->m_context.render.mode == Application::CApplicationContext::EXPLICIT_WINDOW)
{
this->m_fullWidth = this->m_context.render.window.geometry.z;
this->m_fullHeight = this->m_context.render.window.geometry.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 CGLFWWindowOutput::repositionWindow ()
{
// reposition the window
this->m_driver.resizeWindow (this->m_context.render.window.geometry);
}
void CGLFWWindowOutput::reset ()
{
if (this->m_context.render.mode == Application::CApplicationContext::EXPLICIT_WINDOW)
this->repositionWindow ();
}
bool CGLFWWindowOutput::renderVFlip () const
{
return true;
}
bool CGLFWWindowOutput::renderMultiple () const
{
return false;
}
bool CGLFWWindowOutput::haveImageBuffer () const
{
return false;
}
void* CGLFWWindowOutput::getImageBuffer () const
{
return nullptr;
}
void CGLFWWindowOutput::updateRender () const
{
if (this->m_context.render.mode != 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"};
}

View File

@ -0,0 +1,25 @@
#pragma once
#include "WallpaperEngine/Render/Drivers/CVideoDriver.h"
#include "COutput.h"
namespace WallpaperEngine::Render::Drivers::Output
{
class CGLFWWindowOutput : public COutput
{
public:
CGLFWWindowOutput (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;
};
}

View File

@ -3,21 +3,21 @@
using namespace WallpaperEngine::Render::Drivers::Output; using namespace WallpaperEngine::Render::Drivers::Output;
COutput::COutput (CApplicationContext& context) : COutput::COutput (CApplicationContext& context) :
m_context (context) m_context (context)
{ {
} }
const std::map <std::string, COutput::ScreenInfo>& COutput::getViewports () const const std::map <std::string, COutput::ScreenInfo>& COutput::getViewports () const
{ {
return this->m_viewports; return this->m_viewports;
} }
int COutput::getFullWidth () const int COutput::getFullWidth () const
{ {
return this->m_fullWidth; return this->m_fullWidth;
} }
int COutput::getFullHeight () const int COutput::getFullHeight () const
{ {
return this->m_fullHeight; return this->m_fullHeight;
} }

View File

@ -10,38 +10,38 @@ using namespace WallpaperEngine::Application;
namespace WallpaperEngine::Application namespace WallpaperEngine::Application
{ {
class CApplicationContext; class CApplicationContext;
} }
namespace WallpaperEngine::Render::Drivers::Output namespace WallpaperEngine::Render::Drivers::Output
{ {
class COutput class COutput
{ {
public: public:
COutput (CApplicationContext& context); COutput (CApplicationContext& context);
virtual void reset () = 0; virtual void reset () = 0;
int getFullWidth () const; int getFullWidth () const;
int getFullHeight () const; int getFullHeight () const;
struct ScreenInfo struct ScreenInfo
{ {
glm::ivec4 viewport; glm::ivec4 viewport;
std::string name; std::string name;
}; };
virtual bool renderVFlip () const = 0; virtual bool renderVFlip () const = 0;
virtual bool renderMultiple () const = 0; virtual bool renderMultiple () const = 0;
virtual bool haveImageBuffer () const = 0; virtual bool haveImageBuffer () const = 0;
const std::map <std::string, ScreenInfo>& getViewports () const; const std::map <std::string, ScreenInfo>& getViewports () const;
virtual void* getImageBuffer () const = 0; virtual void* getImageBuffer () const = 0;
virtual void updateRender () const = 0; virtual void updateRender () const = 0;
protected: protected:
mutable int m_fullWidth; mutable int m_fullWidth;
mutable int m_fullHeight; mutable int m_fullHeight;
mutable std::map <std::string, ScreenInfo> m_viewports; mutable std::map <std::string, ScreenInfo> m_viewports;
CApplicationContext& m_context; CApplicationContext& m_context;
}; };
} }

View File

@ -1,77 +0,0 @@
#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"};
}

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