+ added some extra documentation on rendering based on observations and trial and error

~ deprecated --dir --pkg options, the software will automatically detect the background we're loading
+ first draft of FBO support, there's still some extra work to do
~ texture header is now hidden behind getters so the textures can be any kind of source
~ proper setting of resolution and translation variables for textures
~ simplified call flow for any pass rendering, removing render functions on effect and material
~ framebuffer setup has to happen before object setup in the scene

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
Alexis Maiquez 2021-09-27 01:39:23 +02:00
parent 6c8187324e
commit 5828b2ee80
39 changed files with 675 additions and 332 deletions

View File

@ -47,6 +47,7 @@ add_executable(
src/WallpaperEngine/Assets/CDirectory.cpp src/WallpaperEngine/Assets/CDirectory.cpp
src/WallpaperEngine/Assets/CPackage.h src/WallpaperEngine/Assets/CPackage.h
src/WallpaperEngine/Assets/CPackage.cpp src/WallpaperEngine/Assets/CPackage.cpp
src/WallpaperEngine/Assets/ITexture.h
src/WallpaperEngine/Assets/CTexture.h src/WallpaperEngine/Assets/CTexture.h
src/WallpaperEngine/Assets/CTexture.cpp src/WallpaperEngine/Assets/CTexture.cpp
@ -90,8 +91,8 @@ add_executable(
src/WallpaperEngine/Render/Objects/CEffect.h src/WallpaperEngine/Render/Objects/CEffect.h
src/WallpaperEngine/Render/Objects/CEffect.cpp src/WallpaperEngine/Render/Objects/CEffect.cpp
src/WallpaperEngine/Render/Objects/Effects/CFBO.h src/WallpaperEngine/Render/CFBO.h
src/WallpaperEngine/Render/Objects/Effects/CFBO.cpp src/WallpaperEngine/Render/CFBO.cpp
src/WallpaperEngine/Render/Objects/Effects/CPass.h src/WallpaperEngine/Render/Objects/Effects/CPass.h
src/WallpaperEngine/Render/Objects/Effects/CPass.cpp src/WallpaperEngine/Render/Objects/Effects/CPass.cpp
src/WallpaperEngine/Render/Objects/Effects/CMaterial.h 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/CShaderConstantFloat.cpp
src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h
src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.cpp 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.h
src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.cpp src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.cpp

10
docs/JSON_FORMAT.md Normal file
View File

@ -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)

View File

@ -0,0 +1,5 @@
# camera settings
- camera:
- eye: where the camera is at
- center: wherte the camera is pointing at
- up: the up vector

View File

@ -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)

View File

@ -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

View File

View File

@ -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

View File

