+ 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/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

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[])
{
std::vector <std::string> 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;

View File

@ -1,11 +1,12 @@
#include "CContainer.h"
#include "CTexture.h"
#include <cstring>
#include <utility>
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";

View File

@ -1,11 +1,7 @@
//
// Created by almamu on 8/8/21.
//
#pragma once
#include <string>
#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

View File

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

View File

@ -8,10 +8,11 @@
#include <glm/vec4.hpp>
#include <FreeImage.h>
#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,

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/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
{

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;
CShaderConstantVector3::CShaderConstantVector3 (glm::vec3 value) :
CShaderConstant (Type),
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 ()->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

View File

@ -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");
}
void CWallpaper::setupFramebuffers ()
{
this->createFramebuffer (&this->m_mainFramebuffer, &this->m_mainDepthBuffer, &this->m_mainTexture);
this->createFramebuffer (&this->m_subFramebuffer, &this->m_subDepthBuffer, &this->m_subTexture);
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->createFramebuffer (&this->m_sceneFramebuffer, &this->m_sceneDepthBuffer, &this->m_sceneTexture);
this->m_sceneFBO = this->createFBO ("_rt_FullFrameBuffer", ITexture::TextureFormat::ARGB8888, 1.0, windowWidth, windowHeight, windowWidth, windowHeight);
}
CFBO* CWallpaper::createFBO (const std::string& name, ITexture::TextureFormat format, float scale, uint32_t realWidth, uint32_t realHeight, uint32_t textureWidth, uint32_t textureHeight)
{
CFBO* fbo = new CFBO (name, format, scale, realWidth, realHeight, textureWidth, textureHeight);
this->m_fbos.insert (std::make_pair (name, fbo));
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/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<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:
/**
@ -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<std::string, CFBO*> m_fbos;
};
}

View File

@ -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<Effects::CMaterial*>& 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);
}
}

View File

@ -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<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:
void generatePasses ();
void generateFBOs ();
@ -33,7 +32,7 @@ namespace WallpaperEngine::Render::Objects
CImage* m_image;
Core::Objects::CEffect* m_effect;
std::vector<Effects::CFBO*> m_fbos;
std::vector<CFBO*> m_fbos;
std::vector<Effects::CMaterial*> m_materials;
};
};

View File

@ -1,3 +1,4 @@
#include <sstream>
#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;
}

View File

@ -9,7 +9,7 @@
#include "WallpaperEngine/Render/Shaders/Compiler.h"
#include "WallpaperEngine/Assets/CTexture.h"
#include "WallpaperEngine/Assets/ITexture.h"
#include <glm/vec3.hpp>
@ -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;

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;
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<CPass*>& 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 ()
@ -30,27 +30,3 @@ void CMaterial::generatePasses ()
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);
}
}

View File

@ -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<CPass*>& 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<CPass*> m_passes;

View File

@ -1,5 +1,6 @@
#include <sstream>
#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 <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;
// 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 <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
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
{
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 ());
else if ((*cur).second->is <CShaderConstantInteger> ())
this->addUniform (var->getName (), (*cur).second->as <CShaderConstantInteger> ()->getValue ());
else if ((*cur).second->is <CShaderConstantVector3> ())
this->addUniform (var->getName (), (*cur).second->as <CShaderConstantVector3> ()->getValue ());
else if ((*cur).second->is <CShaderConstantVector4> ())
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/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<CTexture*> m_textures;
std::vector<ITexture*> m_textures;
std::map<int, CFBO*> m_fbos;
std::vector<AttribEntry*> m_attribs;
std::map<std::string, UniformEntry*> m_uniforms;
glm::mat4 m_modelViewProjectionMatrix;

View File

@ -8,7 +8,7 @@
// shader compiler
#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/CShaderConstantFloat.h>
@ -554,7 +554,7 @@ namespace WallpaperEngine::Render::Shaders
parameter = new Variables::CShaderVariableVector3 (
constant == this->m_constants.end ()
? WallpaperEngine::Core::aToVector3 (*defvalue)
: *(*constant).second->as <CShaderConstantVector3> ()->getValue ()
: *(*constant).second->as <CShaderConstantVector4> ()->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 <std::string, int> (*combo, 1));
// 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
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 <int, CTexture*>& Compiler::getTextures () const
const std::map <int, ITexture*>& Compiler::getTextures () const
{
return this->m_textures;
}

View File

@ -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 <int, CTexture*>& getTextures () const;
const std::map <int, ITexture*>& 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<int, CTexture*> m_textures;
std::map<int, ITexture*> m_textures;
};
}

View File

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

View File

@ -1,5 +1,5 @@
#pragma once
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#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;
};
}