Added parsing for text properties

Simplified how passes rendering works and separated it into a two stages process
  Setup (prepares shaders, uniforms, attributes, etc)
  Render (only performs the actual rendering)

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
Alexis Maiquez 2022-11-04 10:16:13 +01:00
parent d8d05363a9
commit ed1efdcd66
9 changed files with 292 additions and 93 deletions

View File

@ -136,6 +136,8 @@ add_executable(
src/WallpaperEngine/Core/Projects/CPropertySlider.cpp
src/WallpaperEngine/Core/Projects/CPropertyCombo.h
src/WallpaperEngine/Core/Projects/CPropertyCombo.cpp
src/WallpaperEngine/Core/Projects/CPropertyText.h
src/WallpaperEngine/Core/Projects/CPropertyText.cpp
src/WallpaperEngine/Core/Scenes/CCamera.cpp
src/WallpaperEngine/Core/Scenes/CCamera.h

View File

@ -60,9 +60,10 @@ CProject* CProject::fromFile (const std::string& filename, CContainer* container
for (; cur != end; cur ++)
{
project->insertProperty (
Projects::CProperty::fromJSON (*cur, cur.key ())
);
Projects::CProperty* property = Projects::CProperty::fromJSON (*cur, cur.key ());
if (property != nullptr)
project->insertProperty (property);
}
}
}

View File

@ -1,34 +1,33 @@
#include <sstream>
#include <iostream>
#include "CProperty.h"
#include "CPropertyColor.h"
#include "CPropertyCombo.h"
#include "CPropertySlider.h"
#include "CPropertyBoolean.h"
#include "CPropertyText.h"
using namespace WallpaperEngine::Core::Projects;
CProperty* CProperty::fromJSON (json data, const std::string& name)
{
auto type = jsonFindRequired (data, "type", "Project properties must have the type field");
auto value = jsonFindRequired (data, "value", "Project properties must have the value field");
auto text = data.find ("text");
if (*type == CPropertyColor::Type)
return CPropertyColor::fromJSON (data, name);
if (*type == CPropertyBoolean::Type)
return CPropertyBoolean::fromJSON (data, name);
if (*type == CPropertySlider::Type)
return CPropertySlider::fromJSON (data, name);
if (*type == CPropertyCombo::Type)
return CPropertyCombo::fromJSON (data, name);
if (*type == CPropertyText::Type)
return CPropertyText::fromJSON (data, name);
std::stringstream buffer;
buffer << "Unexpected type for property:" << *type << std::endl << data;
// throw an exception
throw std::runtime_error (buffer.str());
// show the error and ignore this property
std::cout << "Unexpected type for property:" << *type << std::endl << data << std::endl;
return nullptr;
}
CProperty::CProperty (std::string name, std::string type, std::string text) :

View File

@ -0,0 +1,21 @@
#include "CPropertyText.h"
#include "WallpaperEngine/Core/Core.h"
using namespace WallpaperEngine::Core::Projects;
CPropertyText* CPropertyText::fromJSON (json data, const std::string& name)
{
json::const_iterator text = data.find ("type");
return new CPropertyText (
name,
*text
);
}
CPropertyText::CPropertyText (const std::string& name, const std::string& text) :
CProperty (name, Type, text)
{
}
const std::string CPropertyText::Type = "text";

View File

@ -0,0 +1,19 @@
#pragma once
#include "CProperty.h"
namespace WallpaperEngine::Core::Projects
{
using json = nlohmann::json;
class CPropertyText : public CProperty
{
public:
static CPropertyText* fromJSON (json data, const std::string& name);
static const std::string Type;
private:
CPropertyText (const std::string& name, const std::string& text);
};
};

View File