@ -71,9 +71,7 @@ std::string stringPathFixes(const std::string& s)
int main (int argc, char* argv[]) int main (int argc, char* argv[])
{ {
std::vector <std::string> screens; std::vector <std::string> screens;
bool isRootWindow = false;
int mode = RUN_MODE_UNKNOWN;
int maximumFPS = 30; int maximumFPS = 30;
bool shouldEnableAudio = true; bool shouldEnableAudio = true;
std::string path; std::string path;
@ -100,19 +98,12 @@ int main (int argc, char* argv[])
switch (c) switch (c)
{ {
case 'r': case 'r':
isRootWindow = true;
screens.emplace_back (optarg); screens.emplace_back (optarg);
break; break;
case 'p': case 'p':
if (mode == RUN_MODE_UNKNOWN)
mode = RUN_MODE_PACKAGE;
path = stringPathFixes (optarg);
break;
case 'd': case 'd':
if (mode == RUN_MODE_UNKNOWN) std::cout << "--dir/--pkg is deprecated and not used anymore" << std::endl;
mode = RUN_MODE_DIRECTORY;
path = stringPathFixes (optarg); path = stringPathFixes (optarg);
break; break;
@ -121,7 +112,7 @@ int main (int argc, char* argv[])
break; break;
case 'h': case 'h':
mode = RUN_MODE_HELP; print_help (argv [0]);
break; break;
case 'f': 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]); print_help (argv [0]);
return 0; return 0;
@ -161,17 +152,17 @@ int main (int argc, char* argv[])
containers->add (new WallpaperEngine::Assets::CDirectory ("./assets/")); 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 // the background's path is required to load project.json regardless of the type of background we're using
containers->add (new WallpaperEngine::Assets::CDirectory (path)); containers->add (new WallpaperEngine::Assets::CDirectory (path));
// check if scene.pkg exists and add it to the list
if (mode == RUN_MODE_PACKAGE) try
{ {
std::string scene_path = path + "scene.pkg"; std::string scene_path = path + "scene.pkg";
// add the package to the list // add the package to the list
containers->add (new WallpaperEngine::Assets::CPackage (scene_path)); 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 // parse the project.json file
@ -259,7 +250,7 @@ int main (int argc, char* argv[])
glDepthFunc (GL_LESS); glDepthFunc (GL_LESS);
// cull anything that doesn't look at the camera (might be useful to disable in the future) // 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 minimumTime = 1000 / maximumFPS;
clock_t startTime = 0; clock_t startTime = 0;

View File

@ -1,11 +1,12 @@
#include "CContainer.h" #include "CContainer.h"
#include "CTexture.h"
#include <cstring> #include <cstring>
#include <utility> #include <utility>
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
CTexture* CContainer::readTexture (std::string filename) ITexture* CContainer::readTexture (std::string filename)
{ {
// get the texture's filename (usually .tex) // get the texture's filename (usually .tex)
filename = "materials/" + filename + ".tex"; filename = "materials/" + filename + ".tex";

View File

@ -1,11 +1,7 @@
//
// Created by almamu on 8/8/21.
//
#pragma once #pragma once
#include <string> #include <string>
#include "WallpaperEngine/Assets/CTexture.h" #include "WallpaperEngine/Assets/ITexture.h"
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets
{ {
@ -30,7 +26,7 @@ namespace WallpaperEngine::Assets
* *
* @return * @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 * Wrapper for readFile, appends the .vert extension at the end and opens the given shader file

View File

@ -177,6 +177,31 @@ const GLuint CTexture::getTextureID () const
return this->m_textureID; 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 const CTexture::TextureHeader* CTexture::getHeader () const
{ {
return this->m_header; return this->m_header;

View File

@ -8,10 +8,11 @@
#include <glm/vec4.hpp> #include <glm/vec4.hpp>
#include <FreeImage.h> #include <FreeImage.h>
#include "ITexture.h"
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets
{ {
class CTexture class CTexture : public ITexture
{ {
struct TextureHeader; struct TextureHeader;
@ -19,21 +20,17 @@ namespace WallpaperEngine::Assets
CTexture (void* fileData); CTexture (void* fileData);
~CTexture (); ~CTexture ();
const GLuint getTextureID () const; const GLuint getTextureID () const override;
const TextureHeader* getHeader () const; const uint32_t getTextureWidth () const override;
const glm::vec4* getResolution () const; 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: private:
const TextureHeader* getHeader () const;
enum ContainerVersion : int enum ContainerVersion : int
{ {
UNKNOWN = -1, UNKNOWN = -1,

View File

@ -0,0 +1,29 @@
#pragma once
#include <GL/glew.h>
#include <glm/vec4.hpp>
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;
};
};

View File

@ -5,7 +5,7 @@
#include "WallpaperEngine/Core/Objects/CImage.h" #include "WallpaperEngine/Core/Objects/CImage.h"
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h" #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.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/Core/Objects/Effects/Constants/CShaderConstantInteger.h"
#include "WallpaperEngine/FileSystem/FileSystem.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) 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 else
{ {

View File

@ -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";

View File

@ -0,0 +1,21 @@
#pragma once
#include "CShaderConstant.h"
#include <string>
#include <glm/vec3.hpp>
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;
};
}

View File

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

View File

@ -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";

View File

@ -0,0 +1,21 @@
#pragma once
#include "CShaderConstant.h"
#include <string>
#include <glm/vec4.hpp>
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;
};
}

View File

@ -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;
}

View File

@ -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;
};
};

View File

@ -18,6 +18,8 @@ CScene::CScene (Core::CScene* scene, CContainer* container) :
scene->getOrthogonalProjection ()->getWidth (), scene->getOrthogonalProjection ()->getWidth (),
scene->getOrthogonalProjection ()->getHeight () scene->getOrthogonalProjection ()->getHeight ()
); );
// setup framebuffers
this->setupFramebuffers ();
auto cur = scene->getObjects ().begin (); auto cur = scene->getObjects ().begin ();
auto end = scene->getObjects ().end (); auto end = scene->getObjects ().end ();
@ -38,8 +40,6 @@ CScene::CScene (Core::CScene* scene, CContainer* container) :
if (object != nullptr) if (object != nullptr)
this->m_objects.emplace_back (object); this->m_objects.emplace_back (object);
} }
this->setupFramebuffers ();
} }
CCamera* CScene::getCamera () const CCamera* CScene::getCamera () const

View File

@ -123,7 +123,7 @@ void CVideo::renderFrame ()
writeFrameToImage (); writeFrameToImage ();
glViewport (0, 0, this->getWidth (), this->getHeight ()); glViewport (0, 0, this->getWidth (), this->getHeight ());
// do the actual rendering // do the actual rendering
// write to default's framebuffer // write to default's framebuffer
glBindFramebuffer (GL_FRAMEBUFFER, this->getWallpaperFramebuffer()); glBindFramebuffer (GL_FRAMEBUFFER, this->getWallpaperFramebuffer());

View File

@ -59,12 +59,12 @@ WallpaperEngine::Core::CWallpaper* CWallpaper::getWallpaperData ()
GLuint CWallpaper::getWallpaperFramebuffer () const GLuint CWallpaper::getWallpaperFramebuffer () const
{ {
return this->m_sceneFramebuffer; return this->m_sceneFBO->getFramebuffer ();
} }
GLuint CWallpaper::getWallpaperTexture () const GLuint CWallpaper::getWallpaperTexture () const
{ {
return this->m_sceneTexture; return this->m_sceneFBO->getTextureID();
} }
void CWallpaper::setupShaders () void CWallpaper::setupShaders ()
@ -287,25 +287,21 @@ void CWallpaper::render (glm::vec4 viewport, bool newFrame)
void CWallpaper::pinpongFramebuffer (GLuint* drawTo, GLuint* inputTexture) void CWallpaper::pinpongFramebuffer (GLuint* drawTo, GLuint* inputTexture)
{ {
// get current main framebuffer and texture so we can swap them // temporarily store FBOs used
GLuint currentMainFramebuffer = this->m_mainFramebuffer; CFBO* currentMainFBO = this->m_mainFBO;
GLuint currentMainTexture = this->m_mainTexture; CFBO* currentSubFBO = this->m_subFBO;
GLuint currentSubFramebuffer = this->m_subFramebuffer;
GLuint currentSubTexture = this->m_subTexture;
if (drawTo != nullptr) if (drawTo != nullptr)
*drawTo = currentSubFramebuffer; *drawTo = currentSubFBO->getFramebuffer ();
if (inputTexture != nullptr) if (inputTexture != nullptr)
*inputTexture = currentMainTexture; *inputTexture = currentMainFBO->getTextureID();
// swap the textures // swap the FBOs
this->m_mainFramebuffer = currentSubFramebuffer; this->m_mainFBO = currentSubFBO;
this->m_mainTexture = currentSubTexture; this->m_subFBO = currentMainFBO;
this->m_subFramebuffer = currentMainFramebuffer;
this->m_subTexture = currentMainTexture;
} }
void CWallpaper::createFramebuffer (GLuint* framebuffer, GLuint* depthbuffer, GLuint* texture) void CWallpaper::setupFramebuffers ()
{ {
int windowWidth = 1920; int windowWidth = 1920;
int windowHeight = 1080; int windowHeight = 1080;
@ -325,42 +321,33 @@ void CWallpaper::createFramebuffer (GLuint* framebuffer, GLuint* depthbuffer, GL
windowHeight = video->getHeight (); windowHeight = video->getHeight ();
} }
GLenum drawBuffers [1] = {GL_COLOR_ATTACHMENT0}; this->m_mainFBO = this->createFBO ("_rt_FullFrameBuffera", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight);
// create the main framebuffer this->m_subFBO = this->createFBO ("_rt_FullFrameBuffera", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight);
glGenFramebuffers (1, framebuffer); // create framebuffer for the scene
glBindFramebuffer (GL_FRAMEBUFFER, *framebuffer); this->m_sceneFBO = this->createFBO ("_rt_FullFrameBuffer", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight);
// 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");
} }
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); CFBO* fbo = new CFBO (name, format, scale, realWidth, realHeight, textureWidth, textureHeight);
this->createFramebuffer (&this->m_subFramebuffer, &this->m_subDepthBuffer, &this->m_subTexture);
// create framebuffer for the scene this->m_fbos.insert (std::make_pair (name, fbo));
this->createFramebuffer (&this->m_sceneFramebuffer, &this->m_sceneDepthBuffer, &this->m_sceneTexture);
return fbo;
}
const std::map<std::string, CFBO*>& 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;
} }

