From b55f2e8bf47c174c4374678cacb1a19f0dce932e Mon Sep 17 00:00:00 2001 From: Alexis Maiquez Date: Fri, 3 Dec 2021 02:02:46 +0100 Subject: [PATCH] + Added PKGV0015 support + Added basic support for mouse position on shaders (still needs to be adjusted for backgrounds that are too big for the screen) (this makes XRAY effects work) Signed-off-by: Alexis Maiquez --- CMakeLists.txt | 3 ++ main.cpp | 14 ++++--- src/WallpaperEngine/Assets/CPackage.cpp | 3 +- src/WallpaperEngine/Input/CMouseInput.cpp | 14 +++++++ src/WallpaperEngine/Input/CMouseInput.h | 37 +++++++++++++++++++ src/WallpaperEngine/Render/CContext.cpp | 18 ++++++--- src/WallpaperEngine/Render/CContext.h | 11 ++++-- src/WallpaperEngine/Render/CScene.cpp | 28 ++++++++++++-- src/WallpaperEngine/Render/CScene.h | 8 +++- src/WallpaperEngine/Render/CVideo.cpp | 6 +-- src/WallpaperEngine/Render/CVideo.h | 4 +- src/WallpaperEngine/Render/CWallpaper.cpp | 12 ++++-- src/WallpaperEngine/Render/CWallpaper.h | 16 +++++++- .../Render/Objects/Effects/CPass.cpp | 3 ++ 14 files changed, 147 insertions(+), 30 deletions(-) create mode 100644 src/WallpaperEngine/Input/CMouseInput.cpp create mode 100644 src/WallpaperEngine/Input/CMouseInput.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c360555..f12fcba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,9 @@ add_executable( src/WallpaperEngine/Core/Core.h src/WallpaperEngine/Core/Core.cpp + src/WallpaperEngine/Input/CMouseInput.h + src/WallpaperEngine/Input/CMouseInput.cpp + src/WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h src/WallpaperEngine/Render/Shaders/Variables/CShaderVariable.cpp src/WallpaperEngine/Render/Shaders/Variables/CShaderVariableFloat.h diff --git a/main.cpp b/main.cpp index d26ffe9..d7bf22d 100644 --- a/main.cpp +++ b/main.cpp @@ -180,9 +180,6 @@ int main (int argc, char* argv[]) auto project = WallpaperEngine::Core::CProject::fromFile ("project.json", containers); WallpaperEngine::Render::CWallpaper* wallpaper; - // initialize custom context class - WallpaperEngine::Render::CContext* context = new WallpaperEngine::Render::CContext (screens); - // auto projection = project->getWallpaper ()->as ()->getOrthogonalProjection (); // create the window! // TODO: DO WE NEED TO PASS MONITOR HERE OR ANYTHING? @@ -198,6 +195,11 @@ int main (int argc, char* argv[]) glfwMakeContextCurrent (window); + // initialize inputs + CMouseInput* mouseInput = new CMouseInput (window); + // initialize custom context class + WallpaperEngine::Render::CContext* context = new WallpaperEngine::Render::CContext (screens, mouseInput); + // TODO: FIGURE THESE OUT BASED ON THE SCREEN int windowWidth = 1920; int windowHeight = 1080; @@ -218,7 +220,7 @@ int main (int argc, char* argv[]) if (project->getType () == "scene") { WallpaperEngine::Core::CScene* scene = project->getWallpaper ()->as (); - wallpaper = new WallpaperEngine::Render::CScene (scene, containers); + wallpaper = new WallpaperEngine::Render::CScene (scene, containers, context); } else if (project->getType () == "video") { @@ -227,7 +229,7 @@ int main (int argc, char* argv[]) chdir (path.c_str ()); WallpaperEngine::Core::CVideo* video = project->getWallpaper ()->as (); - wallpaper = new WallpaperEngine::Render::CVideo (video, containers); + wallpaper = new WallpaperEngine::Render::CVideo (video, containers, context); } else { @@ -277,6 +279,8 @@ int main (int argc, char* argv[]) g_Time = (float) glfwGetTime (); // get the start time of the frame startTime = clock (); + // update our inputs first + mouseInput->update (); // render the scene context->render (); // do buffer swapping diff --git a/src/WallpaperEngine/Assets/CPackage.cpp b/src/WallpaperEngine/Assets/CPackage.cpp index 1466cf9..9a31a76 100644 --- a/src/WallpaperEngine/Assets/CPackage.cpp +++ b/src/WallpaperEngine/Assets/CPackage.cpp @@ -111,7 +111,8 @@ void CPackage::validateHeader (FILE* fp) strcmp ("PKGV0005", pointer) != 0 && strcmp ("PKGV0006", pointer) != 0 && strcmp ("PKGV0013", pointer) != 0 && - strcmp ("PKGV0014", pointer) != 0) + strcmp ("PKGV0014", pointer) != 0 && + strcmp ("PKGV0015", pointer) != 0) { delete[] pointer; throw std::runtime_error ("Unsupported package version"); diff --git a/src/WallpaperEngine/Input/CMouseInput.cpp b/src/WallpaperEngine/Input/CMouseInput.cpp new file mode 100644 index 0000000..4338b50 --- /dev/null +++ b/src/WallpaperEngine/Input/CMouseInput.cpp @@ -0,0 +1,14 @@ +#include +#include "CMouseInput.h" + +using namespace WallpaperEngine::Input; + +CMouseInput::CMouseInput (GLFWwindow* window) : position(0, 0), m_window (window) {} + +void CMouseInput::update () +{ + // update current mouse position + glfwGetCursorPos (this->m_window, &this->m_mousePosition.x, &this->m_mousePosition.y); + // interpolate to the new position + this->position = glm::mix (this->position, this->m_mousePosition, 1.0); +} \ No newline at end of file diff --git a/src/WallpaperEngine/Input/CMouseInput.h b/src/WallpaperEngine/Input/CMouseInput.h new file mode 100644 index 0000000..746c2d9 --- /dev/null +++ b/src/WallpaperEngine/Input/CMouseInput.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include "GLFW/glfw3.h" + +namespace WallpaperEngine::Input +{ + /** + * Handles mouse input for the background + */ + class CMouseInput + { + public: + CMouseInput(GLFWwindow* window); + + /** + * Takes current mouse position and updates it + */ + void update (); + + /** + * The virtual pointer's position + */ + glm::dvec2 position; + private: + /** + * The GLFW window to get mouse position from + */ + GLFWwindow* m_window; + + /** + * The current mouse position + */ + glm::dvec2 m_mousePosition; + }; +}; + diff --git a/src/WallpaperEngine/Render/CContext.cpp b/src/WallpaperEngine/Render/CContext.cpp index 9aaadb4..e679cf1 100644 --- a/src/WallpaperEngine/Render/CContext.cpp +++ b/src/WallpaperEngine/Render/CContext.cpp @@ -6,15 +6,16 @@ #include #include "CContext.h" +#include "CVideo.h" using namespace WallpaperEngine::Render; -CContext::CContext (std::vector screens) : +CContext::CContext (std::vector screens, CMouseInput* mouse) : m_wallpaper (nullptr), m_screens (std::move (screens)), m_isRootWindow (m_screens.empty () == false), - m_window (0), - m_defaultViewport ({0, 0, 1920, 1080}) + m_defaultViewport ({0, 0, 1920, 1080}), + m_mouse (mouse) { this->initializeViewports (); } @@ -76,8 +77,6 @@ void CContext::initializeViewports () XRRFreeScreenResources (screenResources); - // store the window - this->m_window = DefaultRootWindow (display); // set the glfwWindowHintPointer (GLFW_NATIVE_PARENT_HANDLE, reinterpret_cast (DefaultRootWindow (display))); } @@ -96,7 +95,9 @@ void CContext::render () for (; cur != end; cur ++) { this->m_wallpaper->render (*cur, firstFrame); - firstFrame = false; + // 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 = !this->m_wallpaper->is (); } } else @@ -111,4 +112,9 @@ void CContext::setWallpaper (CWallpaper* wallpaper) void CContext::setDefaultViewport (glm::vec4 defaultViewport) { this->m_defaultViewport = defaultViewport; +} + +CMouseInput* CContext::getMouse () const +{ + return this->m_mouse; } \ No newline at end of file diff --git a/src/WallpaperEngine/Render/CContext.h b/src/WallpaperEngine/Render/CContext.h index c63ad49..2f00b87 100644 --- a/src/WallpaperEngine/Render/CContext.h +++ b/src/WallpaperEngine/Render/CContext.h @@ -3,26 +3,31 @@ #include #include +#include "WallpaperEngine/Input/CMouseInput.h" #include "CWallpaper.h" +using namespace WallpaperEngine::Input; + namespace WallpaperEngine::Render { + class CWallpaper; + class CContext { public: - CContext (std::vector screens); + CContext (std::vector screens, CMouseInput* mouse); void initializeViewports (); void render (); void setWallpaper (CWallpaper* wallpaper); void setDefaultViewport (glm::vec4 defaultViewport); - + CMouseInput* getMouse () const; private: - Window m_window; std::vector m_screens; std::vector m_viewports; glm::vec4 m_defaultViewport; CWallpaper* m_wallpaper; + CMouseInput* m_mouse; bool m_isRootWindow; }; } \ No newline at end of file diff --git a/src/WallpaperEngine/Render/CScene.cpp b/src/WallpaperEngine/Render/CScene.cpp index ef6d4be..fee694f 100644 --- a/src/WallpaperEngine/Render/CScene.cpp +++ b/src/WallpaperEngine/Render/CScene.cpp @@ -9,8 +9,8 @@ using namespace WallpaperEngine; using namespace WallpaperEngine::Render; -CScene::CScene (Core::CScene* scene, CContainer* container) : - CWallpaper (scene, Type, container) +CScene::CScene (Core::CScene* scene, CContainer* container, CContext* context) : + CWallpaper (scene, Type, container, context) { // setup the scene camera this->m_camera = new CCamera (this, scene->getCamera ()); @@ -56,12 +56,15 @@ CCamera* CScene::getCamera () const return this->m_camera; } -void CScene::renderFrame () +void CScene::renderFrame (glm::vec4 viewport) { auto projection = this->getScene ()->getOrthogonalProjection (); auto cur = this->m_objects.begin (); auto end = this->m_objects.end (); + // ensure the virtual mouse position is up to date + this->updateMouse (viewport); + // clear screen FloatColor clearColor = this->getScene ()->getClearColor (); @@ -79,9 +82,28 @@ void CScene::renderFrame () glViewport (0, 0, projection->getWidth (), projection->getHeight ()); } +void CScene::updateMouse (glm::vec4 viewport) +{ + // projection also affects the mouse position + auto projection = this->getScene ()->getOrthogonalProjection (); + // update virtual mouse position first + CMouseInput* mouse = this->getContext ()->getMouse (); + // TODO: PROPERLY TRANSLATE THESE TO WHAT'S VISIBLE ON SCREEN (FOR BACKGROUNDS THAT DO NOT EXACTLY FIT ON SCREEN) + + this->m_mousePosition.x = glm::clamp ((mouse->position.x - viewport.x) / viewport.z, 0.0, 1.0); + this->m_mousePosition.y = glm::clamp ((mouse->position.y - viewport.y) / viewport.w, 0.0, 1.0); + + // screen-space positions have to be transposed to what the screen will actually show +} + Core::CScene* CScene::getScene () { return this->getWallpaperData ()->as (); } +glm::vec2* CScene::getMousePosition () +{ + return &this->m_mousePosition; +} + const std::string CScene::Type = "scene"; diff --git a/src/WallpaperEngine/Render/CScene.h b/src/WallpaperEngine/Render/CScene.h index 985598d..4ea2a62 100644 --- a/src/WallpaperEngine/Render/CScene.h +++ b/src/WallpaperEngine/Render/CScene.h @@ -15,14 +15,17 @@ namespace WallpaperEngine::Render class CScene : public CWallpaper { public: - CScene (Core::CScene* scene, CContainer* container); + CScene (Core::CScene* scene, CContainer* container, CContext* context); CCamera* getCamera () const; Core::CScene* getScene (); + glm::vec2* getMousePosition (); + protected: - void renderFrame () override; + void renderFrame (glm::vec4 viewport) override; + void updateMouse (glm::vec4 viewport); friend class CWallpaper; @@ -31,5 +34,6 @@ namespace WallpaperEngine::Render private: CCamera* m_camera; std::vector m_objects; + glm::vec2 m_mousePosition; }; } diff --git a/src/WallpaperEngine/Render/CVideo.cpp b/src/WallpaperEngine/Render/CVideo.cpp index 539ed28..85303b2 100644 --- a/src/WallpaperEngine/Render/CVideo.cpp +++ b/src/WallpaperEngine/Render/CVideo.cpp @@ -3,8 +3,8 @@ using namespace WallpaperEngine; using namespace WallpaperEngine::Render; -CVideo::CVideo (Core::CVideo* video, CContainer* container) : - CWallpaper (video, Type, container) +CVideo::CVideo (Core::CVideo* video, CContainer* container, CContext* context) : + CWallpaper (video, Type, container, context) { if (avformat_open_input (&m_formatCtx, video->getFilename ().c_str (), NULL, NULL) < 0) throw std::runtime_error ("Failed to open video file"); @@ -115,7 +115,7 @@ void CVideo::setSize (int width, int height) SWS_BILINEAR, NULL, NULL, NULL); } -void CVideo::renderFrame () +void CVideo::renderFrame (glm::vec4 viewport) { // do not render using the CWallpaper function, just use this one this->setSize (m_codecCtx->width, m_codecCtx->height); diff --git a/src/WallpaperEngine/Render/CVideo.h b/src/WallpaperEngine/Render/CVideo.h index c338c31..329d206 100644 --- a/src/WallpaperEngine/Render/CVideo.h +++ b/src/WallpaperEngine/Render/CVideo.h @@ -17,7 +17,7 @@ namespace WallpaperEngine::Render class CVideo : public CWallpaper { public: - CVideo (Core::CVideo* video, CContainer* container); + CVideo (Core::CVideo* video, CContainer* container, CContext* context); Core::CVideo* getVideo (); @@ -25,7 +25,7 @@ namespace WallpaperEngine::Render int getHeight (); protected: - void renderFrame () override; + void renderFrame (glm::vec4 viewport) override; friend class CWallpaper; diff --git a/src/WallpaperEngine/Render/CWallpaper.cpp b/src/WallpaperEngine/Render/CWallpaper.cpp index b57ca80..a517d96 100644 --- a/src/WallpaperEngine/Render/CWallpaper.cpp +++ b/src/WallpaperEngine/Render/CWallpaper.cpp @@ -8,10 +8,11 @@ using namespace WallpaperEngine::Render; -CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CContainer* container) : +CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CContainer* container, CContext* context) : m_container (container), m_wallpaperData (wallpaperData), - m_type (std::move(type)) + m_type (std::move(type)), + m_context (context) { this->setupShaders (); @@ -187,7 +188,7 @@ void CWallpaper::setupShaders () void CWallpaper::render (glm::vec4 viewport, bool newFrame) { if (newFrame == true) - this->renderFrame (); + this->renderFrame (viewport); int windowWidth = 1920; int windowHeight = 1080; @@ -310,6 +311,11 @@ void CWallpaper::setupFramebuffers () this->m_sceneFBO = this->createFBO ("_rt_FullFrameBuffer", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight); } +CContext* CWallpaper::getContext () +{ + return this->m_context; +} + CFBO* CWallpaper::createFBO (const std::string& name, ITexture::TextureFormat format, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight) { CFBO* fbo = new CFBO (name, format, scale, realWidth, realHeight, textureWidth, textureHeight); diff --git a/src/WallpaperEngine/Render/CWallpaper.h b/src/WallpaperEngine/Render/CWallpaper.h index f0d235f..f247596 100644 --- a/src/WallpaperEngine/Render/CWallpaper.h +++ b/src/WallpaperEngine/Render/CWallpaper.h @@ -9,11 +9,14 @@ #include "WallpaperEngine/Assets/CContainer.h" #include "CFBO.h" +#include "CContext.h" using namespace WallpaperEngine::Assets; namespace WallpaperEngine::Render { + class CContext; + class CWallpaper { public: @@ -22,7 +25,7 @@ namespace WallpaperEngine::Render template bool is () { return this->m_type == T::Type; } - CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CContainer* container); + CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CContainer* container, CContext* context); ~CWallpaper (); /** @@ -72,13 +75,18 @@ namespace WallpaperEngine::Render /** * Renders a frame of the wallpaper */ - virtual void renderFrame () = 0; + virtual void renderFrame (glm::vec4 viewport) = 0; /** * Setups OpenGL's framebuffers for ping-pong and scene rendering */ void setupFramebuffers (); + /** + * @return The current context rendering this wallpaper + */ + CContext* getContext (); + CContainer* m_container; Core::CWallpaper* m_wallpaperData; @@ -113,5 +121,9 @@ namespace WallpaperEngine::Render * List of FBOs registered for this wallpaper */ std::map m_fbos; + /** + * Context that is using this wallpaper + */ + CContext* m_context; }; } diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp index 8d0668d..6e67473 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp @@ -470,6 +470,9 @@ void CPass::setupUniforms () this->addUniform ("g_Time", &g_Time); // add model-view-projection matrix this->addUniform ("g_ModelViewProjectionMatrix", &this->m_modelViewProjectionMatrix); + this->addUniform ("g_PointerPosition", this->m_material->getImage ()->getScene ()->getMousePosition ()); + this->addUniform ("g_EffectTextureProjectionMatrix", glm::mat4(1.0)); + this->addUniform ("g_EffectTextureProjectionMatrixInverse", glm::mat4(1.0)); } void CPass::addAttribute (const std::string& name, GLint type, GLint elements, const GLuint* value)