@ -312,9 +312,63 @@ void CImage::setup ()
this->m_animationTime += (*cur)->frametime;
}
this->setupPasses ();
this->m_initialized = true;
}
void CImage::setupPasses ()
{
// do a pass on everything and setup proper inputs and values
const CFBO* drawTo = this->m_currentMainFBO;
const ITexture* asInput = this->getTexture ();
GLuint texcoord = this->getTexCoordCopy ();
auto cur = this->m_passes.begin ();
auto end = this->m_passes.end ();
for (; cur != end; cur ++)
{
Effects::CPass* pass = *cur;
const CFBO* prevDrawTo = drawTo;
GLuint spacePosition = this->getCopySpacePosition ();
glm::mat4* projection = &this->m_modelViewProjectionPass;
// set viewport and target texture if needed
if (pass->getMaterial ()->getMaterial ()->hasTarget () == true)
{
// setup target texture
std::string target = pass->getMaterial ()->getMaterial ()->getTarget ();
drawTo = pass->getMaterial ()->getEffect ()->findFBO (target);
spacePosition = this->getPassSpacePosition ();
// not a local fbo, try to find a scene fbo with the same name
if (drawTo == nullptr)
// this one throws if no fbo was found
drawTo = this->getScene ()->findFBO (target);
}
// determine if it's the last element in the list as this is a screen-copy-like process
else if (std::next (cur) == end && this->getImage ()->isVisible () == true)
{
spacePosition = this->getSceneSpacePosition ();
drawTo = this->getScene ()->getFBO ();
projection = &this->m_modelViewProjectionScreen;
}
pass->setDestination (drawTo);
pass->setInput (asInput);
pass->setPosition (spacePosition);
pass->setTexCoord (texcoord);
pass->setModelViewProjectionMatrix (projection);
texcoord = this->getTexCoordPass ();
drawTo = prevDrawTo;
if (pass->getMaterial ()->getMaterial ()->hasTarget () == false)
this->pinpongFramebuffer (&drawTo, &asInput);
}
}
void CImage::pinpongFramebuffer (const CFBO** drawTo, const ITexture** asInput)
{
// temporarily store FBOs used
@ -337,63 +391,21 @@ void CImage::render ()
if (this->m_initialized == false)
return;
// reset the framebuffers so the drawing always happens on the same order
this->m_currentMainFBO = this->m_mainFBO;
this->m_currentSubFBO = this->m_subFBO;
glColorMask (true, true, true, true);
// start drawing to the main framebuffer
const CFBO* drawTo = this->m_currentMainFBO;
const ITexture* asInput = this->getTexture ();
GLuint texcoord = *this->getTexCoordCopy ();
// update the position if required
if (this->getScene ()->getScene ()->isCameraParallax () == true)
this->updateScreenSpacePosition ();
auto cur = this->m_passes.begin ();
auto end = this->m_passes.end ();
for (; cur != end; cur ++)
{
Effects::CPass* pass = *cur;
const CFBO* prevDrawTo = drawTo;
GLuint spacePosition = *this->getCopySpacePosition ();
glm::mat4 projection = this->m_modelViewProjectionPass;
// set viewport and target texture if needed
if (pass->getMaterial ()->getMaterial ()->hasTarget () == true)
{
// setup target texture
std::string target = pass->getMaterial ()->getMaterial ()->getTarget ();
drawTo = pass->getMaterial ()->getEffect ()->findFBO (target);
spacePosition = *this->getPassSpacePosition ();
// not a local fbo, try to find a scene fbo with the same name
if (drawTo == nullptr)
// this one throws if no fbo was found
drawTo = this->getScene ()->findFBO (target);
}
// determine if it's the last element in the list as this is a screen-copy-like process
else if (std::next (cur) == end && this->getImage ()->isVisible () == true)
{
if (this->getScene ()->getScene ()->isCameraParallax () == true)
{
this->updateScreenSpacePosition ();
}
spacePosition = *this->getSceneSpacePosition ();
drawTo = this->getScene ()->getFBO ();
projection = this->m_modelViewProjectionScreen;
if (std::next (cur) == end)
glColorMask (true, true, true, false);
}
pass->render (drawTo, asInput, spacePosition, texcoord, projection);
texcoord = *this->getTexCoordPass ();
drawTo = prevDrawTo;
if (pass->getMaterial ()->getMaterial ()->hasTarget () == false)
this->pinpongFramebuffer (&drawTo, &asInput);
(*cur)->render ();
}
}
@ -445,29 +457,29 @@ const glm::vec2 CImage::getSize() const
return {this->m_texture->getRealWidth (), this->m_texture->getRealHeight ()};
}
const GLuint* CImage::getSceneSpacePosition () const
const GLuint CImage::getSceneSpacePosition () const
{
return &this->m_sceneSpacePosition;
return this->m_sceneSpacePosition;
}
const GLuint* CImage::getCopySpacePosition () const
const GLuint CImage::getCopySpacePosition () const
{
return &this->m_copySpacePosition;
return this->m_copySpacePosition;
}
const GLuint* CImage::getPassSpacePosition () const
const GLuint CImage::getPassSpacePosition () const
{
return &this->m_passSpacePosition;
return this->m_passSpacePosition;
}
const GLuint* CImage::getTexCoordCopy () const
const GLuint CImage::getTexCoordCopy () const
{
return &this->m_texcoordCopy;
return this->m_texcoordCopy;
}
const GLuint* CImage::getTexCoordPass () const
const GLuint CImage::getTexCoordPass () const
{
return &this->m_texcoordPass;
return this->m_texcoordPass;
}
const std::string CImage::Type = "image";