View File

@ -8,6 +8,7 @@
#include "WallpaperEngine/Core/CVideo.h" #include "WallpaperEngine/Core/CVideo.h"
#include "WallpaperEngine/Assets/CContainer.h" #include "WallpaperEngine/Assets/CContainer.h"
#include "CFBO.h"
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
@ -50,6 +51,25 @@ namespace WallpaperEngine::Render
* @return The scene's texture * @return The scene's texture
*/ */
GLuint getWallpaperTexture () const; 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<std::string, CFBO*>& getFBOs () const;
/**
* Searches the FBO list for the given FBO
*
* @param name
* @return
*/
const CFBO* findFBO (const std::string& name) const;
protected: protected:
/** /**
@ -62,54 +82,29 @@ namespace WallpaperEngine::Render
*/ */
void setupFramebuffers (); void setupFramebuffers ();
void createFramebuffer (GLuint* framebuffer, GLuint* depthbuffer, GLuint* texture);
CContainer* m_container; CContainer* m_container;
Core::CWallpaper* m_wallpaperData; Core::CWallpaper* m_wallpaperData;
Core::CWallpaper* getWallpaperData (); 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; CFBO* m_sceneFBO;
/**
* 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;
private: private:
/** /**
* The texture used for the scene output * The texture used for the scene output
*/ */
GLuint m_sceneTexture;
GLuint m_texCoordBuffer; GLuint m_texCoordBuffer;
GLuint m_positionBuffer; GLuint m_positionBuffer;
GLuint m_shader; GLuint m_shader;
@ -125,5 +120,10 @@ namespace WallpaperEngine::Render
* The type of background this wallpaper is (used * The type of background this wallpaper is (used
*/ */
std::string m_type; std::string m_type;
/**
* List of FBOs registered for this wallpaper
*/
std::map<std::string, CFBO*> m_fbos;
}; };
} }

