diff --git a/CMakeLists.txt b/CMakeLists.txt index c30bba0..f4fa94d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,7 @@ add_executable( src/WallpaperEngine/Assets/CDirectory.cpp src/WallpaperEngine/Assets/CPackage.h src/WallpaperEngine/Assets/CPackage.cpp + src/WallpaperEngine/Assets/ITexture.h src/WallpaperEngine/Assets/CTexture.h src/WallpaperEngine/Assets/CTexture.cpp @@ -90,8 +91,8 @@ add_executable( src/WallpaperEngine/Render/Objects/CEffect.h src/WallpaperEngine/Render/Objects/CEffect.cpp - src/WallpaperEngine/Render/Objects/Effects/CFBO.h - src/WallpaperEngine/Render/Objects/Effects/CFBO.cpp + src/WallpaperEngine/Render/CFBO.h + src/WallpaperEngine/Render/CFBO.cpp src/WallpaperEngine/Render/Objects/Effects/CPass.h src/WallpaperEngine/Render/Objects/Effects/CPass.cpp src/WallpaperEngine/Render/Objects/Effects/CMaterial.h @@ -146,6 +147,8 @@ add_executable( src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.cpp src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.cpp + src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h + src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.cpp src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.cpp diff --git a/docs/JSON_FORMAT.md b/docs/JSON_FORMAT.md new file mode 100644 index 0000000..c58b6c6 --- /dev/null +++ b/docs/JSON_FORMAT.md @@ -0,0 +1,10 @@ +# scene.json +The scene file contains information about all the objects for the scene with the camera settings in it. + +## Structure +### camera +[see here](rendering/CAMERA_SETTINGS.md) +### general +[see here](rendering/GENERAL_SETTINGS.md) +### objects +[see here](rendering/OBJECTS.md) \ No newline at end of file diff --git a/docs/rendering/CAMERA_SETTINGS.md b/docs/rendering/CAMERA_SETTINGS.md new file mode 100644 index 0000000..019f9da --- /dev/null +++ b/docs/rendering/CAMERA_SETTINGS.md @@ -0,0 +1,5 @@ +# camera settings +- camera: + - eye: where the camera is at + - center: wherte the camera is pointing at + - up: the up vector diff --git a/docs/rendering/GENERAL_SETTINGS.md b/docs/rendering/GENERAL_SETTINGS.md new file mode 100644 index 0000000..b4fdd26 --- /dev/null +++ b/docs/rendering/GENERAL_SETTINGS.md @@ -0,0 +1,12 @@ +# General scene settings +- ambientcolor: Color to use when clearing the scene +- bloom: Whether bloom is enabled or not + +- orthogonalprojection: + - width: width of the orthogonalprojection + - height: height of the orthogonal projection + +# camera settings +- farz: projection's far clip (optional) +- nearz: projection's near clip (optional) +- fov: field of view (optional) \ No newline at end of file diff --git a/docs/rendering/IMAGE_OBJECTS.md b/docs/rendering/IMAGE_OBJECTS.md new file mode 100644 index 0000000..47ab177 --- /dev/null +++ b/docs/rendering/IMAGE_OBJECTS.md @@ -0,0 +1,11 @@ +# Image objects +Image objects are simple quads that display an image in them. These are usually used in orthogonal scenes to display animated effects. + +Looks like every image object has two framebuffers used for ping-pong when rendering, these are usually registered as: +- _rt_imageLayerComposite_{id}_a +- _rt_imageLayerComposite_{id}_b + +There's special textures used for various things: +- _rt_FullFrameBuffer: Represents the things currently rendered to the background's output +- _rt_HalfCompoBuffer1: Unknown for now +- _rt_HalfCompoBuffer2: Unknown for now diff --git a/docs/rendering/OBJECTS.md b/docs/rendering/OBJECTS.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/rendering/SOUND_OBJECTS.md b/docs/rendering/SOUND_OBJECTS.md new file mode 100644 index 0000000..4b2c43a --- /dev/null +++ b/docs/rendering/SOUND_OBJECTS.md @@ -0,0 +1,12 @@ +# Sound objects +These are the simplest ones. They contain a simple list of sounds to play (one after another? needs to be confirmed) and simple information like volume, playmode, etc... + +## Specific json entries +- sound: An array of music files to play +- volume: The volume to play the music at. 0.0f - 1.0f +- mintime: The minimum delay between background rendering starting and sound starting +- maxtime: The maximum delay between background rendering starting and sound starting +- playbackmode: Whether the sound has to be looped or played oneshot... + +## Editor json entries +- muteineditor: Whether the sound has to be muted by default \ No newline at end of file diff --git a/main.cpp b/main.cpp index 918db64..8a05117 100644 --- a/main.cpp +++ b/main.cpp @@ -71,9 +71,7 @@ std::string stringPathFixes(const std::string& s) int main (int argc, char* argv[]) { std::vector screens; - bool isRootWindow = false; - int mode = RUN_MODE_UNKNOWN; int maximumFPS = 30; bool shouldEnableAudio = true; std::string path; @@ -100,19 +98,12 @@ int main (int argc, char* argv[]) switch (c) { case 'r': - isRootWindow = true; screens.emplace_back (optarg); break; case 'p': - if (mode == RUN_MODE_UNKNOWN) - mode = RUN_MODE_PACKAGE; - path = stringPathFixes (optarg); - break; - case 'd': - if (mode == RUN_MODE_UNKNOWN) - mode = RUN_MODE_DIRECTORY; + std::cout << "--dir/--pkg is deprecated and not used anymore" << std::endl; path = stringPathFixes (optarg); break; @@ -121,7 +112,7 @@ int main (int argc, char* argv[]) break; case 'h': - mode = RUN_MODE_HELP; + print_help (argv [0]); break; case 'f': @@ -133,7 +124,7 @@ int main (int argc, char* argv[]) } } - if (mode == RUN_MODE_UNKNOWN || mode == RUN_MODE_HELP) + if (path.empty () == true && option_index == 0 || strlen (argv [option_index]) == 0) { print_help (argv [0]); return 0; @@ -161,17 +152,17 @@ int main (int argc, char* argv[]) containers->add (new WallpaperEngine::Assets::CDirectory ("./assets/")); // the background's path is required to load project.json regardless of the type of background we're using containers->add (new WallpaperEngine::Assets::CDirectory (path)); - - if (mode == RUN_MODE_PACKAGE) + // check if scene.pkg exists and add it to the list + try { std::string scene_path = path + "scene.pkg"; // add the package to the list containers->add (new WallpaperEngine::Assets::CPackage (scene_path)); } - else if (mode == RUN_MODE_DIRECTORY) + catch (std::runtime_error ex) { - // nothing to do here anymore + // ignore the exception, this is to be expected of normal backgrounds } // parse the project.json file @@ -259,7 +250,7 @@ int main (int argc, char* argv[]) glDepthFunc (GL_LESS); // cull anything that doesn't look at the camera (might be useful to disable in the future) - //glEnable (GL_CULL_FACE); + glDisable (GL_CULL_FACE); clock_t minimumTime = 1000 / maximumFPS; clock_t startTime = 0; diff --git a/src/WallpaperEngine/Assets/CContainer.cpp b/src/WallpaperEngine/Assets/CContainer.cpp index c09fe04..97600ce 100644 --- a/src/WallpaperEngine/Assets/CContainer.cpp +++ b/src/WallpaperEngine/Assets/CContainer.cpp @@ -1,11 +1,12 @@ #include "CContainer.h" +#include "CTexture.h" #include #include using namespace WallpaperEngine::Assets; -CTexture* CContainer::readTexture (std::string filename) +ITexture* CContainer::readTexture (std::string filename) { // get the texture's filename (usually .tex) filename = "materials/" + filename + ".tex"; diff --git a/src/WallpaperEngine/Assets/CContainer.h b/src/WallpaperEngine/Assets/CContainer.h index 206633b..568d859 100644 --- a/src/WallpaperEngine/Assets/CContainer.h +++ b/src/WallpaperEngine/Assets/CContainer.h @@ -1,11 +1,7 @@ -// -// Created by almamu on 8/8/21. -// - #pragma once #include -#include "WallpaperEngine/Assets/CTexture.h" +#include "WallpaperEngine/Assets/ITexture.h" namespace WallpaperEngine::Assets { @@ -30,7 +26,7 @@ namespace WallpaperEngine::Assets * * @return */ - CTexture* readTexture (std::string filename); + ITexture* readTexture (std::string filename); /** * Wrapper for readFile, appends the .vert extension at the end and opens the given shader file diff --git a/src/WallpaperEngine/Assets/CTexture.cpp b/src/WallpaperEngine/Assets/CTexture.cpp index 00ede0c..d007631 100644 --- a/src/WallpaperEngine/Assets/CTexture.cpp +++ b/src/WallpaperEngine/Assets/CTexture.cpp @@ -177,6 +177,31 @@ const GLuint CTexture::getTextureID () const return this->m_textureID; } +const uint32_t CTexture::getTextureWidth () const +{ + return this->getHeader ()->textureWidth; +} + +const uint32_t CTexture::getTextureHeight () const +{ + return this->getHeader ()->textureHeight; +} + +const uint32_t CTexture::getRealWidth () const +{ + return this->getHeader ()->width; +} + +const uint32_t CTexture::getRealHeight () const +{ + return this->getHeader ()->height; +} + +const ITexture::TextureFormat CTexture::getFormat () const +{ + return this->getHeader ()->format; +} + const CTexture::TextureHeader* CTexture::getHeader () const { return this->m_header; diff --git a/src/WallpaperEngine/Assets/CTexture.h b/src/WallpaperEngine/Assets/CTexture.h index 8bd3c9a..82060ee 100644 --- a/src/WallpaperEngine/Assets/CTexture.h +++ b/src/WallpaperEngine/Assets/CTexture.h @@ -8,10 +8,11 @@ #include #include +#include "ITexture.h" namespace WallpaperEngine::Assets { - class CTexture + class CTexture : public ITexture { struct TextureHeader; @@ -19,21 +20,17 @@ namespace WallpaperEngine::Assets CTexture (void* fileData); ~CTexture (); - const GLuint getTextureID () const; - const TextureHeader* getHeader () const; - const glm::vec4* getResolution () const; + const GLuint getTextureID () const override; + const uint32_t getTextureWidth () const override; + const uint32_t getTextureHeight () const override; + const uint32_t getRealWidth () const override; + const uint32_t getRealHeight () const override; + const TextureFormat getFormat () const override; + const glm::vec4* getResolution () const override; - - enum TextureFormat : uint32_t - { - ARGB8888 = 0, - DXT5 = 4, - DXT3 = 6, - DXT1 = 7, - RG88 = 8, - R8 = 9, - }; private: + const TextureHeader* getHeader () const; + enum ContainerVersion : int { UNKNOWN = -1, diff --git a/src/WallpaperEngine/Assets/ITexture.h b/src/WallpaperEngine/Assets/ITexture.h new file mode 100644 index 0000000..6419b8e --- /dev/null +++ b/src/WallpaperEngine/Assets/ITexture.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +namespace WallpaperEngine::Assets +{ + class ITexture + { + public: + enum TextureFormat : uint32_t + { + ARGB8888 = 0, + DXT5 = 4, + DXT3 = 6, + DXT1 = 7, + RG88 = 8, + R8 = 9, + }; + + virtual const GLuint getTextureID () const = 0; + virtual const uint32_t getTextureWidth () const = 0; + virtual const uint32_t getTextureHeight () const = 0; + virtual const uint32_t getRealWidth () const = 0; + virtual const uint32_t getRealHeight () const = 0; + virtual const TextureFormat getFormat () const = 0; + virtual const glm::vec4* getResolution () const = 0; + }; +}; \ No newline at end of file diff --git a/src/WallpaperEngine/Core/Objects/CEffect.cpp b/src/WallpaperEngine/Core/Objects/CEffect.cpp index 45abe3f..859c021 100644 --- a/src/WallpaperEngine/Core/Objects/CEffect.cpp +++ b/src/WallpaperEngine/Core/Objects/CEffect.cpp @@ -5,7 +5,7 @@ #include "WallpaperEngine/Core/Objects/CImage.h" #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h" #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h" -#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h" +#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h" #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h" #include "WallpaperEngine/FileSystem/FileSystem.h" @@ -161,7 +161,8 @@ void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Object } else if ((*cur).is_string () == true) { - constant = new Effects::Constants::CShaderConstantVector3 (WallpaperEngine::Core::aToVector3 (*cur)); + // try a vector 4 first, then a vector3 and then a vector 2 + constant = new Effects::Constants::CShaderConstantVector4 (WallpaperEngine::Core::aToVector4 (*cur)); } else { diff --git a/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector2.cpp b/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector2.cpp new file mode 100644 index 0000000..a121b9a --- /dev/null +++ b/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector2.cpp @@ -0,0 +1,17 @@ +#include "CShaderConstantVector2.h" + +using namespace WallpaperEngine::Core::Objects::Effects::Constants; + + +CShaderConstantVector2::CShaderConstantVector2 (glm::vec2 value) : + CShaderConstant (Type), + m_value (value) +{ +} + +glm::vec2* CShaderConstantVector2::getValue () +{ + return &this->m_value; +} + +const std::string CShaderConstantVector3::Type = "vec2"; \ No newline at end of file diff --git a/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector2.h b/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector2.h new file mode 100644 index 0000000..7740140 --- /dev/null +++ b/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector2.h @@ -0,0 +1,21 @@ +#pragma once + +#include "CShaderConstant.h" + +#include +#include + +namespace WallpaperEngine::Core::Objects::Effects::Constants +{ + class CShaderConstantVector2 : public CShaderConstant + { + public: + CShaderConstantVector2 (glm::vec2 value); + + glm::vec2* getValue (); + + static const std::string Type; + protected: + glm::vec2 m_value; + }; +} diff --git a/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.cpp b/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.cpp index 71596e6..5afd7bf 100644 --- a/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.cpp +++ b/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.cpp @@ -2,7 +2,6 @@ using namespace WallpaperEngine::Core::Objects::Effects::Constants; - CShaderConstantVector3::CShaderConstantVector3 (glm::vec3 value) : CShaderConstant (Type), m_value (value) diff --git a/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.cpp b/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.cpp new file mode 100644 index 0000000..173db22 --- /dev/null +++ b/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.cpp @@ -0,0 +1,17 @@ +#include "CShaderConstantVector4.h" + +using namespace WallpaperEngine::Core::Objects::Effects::Constants; + + +CShaderConstantVector4::CShaderConstantVector4 (glm::vec4 value) : + CShaderConstant (Type), + m_value (value) +{ +} + +glm::vec4* CShaderConstantVector4::getValue () +{ + return &this->m_value; +} + +const std::string CShaderConstantVector4::Type = "vec4"; \ No newline at end of file diff --git a/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h b/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h new file mode 100644 index 0000000..c080127 --- /dev/null +++ b/src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h @@ -0,0 +1,21 @@ +#pragma once + +#include "CShaderConstant.h" + +#include +#include + +namespace WallpaperEngine::Core::Objects::Effects::Constants +{ + class CShaderConstantVector4 : public CShaderConstant + { + public: + CShaderConstantVector4 (glm::vec4 value); + + glm::vec4* getValue (); + + static const std::string Type; + protected: + glm::vec4 m_value; + }; +} diff --git a/src/WallpaperEngine/Render/CFBO.cpp b/src/WallpaperEngine/Render/CFBO.cpp new file mode 100644 index 0000000..8938eaa --- /dev/null +++ b/src/WallpaperEngine/Render/CFBO.cpp @@ -0,0 +1,99 @@ +#include "CFBO.h" + +using namespace WallpaperEngine::Render; + +CFBO::CFBO (std::string name, ITexture::TextureFormat format, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight) : + m_name (std::move (name)), + m_format (format), + m_scale (scale) +{ + GLenum drawBuffers [1] = {GL_COLOR_ATTACHMENT0}; + // create the main framebuffer + glGenFramebuffers (1, &this->m_framebuffer); + glBindFramebuffer (GL_FRAMEBUFFER, this->m_framebuffer); + // create the main texture + glGenTextures (1, &this->m_texture); + // bind the new texture to set settings on it + glBindTexture (GL_TEXTURE_2D, this->m_texture); + // give OpenGL an empty image + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + // set filtering parameters, otherwise the texture is not rendered + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + // create the depth render buffer for the main framebuffer + glGenRenderbuffers (1, &this->m_depthbuffer); + glBindRenderbuffer (GL_RENDERBUFFER, this->m_depthbuffer); + glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT, textureWidth, textureHeight); + glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, this->m_depthbuffer); + // set the texture as the colour attachmend #0 + glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->m_texture, 0); + // finally set the list of draw buffers + glDrawBuffers (1, drawBuffers); + + // ensure first framebuffer is okay + if (glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + throw std::runtime_error ("Framebuffers are not properly set"); + + this->m_resolution = { + textureWidth, textureHeight, + realWidth, realHeight + }; +} + +const std::string& CFBO::getName () const +{ + return this->m_name; +} + +const float& CFBO::getScale () const +{ + return this->m_scale; +} + +const ITexture::TextureFormat CFBO::getFormat () const +{ + return this->m_format; +} + +GLuint CFBO::getFramebuffer () const +{ + return this->m_framebuffer; +} + +GLuint CFBO::getDepthbuffer () const +{ + return this->m_depthbuffer; +} + +const GLuint CFBO::getTextureID () const +{ + return this->m_texture; +} + +const uint32_t CFBO::getTextureWidth () const +{ + return this->m_resolution.x; +} +const uint32_t CFBO::getTextureHeight () const +{ + return this->m_resolution.y; +} + +const uint32_t CFBO::getRealWidth () const +{ + return this->m_resolution.z; +} + +const uint32_t CFBO::getRealHeight () const +{ + return this->m_resolution.w; +} + +const glm::vec4* CFBO::getResolution () const +{ + return &this->m_resolution; +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/CFBO.h b/src/WallpaperEngine/Render/CFBO.h new file mode 100644 index 0000000..0d5ae71 --- /dev/null +++ b/src/WallpaperEngine/Render/CFBO.h @@ -0,0 +1,38 @@ +#pragma once + +#include "WallpaperEngine/Core/Objects/Effects/CFBO.h" +#include "WallpaperEngine/Core/Objects/CImage.h" +#include "WallpaperEngine/Assets/ITexture.h" + +using namespace WallpaperEngine::Assets; + +namespace WallpaperEngine::Render +{ + class CFBO : public ITexture + { + public: + CFBO (std::string name, ITexture::TextureFormat format, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight); + + const std::string& getName () const; + const float& getScale () const; + const ITexture::TextureFormat getFormat () const override; + GLuint getFramebuffer () const; + GLuint getDepthbuffer () const; + const GLuint getTextureID () const override; + const uint32_t getTextureWidth () const override; + const uint32_t getTextureHeight () const override; + const uint32_t getRealWidth () const override; + const uint32_t getRealHeight () const override; + const glm::vec4* getResolution () const override; + + private: + + GLuint m_framebuffer; + GLuint m_depthbuffer; + GLuint m_texture; + glm::vec4 m_resolution; + float m_scale; + std::string m_name; + ITexture::TextureFormat m_format; + }; +}; diff --git a/src/WallpaperEngine/Render/CScene.cpp b/src/WallpaperEngine/Render/CScene.cpp index 588f3bc..03cbfd3 100644 --- a/src/WallpaperEngine/Render/CScene.cpp +++ b/src/WallpaperEngine/Render/CScene.cpp @@ -18,6 +18,8 @@ CScene::CScene (Core::CScene* scene, CContainer* container) : scene->getOrthogonalProjection ()->getWidth (), scene->getOrthogonalProjection ()->getHeight () ); + // setup framebuffers + this->setupFramebuffers (); auto cur = scene->getObjects ().begin (); auto end = scene->getObjects ().end (); @@ -38,8 +40,6 @@ CScene::CScene (Core::CScene* scene, CContainer* container) : if (object != nullptr) this->m_objects.emplace_back (object); } - - this->setupFramebuffers (); } CCamera* CScene::getCamera () const diff --git a/src/WallpaperEngine/Render/CVideo.cpp b/src/WallpaperEngine/Render/CVideo.cpp index 6c6039b..de67743 100644 --- a/src/WallpaperEngine/Render/CVideo.cpp +++ b/src/WallpaperEngine/Render/CVideo.cpp @@ -123,7 +123,7 @@ void CVideo::renderFrame () writeFrameToImage (); glViewport (0, 0, this->getWidth (), this->getHeight ()); - + // do the actual rendering // write to default's framebuffer glBindFramebuffer (GL_FRAMEBUFFER, this->getWallpaperFramebuffer()); diff --git a/src/WallpaperEngine/Render/CWallpaper.cpp b/src/WallpaperEngine/Render/CWallpaper.cpp index b8b8b80..01c1731 100644 --- a/src/WallpaperEngine/Render/CWallpaper.cpp +++ b/src/WallpaperEngine/Render/CWallpaper.cpp @@ -59,12 +59,12 @@ WallpaperEngine::Core::CWallpaper* CWallpaper::getWallpaperData () GLuint CWallpaper::getWallpaperFramebuffer () const { - return this->m_sceneFramebuffer; + return this->m_sceneFBO->getFramebuffer (); } GLuint CWallpaper::getWallpaperTexture () const { - return this->m_sceneTexture; + return this->m_sceneFBO->getTextureID(); } void CWallpaper::setupShaders () @@ -287,25 +287,21 @@ void CWallpaper::render (glm::vec4 viewport, bool newFrame) void CWallpaper::pinpongFramebuffer (GLuint* drawTo, GLuint* inputTexture) { - // get current main framebuffer and texture so we can swap them - GLuint currentMainFramebuffer = this->m_mainFramebuffer; - GLuint currentMainTexture = this->m_mainTexture; - GLuint currentSubFramebuffer = this->m_subFramebuffer; - GLuint currentSubTexture = this->m_subTexture; + // temporarily store FBOs used + CFBO* currentMainFBO = this->m_mainFBO; + CFBO* currentSubFBO = this->m_subFBO; if (drawTo != nullptr) - *drawTo = currentSubFramebuffer; + *drawTo = currentSubFBO->getFramebuffer (); if (inputTexture != nullptr) - *inputTexture = currentMainTexture; + *inputTexture = currentMainFBO->getTextureID(); - // swap the textures - this->m_mainFramebuffer = currentSubFramebuffer; - this->m_mainTexture = currentSubTexture; - this->m_subFramebuffer = currentMainFramebuffer; - this->m_subTexture = currentMainTexture; + // swap the FBOs + this->m_mainFBO = currentSubFBO; + this->m_subFBO = currentMainFBO; } -void CWallpaper::createFramebuffer (GLuint* framebuffer, GLuint* depthbuffer, GLuint* texture) +void CWallpaper::setupFramebuffers () { int windowWidth = 1920; int windowHeight = 1080; @@ -325,42 +321,33 @@ void CWallpaper::createFramebuffer (GLuint* framebuffer, GLuint* depthbuffer, GL windowHeight = video->getHeight (); } - GLenum drawBuffers [1] = {GL_COLOR_ATTACHMENT0}; - // create the main framebuffer - glGenFramebuffers (1, framebuffer); - glBindFramebuffer (GL_FRAMEBUFFER, *framebuffer); - // create the main texture - glGenTextures (1, texture); - // bind the new texture to set settings on it - glBindTexture (GL_TEXTURE_2D, *texture); - // give OpenGL an empty image - glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, windowWidth, windowHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - - // set filtering parameters, otherwise the texture is not rendered - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - // create the depth render buffer for the main framebuffer - glGenRenderbuffers (1, depthbuffer); - glBindRenderbuffer (GL_RENDERBUFFER, *depthbuffer); - glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT, windowWidth, windowHeight); - glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *depthbuffer); - // set the texture as the colour attachmend #0 - glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texture, 0); - // finally set the list of draw buffers - glDrawBuffers (1, drawBuffers); - - // ensure first framebuffer is okay - if (glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - throw std::runtime_error ("Framebuffers are not properly set"); + this->m_mainFBO = this->createFBO ("_rt_FullFrameBuffera", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight); + this->m_subFBO = this->createFBO ("_rt_FullFrameBuffera", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight); + // create framebuffer for the scene + this->m_sceneFBO = this->createFBO ("_rt_FullFrameBuffer", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight); } -void CWallpaper::setupFramebuffers () +CFBO* CWallpaper::createFBO (const std::string& name, ITexture::TextureFormat format, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight) { - this->createFramebuffer (&this->m_mainFramebuffer, &this->m_mainDepthBuffer, &this->m_mainTexture); - this->createFramebuffer (&this->m_subFramebuffer, &this->m_subDepthBuffer, &this->m_subTexture); - // create framebuffer for the scene - this->createFramebuffer (&this->m_sceneFramebuffer, &this->m_sceneDepthBuffer, &this->m_sceneTexture); + CFBO* fbo = new CFBO (name, format, scale, realWidth, realHeight, textureWidth, textureHeight); + + this->m_fbos.insert (std::make_pair (name, fbo)); + + return fbo; +} + +const std::map& CWallpaper::getFBOs () const +{ + return this->m_fbos; +} + + +const CFBO* CWallpaper::findFBO (const std::string& name) const +{ + auto it = this->m_fbos.find (name); + + if (it == this->m_fbos.end ()) + throw std::runtime_error ("Cannot find given FBO"); + + return it->second; } \ No newline at end of file diff --git a/src/WallpaperEngine/Render/CWallpaper.h b/src/WallpaperEngine/Render/CWallpaper.h index e667f77..b114dd9 100644 --- a/src/WallpaperEngine/Render/CWallpaper.h +++ b/src/WallpaperEngine/Render/CWallpaper.h @@ -8,6 +8,7 @@ #include "WallpaperEngine/Core/CVideo.h" #include "WallpaperEngine/Assets/CContainer.h" +#include "CFBO.h" using namespace WallpaperEngine::Assets; @@ -50,6 +51,25 @@ namespace WallpaperEngine::Render * @return The scene's texture */ GLuint getWallpaperTexture () const; + /** + * Creates a new FBO for this wallpaper + * + * @param name The name of the FBO + * @return + */ + CFBO* createFBO (const std::string& name, ITexture::TextureFormat format, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight); + + /** + * @return The full FBO list to work with + */ + const std::map& getFBOs () const; + /** + * Searches the FBO list for the given FBO + * + * @param name + * @return + */ + const CFBO* findFBO (const std::string& name) const; protected: /** @@ -62,54 +82,29 @@ namespace WallpaperEngine::Render */ void setupFramebuffers (); - void createFramebuffer (GLuint* framebuffer, GLuint* depthbuffer, GLuint* texture); - CContainer* m_container; Core::CWallpaper* m_wallpaperData; Core::CWallpaper* getWallpaperData (); /** - * The main framebuffer + * The main FBO used for ping pong */ - GLuint m_mainFramebuffer; + CFBO* m_mainFBO; /** - * The sub framebuffer + * The sub FBO used for ping pong */ - GLuint m_subFramebuffer; + CFBO* m_subFBO; /** - * The main depth render buffer + * The FBO used for scene output */ - GLuint m_mainDepthBuffer; - /** - * The sub depth render buffer - */ - GLuint m_subDepthBuffer; - - /** - * The main texture used on the framebuffer - */ - GLuint m_mainTexture; - /** - * The sub texture used on the framebuffer - */ - GLuint m_subTexture; - - /** - * The framebuffer used for the scene output - */ - GLuint m_sceneFramebuffer; - /** - * The depthbuffer used for the scene output - */ - GLuint m_sceneDepthBuffer; + CFBO* m_sceneFBO; private: /** * The texture used for the scene output */ - GLuint m_sceneTexture; GLuint m_texCoordBuffer; GLuint m_positionBuffer; GLuint m_shader; @@ -125,5 +120,10 @@ namespace WallpaperEngine::Render * The type of background this wallpaper is (used */ std::string m_type; + + /** + * List of FBOs registered for this wallpaper + */ + std::map m_fbos; }; } diff --git a/src/WallpaperEngine/Render/Objects/CEffect.cpp b/src/WallpaperEngine/Render/Objects/CEffect.cpp index 0afa5d6..3266609 100644 --- a/src/WallpaperEngine/Render/Objects/CEffect.cpp +++ b/src/WallpaperEngine/Render/Objects/CEffect.cpp @@ -1,6 +1,7 @@ #include "CEffect.h" using namespace WallpaperEngine::Render::Objects; +using namespace WallpaperEngine::Render; CEffect::CEffect (CImage* image, Core::Objects::CEffect* effect) : m_image (image), @@ -10,7 +11,7 @@ CEffect::CEffect (CImage* image, Core::Objects::CEffect* effect) : this->generatePasses (); } -const CImage* CEffect::getImage () const +CImage* CEffect::getImage () const { return this->m_image; } @@ -20,7 +21,7 @@ const std::vector& CEffect::getMaterials () const return this->m_materials; } -Effects::CFBO* CEffect::findFBO (const std::string& name) +const CFBO* CEffect::findFBO (const std::string& name) const { auto cur = this->m_fbos.begin (); auto end = this->m_fbos.end (); @@ -42,7 +43,7 @@ void CEffect::generatePasses () auto end = this->m_effect->getMaterials ().end (); for (; cur != end; cur ++) - this->m_materials.emplace_back (new Effects::CMaterial (this->getImage (), *cur)); + this->m_materials.emplace_back (new Effects::CMaterial (this, *cur)); } void CEffect::generateFBOs () @@ -53,23 +54,15 @@ void CEffect::generateFBOs () for (; cur != end; cur ++) { this->m_fbos.push_back ( - new Effects::CFBO (*cur, this->m_image->getImage ()) + new CFBO ( + (*cur)->getName (), + ITexture::TextureFormat::ARGB8888, // TODO: CHANGE + (*cur)->getScale (), + this->m_image->getImage ()->getSize ().x, + this->m_image->getImage ()->getSize ().y, + this->m_image->getImage ()->getSize ().x, + this->m_image->getImage ()->getSize ().y + ) ); } -} - -void CEffect::render (GLuint drawTo, GLuint inputTexture) -{ - auto begin = this->getMaterials ().begin (); - auto cur = this->getMaterials ().begin (); - auto end = this->getMaterials ().end (); - - for (; cur != end; cur ++) - { - // pingpong buffer only if not the first pass (as it would be taken care by the CImage) - if (cur != begin) - this->getImage ()->getScene ()->pinpongFramebuffer (&drawTo, &inputTexture); - - (*cur)->render (drawTo, inputTexture); - } } \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Objects/CEffect.h b/src/WallpaperEngine/Render/Objects/CEffect.h index 5c3799a..3d92b4a 100644 --- a/src/WallpaperEngine/Render/Objects/CEffect.h +++ b/src/WallpaperEngine/Render/Objects/CEffect.h @@ -1,7 +1,7 @@ #pragma once #include "WallpaperEngine/Render/Objects/CImage.h" -#include "WallpaperEngine/Render/Objects/Effects/CFBO.h" +#include "WallpaperEngine/Render/CFBO.h" #include "WallpaperEngine/Render/Objects/Effects/CPass.h" #include "WallpaperEngine/Render/Objects/Effects/CMaterial.h" @@ -19,13 +19,12 @@ namespace WallpaperEngine::Render::Objects public: CEffect (CImage* image, Core::Objects::CEffect* effect); - const CImage* getImage () const; + CImage* getImage () const; const std::vector& getMaterials () const; - Effects::CFBO* findFBO (const std::string& name); + const CFBO* findFBO (const std::string& name) const; - void render (GLuint drawTo, GLuint inputTexture); private: void generatePasses (); void generateFBOs (); @@ -33,7 +32,7 @@ namespace WallpaperEngine::Render::Objects CImage* m_image; Core::Objects::CEffect* m_effect; - std::vector m_fbos; + std::vector m_fbos; std::vector m_materials; }; }; diff --git a/src/WallpaperEngine/Render/Objects/CImage.cpp b/src/WallpaperEngine/Render/Objects/CImage.cpp index e3b9ccd..8515151 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.cpp +++ b/src/WallpaperEngine/Render/Objects/CImage.cpp @@ -1,3 +1,4 @@ +#include #include "CImage.h" using namespace WallpaperEngine; @@ -5,7 +6,8 @@ using namespace WallpaperEngine::Render::Objects; CImage::CImage (CScene* scene, Core::Objects::CImage* image) : Render::CObject (scene, Type, image), - m_image (image) + m_image (image), + m_texture (nullptr) { auto projection = this->getScene ()->getScene ()->getOrthogonalProjection (); @@ -22,24 +24,40 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : // depending on the alignment these values might change, for now just support center if (this->getImage ()->getAlignment () == "center") { + glm::vec2 size = this->getImage ()->getSize (); + glm::vec3 scale = this->getImage ()->getScale (); + // calculate the real position of the image - xleft = this->getImage ()->getOrigin ().x - (this->getImage ()->getSize ().x / 2); - xright = this->getImage ()->getOrigin ().x + (this->getImage ()->getSize ().x / 2); - ytop = this->getImage ()->getOrigin ().y - (this->getImage ()->getSize ().y / 2); - ybottom = this->getImage ()->getOrigin ().y + (this->getImage ()->getSize ().y / 2); + xleft = this->getImage ()->getOrigin ().x - (size.x * scale.x / 2); + xright = this->getImage ()->getOrigin ().x + (size.x * scale.x / 2); + ytop = this->getImage ()->getOrigin ().y - (size.y * scale.y / 2); + ybottom = this->getImage ()->getOrigin ().y + (size.y * scale.y / 2); } else { throw std::runtime_error ("Only centered images are supported for now!"); } - // load image from the .tex file - uint32_t textureSize = 0; + std::string textureName = (*(*this->m_image->getMaterial ()->getPasses ().begin ())->getTextures ().begin ()); - // get the first texture on the first pass (this one represents the image assigned to this object) - this->m_texture = this->getScene ()->getContainer ()->readTexture ( - (*(*this->m_image->getMaterial ()->getPasses ().begin ())->getTextures ().begin ()) - ); + if (textureName.find ("_rt_") == 0) + { + this->m_texture = this->getScene ()->findFBO (textureName); + } + else + { + // get the first texture on the first pass (this one represents the image assigned to this object) + this->m_texture = this->getScene ()->getContainer ()->readTexture (textureName); + } + + // register both FBOs into the scene + std::ostringstream nameA, nameB; + + nameA << "_rt_imageLayerComposite_" << this->getImage ()->getId () << "_a"; + nameA << "_rt_imageLayerComposite_" << this->getImage ()->getId () << "_b"; + + this->m_mainFBO = scene->createFBO (nameA.str (), ITexture::TextureFormat::ARGB8888, 1, this->m_texture->getRealWidth (), this->m_texture->getRealHeight (), this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight ()); + this->m_subFBO = scene->createFBO (nameB.str (), ITexture::TextureFormat::ARGB8888, 1, this->m_texture->getRealWidth (), this->m_texture->getRealHeight (), this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight ()); // build a list of vertices, these might need some change later (or maybe invert the camera) GLfloat data [] = { @@ -68,17 +86,21 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : float height = 1.0f; // calculate the correct texCoord limits for the texture based on the texture screen size and real size - if (this->getTexture ()->getHeader ()->textureWidth != this->getTexture ()->getHeader ()->width || - this->getTexture ()->getHeader ()->textureHeight != this->getTexture ()->getHeader ()->height) + if (this->getTexture () != nullptr && + (this->getTexture ()->getTextureWidth () != this->getTexture ()->getRealWidth () || + this->getTexture ()->getTextureHeight () != this->getTexture ()->getRealHeight ()) + ) { uint32_t x = 1; uint32_t y = 1; + glm::vec2 size = this->getImage ()->getSize (); + glm::vec3 scale = this->getImage ()->getScale (); - while (x < this->getImage ()->getSize ().x) x <<= 1; - while (y < this->getImage ()->getSize ().y) y <<= 1; + while (x < size.x) x <<= 1; + while (y < size.y) y <<= 1; - width = this->getImage ()->getSize ().x / x; - height = this->getImage ()->getSize ().y / y; + width = size.x * scale.x / x; + height = size.y * scale.y / y; } GLfloat data2 [] = { @@ -122,7 +144,10 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : glBufferData (GL_ARRAY_BUFFER, sizeof (this->m_passTexCoordList), this->m_passTexCoordList, GL_STATIC_DRAW); // generate the main material used to render the image - this->m_material = new Effects::CMaterial (this, this->m_image->getMaterial ()); + this->m_material = new Effects::CMaterial ( + new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image)), + this->m_image->getMaterial () + ); // generate the effects used by this material auto cur = this->getImage ()->getEffects ().begin (); @@ -132,40 +157,72 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : this->m_effects.emplace_back (new CEffect (this, *cur)); } +void CImage::pinpongFramebuffer (GLuint* drawTo, GLuint* inputTexture) +{ + // temporarily store FBOs used + CFBO* currentMainFBO = this->m_mainFBO; + CFBO* currentSubFBO = this->m_subFBO; + + if (drawTo != nullptr) + *drawTo = currentSubFBO->getFramebuffer (); + if (inputTexture != nullptr) + *inputTexture = currentMainFBO->getTextureID (); + + // swap the FBOs + this->m_mainFBO = currentSubFBO; + this->m_subFBO = currentMainFBO; +} + void CImage::render () { - // ensure this image is visible first - if (this->getImage ()->isVisible () == false) - return; + // start drawing to the main framebuffer + GLuint drawTo = this->m_mainFBO->getFramebuffer (); + GLuint inputTexture = this->getTexture ()->getTextureID (); - GLuint drawTo = this->getScene()->getWallpaperFramebuffer(); - GLuint inputTexture = this->m_texture->getTextureID (); - - // pinpong current buffer - this->getScene ()->pinpongFramebuffer (&drawTo, nullptr); // render all the other materials auto cur = this->getEffects ().begin (); auto end = this->getEffects ().end (); - auto begin = this->getEffects ().begin (); + inputTexture = this->getTexture ()->getTextureID (); + + // set the correct viewport + glViewport (0, 0, this->getTexture ()->getRealWidth (), this->getTexture ()->getRealHeight ()); + + // render all the passes first for (; cur != end; cur ++) { - if (cur != begin) - // pinpong current buffer - this->getScene ()->pinpongFramebuffer (&drawTo, &inputTexture); + auto materialCur = (*cur)->getMaterials ().begin (); + auto materialEnd = (*cur)->getMaterials ().end (); - // render now - (*cur)->render (drawTo, inputTexture); + for (; materialCur != materialEnd; materialCur ++) + { + auto passCur = (*materialCur)->getPasses ().begin (); + auto passEnd = (*materialCur)->getPasses ().end (); + + for (; passCur != passEnd; passCur ++) + { + (*passCur)->render (drawTo, inputTexture); + + this->pinpongFramebuffer (&drawTo, &inputTexture); + } + } } - if (this->getEffects ().size () > 0) - this->getScene ()->pinpongFramebuffer (nullptr, &inputTexture); + if (this->getImage ()->isVisible () == false) + return; - // render the main material - this->m_material->render (this->getScene()->getWallpaperFramebuffer(), inputTexture); + // this material only has one pass that we know of + // so just take that and render it to the screen's framebuffer + auto pass = this->m_material->getPasses ().begin (); + auto projection = this->getScene ()->getScene ()->getOrthogonalProjection (); + + // set the viewport properly + glViewport (0, 0, projection->getWidth (), projection->getHeight ()); + + (*pass)->render (this->getScene ()->getWallpaperFramebuffer (), inputTexture); } -const CTexture* CImage::getTexture () const +const ITexture* CImage::getTexture () const { return this->m_texture; } diff --git a/src/WallpaperEngine/Render/Objects/CImage.h b/src/WallpaperEngine/Render/Objects/CImage.h index 182ccaf..a801b24 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.h +++ b/src/WallpaperEngine/Render/Objects/CImage.h @@ -9,7 +9,7 @@ #include "WallpaperEngine/Render/Shaders/Compiler.h" -#include "WallpaperEngine/Assets/CTexture.h" +#include "WallpaperEngine/Assets/ITexture.h" #include @@ -40,13 +40,21 @@ namespace WallpaperEngine::Render::Objects const GLuint* getPassVertexBuffer () const; const GLuint* getTexCoordBuffer () const; const GLuint* getPassTexCoordBuffer () const; - const CTexture* getTexture () const; + const ITexture* getTexture () const; + + /** + * Performs a ping-pong on the available framebuffers to be able to continue rendering things to them + * + * @param drawTo The framebuffer to use + * @param asInput The last texture used as output (if needed) + */ + void pinpongFramebuffer (GLuint* drawTo, GLuint* inputTexture); protected: static const std::string Type; private: - CTexture* m_texture; + const ITexture* m_texture; GLfloat m_vertexList [6 * 3]; GLfloat m_passesVertexList [6 * 3]; GLfloat m_texCoordList [6 * 2]; @@ -57,6 +65,8 @@ namespace WallpaperEngine::Render::Objects GLuint m_passTexCoordBuffer; uint16_t m_vertexIndices [6]; + CFBO* m_mainFBO; + CFBO* m_subFBO; Core::Objects::CImage* m_image; diff --git a/src/WallpaperEngine/Render/Objects/Effects/CFBO.cpp b/src/WallpaperEngine/Render/Objects/Effects/CFBO.cpp deleted file mode 100644 index 00aff8b..0000000 --- a/src/WallpaperEngine/Render/Objects/Effects/CFBO.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "CFBO.h" - -using namespace WallpaperEngine::Render::Objects::Effects; - -CFBO::CFBO (Core::Objects::Effects::CFBO* fbo, const Core::Objects::CImage* image) : - m_fbo (fbo) -{ - // TODO: REWRITE - /*irr::core::dimension2du size = irr::core::dimension2du ( - image->getSize ().x * this->getScale (), - image->getSize ().y * this->getScale () - ); - - context->getDevice ()->getVideoDriver ()->addRenderTargetTexture (size, this->getName ().c_str ());*/ -} - -const std::string& CFBO::getName () const -{ - return this->m_fbo->getName (); -} - -const float& CFBO::getScale () const -{ - return this->m_fbo->getScale (); -} - -const std::string& CFBO::getFormat () const -{ - return this->m_fbo->getFormat (); -} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Objects/Effects/CFBO.h b/src/WallpaperEngine/Render/Objects/Effects/CFBO.h deleted file mode 100644 index ab42f8e..0000000 --- a/src/WallpaperEngine/Render/Objects/Effects/CFBO.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "WallpaperEngine/Core/Objects/Effects/CFBO.h" -#include "WallpaperEngine/Core/Objects/CImage.h" - -namespace WallpaperEngine::Render::Objects::Effects -{ - class CFBO - { - public: - CFBO (Core::Objects::Effects::CFBO* fbo, const Core::Objects::CImage* image); - - const std::string& getName () const; - const float& getScale () const; - const std::string& getFormat () const; - - private: - const Core::Objects::Effects::CFBO* m_fbo; - }; -}; diff --git a/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp index 0230bc3..23687f6 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp +++ b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp @@ -4,8 +4,8 @@ using namespace WallpaperEngine::Render::Objects; using namespace WallpaperEngine::Render::Objects::Effects; -CMaterial::CMaterial (const Render::Objects::CImage* image, const Core::Objects::Images::CMaterial* material) : - m_image (image), +CMaterial::CMaterial (const Render::Objects::CEffect* effect, const Core::Objects::Images::CMaterial* material) : + m_effect (effect), m_material (material) { this->generatePasses (); @@ -16,9 +16,9 @@ const std::vector& CMaterial::getPasses () const return this->m_passes; } -const CImage* CMaterial::getImage () const +CImage* CMaterial::getImage () const { - return this->m_image; + return this->m_effect->getImage (); } void CMaterial::generatePasses () @@ -29,28 +29,4 @@ void CMaterial::generatePasses () // these are simple now, just create the entries and done for (; cur != end; cur ++) this->m_passes.emplace_back (new CPass (this, *cur)); -} - -void CMaterial::render (GLuint drawTo, GLuint inputTexture) -{ - // get the orthogonal projection - auto projection = this->getImage ()->getScene ()->getScene ()->getOrthogonalProjection (); - - auto begin = this->getPasses ().begin (); - auto cur = this->getPasses ().begin (); - auto end = this->getPasses ().end (); - - for (; cur != end; cur ++) - { - // get the current framebuffer to use (only after the first iteration) - if (cur != begin) - this->getImage ()->getScene ()->pinpongFramebuffer (&drawTo, &inputTexture); - - // bind to this new framebuffer - glBindFramebuffer (GL_FRAMEBUFFER, drawTo); - // set the viewport, for now use the scene width/height but we might want to use image's size TODO: INVESTIGATE THAT - glViewport (0, 0, projection->getWidth (), projection->getHeight ()); - // render the pass - (*cur)->render (drawTo, inputTexture); - } } \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Objects/Effects/CMaterial.h b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.h index e560340..1bf9b7b 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CMaterial.h +++ b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.h @@ -24,23 +24,15 @@ namespace WallpaperEngine::Render::Objects::Effects { friend class CPass; public: - CMaterial (const Render::Objects::CImage* image, const Core::Objects::Images::CMaterial* material); + CMaterial (const Render::Objects::CEffect* effect, const Core::Objects::Images::CMaterial* material); const std::vector& getPasses () const; - const CImage* getImage () const; - - /** - * Renders the given material, using inputTexture as first texture of the shader - * - * @param drawTo - * @param inputTexture - */ - void render (GLuint drawTo, GLuint inputTexture); + CImage* getImage () const; private: void generatePasses (); - const Render::Objects::CImage* m_image; + const Render::Objects::CEffect* m_effect; const Core::Objects::Images::CMaterial* m_material; std::vector m_passes; diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp index f4cbbe9..18fe570 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp @@ -1,5 +1,6 @@ #include #include "CPass.h" +#include "WallpaperEngine/Render/CFBO.h" #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h" #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableFloat.h" @@ -11,7 +12,7 @@ #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h" #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h" #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h" -#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h" +#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h" using namespace WallpaperEngine::Core::Objects::Effects::Constants; using namespace WallpaperEngine::Render::Shaders::Variables; @@ -31,6 +32,9 @@ CPass::CPass (CMaterial* material, Core::Objects::Images::Materials::CPass* pass void CPass::render (GLuint drawTo, GLuint input) { + // set the framebuffer we're drawing to + glBindFramebuffer (GL_FRAMEBUFFER, drawTo); + // clear whatever buffer we're drawing to if we're not drawing to screen if (drawTo != this->m_material->getImage()->getScene()->getWallpaperFramebuffer()) glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -66,6 +70,8 @@ void CPass::render (GLuint drawTo, GLuint input) glEnable (GL_DEPTH_TEST); } + // TODO: SUPPORT TARGET TO DRAW TEXTURE TO + // update variables used in the render process (like g_ModelViewProjectionMatrix) this->m_modelViewProjectionMatrix = this->m_material->getImage ()->getScene ()->getCamera ()->getProjection () * @@ -75,12 +81,20 @@ void CPass::render (GLuint drawTo, GLuint input) // update a_TexCoord and a_Position based on what to draw to // this should not be required once we do some prediction on rendering things // but for now should be enough - this->a_TexCoord = (input == this->m_material->getImage ()->getTexture ()->getTextureID ()) ? *this->m_material->getImage ()->getTexCoordBuffer () : *this->m_material->getImage ()->getPassTexCoordBuffer (); - this->a_Position = (drawTo != this->m_material->getImage()->getScene()->getWallpaperFramebuffer()) ? *this->m_material->getImage ()->getPassVertexBuffer () : *this->m_material->getImage ()->getVertexBuffer (); + this->a_TexCoord = *this->m_material->getImage ()->getTexCoordBuffer (); + this->a_Position = *this->m_material->getImage ()->getVertexBuffer (); + // use the shader we have registered glUseProgram (this->m_programID); - // bind the input texture + // bind the input texture (take into account input fbos) + auto it = this->m_fbos.find (0); + + if (it != this->m_fbos.end ()) + { + input = (*it).second->getTextureID(); + } + glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, input); int lastTextureIndex = 0; @@ -93,10 +107,25 @@ void CPass::render (GLuint drawTo, GLuint input) for (int index = 1; cur != end; cur ++, index ++) { - // set the active texture index - glActiveTexture (GL_TEXTURE0 + index); - // bind the correct texture there - glBindTexture (GL_TEXTURE_2D, (*cur)->getTextureID ()); + if ((*cur) == nullptr) + { + auto it = this->m_fbos.find (index); + + if (it == this->m_fbos.end ()) + continue; + + // set the active texture index + glActiveTexture (GL_TEXTURE0 + index); + // bind the correct texture there + glBindTexture (GL_TEXTURE_2D, (*it).second->getTextureID()); + } + else + { + // set the active texture index + glActiveTexture (GL_TEXTURE0 + index); + // bind the correct texture there + glBindTexture (GL_TEXTURE_2D, (*cur)->getTextureID ()); + } // increase the number of textures counter lastTextureIndex ++; } @@ -174,11 +203,11 @@ void CPass::render (GLuint drawTo, GLuint input) if (this->g_Texture0Rotation != -1) { - glUniform2f (this->g_Texture0Rotation, 0.0f, 0.0f); + glUniform4f (this->g_Texture0Rotation, 1.0f, 0.0f, 1.0f, 0.0f); } if (this->g_Texture0Translation != -1) { - glUniform4f (this->g_Texture0Translation, 0.0f, 0.0f, 0.0f, 0.0f); + glUniform2f (this->g_Texture0Translation, 0.0f, 0.0f); } { auto cur = this->m_attribs.begin (); @@ -245,16 +274,19 @@ GLuint CPass::compileShader (Render::Shaders::Compiler* shader, GLuint type) void CPass::setupShaders () { // ensure the constants are defined - const CTexture* texture0 = this->m_material->getImage ()->getTexture (); + const ITexture* texture0 = this->m_material->getImage ()->getTexture (); // TODO: THE VALUES ARE THE SAME AS THE ENUMERATION, SO MAYBE IT HAS TO BE SPECIFIED FOR THE TEXTURE 0 OF ALL ELEMENTS? - if (texture0->getHeader ()->format == CTexture::TextureFormat::RG88) + if (texture0 != nullptr) { - this->m_pass->insertCombo ("TEX0FORMAT", 8); - } - else if (texture0->getHeader ()->format == CTexture::TextureFormat::R8) - { - this->m_pass->insertCombo ("TEX0FORMAT", 9); + if (texture0->getFormat () == ITexture::TextureFormat::RG88) + { + this->m_pass->insertCombo ("TEX0FORMAT", 8); + } + else if (texture0->getFormat () == ITexture::TextureFormat::R8) + { + this->m_pass->insertCombo ("TEX0FORMAT", 9); + } } // prepare the shaders @@ -342,8 +374,14 @@ void CPass::setupUniforms () this->addUniform ("g_Texture5", 5); this->addUniform ("g_Texture6", 6); this->addUniform ("g_Texture7", 7); - // register all the texture sizes required - this->addUniform ("g_Texture0Resolution", this->m_material->getImage ()->getTexture ()->getResolution ()); + // check if the input is an fbo + auto it = this->m_fbos.find (0); + + if (it == this->m_fbos.end ()) + this->addUniform ("g_Texture0Resolution", this->m_material->getImage ()->getTexture ()->getResolution ()); + else + this->addUniform ("g_Texture0Resolution", (*it).second->getResolution ()); + int lastTextureIndex = 0; // register the extra texture resolutions { @@ -356,7 +394,20 @@ void CPass::setupUniforms () namestream << "g_Texture" << index << "Resolution"; - this->addUniform (namestream.str (), (*cur)->getResolution ()); + if ((*cur) == nullptr) + { + // fbo used + auto it = this->m_fbos.find (index); + + if (it == this->m_fbos.end ()) + continue; + + this->addUniform (namestream.str (), (*it).second->getResolution ()); + } + else + { + this->addUniform (namestream.str (), (*cur)->getResolution ()); + } lastTextureIndex ++; } } @@ -459,14 +510,29 @@ void CPass::setupTextures () for (int index = 0; cur != end; cur ++, index ++) { - // ignore first texture as that'll be the input of the last pass/image + // ignore first texture as that'll be the input of the last pass/image (unless the image is an FBO) if (index == 0) continue; - // get the first texture on the first pass (this one represents the image assigned to this object) - this->m_textures.emplace_back ( - this->m_material->getImage ()->getContainer ()->readTexture ((*cur)) - ); + if ((*cur).find ("_rt_") == 0) + { + const CFBO* fbo = this->m_material->m_effect->findFBO ((*cur)); + + if (fbo != nullptr) + { + this->m_fbos.insert (std::make_pair (index, const_cast (fbo))); + this->m_textures.emplace_back ( + nullptr + ); + } + // _rt_texture + } + else + { + this->m_textures.emplace_back ( + this->m_material->getImage ()->getContainer ()->readTexture ((*cur)) + ); + } } } @@ -487,11 +553,11 @@ void CPass::setupShaderVariables () continue; // if both can be found, ensure they're the correct type - if (vertexVar != nullptr && pixelVar != nullptr) + /*if (vertexVar != nullptr && pixelVar != nullptr) { if (vertexVar->getType () != pixelVar->getType ()) throw std::runtime_error ("Pixel and vertex shader variable types do not match"); - } + }*/ // get one instance of it CShaderVariable* var = vertexVar == nullptr ? pixelVar : vertexVar; @@ -514,13 +580,19 @@ void CPass::setupShaderVariables () // create a float value from an integer this->addUniform (var->getName (), static_cast (*(*cur).second->as ()->getValue ())); } - else if ((*cur).second->is () == true && var->is () == true) + else if ((*cur).second->is () == true && var->is () == true) { - CShaderConstantVector3* val = (*cur).second->as (); + CShaderConstantVector4* val = (*cur).second->as (); // create a new vector2 with the first two values this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y}); } + else if ((*cur).second->is () == true && var->is () == true) + { + CShaderConstantVector4* val = (*cur).second->as (); + + this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y, val->getValue ()->z}); + } else { throw std::runtime_error ("Constant and pixel/vertex variable are not of the same type"); @@ -533,8 +605,8 @@ void CPass::setupShaderVariables () this->addUniform (var->getName (), (*cur).second->as ()->getValue ()); else if ((*cur).second->is ()) this->addUniform (var->getName (), (*cur).second->as ()->getValue ()); - else if ((*cur).second->is ()) - this->addUniform (var->getName (), (*cur).second->as ()->getValue ()); + else if ((*cur).second->is ()) + this->addUniform (var->getName (), (*cur).second->as ()->getValue ()); } } } diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.h b/src/WallpaperEngine/Render/Objects/Effects/CPass.h index 511f32f..d470d45 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.h +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.h @@ -6,7 +6,8 @@ #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h" #include "WallpaperEngine/Render/Objects/Effects/CMaterial.h" #include "WallpaperEngine/Render/Shaders/Compiler.h" -#include "WallpaperEngine/Assets/CTexture.h" +#include "WallpaperEngine/Assets/ITexture.h" +#include "WallpaperEngine/Render/CFBO.h" namespace WallpaperEngine::Render::Objects::Effects { @@ -85,7 +86,8 @@ namespace WallpaperEngine::Render::Objects::Effects CMaterial* m_material; Core::Objects::Images::Materials::CPass* m_pass; - std::vector m_textures; + std::vector m_textures; + std::map m_fbos; std::vector m_attribs; std::map m_uniforms; glm::mat4 m_modelViewProjectionMatrix; diff --git a/src/WallpaperEngine/Render/Shaders/Compiler.cpp b/src/WallpaperEngine/Render/Shaders/Compiler.cpp index 9122cc9..6269092 100644 --- a/src/WallpaperEngine/Render/Shaders/Compiler.cpp +++ b/src/WallpaperEngine/Render/Shaders/Compiler.cpp @@ -8,7 +8,7 @@ // shader compiler #include -#include +#include #include #include @@ -554,7 +554,7 @@ namespace WallpaperEngine::Render::Shaders parameter = new Variables::CShaderVariableVector3 ( constant == this->m_constants.end () ? WallpaperEngine::Core::aToVector3 (*defvalue) - : *(*constant).second->as ()->getValue () + : *(*constant).second->as ()->getValue () ); } else if (type == "vec2") @@ -601,7 +601,7 @@ namespace WallpaperEngine::Render::Shaders // add the new combo to the list this->m_combos->insert (std::make_pair (*combo, 1)); // also ensure that the textureName is loaded and we know about it - CTexture* texture = this->m_container->readTexture ((*textureName).get ()); + ITexture* texture = this->m_container->readTexture ((*textureName).get ()); // extract the texture number from the name char value = name.at (std::string("g_Texture").length ()); // now convert it to integer @@ -654,7 +654,7 @@ namespace WallpaperEngine::Render::Shaders return this->m_combos; } - const std::map & Compiler::getTextures () const + const std::map & Compiler::getTextures () const { return this->m_textures; } diff --git a/src/WallpaperEngine/Render/Shaders/Compiler.h b/src/WallpaperEngine/Render/Shaders/Compiler.h index 62e94a3..4a6e8d4 100644 --- a/src/WallpaperEngine/Render/Shaders/Compiler.h +++ b/src/WallpaperEngine/Render/Shaders/Compiler.h @@ -6,7 +6,7 @@ #include "WallpaperEngine/Core/Core.h" #include "WallpaperEngine/Assets/CContainer.h" -#include "WallpaperEngine/Assets/CTexture.h" +#include "WallpaperEngine/Assets/ITexture.h" #include "WallpaperEngine/FileSystem/FileSystem.h" #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h" #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h" @@ -89,7 +89,7 @@ namespace WallpaperEngine::Render::Shaders /** * @return The list of textures inferred from the shader's code */ - const std::map & getTextures () const; + const std::map & getTextures () const; private: /** @@ -244,6 +244,6 @@ namespace WallpaperEngine::Render::Shaders /** * List of textures that the shader expects (inferred from sampler2D and it's JSON data) */ - std::map m_textures; + std::map m_textures; }; } diff --git a/src/WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.cpp b/src/WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.cpp index c085b2a..142777e 100644 --- a/src/WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.cpp +++ b/src/WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.cpp @@ -4,22 +4,22 @@ using namespace WallpaperEngine::Render::Shaders::Variables; -CShaderVariableVector4::CShaderVariableVector4 (const glm::vec3& defaultValue) : +CShaderVariableVector4::CShaderVariableVector4 (const glm::vec4& defaultValue) : m_defaultValue (defaultValue), - m_value (glm::vec3 ()), + m_value (glm::vec4 ()), CShaderVariable (&this->m_defaultValue, nullptr, Type) { } -CShaderVariableVector4::CShaderVariableVector4 (const glm::vec3& defaultValue, std::string name) : +CShaderVariableVector4::CShaderVariableVector4 (const glm::vec4& defaultValue, std::string name) : m_defaultValue (defaultValue), - m_value (glm::vec3 ()), + m_value (glm::vec4 ()), CShaderVariable (&this->m_defaultValue, nullptr, Type) { this->setName (std::move(name)); } -void CShaderVariableVector4::setValue (const glm::vec3& value) +void CShaderVariableVector4::setValue (const glm::vec4& value) { this->m_value = value; CShaderVariable::setValue (&this->m_value); diff --git a/src/WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.h b/src/WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.h index e0d9407..6bc7dae 100644 --- a/src/WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.h +++ b/src/WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.h @@ -1,5 +1,5 @@ #pragma once -#include +#include #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h" @@ -8,17 +8,17 @@ namespace WallpaperEngine::Render::Shaders::Variables class CShaderVariableVector4 : public CShaderVariable { public: - explicit CShaderVariableVector4 (const glm::vec3& defaultValue); - CShaderVariableVector4 (const glm::vec3& defaultValue, std::string name); + explicit CShaderVariableVector4 (const glm::vec4& defaultValue); + CShaderVariableVector4 (const glm::vec4& defaultValue, std::string name); const int getSize () const override; - void setValue (const glm::vec3& value); + void setValue (const glm::vec4& value); static const std::string Type; private: - glm::vec3 m_defaultValue; - glm::vec3 m_value; + glm::vec4 m_defaultValue; + glm::vec4 m_value; }; }