View File

@ -40,12 +40,11 @@ namespace WallpaperEngine::Render::Objects
const std::vector<CEffect*>& getEffects () const;
const glm::vec2 getSize() const;
const GLfloat* getVertex () const;
const GLuint* getSceneSpacePosition () const;
const GLuint* getCopySpacePosition () const;
const GLuint* getPassSpacePosition () const;
const GLuint* getTexCoordCopy () const;
const GLuint* getTexCoordPass () const;
const GLuint getSceneSpacePosition () const;
const GLuint getCopySpacePosition () const;
const GLuint getPassSpacePosition () const;
const GLuint getTexCoordCopy () const;
const GLuint getTexCoordPass () const;
const ITexture* getTexture () const;
const double getAnimationTime () const;
@ -60,6 +59,8 @@ namespace WallpaperEngine::Render::Objects
protected:
static const std::string Type;
void setupPasses ();
void updateScreenSpacePosition ();
private:
const ITexture* m_texture;

View File

@ -63,13 +63,13 @@ const ITexture* CPass::resolveTexture (const ITexture* expected, int index, cons
return fbo;
}
void CPass::render (const CFBO* drawTo, const ITexture* input, GLuint position, GLuint texcoord, glm::mat4 projection)
void CPass::render ()
{
// set the framebuffer we're drawing to
glBindFramebuffer (GL_FRAMEBUFFER, drawTo->getFramebuffer ());
glBindFramebuffer (GL_FRAMEBUFFER, this->m_drawTo->getFramebuffer ());
// set proper viewport based on what we're drawing to
glViewport (0, 0, drawTo->getRealWidth (), drawTo->getRealHeight ());
glViewport (0, 0, this->m_drawTo->getRealWidth (), this->m_drawTo->getRealHeight ());
// set texture blending
if (this->m_pass->getBlendingMode () == "translucent")
@ -120,19 +120,11 @@ void CPass::render (const CFBO* drawTo, const ITexture* input, GLuint position,
glDepthMask (true);
}
// update variables used in the render process (like g_ModelViewProjectionMatrix)
this->m_modelViewProjectionMatrix = projection;
// 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 = texcoord;
this->a_Position = position;
// use the shader we have registered
glUseProgram (this->m_programID);
const ITexture* texture = this->resolveTexture (input, 0, input);
// maybe we can do this when setting the texture?
const ITexture* texture = this->resolveTexture (this->m_input, 0, this->m_input);
uint32_t currentTexture = 0;
glm::vec2 translation = {0.0f, 0.0f};
@ -180,7 +172,7 @@ void CPass::render (const CFBO* drawTo, const ITexture* input, GLuint position,
for (; cur != end; cur ++)
{
texture = this->resolveTexture ((*cur).second, (*cur).first, input);
texture = this->resolveTexture ((*cur).second, (*cur).first, this->m_input);
glActiveTexture (GL_TEXTURE0 + (*cur).first);
glBindTexture (GL_TEXTURE_2D, texture->getTextureID (0));
@ -222,6 +214,41 @@ void CPass::render (const CFBO* drawTo, const ITexture* input, GLuint position,
}
}
}
// add reference uniforms
{
auto cur = this->m_referenceUniforms.begin ();
auto end = this->m_referenceUniforms.end ();
for (; cur != end; cur ++)
{
ReferenceUniformEntry* entry = (*cur).second;
switch (entry->type)
{
case Double:
glUniform1d (entry->id, *reinterpret_cast <const double*> (*entry->value));
break;
case Float:
glUniform1f (entry->id, *reinterpret_cast <const float*> (*entry->value));
break;
case Integer:
glUniform1i (entry->id, *reinterpret_cast <const int*> (*entry->value));
break;
case Vector4:
glUniform4fv (entry->id, 1, glm::value_ptr (*reinterpret_cast <const glm::vec4*> (*entry->value)));
break;
case Vector3:
glUniform3fv (entry->id, 1, glm::value_ptr (*reinterpret_cast <const glm::vec3*> (*entry->value)));
break;
case Vector2:
glUniform2fv (entry->id, 1, glm::value_ptr (*reinterpret_cast <const glm::vec2*> (*entry->value)));
break;
case Matrix4:
glUniformMatrix4fv (entry->id, 1, GL_FALSE, glm::value_ptr (*reinterpret_cast <const glm::mat4*> (*entry->value)));
break;
}
}
}
if (this->g_Texture0Rotation != -1)
{
@ -255,7 +282,7 @@ void CPass::render (const CFBO* drawTo, const ITexture* input, GLuint position,
}
// start actual rendering now
glBindBuffer (GL_ARRAY_BUFFER, position);
glBindBuffer (GL_ARRAY_BUFFER, this->a_Position);
glDrawArrays (GL_TRIANGLES, 0, 6);
// disable vertex attribs array and textures
@ -290,6 +317,36 @@ const CMaterial* CPass::getMaterial () const
return this->m_material;
}
void CPass::setDestination (const CFBO* drawTo)
{
this->m_drawTo = drawTo;
}
void CPass::setInput (const ITexture* input)
{
this->m_input = input;
}
void CPass::setModelViewProjectionMatrix (const glm::mat4* projection)
{
this->m_modelViewProjectionMatrix = projection;
}
void CPass::setModelMatrix (glm::mat4 model)
{
this->m_modelMatrix = model;
}
void CPass::setTexCoord (GLuint texcoord)
{
this->a_TexCoord = texcoord;
}
void CPass::setPosition (GLuint position)
{
this->a_Position = position;
}
Core::Objects::Images::Materials::CPass* CPass::getPass ()
{
return this->m_pass;
@ -623,6 +680,23 @@ void CPass::addUniform (const std::string& name, UniformType type, T* value)
);
}
template <typename T>
void CPass::addUniform (const std::string& name, UniformType type, T** value)
{
// this version is used to reference to system variables so things like g_Time works fine
GLint id = glGetUniformLocation (this->m_programID, name.c_str ());
// parameter not found, can be ignored
if (id == -1)
return;
// uniform found, add it to the list
this->m_referenceUniforms.insert (
std::make_pair (name, new ReferenceUniformEntry (id, name, type, reinterpret_cast <const void**> (value)))
);
}
void CPass::setupTextures ()
{
auto cur = this->m_pass->getTextures ().begin ();
@ -798,6 +872,11 @@ void CPass::addUniform (const std::string& name, const int* value)
this->addUniform (name, UniformType::Integer, value);
}
void CPass::addUniform (const std::string& name, const int** value)
{
this->addUniform (name, UniformType::Integer, value);
}
void CPass::addUniform (const std::string& name, double value)
{
this->addUniform (name, UniformType::Double, value);
@ -808,6 +887,11 @@ void CPass::addUniform (const std::string& name, const double* value)
this->addUniform (name, UniformType::Double, value);
}
void CPass::addUniform (const std::string& name, const double** value)
{
this->addUniform (name, UniformType::Double, value);
}
void CPass::addUniform (const std::string& name, float value)
{
this->addUniform (name, UniformType::Float, value);
@ -818,6 +902,12 @@ void CPass::addUniform (const std::string& name, const float* value)
this->addUniform (name, UniformType::Float, value);
}
void CPass::addUniform (const std::string& name, const float** value)
{
this->addUniform (name, UniformType::Float, value);
}
void CPass::addUniform (const std::string& name, glm::vec2 value)
{
this->addUniform (name, UniformType::Vector2, value);
@ -828,6 +918,12 @@ void CPass::addUniform (const std::string& name, const glm::vec2* value)
this->addUniform (name, UniformType::Vector2, value);
}
void CPass::addUniform (const std::string& name, const glm::vec2** value)
{
this->addUniform (name, UniformType::Vector2, value);
}
void CPass::addUniform (const std::string& name, glm::vec3 value)
{
this->addUniform (name, UniformType::Vector3, value);
@ -838,6 +934,12 @@ void CPass::addUniform (const std::string& name, const glm::vec3* value)
this->addUniform (name, UniformType::Vector3, value);
}
void CPass::addUniform (const std::string& name, const glm::vec3** value)
{
this->addUniform (name, UniformType::Vector3, value);
}
void CPass::addUniform (const std::string& name, glm::vec4 value)
{
this->addUniform (name, UniformType::Vector4, value);
@ -848,6 +950,11 @@ void CPass::addUniform (const std::string& name, const glm::vec4* value)
this->addUniform (name, UniformType::Vector4, value);
}
void CPass::addUniform (const std::string& name, const glm::vec4** value)
{
this->addUniform (name, UniformType::Vector4, value);
}
void CPass::addUniform (const std::string& name, glm::mat4 value)
{
this->addUniform (name, UniformType::Matrix4, value);
@ -857,3 +964,8 @@ void CPass::addUniform (const std::string& name, const glm::mat4* value)
{
this->addUniform (name, UniformType::Matrix4, value);
}
void CPass::addUniform (const std::string& name, const glm::mat4** value)
{
this->addUniform (name, UniformType::Matrix4, value);
}

View File

@ -21,7 +21,14 @@ namespace WallpaperEngine::Render::Objects::Effects
public:
CPass (CMaterial* material, Core::Objects::Images::Materials::CPass* pass);
void render (const CFBO* drawTo, const ITexture* input, GLuint position, GLuint texcoord, glm::mat4 projection);
void render ();
void setDestination (const CFBO* drawTo);
void setInput (const ITexture* input);
void setTexCoord (GLuint texcoord);
void setPosition (GLuint position);
void setModelViewProjectionMatrix (const glm::mat4* projection);
void setModelMatrix (glm::mat4 model);
const CMaterial* getMaterial () const;
Core::Objects::Images::Materials::CPass* getPass ();
@ -50,6 +57,18 @@ namespace WallpaperEngine::Render::Objects::Effects
const void* value;
};
class ReferenceUniformEntry
{
public:
ReferenceUniformEntry (GLint id, std::string name, UniformType type, const void** value) :
id (id), name (std::move (name)), type (type), value (value) { }
GLint id;
std::string name;
UniformType type;
const void** value;
};
class AttribEntry
{
public:
@ -84,8 +103,16 @@ namespace WallpaperEngine::Render::Objects::Effects
void addUniform (const std::string& name, const glm::vec3* value);
void addUniform (const std::string& name, const glm::vec4* value);
void addUniform (const std::string& name, const glm::mat4* value);
void addUniform (const std::string& name, const int** value);
void addUniform (const std::string& name, const double** value);
void addUniform (const std::string& name, const float** value);
void addUniform (const std::string& name, const glm::vec2** value);
void addUniform (const std::string& name, const glm::vec3** value);
void addUniform (const std::string& name, const glm::vec4** value);
void addUniform (const std::string& name, const glm::mat4** value);
template <typename T> void addUniform (const std::string& name, UniformType type, T value);
template <typename T> void addUniform (const std::string& name, UniformType type, T* value);
template <typename T> void addUniform (const std::string& name, UniformType type, T** value);
const ITexture* resolveTexture (const ITexture* expected, int index, const ITexture* previous = nullptr);
@ -96,7 +123,9 @@ namespace WallpaperEngine::Render::Objects::Effects
std::map <std::string, bool> m_foundCombos;
std::vector<AttribEntry*> m_attribs;
std::map<std::string, UniformEntry*> m_uniforms;
glm::mat4 m_modelViewProjectionMatrix;
std::map<std::string, ReferenceUniformEntry*> m_referenceUniforms;
const glm::mat4* m_modelViewProjectionMatrix;
glm::mat4 m_modelMatrix;
/**
* Contains the final map of textures to be used
@ -106,6 +135,9 @@ namespace WallpaperEngine::Render::Objects::Effects
Render::Shaders::Compiler* m_fragShader;
Render::Shaders::Compiler* m_vertShader;
const CFBO* m_drawTo;
const ITexture* m_input;
GLuint m_programID;
// shader variables used temporary