View File

@ -1,6 +1,7 @@
#include "CEffect.h" #include "CEffect.h"
using namespace WallpaperEngine::Render::Objects; using namespace WallpaperEngine::Render::Objects;
using namespace WallpaperEngine::Render;
CEffect::CEffect (CImage* image, Core::Objects::CEffect* effect) : CEffect::CEffect (CImage* image, Core::Objects::CEffect* effect) :
m_image (image), m_image (image),
@ -10,7 +11,7 @@ CEffect::CEffect (CImage* image, Core::Objects::CEffect* effect) :
this->generatePasses (); this->generatePasses ();
} }
const CImage* CEffect::getImage () const CImage* CEffect::getImage () const
{ {
return this->m_image; return this->m_image;
} }
@ -20,7 +21,7 @@ const std::vector<Effects::CMaterial*>& CEffect::getMaterials () const
return this->m_materials; 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 cur = this->m_fbos.begin ();
auto end = this->m_fbos.end (); auto end = this->m_fbos.end ();
@ -42,7 +43,7 @@ void CEffect::generatePasses ()
auto end = this->m_effect->getMaterials ().end (); auto end = this->m_effect->getMaterials ().end ();
for (; cur != end; cur ++) 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 () void CEffect::generateFBOs ()
@ -53,23 +54,15 @@ void CEffect::generateFBOs ()
for (; cur != end; cur ++) for (; cur != end; cur ++)
{ {
this->m_fbos.push_back ( 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);
}
} }

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "WallpaperEngine/Render/Objects/CImage.h" #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/CPass.h"
#include "WallpaperEngine/Render/Objects/Effects/CMaterial.h" #include "WallpaperEngine/Render/Objects/Effects/CMaterial.h"
@ -19,13 +19,12 @@ namespace WallpaperEngine::Render::Objects
public: public:
CEffect (CImage* image, Core::Objects::CEffect* effect); CEffect (CImage* image, Core::Objects::CEffect* effect);
const CImage* getImage () const; CImage* getImage () const;
const std::vector<Effects::CMaterial*>& getMaterials () const; const std::vector<Effects::CMaterial*>& getMaterials () const;
Effects::CFBO* findFBO (const std::string& name); const CFBO* findFBO (const std::string& name) const;
void render (GLuint drawTo, GLuint inputTexture);
private: private:
void generatePasses (); void generatePasses ();
void generateFBOs (); void generateFBOs ();
@ -33,7 +32,7 @@ namespace WallpaperEngine::Render::Objects
CImage* m_image; CImage* m_image;
Core::Objects::CEffect* m_effect; Core::Objects::CEffect* m_effect;
std::vector<Effects::CFBO*> m_fbos; std::vector<CFBO*> m_fbos;
std::vector<Effects::CMaterial*> m_materials; std::vector<Effects::CMaterial*> m_materials;
}; };
}; };

View File

@ -1,3 +1,4 @@
#include <sstream>
#include "CImage.h" #include "CImage.h"
using namespace WallpaperEngine; using namespace WallpaperEngine;
@ -5,7 +6,8 @@ using namespace WallpaperEngine::Render::Objects;
CImage::CImage (CScene* scene, Core::Objects::CImage* image) : CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
Render::CObject (scene, Type, image), Render::CObject (scene, Type, image),
m_image (image) m_image (image),
m_texture (nullptr)
{ {
auto projection = this->getScene ()->getScene ()->getOrthogonalProjection (); 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 // depending on the alignment these values might change, for now just support center
if (this->getImage ()->getAlignment () == "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 // calculate the real position of the image
xleft = this->getImage ()->getOrigin ().x - (this->getImage ()->getSize ().x / 2); xleft = this->getImage ()->getOrigin ().x - (size.x * scale.x / 2);
xright = this->getImage ()->getOrigin ().x + (this->getImage ()->getSize ().x / 2); xright = this->getImage ()->getOrigin ().x + (size.x * scale.x / 2);
ytop = this->getImage ()->getOrigin ().y - (this->getImage ()->getSize ().y / 2); ytop = this->getImage ()->getOrigin ().y - (size.y * scale.y / 2);
ybottom = this->getImage ()->getOrigin ().y + (this->getImage ()->getSize ().y / 2); ybottom = this->getImage ()->getOrigin ().y + (size.y * scale.y / 2);
} }
else else
{ {
throw std::runtime_error ("Only centered images are supported for now!"); throw std::runtime_error ("Only centered images are supported for now!");
} }
// load image from the .tex file std::string textureName = (*(*this->m_image->getMaterial ()->getPasses ().begin ())->getTextures ().begin ());
uint32_t textureSize = 0;
// get the first texture on the first pass (this one represents the image assigned to this object) if (textureName.find ("_rt_") == 0)
this->m_texture = this->getScene ()->getContainer ()->readTexture ( {
(*(*this->m_image->getMaterial ()->getPasses ().begin ())->getTextures ().begin ()) 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) // build a list of vertices, these might need some change later (or maybe invert the camera)
GLfloat data [] = { GLfloat data [] = {
@ -68,17 +86,21 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
float height = 1.0f; float height = 1.0f;
// calculate the correct texCoord limits for the texture based on the texture screen size and real size // 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 || if (this->getTexture () != nullptr &&
this->getTexture ()->getHeader ()->textureHeight != this->getTexture ()->getHeader ()->height) (this->getTexture ()->getTextureWidth () != this->getTexture ()->getRealWidth () ||
this->getTexture ()->getTextureHeight () != this->getTexture ()->getRealHeight ())
)
{ {
uint32_t x = 1; uint32_t x = 1;
uint32_t y = 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 (x < size.x) x <<= 1;
while (y < this->getImage ()->getSize ().y) y <<= 1; while (y < size.y) y <<= 1;
width = this->getImage ()->getSize ().x / x; width = size.x * scale.x / x;
height = this->getImage ()->getSize ().y / y; height = size.y * scale.y / y;
} }
GLfloat data2 [] = { 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); glBufferData (GL_ARRAY_BUFFER, sizeof (this->m_passTexCoordList), this->m_passTexCoordList, GL_STATIC_DRAW);
// generate the main material used to render the image // 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 // generate the effects used by this material
auto cur = this->getImage ()->getEffects ().begin (); 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)); 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 () void CImage::render ()
{ {
// ensure this image is visible first // start drawing to the main framebuffer
if (this->getImage ()->isVisible () == false) GLuint drawTo = this->m_mainFBO->getFramebuffer ();
return; 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 // render all the other materials
auto cur = this->getEffects ().begin (); auto cur = this->getEffects ().begin ();
auto end = this->getEffects ().end (); 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 ++) for (; cur != end; cur ++)
{ {
if (cur != begin) auto materialCur = (*cur)->getMaterials ().begin ();
// pinpong current buffer auto materialEnd = (*cur)->getMaterials ().end ();
this->getScene ()->pinpongFramebuffer (&drawTo, &inputTexture);
// render now for (; materialCur != materialEnd; materialCur ++)
(*cur)->render (drawTo, inputTexture); {
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) if (this->getImage ()->isVisible () == false)
this->getScene ()->pinpongFramebuffer (nullptr, &inputTexture); return;
// render the main material // this material only has one pass that we know of
this->m_material->render (this->getScene()->getWallpaperFramebuffer(), inputTexture); // 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; return this->m_texture;
} }

View File

@ -9,7 +9,7 @@
#include "WallpaperEngine/Render/Shaders/Compiler.h" #include "WallpaperEngine/Render/Shaders/Compiler.h"
#include "WallpaperEngine/Assets/CTexture.h" #include "WallpaperEngine/Assets/ITexture.h"
#include <glm/vec3.hpp> #include <glm/vec3.hpp>
@ -40,13 +40,21 @@ namespace WallpaperEngine::Render::Objects
const GLuint* getPassVertexBuffer () const; const GLuint* getPassVertexBuffer () const;
const GLuint* getTexCoordBuffer () const; const GLuint* getTexCoordBuffer () const;
const GLuint* getPassTexCoordBuffer () 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: protected:
static const std::string Type; static const std::string Type;
private: private:
CTexture* m_texture; const ITexture* m_texture;
GLfloat m_vertexList [6 * 3]; GLfloat m_vertexList [6 * 3];
GLfloat m_passesVertexList [6 * 3]; GLfloat m_passesVertexList [6 * 3];
GLfloat m_texCoordList [6 * 2]; GLfloat m_texCoordList [6 * 2];
@ -57,6 +65,8 @@ namespace WallpaperEngine::Render::Objects
GLuint m_passTexCoordBuffer; GLuint m_passTexCoordBuffer;
uint16_t m_vertexIndices [6]; uint16_t m_vertexIndices [6];
CFBO* m_mainFBO;
CFBO* m_subFBO;
Core::Objects::CImage* m_image; Core::Objects::CImage* m_image;

View File

@ -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 ();
}

View File

@ -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;
};
};

View File

@ -4,8 +4,8 @@ using namespace WallpaperEngine::Render::Objects;
using namespace WallpaperEngine::Render::Objects::Effects; using namespace WallpaperEngine::Render::Objects::Effects;
CMaterial::CMaterial (const Render::Objects::CImage* image, const Core::Objects::Images::CMaterial* material) : CMaterial::CMaterial (const Render::Objects::CEffect* effect, const Core::Objects::Images::CMaterial* material) :
m_image (image), m_effect (effect),
m_material (material) m_material (material)
{ {
this->generatePasses (); this->generatePasses ();
@ -16,9 +16,9 @@ const std::vector<CPass*>& CMaterial::getPasses () const
return this->m_passes; 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 () void CMaterial::generatePasses ()
@ -29,28 +29,4 @@ void CMaterial::generatePasses ()
// these are simple now, just create the entries and done // these are simple now, just create the entries and done
for (; cur != end; cur ++) for (; cur != end; cur ++)
this->m_passes.emplace_back (new CPass (this, *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);
}
} }

View File

@ -24,23 +24,15 @@ namespace WallpaperEngine::Render::Objects::Effects
{ {
friend class CPass; friend class CPass;
public: 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<CPass*>& getPasses () const; const std::vector<CPass*>& getPasses () const;
const CImage* getImage () 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);
private: private:
void generatePasses (); void generatePasses ();
const Render::Objects::CImage* m_image; const Render::Objects::CEffect* m_effect;
const Core::Objects::Images::CMaterial* m_material; const Core::Objects::Images::CMaterial* m_material;
std::vector<CPass*> m_passes; std::vector<CPass*> m_passes;

View File

@ -1,5 +1,6 @@
#include <sstream> #include <sstream>
#include "CPass.h" #include "CPass.h"
#include "WallpaperEngine/Render/CFBO.h"
#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h" #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h"
#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableFloat.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/CShaderConstant.h"
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h" #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h"
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.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::Core::Objects::Effects::Constants;
using namespace WallpaperEngine::Render::Shaders::Variables; 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) 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 // clear whatever buffer we're drawing to if we're not drawing to screen
if (drawTo != this->m_material->getImage()->getScene()->getWallpaperFramebuffer()) if (drawTo != this->m_material->getImage()->getScene()->getWallpaperFramebuffer())
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -66,6 +70,8 @@ void CPass::render (GLuint drawTo, GLuint input)
glEnable (GL_DEPTH_TEST); glEnable (GL_DEPTH_TEST);
} }
// TODO: SUPPORT TARGET TO DRAW TEXTURE TO
// update variables used in the render process (like g_ModelViewProjectionMatrix) // update variables used in the render process (like g_ModelViewProjectionMatrix)
this->m_modelViewProjectionMatrix = this->m_modelViewProjectionMatrix =
this->m_material->getImage ()->getScene ()->getCamera ()->getProjection () * 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 // 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 // this should not be required once we do some prediction on rendering things
// but for now should be enough // 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_TexCoord = *this->m_material->getImage ()->getTexCoordBuffer ();
this->a_Position = (drawTo != this->m_material->getImage()->getScene()->getWallpaperFramebuffer()) ? *this->m_material->getImage ()->getPassVertexBuffer () : *this->m_material->getImage ()->getVertexBuffer (); this->a_Position = *this->m_material->getImage ()->getVertexBuffer ();
// use the shader we have registered // use the shader we have registered
glUseProgram (this->m_programID); 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); glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, input); glBindTexture (GL_TEXTURE_2D, input);
int lastTextureIndex = 0; int lastTextureIndex = 0;
@ -93,10 +107,25 @@ void CPass::render (GLuint drawTo, GLuint input)
for (int index = 1; cur != end; cur ++, index ++) for (int index = 1; cur != end; cur ++, index ++)
{ {
// set the active texture index if ((*cur) == nullptr)
glActiveTexture (GL_TEXTURE0 + index); {
// bind the correct texture there auto it = this->m_fbos.find (index);
glBindTexture (GL_TEXTURE_2D, (*cur)->getTextureID ());
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 // increase the number of textures counter
lastTextureIndex ++; lastTextureIndex ++;
} }
@ -174,11 +203,11 @@ void CPass::render (GLuint drawTo, GLuint input)
if (this->g_Texture0Rotation != -1) 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) 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 (); auto cur = this->m_attribs.begin ();
@ -245,16 +274,19 @@ GLuint CPass::compileShader (Render::Shaders::Compiler* shader, GLuint type)
void CPass::setupShaders () void CPass::setupShaders ()
{ {
// ensure the constants are defined // 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? // 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); if (texture0->getFormat () == ITexture::TextureFormat::RG88)
} {
else if (texture0->getHeader ()->format == CTexture::TextureFormat::R8) this->m_pass->insertCombo ("TEX0FORMAT", 8);
{ }
this->m_pass->insertCombo ("TEX0FORMAT", 9); else if (texture0->getFormat () == ITexture::TextureFormat::R8)
{
this->m_pass->insertCombo ("TEX0FORMAT", 9);
}
} }
// prepare the shaders // prepare the shaders
@ -342,8 +374,14 @@ void CPass::setupUniforms ()
this->addUniform ("g_Texture5", 5); this->addUniform ("g_Texture5", 5);
this->addUniform ("g_Texture6", 6); this->addUniform ("g_Texture6", 6);
this->addUniform ("g_Texture7", 7); this->addUniform ("g_Texture7", 7);
// register all the texture sizes required // check if the input is an fbo
this->addUniform ("g_Texture0Resolution", this->m_material->getImage ()->getTexture ()->getResolution ()); 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; int lastTextureIndex = 0;
// register the extra texture resolutions // register the extra texture resolutions
{ {
@ -356,7 +394,20 @@ void CPass::setupUniforms ()
namestream << "g_Texture" << index << "Resolution"; 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 ++; lastTextureIndex ++;
} }
} }
@ -459,14 +510,29 @@ void CPass::setupTextures ()
for (int index = 0; cur != end; cur ++, index ++) 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) if (index == 0)
continue; continue;
// get the first texture on the first pass (this one represents the image assigned to this object) if ((*cur).find ("_rt_") == 0)
this->m_textures.emplace_back ( {
this->m_material->getImage ()->getContainer ()->readTexture ((*cur)) const CFBO* fbo = this->m_material->m_effect->findFBO ((*cur));
);
if (fbo != nullptr)
{
this->m_fbos.insert (std::make_pair (index, const_cast <CFBO*> (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; continue;
// if both can be found, ensure they're the correct type // 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 ()) if (vertexVar->getType () != pixelVar->getType ())
throw std::runtime_error ("Pixel and vertex shader variable types do not match"); throw std::runtime_error ("Pixel and vertex shader variable types do not match");
} }*/
// get one instance of it // get one instance of it
CShaderVariable* var = vertexVar == nullptr ? pixelVar : vertexVar; CShaderVariable* var = vertexVar == nullptr ? pixelVar : vertexVar;
@ -514,13 +580,19 @@ void CPass::setupShaderVariables ()
// create a float value from an integer // create a float value from an integer
this->addUniform (var->getName (), static_cast <float> (*(*cur).second->as <CShaderConstantInteger> ()->getValue ())); this->addUniform (var->getName (), static_cast <float> (*(*cur).second->as <CShaderConstantInteger> ()->getValue ()));
} }
else if ((*cur).second->is <CShaderConstantVector3> () == true && var->is <CShaderVariableVector2> () == true) else if ((*cur).second->is <CShaderConstantVector4> () == true && var->is <CShaderVariableVector2> () == true)
{ {
CShaderConstantVector3* val = (*cur).second->as <CShaderConstantVector3> (); CShaderConstantVector4* val = (*cur).second->as <CShaderConstantVector4> ();
// create a new vector2 with the first two values // create a new vector2 with the first two values
this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y}); this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y});
} }
else if ((*cur).second->is <CShaderConstantVector4> () == true && var->is <CShaderVariableVector3> () == true)
{
CShaderConstantVector4* val = (*cur).second->as <CShaderConstantVector4> ();
this->addUniform (var->getName (), {val->getValue ()->x, val->getValue ()->y, val->getValue ()->z});
}
else else
{ {
throw std::runtime_error ("Constant and pixel/vertex variable are not of the same type"); 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 <CShaderConstantFloat> ()->getValue ()); this->addUniform (var->getName (), (*cur).second->as <CShaderConstantFloat> ()->getValue ());
else if ((*cur).second->is <CShaderConstantInteger> ()) else if ((*cur).second->is <CShaderConstantInteger> ())
this->addUniform (var->getName (), (*cur).second->as <CShaderConstantInteger> ()->getValue ()); this->addUniform (var->getName (), (*cur).second->as <CShaderConstantInteger> ()->getValue ());
else if ((*cur).second->is <CShaderConstantVector3> ()) else if ((*cur).second->is <CShaderConstantVector4> ())
this->addUniform (var->getName (), (*cur).second->as <CShaderConstantVector3> ()->getValue ()); this->addUniform (var->getName (), (*cur).second->as <CShaderConstantVector4> ()->getValue ());
} }
} }
} }

View File

@ -6,7 +6,8 @@
#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h" #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h"
#include "WallpaperEngine/Render/Objects/Effects/CMaterial.h" #include "WallpaperEngine/Render/Objects/Effects/CMaterial.h"
#include "WallpaperEngine/Render/Shaders/Compiler.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 namespace WallpaperEngine::Render::Objects::Effects
{ {
@ -85,7 +86,8 @@ namespace WallpaperEngine::Render::Objects::Effects
CMaterial* m_material; CMaterial* m_material;
Core::Objects::Images::Materials::CPass* m_pass; Core::Objects::Images::Materials::CPass* m_pass;
std::vector<CTexture*> m_textures; std::vector<ITexture*> m_textures;
std::map<int, CFBO*> m_fbos;
std::vector<AttribEntry*> m_attribs; std::vector<AttribEntry*> m_attribs;
std::map<std::string, UniformEntry*> m_uniforms; std::map<std::string, UniformEntry*> m_uniforms;
glm::mat4 m_modelViewProjectionMatrix; glm::mat4 m_modelViewProjectionMatrix;

View File

@ -8,7 +8,7 @@
// shader compiler // shader compiler
#include <WallpaperEngine/Render/Shaders/Compiler.h> #include <WallpaperEngine/Render/Shaders/Compiler.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/Core/Objects/Effects/Constants/CShaderConstantInteger.h>
#include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h> #include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h>
@ -554,7 +554,7 @@ namespace WallpaperEngine::Render::Shaders
parameter = new Variables::CShaderVariableVector3 ( parameter = new Variables::CShaderVariableVector3 (
constant == this->m_constants.end () constant == this->m_constants.end ()
? WallpaperEngine::Core::aToVector3 (*defvalue) ? WallpaperEngine::Core::aToVector3 (*defvalue)
: *(*constant).second->as <CShaderConstantVector3> ()->getValue () : *(*constant).second->as <CShaderConstantVector4> ()->getValue ()
); );
} }
else if (type == "vec2") else if (type == "vec2")
@ -601,7 +601,7 @@ namespace WallpaperEngine::Render::Shaders
// add the new combo to the list // add the new combo to the list
this->m_combos->insert (std::make_pair <std::string, int> (*combo, 1)); this->m_combos->insert (std::make_pair <std::string, int> (*combo, 1));
// also ensure that the textureName is loaded and we know about it // also ensure that the textureName is loaded and we know about it
CTexture* texture = this->m_container->readTexture ((*textureName).get <std::string> ()); ITexture* texture = this->m_container->readTexture ((*textureName).get <std::string> ());
// extract the texture number from the name // extract the texture number from the name
char value = name.at (std::string("g_Texture").length ()); char value = name.at (std::string("g_Texture").length ());
// now convert it to integer // now convert it to integer
@ -654,7 +654,7 @@ namespace WallpaperEngine::Render::Shaders
return this->m_combos; return this->m_combos;
} }
const std::map <int, CTexture*>& Compiler::getTextures () const const std::map <int, ITexture*>& Compiler::getTextures () const
{ {
return this->m_textures; return this->m_textures;
} }

View File

@ -6,7 +6,7 @@
#include "WallpaperEngine/Core/Core.h" #include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Assets/CContainer.h" #include "WallpaperEngine/Assets/CContainer.h"
#include "WallpaperEngine/Assets/CTexture.h" #include "WallpaperEngine/Assets/ITexture.h"
#include "WallpaperEngine/FileSystem/FileSystem.h" #include "WallpaperEngine/FileSystem/FileSystem.h"
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h" #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.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 * @return The list of textures inferred from the shader's code
*/ */
const std::map <int, CTexture*>& getTextures () const; const std::map <int, ITexture*>& getTextures () const;
private: private:
/** /**
@ -244,6 +244,6 @@ namespace WallpaperEngine::Render::Shaders
/** /**
* List of textures that the shader expects (inferred from sampler2D and it's JSON data) * List of textures that the shader expects (inferred from sampler2D and it's JSON data)
*/ */
std::map<int, CTexture*> m_textures; std::map<int, ITexture*> m_textures;
}; };
} }

View File

@ -4,22 +4,22 @@
using namespace WallpaperEngine::Render::Shaders::Variables; using namespace WallpaperEngine::Render::Shaders::Variables;
CShaderVariableVector4::CShaderVariableVector4 (const glm::vec3& defaultValue) : CShaderVariableVector4::CShaderVariableVector4 (const glm::vec4& defaultValue) :
m_defaultValue (defaultValue), m_defaultValue (defaultValue),
m_value (glm::vec3 ()), m_value (glm::vec4 ()),
CShaderVariable (&this->m_defaultValue, nullptr, Type) 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_defaultValue (defaultValue),
m_value (glm::vec3 ()), m_value (glm::vec4 ()),
CShaderVariable (&this->m_defaultValue, nullptr, Type) CShaderVariable (&this->m_defaultValue, nullptr, Type)
{ {
this->setName (std::move(name)); this->setName (std::move(name));
} }
void CShaderVariableVector4::setValue (const glm::vec3& value) void CShaderVariableVector4::setValue (const glm::vec4& value)
{ {
this->m_value = value; this->m_value = value;
CShaderVariable::setValue (&this->m_value); CShaderVariable::setValue (&this->m_value);

View File

@ -1,5 +1,5 @@
#pragma once #pragma once
#include <glm/vec3.hpp> #include <glm/vec4.hpp>
#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h" #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h"
@ -8,17 +8,17 @@ namespace WallpaperEngine::Render::Shaders::Variables
class CShaderVariableVector4 : public CShaderVariable class CShaderVariableVector4 : public CShaderVariable
{ {
public: public:
explicit CShaderVariableVector4 (const glm::vec3& defaultValue); explicit CShaderVariableVector4 (const glm::vec4& defaultValue);
CShaderVariableVector4 (const glm::vec3& defaultValue, std::string name); CShaderVariableVector4 (const glm::vec4& defaultValue, std::string name);
const int getSize () const override; const int getSize () const override;
void setValue (const glm::vec3& value); void setValue (const glm::vec4& value);
static const std::string Type; static const std::string Type;
private: private:
glm::vec3 m_defaultValue; glm::vec4 m_defaultValue;
glm::vec3 m_value; glm::vec4 m_value;
}; };
} }