mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-09-14 05:46:48 +08:00
+ Basic parsing for json files on project (just scene, project objects and basic images)
+ Re-structured some code to its (hopefully) final form (shader compiler, file finding, etc) Signed-off-by: Alexis Maiquez Murcia <almamu@almamu.com>
This commit is contained in:
parent
c8534b9a6e
commit
1821731d5a
File diff suppressed because it is too large
Load Diff
@ -1,366 +0,0 @@
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include "BasicShaderLoader.h"
|
||||
#include "nier_test.h"
|
||||
#include "common.h"
|
||||
|
||||
BasicShaderLoader::BasicShaderLoader (irr::io::path file, Type type, bool recursive)
|
||||
{
|
||||
// begin with an space so it gets ignored properly on parse
|
||||
if (recursive == false)
|
||||
{
|
||||
this->m_content = "#version 120\n"
|
||||
"#define texSample2D texture2D\n"
|
||||
"#define frac fract\n"
|
||||
"vec4 mul(vec4 x, mat4 y) { return x * y; }\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_content = "";
|
||||
}
|
||||
|
||||
std::ifstream _in (file.c_str ());
|
||||
this->m_content.append (std::istreambuf_iterator<char> (_in), std::istreambuf_iterator<char> ());
|
||||
this->m_type = type;
|
||||
}
|
||||
|
||||
bool BasicShaderLoader::peekString(std::string str, std::string::const_iterator& it)
|
||||
{
|
||||
std::string::const_iterator check = str.begin();
|
||||
std::string::const_iterator cur = it;
|
||||
|
||||
while (cur != this->m_content.end () && check != str.end ())
|
||||
{
|
||||
if (*cur != *check) return false;
|
||||
|
||||
cur ++; check ++;
|
||||
}
|
||||
|
||||
if (cur == this->m_content.end ())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (check != str.end ())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
it = cur;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BasicShaderLoader::expectSemicolon (std::string::const_iterator& it)
|
||||
{
|
||||
if (*it != ';')
|
||||
{
|
||||
this->m_error = true;
|
||||
this->m_errorInfo = "Expected semicolon but got " + *it;
|
||||
return false;
|
||||
}
|
||||
|
||||
it ++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BasicShaderLoader::ignoreSpaces(std::string::const_iterator &it)
|
||||
{
|
||||
while (it != this->m_content.end() && (*it == ' ' || *it == '\t')) it ++;
|
||||
}
|
||||
|
||||
void BasicShaderLoader::ignoreUpToNextLineFeed (std::string::const_iterator& it)
|
||||
{
|
||||
while (it != this->m_content.end() && *it != '\n') it ++;
|
||||
}
|
||||
|
||||
void BasicShaderLoader::ignoreUpToBlockCommentEnd (std::string::const_iterator& it)
|
||||
{
|
||||
while (it != this->m_content.end() && this->peekString ("*/", it) == false) it ++;
|
||||
}
|
||||
|
||||
std::string BasicShaderLoader::extractType (std::string::const_iterator& it)
|
||||
{
|
||||
std::vector<std::string>::const_iterator cur = sTypes.begin ();
|
||||
std::vector<std::string>::const_iterator end = sTypes.end ();
|
||||
|
||||
while (cur != end)
|
||||
{
|
||||
if (this->peekString (*cur, it) == true)
|
||||
{
|
||||
return *cur;
|
||||
}
|
||||
|
||||
cur ++;
|
||||
}
|
||||
|
||||
this->m_error = true;
|
||||
this->m_errorInfo = "Expected type";
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string BasicShaderLoader::extractName (std::string::const_iterator& it)
|
||||
{
|
||||
std::string::const_iterator cur = it;
|
||||
std::string::const_iterator begin = cur;
|
||||
|
||||
// first character has to be a valid alphabetic characer
|
||||
if (this->isChar (cur) == false && *cur != '_')
|
||||
{
|
||||
this->m_error = true;
|
||||
this->m_errorInfo = "Expected name doesn't start with a valid character";
|
||||
return "";
|
||||
}
|
||||
|
||||
cur ++;
|
||||
|
||||
while (cur != this->m_content.end () && (this->isChar (cur) == true || *cur == '_' || this->isNumeric (cur) == true)) cur ++;
|
||||
|
||||
it = cur;
|
||||
|
||||
return std::string (begin, cur);
|
||||
}
|
||||
|
||||
bool BasicShaderLoader::isChar (std::string::const_iterator& it)
|
||||
{
|
||||
return ((*it) >= 'A' && (*it) <= 'Z') || ((*it) >= 'a' && (*it) <= 'z');
|
||||
}
|
||||
|
||||
bool BasicShaderLoader::isNumeric (std::string::const_iterator& it)
|
||||
{
|
||||
return (*it) >= '0' && (*it) <= '9';
|
||||
}
|
||||
|
||||
std::string BasicShaderLoader::extractQuotedValue(std::string::const_iterator& it)
|
||||
{
|
||||
std::string::const_iterator cur = it;
|
||||
|
||||
if (*cur != '"')
|
||||
{
|
||||
m_error = true;
|
||||
m_errorInfo = "Expected opening \" but got " + (*cur);
|
||||
return "";
|
||||
}
|
||||
|
||||
cur ++;
|
||||
|
||||
while (cur != this->m_content.end () && *cur != '\n' && *cur != '"') cur ++;
|
||||
|
||||
if (cur == this->m_content.end ())
|
||||
{
|
||||
m_error = true;
|
||||
m_errorInfo = "Expected closing \" not found";
|
||||
it = cur;
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string filename = std::string (++it, cur);
|
||||
|
||||
it = ++cur;
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
std::string BasicShaderLoader::lookupShaderFile (std::string filename)
|
||||
{
|
||||
irr::io::path shaderTest = _example_base_folder; shaderTest += "/"; shaderTest += filename.c_str ();
|
||||
irr::io::IFileSystem *fs = device->getFileSystem ();
|
||||
|
||||
// by default try to load from current folder
|
||||
// we might want, in the future, to load things from different folders
|
||||
// to provide standard functionality
|
||||
if (fs->existFile (shaderTest) == false)
|
||||
{
|
||||
this->m_error = true;
|
||||
this->m_errorInfo = "Cannot find file " + filename + " to include";
|
||||
return "";
|
||||
}
|
||||
|
||||
// now compile the new shader
|
||||
// do not include the default header (as it's already included in the parent)
|
||||
BasicShaderLoader loader (shaderTest, this->m_type, true);
|
||||
|
||||
return *loader.precompile ();
|
||||
}
|
||||
|
||||
std::string BasicShaderLoader::lookupReplaceSymbol (std::string symbol)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator cur = sVariableReplacement.begin ();
|
||||
std::map<std::string, std::string>::const_iterator end = sVariableReplacement.end ();
|
||||
|
||||
while (cur != end)
|
||||
{
|
||||
if (cur->first == symbol)
|
||||
{
|
||||
return cur->second;
|
||||
}
|
||||
|
||||
cur ++;
|
||||
}
|
||||
|
||||
// if there is no replacement, return the original
|
||||
return symbol;
|
||||
}
|
||||
|
||||
std::string* BasicShaderLoader::precompile ()
|
||||
{
|
||||
#define BREAK_IF_ERROR if (this->m_error == true) { device->getLogger ()->log ("ERROR COMPILING SHADER"); device->getLogger ()->log (this->m_errorInfo.c_str ()); return nullptr; }
|
||||
// parse the shader and find #includes and such things and translate them to the correct name
|
||||
// also remove any #version definition to prevent errors
|
||||
std::string::const_iterator it = this->m_content.begin ();
|
||||
|
||||
// reset error indicator
|
||||
this->m_error = false;
|
||||
this->m_errorInfo = "";
|
||||
|
||||
// search preprocessor macros and parse them
|
||||
while (it != this->m_content.end () && this->m_error == false)
|
||||
{
|
||||
if (*it == ' ' || *it == '\t' || *it == '\n' || *it == '\r' || *it == '\0' || *it == '{' || *it == '}' || *it == '[' || *it == ']' || *it == '.')
|
||||
{
|
||||
this->m_compiledContent += *it;
|
||||
it ++;
|
||||
}
|
||||
else if (*it == '#')
|
||||
{
|
||||
if (this->peekString ("#include", it) == true)
|
||||
{
|
||||
std::string filename = "";
|
||||
|
||||
// ignore whitespaces
|
||||
this->ignoreSpaces (it); BREAK_IF_ERROR
|
||||
// extract value between quotes
|
||||
filename = this->extractQuotedValue (it); BREAK_IF_ERROR
|
||||
|
||||
// try to find the file first
|
||||
this->m_compiledContent += "// begin of included from file " + filename + "\r\n";
|
||||
this->m_compiledContent += this->lookupShaderFile (filename);
|
||||
this->m_compiledContent += "\r\n// end of included from file " + filename + "\r\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_compiledContent += '#';
|
||||
it ++;
|
||||
}
|
||||
}
|
||||
else if (*it == 'a')
|
||||
{
|
||||
// find attribute definitions
|
||||
if (this->peekString ("attribute", it) == true)
|
||||
{
|
||||
this->ignoreSpaces (it);
|
||||
std::string type = this->extractType (it); BREAK_IF_ERROR
|
||||
this->ignoreSpaces (it);
|
||||
std::string name = this->extractName (it); BREAK_IF_ERROR
|
||||
this->ignoreSpaces (it);
|
||||
this->expectSemicolon (it); BREAK_IF_ERROR
|
||||
|
||||
this->m_compiledContent += "// attribute";
|
||||
this->m_compiledContent += " " + type + " ";
|
||||
this->m_compiledContent += name;
|
||||
this->m_compiledContent += "; /* replaced by " + this->lookupReplaceSymbol (name) + " */";
|
||||
}
|
||||
else
|
||||
{
|
||||
// check for types first
|
||||
std::string type = this->extractType (it);
|
||||
|
||||
// types not found, try names
|
||||
if (this->m_error == false)
|
||||
{
|
||||
this->m_compiledContent += type;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_error = false;
|
||||
std::string name = this->extractName (it);
|
||||
|
||||
if (this->m_error == false)
|
||||
{
|
||||
// check if the name is a translated one or not
|
||||
this->m_compiledContent += this->lookupReplaceSymbol (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_error = false;
|
||||
this->m_compiledContent += *it;
|
||||
it ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*it == '/')
|
||||
{
|
||||
if (this->peekString ("//", it) == true)
|
||||
{
|
||||
std::string::const_iterator begin = it - 2;
|
||||
this->ignoreUpToNextLineFeed (it);
|
||||
this->m_compiledContent.append (begin, it);
|
||||
device->getLogger ()->log (*it + "asdf");
|
||||
}
|
||||
else if (this->peekString ("/*", it) == true)
|
||||
{
|
||||
std::string::const_iterator begin = it - 2;
|
||||
this->ignoreUpToBlockCommentEnd (it);
|
||||
this->m_compiledContent.append (begin, it);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_compiledContent += *it;
|
||||
it ++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// check for types first
|
||||
std::string type = this->extractType (it);
|
||||
|
||||
// types not found, try names
|
||||
if (this->m_error == false)
|
||||
{
|
||||
this->m_compiledContent += type;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_error = false;
|
||||
std::string name = this->extractName (it);
|
||||
|
||||
if (this->m_error == false)
|
||||
{
|
||||
// check if the name is a translated one or not
|
||||
this->m_compiledContent += this->lookupReplaceSymbol (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_error = false;
|
||||
this->m_compiledContent += *it;
|
||||
it ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
device->getLogger ()->log ("Compiled shader output");
|
||||
device->getLogger ()->log (this->m_compiledContent.c_str ());
|
||||
|
||||
return &this->m_compiledContent;
|
||||
#undef BREAK_IF_ERROR
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> BasicShaderLoader::sVariableReplacement =
|
||||
{
|
||||
// attribute vec3 a_position
|
||||
{"a_Position", "gl_Vertex.xyz"},
|
||||
// attribute vec2 a_TexCoord
|
||||
{"a_TexCoord", "gl_MultiTexCoord0.xy"},
|
||||
// attribute vec3 a_Normal
|
||||
{"a_Normal", "gl_Normal.xyz"}
|
||||
};
|
||||
|
||||
std::vector<std::string> BasicShaderLoader::sTypes =
|
||||
{
|
||||
"vec4", "vec3", "vec2", "float"
|
||||
};
|
@ -1,61 +0,0 @@
|
||||
#ifndef __BASIC_SHADER_LOADER_H__
|
||||
#define __BASIC_SHADER_LOADER_H__
|
||||
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
/**
|
||||
* A basic shader loader that adds basic function definitions to every loaded shader
|
||||
*/
|
||||
class BasicShaderLoader
|
||||
{
|
||||
public:
|
||||
struct VariableReplacement
|
||||
{
|
||||
const char* original;
|
||||
const char* replacement;
|
||||
};
|
||||
|
||||
struct TypeName
|
||||
{
|
||||
const char* name;
|
||||
int size;
|
||||
};
|
||||
|
||||
enum Type
|
||||
{
|
||||
Type_Vertex = 0,
|
||||
Type_Pixel = 1,
|
||||
};
|
||||
|
||||
static std::map<std::string, std::string> sVariableReplacement;
|
||||
static std::vector<std::string> sTypes;
|
||||
|
||||
BasicShaderLoader (irr::io::path file, Type type, bool recursive = false);
|
||||
std::string* precompile ();
|
||||
|
||||
private:
|
||||
bool peekString (std::string str, std::string::const_iterator& it);
|
||||
bool expectSemicolon (std::string::const_iterator& it);
|
||||
void ignoreSpaces (std::string::const_iterator& it);
|
||||
void ignoreUpToNextLineFeed (std::string::const_iterator& it);
|
||||
void ignoreUpToBlockCommentEnd (std::string::const_iterator& it);
|
||||
std::string extractType (std::string::const_iterator& it);
|
||||
std::string extractName (std::string::const_iterator& it);
|
||||
std::string extractQuotedValue (std::string::const_iterator& it);
|
||||
std::string lookupShaderFile (std::string filename);
|
||||
std::string lookupReplaceSymbol (std::string symbol);
|
||||
|
||||
bool isChar (std::string::const_iterator& it);
|
||||
bool isNumeric (std::string::const_iterator& it);
|
||||
|
||||
std::string m_content;
|
||||
std::string m_compiledContent;
|
||||
bool m_error;
|
||||
std::string m_errorInfo;
|
||||
Type m_type;
|
||||
};
|
||||
|
||||
#endif /* !__BASIC_SHADER_LOADER_H__ */
|
@ -13,6 +13,6 @@ find_package(Irrlicht REQUIRED)
|
||||
|
||||
include_directories(${X11_INCLUDE_DIR} ${IRRLICHT_INCLUDE_DIR} .)
|
||||
|
||||
add_executable(wallengine main.cpp common.h nier_test.cpp BasicShaderLoader.h BasicShaderLoader.cpp nier_test.h wallpaperengine/Project.cpp wallpaperengine/Project.h wallpaperengine/Scene.cpp wallpaperengine/Scene.h wallpaperengine/Object.cpp wallpaperengine/Object.h)
|
||||
add_executable(wallengine main.cpp common.h nier_test.cpp wallpaperengine/shaders/compiler.h wallpaperengine/shaders/compiler.cpp nier_test.h wallpaperengine/project.cpp wallpaperengine/project.h wallpaperengine/scene.cpp wallpaperengine/scene.h wallpaperengine/object.cpp wallpaperengine/object.h wallpaperengine/camera.cpp wallpaperengine/camera.h wallpaperengine/core.cpp wallpaperengine/core.h wallpaperengine/image.cpp wallpaperengine/image.h wallpaperengine/object3d.cpp wallpaperengine/object3d.h wallpaperengine/effect.cpp wallpaperengine/effect.h wallpaperengine/material.cpp wallpaperengine/material.h wallpaperengine/fs/fileResolver.cpp wallpaperengine/fs/fileResolver.h wallpaperengine/irrlicht.cpp wallpaperengine/irrlicht.h wallpaperengine/config.cpp wallpaperengine/config.h)
|
||||
|
||||
target_link_libraries(wallengine ${X11_LIBRARIES} ${X11_Xxf86vm_LIB} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${ZLIB_LIBRARIES} ${IRRLICHT_LIBRARY})
|
24
main.cpp
24
main.cpp
@ -1,7 +1,9 @@
|
||||
#include <iostream>
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <sstream>
|
||||
#include <wallpaperengine/config.h>
|
||||
#include "nier_test.h"
|
||||
#include "wallpaperengine/irrlicht.h"
|
||||
|
||||
int WinID = 0;
|
||||
|
||||
@ -22,11 +24,9 @@ int main(int argc, char* argv[])
|
||||
return game_test_main ();
|
||||
}
|
||||
|
||||
irr::IrrlichtDevice* device = nullptr;
|
||||
irr::video::IVideoDriver* driver = nullptr;
|
||||
irr::SIrrlichtCreationParameters _irr_params;
|
||||
|
||||
int init_driver ()
|
||||
int init_irrlicht()
|
||||
{
|
||||
// prepare basic configuration for irrlicht
|
||||
_irr_params.AntiAlias = 8;
|
||||
@ -46,26 +46,34 @@ int init_driver ()
|
||||
_irr_params.LoggingLevel = irr::ELL_DEBUG;
|
||||
_irr_params.WindowId = reinterpret_cast<void*> (WinID);
|
||||
|
||||
device = irr::createDeviceEx (_irr_params);
|
||||
wp::irrlicht::device = irr::createDeviceEx (_irr_params);
|
||||
|
||||
if (device == nullptr)
|
||||
if (wp::irrlicht::device == nullptr)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
device->setWindowCaption (L"Test game");
|
||||
driver = device->getVideoDriver();
|
||||
wp::irrlicht::device->setWindowCaption (L"Test game");
|
||||
wp::irrlicht::driver = wp::irrlicht::device->getVideoDriver();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void preconfigure_wallpaper_engine ()
|
||||
{
|
||||
wp::config::path::base = wp::irrlicht::device->getFileSystem ()->getAbsolutePath ("../");
|
||||
wp::config::path::resources = wp::config::path::base + "/res";
|
||||
wp::config::path::shaders = wp::config::path::resources + "/shaders";
|
||||
}
|
||||
|
||||
int game_test_main ()
|
||||
{
|
||||
if (init_driver())
|
||||
if (init_irrlicht())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
preconfigure_wallpaper_engine ();
|
||||
nier_test ();
|
||||
|
||||
return 0;
|
||||
|
@ -3,8 +3,10 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "common.h"
|
||||
#include "BasicShaderLoader.h"
|
||||
#include "wallpaperengine/Project.h"
|
||||
#include "wallpaperengine/shaders/compiler.h"
|
||||
#include "wallpaperengine/fs/fileResolver.h"
|
||||
#include "wallpaperengine/project.h"
|
||||
#include "wallpaperengine/irrlicht.h"
|
||||
|
||||
irr::io::path _example_base_folder = "../res/";
|
||||
irr::f32 g_AnimationSpeed = 0.1f;
|
||||
@ -127,17 +129,30 @@ public:
|
||||
|
||||
int nier_test ()
|
||||
{
|
||||
irr::io::path _wp_engine_folder = "/home/almamu/Development/tmp/nier__automata_-_become_as_gods_edition";
|
||||
irr::io::path _wp_engine_folder = "/home/almamu/Downloads/nier__automata_-_become_as_gods_edition/";
|
||||
|
||||
Project* wp_project = new Project (_wp_engine_folder);
|
||||
// set our working directory
|
||||
wp::fs::resolver.changeWorkingDirectory (_wp_engine_folder);
|
||||
// also append base folder for resources
|
||||
wp::fs::resolver.appendEnvironment ("");
|
||||
|
||||
irr::io::path _water_example = _example_base_folder; _water_example += "materials/water-intact.png";
|
||||
irr::io::path _mud_example = _example_base_folder; _mud_example += "materials/plant-on-water.png";
|
||||
irr::io::path _background_example = _example_base_folder; _background_example += "materials/top-part.png";
|
||||
irr::io::path _waterripple_normal = _example_base_folder; _waterripple_normal += "materials/effects/waterripplenormal.png";
|
||||
irr::io::path _waterripple_frag_shader = _example_base_folder; _waterripple_frag_shader += "shaders/effects/waterripple_opengl.frag";
|
||||
irr::io::path _waterripple_vert_shader = _example_base_folder; _waterripple_vert_shader += "shaders/effects/waterripple_opengl.vert";
|
||||
irr::io::path _white = _example_base_folder; _white += "materials/white.png";
|
||||
wp::project* wp_project = new wp::project (_wp_engine_folder);
|
||||
wp::fs::resolver.changeWorkingDirectory ("../res");
|
||||
|
||||
irr::io::path _water_example = wp::fs::resolver.resolve ("materials/water-intact.png");
|
||||
irr::io::path _mud_example = wp::fs::resolver.resolve ("materials/plant-on-water.png");
|
||||
irr::io::path _background_example = wp::fs::resolver.resolve ("materials/top-part.png");
|
||||
irr::io::path _waterripple_normal = wp::fs::resolver.resolve ("materials/effects/waterripplenormal.png");
|
||||
irr::io::path _waterripple_frag_shader = wp::fs::resolver.resolve ("shaders/effects/waterripple_opengl.frag");
|
||||
irr::io::path _waterripple_vert_shader = wp::fs::resolver.resolve ("shaders/effects/waterripple_opengl.vert");
|
||||
irr::io::path _white = wp::fs::resolver.resolve ("materials/white.png");
|
||||
// irr::io::path _water_example = _example_base_folder; _water_example += "materials/water-intact.png";
|
||||
// irr::io::path _mud_example = _example_base_folder; _mud_example += "materials/plant-on-water.png";
|
||||
// irr::io::path _background_example = _example_base_folder; _background_example += "materials/top-part.png";
|
||||
// irr::io::path _waterripple_normal = _example_base_folder; _waterripple_normal += "materials/effects/waterripplenormal.png";
|
||||
// irr::io::path _waterripple_frag_shader = _example_base_folder; _waterripple_frag_shader += "shaders/effects/waterripple_opengl.frag";
|
||||
// irr::io::path _waterripple_vert_shader = _example_base_folder; _waterripple_vert_shader += "shaders/effects/waterripple_opengl.vert";
|
||||
// irr::io::path _white = _example_base_folder; _white += "materials/white.png";
|
||||
|
||||
/*irr::video::E_DRIVER_TYPE driverType = irr::video::E_DRIVER_TYPE::EDT_OPENGL;
|
||||
device = irr::createDevice (driverType, irr::core::dimension2d<uint32_t>(1280, 720));
|
||||
@ -146,19 +161,19 @@ int nier_test ()
|
||||
driver = device->getVideoDriver ();*/
|
||||
|
||||
// check for ps and vs support
|
||||
if (driver->queryFeature (irr::video::EVDF_PIXEL_SHADER_1_1) == false && driver->queryFeature (irr::video::EVDF_ARB_FRAGMENT_PROGRAM_1) == false)
|
||||
if (wp::irrlicht::driver->queryFeature (irr::video::EVDF_PIXEL_SHADER_1_1) == false && wp::irrlicht::driver->queryFeature (irr::video::EVDF_ARB_FRAGMENT_PROGRAM_1) == false)
|
||||
{
|
||||
device->getLogger ()->log ("WARNING: Pixel shaders disabled because of missing driver/hardware support");
|
||||
wp::irrlicht::device->getLogger ()->log ("WARNING: Pixel shaders disabled because of missing driver/hardware support");
|
||||
_waterripple_frag_shader = "";
|
||||
}
|
||||
|
||||
if (driver->queryFeature (irr::video::EVDF_VERTEX_SHADER_1_1) == false && driver->queryFeature (irr::video::EVDF_ARB_VERTEX_PROGRAM_1) == false)
|
||||
if (wp::irrlicht::driver->queryFeature (irr::video::EVDF_VERTEX_SHADER_1_1) == false && wp::irrlicht::driver->queryFeature (irr::video::EVDF_ARB_VERTEX_PROGRAM_1) == false)
|
||||
{
|
||||
device->getLogger ()->log ("WARNING: Vertex shaders disabled because of missing driver/hardware support");
|
||||
wp::irrlicht::device->getLogger ()->log ("WARNING: Vertex shaders disabled because of missing driver/hardware support");
|
||||
_waterripple_vert_shader = "";
|
||||
}
|
||||
|
||||
irr::video::IGPUProgrammingServices* gpuProgrammingServices = driver->getGPUProgrammingServices ();
|
||||
irr::video::IGPUProgrammingServices* gpuProgrammingServices = wp::irrlicht::driver->getGPUProgrammingServices ();
|
||||
|
||||
int32_t materialType1 = 0;
|
||||
|
||||
@ -166,12 +181,12 @@ int nier_test ()
|
||||
{
|
||||
MyShaderCallback* shader = new MyShaderCallback ();
|
||||
|
||||
BasicShaderLoader _vert(_waterripple_vert_shader, BasicShaderLoader::Type::Type_Vertex);
|
||||
BasicShaderLoader _frag(_waterripple_frag_shader, BasicShaderLoader::Type::Type_Pixel);
|
||||
wp::shaders::compiler _vert(_waterripple_vert_shader, wp::shaders::compiler::Type::Type_Vertex);
|
||||
wp::shaders::compiler _frag(_waterripple_frag_shader, wp::shaders::compiler::Type::Type_Pixel);
|
||||
|
||||
materialType1 = gpuProgrammingServices->addHighLevelShaderMaterial(
|
||||
_vert.precompile ()->c_str (), "vertexMain", irr::video::EVST_VS_2_0,
|
||||
_frag.precompile ()->c_str (), "pixelMain", irr::video::EPST_PS_2_0,
|
||||
_vert.precompile ().c_str (), "vertexMain", irr::video::EVST_VS_2_0,
|
||||
_frag.precompile ().c_str (), "pixelMain", irr::video::EPST_PS_2_0,
|
||||
shader, irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL, 0, irr::video::EGSL_DEFAULT
|
||||
);
|
||||
|
||||
@ -179,14 +194,14 @@ int nier_test ()
|
||||
}
|
||||
|
||||
// load some basic textures
|
||||
irr::video::ITexture* waterTexture = driver->getTexture (_water_example.c_str ());
|
||||
irr::video::ITexture* mudTexture = driver->getTexture (_mud_example.c_str ());
|
||||
irr::video::ITexture* backgroundExample = driver->getTexture (_background_example.c_str ());
|
||||
irr::video::ITexture* waterRippleNormalTexture = driver->getTexture (_waterripple_normal.c_str ());
|
||||
irr::video::ITexture* whiteTexture = driver->getTexture (_white.c_str ());
|
||||
irr::video::ITexture* waterTexture = wp::irrlicht::driver->getTexture (_water_example.c_str ());
|
||||
irr::video::ITexture* mudTexture = wp::irrlicht::driver->getTexture (_mud_example.c_str ());
|
||||
irr::video::ITexture* backgroundExample = wp::irrlicht::driver->getTexture (_background_example.c_str ());
|
||||
irr::video::ITexture* waterRippleNormalTexture = wp::irrlicht::driver->getTexture (_waterripple_normal.c_str ());
|
||||
irr::video::ITexture* whiteTexture = wp::irrlicht::driver->getTexture (_white.c_str ());
|
||||
|
||||
// get scene manager
|
||||
irr::scene::ISceneManager* sceneManager = device->getSceneManager ();
|
||||
irr::scene::ISceneManager* sceneManager = wp::irrlicht::device->getSceneManager ();
|
||||
|
||||
sceneManager->addCameraSceneNode (0, irr::core::vector3df (0.0f, 0.0f, -_map_size.Z), irr::core::vector3df (0.0f, 0.0f, _map_size.Z));
|
||||
|
||||
@ -211,35 +226,33 @@ int nier_test ()
|
||||
irr::core::matrix4 identity; identity.makeIdentity ();
|
||||
irr::core::matrix4 orthoProjection; orthoProjection.buildProjectionMatrixOrthoLH (1.0f, 1.0f, 0.0f, 1.0f);
|
||||
|
||||
driver->setTransform (irr::video::ETS_PROJECTION, orthoProjection);
|
||||
driver->setTransform (irr::video::ETS_VIEW, identity);
|
||||
driver->setTransform (irr::video::ETS_WORLD, identity);
|
||||
wp::irrlicht::driver->setTransform (irr::video::ETS_PROJECTION, orthoProjection);
|
||||
wp::irrlicht::driver->setTransform (irr::video::ETS_VIEW, identity);
|
||||
wp::irrlicht::driver->setTransform (irr::video::ETS_WORLD, identity);
|
||||
|
||||
int32_t lastTime = 0;
|
||||
int32_t minimumTime = 1000 / 90;
|
||||
int32_t currentTime = 0;
|
||||
|
||||
while (device->run () && driver)
|
||||
while (wp::irrlicht::device->run () && wp::irrlicht::driver)
|
||||
{
|
||||
// if (device->isWindowActive ())
|
||||
{
|
||||
currentTime = device->getTimer ()->getTime ();
|
||||
currentTime = wp::irrlicht::device->getTimer ()->getTime ();
|
||||
g_Time = currentTime / 1000.0f;
|
||||
|
||||
if (currentTime - lastTime > minimumTime)
|
||||
{
|
||||
driver->beginScene (true, true, irr::video::SColor(0, 0, 0, 0));
|
||||
wp::irrlicht::driver->beginScene (true, true, irr::video::SColor(0, 0, 0, 0));
|
||||
sceneManager->drawAll ();
|
||||
driver->endScene ();
|
||||
wp::irrlicht::driver->endScene ();
|
||||
|
||||
lastTime = currentTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
device->sleep (1, false);
|
||||
wp::irrlicht::device->sleep (1, false);
|
||||
}
|
||||
|
||||
// printf ("FPS: %d\n", driver->getFPS ());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,45 +0,0 @@
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "Object.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
Object::Object (json json_data)
|
||||
{
|
||||
json::const_iterator angles = json_data.find ("angles");
|
||||
json::const_iterator image = json_data.find ("image");
|
||||
json::const_iterator id = json_data.find ("id");
|
||||
json::const_iterator visible = json_data.find ("visible");
|
||||
json::const_iterator model = json_data.find ("model");
|
||||
|
||||
if (angles != json_data.end () && angles.value ().is_null() == false)
|
||||
{
|
||||
this->m_angles = json_data ["angles"];
|
||||
}
|
||||
|
||||
if (image != json_data.end () && image.value ().is_null() == false)
|
||||
{
|
||||
this->m_image = json_data ["image"];
|
||||
}
|
||||
|
||||
if (id != json_data.end () && id.value ().is_null() == false)
|
||||
{
|
||||
this->m_id = json_data ["id"];
|
||||
}
|
||||
|
||||
if (visible != json_data.end () && visible.value ().is_null() == false)
|
||||
{
|
||||
this->m_visible = json_data ["visible"];
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_visible = true;
|
||||
}
|
||||
|
||||
if (model != json_data.end () && model.value ().is_null() == false)
|
||||
{
|
||||
this->m_model = json_data ["model"];
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
#ifndef WALLENGINE_OBJECT_H
|
||||
#define WALLENGINE_OBJECT_H
|
||||
|
||||
#include <iostream>
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
Object (json json_data);
|
||||
|
||||
private:
|
||||
int m_id;
|
||||
|
||||
bool m_visible;
|
||||
|
||||
std::string m_model;
|
||||
std::string m_angles;
|
||||
std::string m_image;
|
||||
};
|
||||
|
||||
|
||||
#endif //WALLENGINE_OBJECT_H
|
@ -1,39 +0,0 @@
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "Project.h"
|
||||
|
||||
Project::Project (irr::io::path baseDirectory)
|
||||
{
|
||||
irr::io::path projectFile = baseDirectory + "/project.json";
|
||||
|
||||
std::ifstream _in (projectFile.c_str ());
|
||||
this->m_content = "";
|
||||
this->m_content.append (std::istreambuf_iterator<char> (_in), std::istreambuf_iterator<char> ());
|
||||
this->m_projectFile = json::parse (this->m_content);
|
||||
|
||||
json::const_iterator file_it = this->m_projectFile.find ("file");
|
||||
json::const_iterator name_it = this->m_projectFile.find ("title");
|
||||
json::const_iterator type_it = this->m_projectFile.find ("type");
|
||||
|
||||
if (file_it != this->m_projectFile.end ())
|
||||
{
|
||||
// load scene file
|
||||
this->m_file = file_it.value ();
|
||||
this->m_file = baseDirectory.c_str ();
|
||||
this->m_file += "/";
|
||||
this->m_file += this->m_projectFile ["file"];
|
||||
this->m_scene = new Scene (this->m_file.c_str ());
|
||||
}
|
||||
|
||||
if (type_it != this->m_projectFile.end ())
|
||||
{
|
||||
this->m_type = type_it.value ();
|
||||
}
|
||||
|
||||
if (name_it != this->m_projectFile.end ())
|
||||
{
|
||||
this->m_title = name_it.value ();
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
#ifndef WALLENGINE_PROJECT_H
|
||||
#define WALLENGINE_PROJECT_H
|
||||
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "Scene.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
class Project
|
||||
{
|
||||
public:
|
||||
Project (irr::io::path baseDirectory);
|
||||
|
||||
private:
|
||||
json m_projectFile;
|
||||
std::string m_content;
|
||||
|
||||
std::string m_title;
|
||||
std::string m_type;
|
||||
std::string m_file;
|
||||
Scene* m_scene;
|
||||
};
|
||||
|
||||
|
||||
#endif //WALLENGINE_PROJECT_H
|
@ -1,31 +0,0 @@
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "Scene.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
Scene::Scene(irr::io::path file)
|
||||
{
|
||||
std::ifstream _in (file.c_str ());
|
||||
this->m_content = "";
|
||||
this->m_content.append (std::istreambuf_iterator<char> (_in), std::istreambuf_iterator<char> ());
|
||||
this->m_json = json::parse (this->m_content);
|
||||
|
||||
// check basic elements
|
||||
json::const_iterator camera_it = this->m_json.find ("camera");
|
||||
json::const_iterator general_it = this->m_json.find ("general");
|
||||
json::const_iterator objects_it = this->m_json.find ("objects");
|
||||
|
||||
if (objects_it != this->m_json.end () && objects_it.value ().is_array() == true)
|
||||
{
|
||||
json::const_iterator cur = this->m_json ["objects"].begin ();
|
||||
json::const_iterator end = this->m_json ["objects"].end ();
|
||||
|
||||
for (; cur != end; cur ++)
|
||||
{
|
||||
this->m_objects.push_back (new Object (*cur));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
#ifndef WALLENGINE_SCENE_H
|
||||
#define WALLENGINE_SCENE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "Object.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
class Scene
|
||||
{
|
||||
public:
|
||||
Scene(irr::io::path file);
|
||||
|
||||
private:
|
||||
irr::io::path m_file;
|
||||
std::string m_content;
|
||||
std::vector<Object*> m_objects;
|
||||
json m_json;
|
||||
};
|
||||
|
||||
|
||||
#endif //WALLENGINE_SCENE_H
|
34
wallpaperengine/camera.cpp
Normal file
34
wallpaperengine/camera.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
#include "camera.h"
|
||||
#include "core.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
camera::camera (json json_data)
|
||||
{
|
||||
json::const_iterator center_it = json_data.find ("center");
|
||||
json::const_iterator eye_it = json_data.find ("eye");
|
||||
json::const_iterator up_it = json_data .find ("up");
|
||||
|
||||
if (center_it != json_data.end ())
|
||||
{
|
||||
// get center value first
|
||||
std::string center = *center_it;
|
||||
|
||||
this->m_center = core::ato3vf(center.c_str());
|
||||
}
|
||||
|
||||
if (eye_it != json_data.end ())
|
||||
{
|
||||
std::string eye = *eye_it;
|
||||
|
||||
this->m_eye = core::ato3vf(eye.c_str());
|
||||
}
|
||||
|
||||
if (up_it != json_data.end ())
|
||||
{
|
||||
std::string up = *up_it;
|
||||
|
||||
this->m_up = core::ato3vf(up.c_str());
|
||||
}
|
||||
}
|
||||
}
|
20
wallpaperengine/camera.h
Normal file
20
wallpaperengine/camera.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef WALLENGINE_CAMERA_H
|
||||
#define WALLENGINE_CAMERA_H
|
||||
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace wp
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
|
||||
class camera
|
||||
{
|
||||
public:
|
||||
camera (json json_data);
|
||||
private:
|
||||
irr::core::vector3df m_center, m_eye, m_up;
|
||||
};
|
||||
};
|
||||
|
||||
#endif //WALLENGINE_CAMERA_H
|
15
wallpaperengine/config.cpp
Normal file
15
wallpaperengine/config.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// Created by almamu on 6/07/18.
|
||||
//
|
||||
|
||||
#include "config.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
namespace config
|
||||
{
|
||||
static irr::io::path path::resources;
|
||||
static irr::io::path path::base;
|
||||
static irr::io::path path::shaders;
|
||||
}
|
||||
}
|
22
wallpaperengine/config.h
Normal file
22
wallpaperengine/config.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef WALLENGINE_CONFIG_H
|
||||
#define WALLENGINE_CONFIG_H
|
||||
|
||||
#include <string>
|
||||
#include <irrlicht/path.h>
|
||||
|
||||
namespace wp
|
||||
{
|
||||
namespace config
|
||||
{
|
||||
class path
|
||||
{
|
||||
public:
|
||||
static irr::io::path resources;
|
||||
static irr::io::path base;
|
||||
static irr::io::path shaders;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //WALLENGINE_CONFIG_H
|
22
wallpaperengine/core.cpp
Normal file
22
wallpaperengine/core.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include <irrlicht/fast_atof.h>
|
||||
#include "core.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
irr::core::vector3df core::ato3vf(const char *str)
|
||||
{
|
||||
irr::f32 x = irr::core::fast_atof (str, &str); while (*str == ' ') str ++;
|
||||
irr::f32 y = irr::core::fast_atof (str, &str); while (*str == ' ') str ++;
|
||||
irr::f32 z = irr::core::fast_atof (str, &str);
|
||||
|
||||
return irr::core::vector3df (x, y, z);
|
||||
}
|
||||
|
||||
irr::core::vector2df core::ato2vf (const char *str)
|
||||
{
|
||||
irr::f32 x = irr::core::fast_atof (str, &str); while (*str == ' ') str ++;
|
||||
irr::f32 y = irr::core::fast_atof (str, &str);
|
||||
|
||||
return irr::core::vector2df (x, y);
|
||||
}
|
||||
}
|
19
wallpaperengine/core.h
Normal file
19
wallpaperengine/core.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef WALLENGINE_CORE_H
|
||||
#define WALLENGINE_CORE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <irrlicht/vector3d.h>
|
||||
#include <irrlicht/vector2d.h>
|
||||
|
||||
namespace wp
|
||||
{
|
||||
|
||||
class core
|
||||
{
|
||||
public:
|
||||
static irr::core::vector3df ato3vf (const char *str);
|
||||
static irr::core::vector2df ato2vf (const char *str);
|
||||
};
|
||||
};
|
||||
|
||||
#endif //WALLENGINE_CORE_H
|
17
wallpaperengine/effect.cpp
Normal file
17
wallpaperengine/effect.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "effect.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
effect::effect (json json_data, irr::io::path basepath)
|
||||
{
|
||||
json::const_iterator file = json_data.find ("file");
|
||||
json::const_iterator pass = json_data.find ("passes");
|
||||
|
||||
if (file != json_data.end () && (*file).is_string () == true)
|
||||
{
|
||||
std::string file_s = *file;
|
||||
|
||||
this->m_file = basepath + "/" + file_s.c_str ();
|
||||
}
|
||||
}
|
||||
};
|
23
wallpaperengine/effect.h
Normal file
23
wallpaperengine/effect.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef WALLENGINE_EFFECT_H
|
||||
#define WALLENGINE_EFFECT_H
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <irrlicht/path.h>
|
||||
|
||||
namespace wp
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
|
||||
class effect
|
||||
{
|
||||
public:
|
||||
effect (json json_data, irr::io::path basepath);
|
||||
|
||||
private:
|
||||
irr::io::path m_file;
|
||||
std::vector<void*> m_passes;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //WALLENGINE_EFFECT_H
|
86
wallpaperengine/fs/fileResolver.cpp
Normal file
86
wallpaperengine/fs/fileResolver.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
#include <sys/stat.h>
|
||||
#include <wallpaperengine/irrlicht.h>
|
||||
#include "fileResolver.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
namespace fs
|
||||
{
|
||||
fileResolver::fileResolver ()
|
||||
{
|
||||
this->m_environment.push_back (".");
|
||||
}
|
||||
|
||||
fileResolver::fileResolver (std::vector<irr::io::path> environment)
|
||||
{
|
||||
this->m_environment.push_back (".");
|
||||
this->m_environment.insert (this->m_environment.end (), environment.begin (), environment.end ());
|
||||
}
|
||||
void fileResolver::appendEnvironment (irr::io::path path)
|
||||
{
|
||||
this->m_environment.push_back (wp::irrlicht::device->getFileSystem ()->getAbsolutePath (path));
|
||||
}
|
||||
|
||||
void fileResolver::removeEnvironment(irr::io::path path)
|
||||
{
|
||||
std::vector<irr::io::path>::const_iterator cur = this->m_environment.begin ();
|
||||
std::vector<irr::io::path>::const_iterator end = this->m_environment.end ();
|
||||
irr::io::path absolute = wp::irrlicht::device->getFileSystem ()->getAbsolutePath (path);
|
||||
|
||||
for (; cur != end; cur ++)
|
||||
{
|
||||
if (*cur == path)
|
||||
{
|
||||
this->m_environment.erase (cur);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fileResolver::prependEnvironment (irr::io::path path)
|
||||
{
|
||||
this->m_environment.insert (
|
||||
this->m_environment.begin (),
|
||||
wp::irrlicht::device->getFileSystem ()->getAbsolutePath (path)
|
||||
);
|
||||
}
|
||||
|
||||
void fileResolver::changeWorkingDirectory (irr::io::path newpath)
|
||||
{
|
||||
this->m_environment.erase (this->m_environment.begin ());
|
||||
this->prependEnvironment (newpath);
|
||||
}
|
||||
|
||||
fileResolver fileResolver::clone ()
|
||||
{
|
||||
return fileResolver (this->m_environment);
|
||||
}
|
||||
|
||||
irr::io::path fileResolver::resolve (irr::io::path name)
|
||||
{
|
||||
std::vector<irr::io::path>::const_iterator cur = this->m_environment.begin ();
|
||||
std::vector<irr::io::path>::const_iterator end = this->m_environment.end ();
|
||||
irr::io::path tmp = "";
|
||||
|
||||
// try to resolve the path
|
||||
for (; cur != end; cur ++)
|
||||
{
|
||||
tmp = *cur;
|
||||
tmp += "/";
|
||||
tmp += name;
|
||||
|
||||
struct stat buffer;
|
||||
|
||||
if (stat (tmp.c_str (), &buffer) == 0)
|
||||
{
|
||||
wp::irrlicht::device->getLogger ()->log ("Resolved file to", tmp.c_str ());
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
wp::irrlicht::device->getLogger ()->log ("Failed resolving file ", name.c_str ());
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
36
wallpaperengine/fs/fileResolver.h
Normal file
36
wallpaperengine/fs/fileResolver.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef WALLENGINE_RESOLVER_H
|
||||
#define WALLENGINE_RESOLVER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <irrlicht/path.h>
|
||||
|
||||
namespace wp
|
||||
{
|
||||
namespace fs
|
||||
{
|
||||
class fileResolver
|
||||
{
|
||||
public:
|
||||
fileResolver ();
|
||||
fileResolver (std::vector<irr::io::path> environment);
|
||||
|
||||
void appendEnvironment (irr::io::path path);
|
||||
void removeEnvironment (irr::io::path path);
|
||||
void changeWorkingDirectory (irr::io::path newpath);
|
||||
fileResolver clone ();
|
||||
irr::io::path resolve (irr::io::path name);
|
||||
|
||||
protected:
|
||||
void prependEnvironment (irr::io::path path);
|
||||
|
||||
private:
|
||||
std::vector<irr::io::path> m_environment;
|
||||
};
|
||||
|
||||
static fileResolver resolver;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif //WALLENGINE_RESOLVER_H
|
24
wallpaperengine/image.cpp
Normal file
24
wallpaperengine/image.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include <irrlicht/path.h>
|
||||
#include "object3d.h"
|
||||
#include "image.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
image::image (json json_data, irr::io::path basepath) : object3d (object3d::Type::Type_Image)
|
||||
{
|
||||
json::const_iterator visible = json_data.find ("visible");
|
||||
json::const_iterator file = json_data.find ("image");
|
||||
|
||||
if (visible != json_data.end () && (*visible).is_boolean () == true)
|
||||
{
|
||||
this->m_visible = *visible;
|
||||
}
|
||||
|
||||
if (file != json_data.end () && (*file).is_string () == true)
|
||||
{
|
||||
std::string file_s = *file;
|
||||
|
||||
this->m_file = basepath + "/" + file_s.c_str ();
|
||||
}
|
||||
}
|
||||
}
|
23
wallpaperengine/image.h
Normal file
23
wallpaperengine/image.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef WALLENGINE_MODEL_H
|
||||
#define WALLENGINE_MODEL_H
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <irrlicht/path.h>
|
||||
|
||||
namespace wp
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
|
||||
class image : public object3d
|
||||
{
|
||||
public:
|
||||
image(json json_data, irr::io::path basepath);
|
||||
|
||||
private:
|
||||
bool m_visible;
|
||||
|
||||
irr::io::path m_file;
|
||||
};
|
||||
};
|
||||
|
||||
#endif //WALLENGINE_MODEL_H
|
7
wallpaperengine/irrlicht.cpp
Normal file
7
wallpaperengine/irrlicht.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include "irrlicht.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
irr::video::IVideoDriver* irrlicht::driver = nullptr;
|
||||
irr::IrrlichtDevice* irrlicht::device = nullptr;
|
||||
}
|
17
wallpaperengine/irrlicht.h
Normal file
17
wallpaperengine/irrlicht.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef WALLENGINE_IRRLICHT_H
|
||||
#define WALLENGINE_IRRLICHT_H
|
||||
|
||||
#include <irrlicht/irrlicht.h>
|
||||
|
||||
namespace wp
|
||||
{
|
||||
class irrlicht
|
||||
{
|
||||
public:
|
||||
static irr::video::IVideoDriver* driver;
|
||||
static irr::IrrlichtDevice* device;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //WALLENGINE_IRRLICHT_H
|
13
wallpaperengine/material.cpp
Normal file
13
wallpaperengine/material.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
//
|
||||
// Created by almamu on 6/07/18.
|
||||
//
|
||||
|
||||
#include "material.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
material::material(json json_data)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
17
wallpaperengine/material.h
Normal file
17
wallpaperengine/material.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef WALLENGINE_MATERIAL_H
|
||||
#define WALLENGINE_MATERIAL_H
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace wp
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
|
||||
class material
|
||||
{
|
||||
material(json json_data);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //WALLENGINE_MATERIAL_H
|
118
wallpaperengine/object.cpp
Normal file
118
wallpaperengine/object.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "object.h"
|
||||
#include "core.h"
|
||||
#include "object3d.h"
|
||||
#include "image.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
|
||||
object::object (json json_data, irr::io::path basepath)
|
||||
{
|
||||
json::const_iterator size = json_data.find ("size");
|
||||
json::const_iterator scale = json_data.find ("scale");
|
||||
json::const_iterator origin = json_data.find ("origin");
|
||||
|
||||
if (size != json_data.end () && size.value ().is_string () == true)
|
||||
{
|
||||
std::string size_s = *size;
|
||||
|
||||
this->m_size = core::ato2vf (size_s.c_str ());
|
||||
}
|
||||
|
||||
if (scale != json_data.end () && scale.value ().is_string () == true)
|
||||
{
|
||||
std::string scale_s = *scale;
|
||||
|
||||
this->m_scale = core::ato3vf (scale_s.c_str ());
|
||||
}
|
||||
|
||||
if (origin != json_data.end () && origin.value ().is_string () == true)
|
||||
{
|
||||
std::string origin_s = *origin;
|
||||
|
||||
this->m_origin = core::ato3vf (origin_s.c_str ());
|
||||
}
|
||||
|
||||
json::const_iterator angles = json_data.find ("angles");
|
||||
json::const_iterator id = json_data.find ("id");
|
||||
json::const_iterator name = json_data.find ("name");
|
||||
|
||||
if (angles != json_data.end () && (*angles).is_string () == true)
|
||||
{
|
||||
std::string angles_s = *angles;
|
||||
|
||||
this->m_angles = core::ato3vf (angles_s.c_str ());
|
||||
}
|
||||
|
||||
if (id != json_data.end () && (*id).is_null () == false)
|
||||
{
|
||||
this->m_id = *id;
|
||||
}
|
||||
|
||||
if (name != json_data.end () && (*name).is_string () == true)
|
||||
{
|
||||
this->m_name = *name;
|
||||
}
|
||||
|
||||
json::const_iterator image = json_data.find ("image");
|
||||
json::const_iterator model = json_data.find ("model");
|
||||
json::const_iterator particle = json_data.find ("particle");
|
||||
|
||||
object3d::Type _type = object3d::Type::Type_None;
|
||||
|
||||
if (image != json_data.end () && (*image).is_null () == false)
|
||||
{
|
||||
_type = object3d::Type::Type_Image;
|
||||
}
|
||||
|
||||
if (model != json_data.end () && (*model).is_null () == false)
|
||||
{
|
||||
_type = object3d::Type::Type_Model;
|
||||
}
|
||||
|
||||
if (particle != json_data.end () && (*particle).is_null () == false)
|
||||
{
|
||||
_type = object3d::Type::Type_Particle;
|
||||
}
|
||||
|
||||
switch (_type)
|
||||
{
|
||||
case object3d::Type::Type_Image:
|
||||
this->m_object3d = new wp::image (json_data, basepath);
|
||||
break;
|
||||
|
||||
case object3d::Type::Type_Model:
|
||||
break;
|
||||
|
||||
case object3d::Type::Type_Particle:
|
||||
break;
|
||||
}
|
||||
|
||||
json::const_iterator effects = json_data.find ("effects");
|
||||
|
||||
if (effects != json_data.end () && (*effects).is_array () == true)
|
||||
{
|
||||
json::const_iterator cur = (*effects).begin ();
|
||||
json::const_iterator end = (*effects).end ();
|
||||
|
||||
for (; cur != end; cur ++)
|
||||
{
|
||||
this->m_effects.push_back (new effect (*cur, basepath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object::~object ()
|
||||
{
|
||||
if (this->m_object3d != nullptr)
|
||||
{
|
||||
delete this->m_object3d;
|
||||
}
|
||||
}
|
||||
}
|
36
wallpaperengine/object.h
Normal file
36
wallpaperengine/object.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef WALLENGINE_OBJECT_H
|
||||
#define WALLENGINE_OBJECT_H
|
||||
|
||||
#include <iostream>
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "effect.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
|
||||
class object3d;
|
||||
class object
|
||||
{
|
||||
public:
|
||||
|
||||
object (json json_data, irr::io::path basepath);
|
||||
~object ();
|
||||
|
||||
private:
|
||||
int m_id;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
irr::core::vector2df m_size;
|
||||
irr::core::vector3df m_scale;
|
||||
irr::core::vector3df m_origin;
|
||||
|
||||
irr::core::vector3df m_angles;
|
||||
wp::object3d* m_object3d;
|
||||
std::vector<effect*> m_effects;
|
||||
};
|
||||
};
|
||||
|
||||
#endif //WALLENGINE_OBJECT_H
|
25
wallpaperengine/object3d.cpp
Normal file
25
wallpaperengine/object3d.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include "object3d.h"
|
||||
#include "image.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
object3d::object3d (object3d::Type type)
|
||||
{
|
||||
this->m_type = type;
|
||||
}
|
||||
|
||||
template <class T> T* object3d::as()
|
||||
{
|
||||
return (T*) this;
|
||||
}
|
||||
|
||||
template <class T> bool object3d::is()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <> bool object3d::is<image>()
|
||||
{
|
||||
return this->m_type == Type::Type_Image;
|
||||
}
|
||||
}
|
27
wallpaperengine/object3d.h
Normal file
27
wallpaperengine/object3d.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef WALLENGINE_OBJECT3D_H
|
||||
#define WALLENGINE_OBJECT3D_H
|
||||
|
||||
namespace wp
|
||||
{
|
||||
class object3d
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
Type_Image = 0,
|
||||
Type_Model = 1,
|
||||
Type_Particle = 2,
|
||||
Type_None = 3
|
||||
};
|
||||
|
||||
object3d (Type type);
|
||||
|
||||
template <class T> T* as();
|
||||
template <class T> bool is();
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
};
|
||||
};
|
||||
|
||||
#endif //WALLENGINE_OBJECT3D_H
|
42
wallpaperengine/project.cpp
Normal file
42
wallpaperengine/project.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "project.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
project::project (irr::io::path baseDirectory)
|
||||
{
|
||||
irr::io::path projectFile = baseDirectory + "/project.json";
|
||||
|
||||
std::ifstream _in (projectFile.c_str ());
|
||||
this->m_content = "";
|
||||
this->m_content.append (std::istreambuf_iterator<char> (_in), std::istreambuf_iterator<char> ());
|
||||
this->m_projectFile = json::parse (this->m_content);
|
||||
|
||||
json::const_iterator file_it = this->m_projectFile.find ("file");
|
||||
json::const_iterator name_it = this->m_projectFile.find ("title");
|
||||
json::const_iterator type_it = this->m_projectFile.find ("type");
|
||||
|
||||
if (file_it != this->m_projectFile.end ())
|
||||
{
|
||||
// load scene file
|
||||
this->m_file = file_it.value ();
|
||||
this->m_file = baseDirectory.c_str ();
|
||||
this->m_file += "/";
|
||||
this->m_file += this->m_projectFile ["file"];
|
||||
this->m_scene = new scene (this->m_file.c_str (), baseDirectory);
|
||||
}
|
||||
|
||||
if (type_it != this->m_projectFile.end ())
|
||||
{
|
||||
this->m_type = type_it.value ();
|
||||
}
|
||||
|
||||
if (name_it != this->m_projectFile.end ())
|
||||
{
|
||||
this->m_title = name_it.value ();
|
||||
}
|
||||
}
|
||||
}
|
28
wallpaperengine/project.h
Normal file
28
wallpaperengine/project.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef WALLENGINE_PROJECT_H
|
||||
#define WALLENGINE_PROJECT_H
|
||||
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "scene.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
|
||||
class project
|
||||
{
|
||||
public:
|
||||
project (irr::io::path baseDirectory);
|
||||
|
||||
private:
|
||||
json m_projectFile;
|
||||
std::string m_content;
|
||||
|
||||
std::string m_title;
|
||||
std::string m_type;
|
||||
std::string m_file;
|
||||
scene* m_scene;
|
||||
};
|
||||
};
|
||||
|
||||
#endif //WALLENGINE_PROJECT_H
|
58
wallpaperengine/scene.cpp
Normal file
58
wallpaperengine/scene.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "scene.h"
|
||||
#include "camera.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
|
||||
scene::scene (irr::io::path file, irr::io::path basepath)
|
||||
{
|
||||
std::ifstream _in (file.c_str ());
|
||||
this->m_content = "";
|
||||
this->m_content.append (std::istreambuf_iterator<char> (_in), std::istreambuf_iterator<char> ());
|
||||
this->m_json = json::parse (this->m_content);
|
||||
|
||||
// check basic elements
|
||||
json::const_iterator camera_it = this->m_json.find ("camera");
|
||||
json::const_iterator general_it = this->m_json.find ("general");
|
||||
json::const_iterator objects_it = this->m_json.find ("objects");
|
||||
|
||||
if (camera_it != this->m_json.end () && objects_it.value ().is_array () == true)
|
||||
{
|
||||
this->m_camera = new camera (*camera_it);
|
||||
}
|
||||
|
||||
if (objects_it != this->m_json.end () && objects_it.value ().is_array () == true)
|
||||
{
|
||||
json::const_iterator cur = this->m_json ["objects"].begin ();
|
||||
json::const_iterator end = this->m_json ["objects"].end ();
|
||||
|
||||
for (; cur != end; cur ++)
|
||||
{
|
||||
this->m_objects.push_back (new object (*cur, basepath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scene::~scene ()
|
||||
{
|
||||
// free memory used by the objects
|
||||
std::vector<object*>::const_iterator cur = this->m_objects.begin ();
|
||||
std::vector<object*>::const_iterator end = this->m_objects.end ();
|
||||
|
||||
for (; cur != end; cur ++)
|
||||
{
|
||||
delete *cur;
|
||||
}
|
||||
|
||||
// remove elements from the vector
|
||||
this->m_objects.erase (this->m_objects.begin (), this->m_objects.end ());
|
||||
|
||||
// free camera
|
||||
delete this->m_camera;
|
||||
}
|
||||
}
|
29
wallpaperengine/scene.h
Normal file
29
wallpaperengine/scene.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef WALLENGINE_SCENE_H
|
||||
#define WALLENGINE_SCENE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "object.h"
|
||||
#include "camera.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
|
||||
class scene
|
||||
{
|
||||
public:
|
||||
scene (irr::io::path file, irr::io::path basepath);
|
||||
~scene ();
|
||||
|
||||
private:
|
||||
irr::io::path m_file;
|
||||
std::string m_content;
|
||||
camera* m_camera;
|
||||
std::vector<object*> m_objects;
|
||||
json m_json;
|
||||
};
|
||||
};
|
||||
|
||||
#endif //WALLENGINE_SCENE_H
|
380
wallpaperengine/shaders/compiler.cpp
Normal file
380
wallpaperengine/shaders/compiler.cpp
Normal file
@ -0,0 +1,380 @@
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <wallpaperengine/config.h>
|
||||
|
||||
#include "compiler.h"
|
||||
#include "nier_test.h"
|
||||
#include "common.h"
|
||||
#include "../irrlicht.h"
|
||||
#include "../fs/fileResolver.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
namespace shaders
|
||||
{
|
||||
compiler::compiler (irr::io::path file, Type type, bool recursive)
|
||||
{
|
||||
// begin with an space so it gets ignored properly on parse
|
||||
if (recursive == false)
|
||||
{
|
||||
this->m_content = "#version 120\n"
|
||||
"#define texSample2D texture2D\n"
|
||||
"#define frac fract\n"
|
||||
"vec4 mul(vec4 x, mat4 y) { return x * y; }\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_content = "";
|
||||
}
|
||||
|
||||
std::ifstream _in (file.c_str ());
|
||||
this->m_content.append (std::istreambuf_iterator<char> (_in), std::istreambuf_iterator<char> ());
|
||||
this->m_type = type;
|
||||
|
||||
this->m_resolver = wp::fs::resolver.clone ();
|
||||
this->m_resolver.appendEnvironment (wp::config::path::shaders);
|
||||
|
||||
this->m_file = file;
|
||||
}
|
||||
|
||||
bool compiler::peekString(std::string str, std::string::const_iterator& it)
|
||||
{
|
||||
std::string::const_iterator check = str.begin();
|
||||
std::string::const_iterator cur = it;
|
||||
|
||||
while (cur != this->m_content.end () && check != str.end ())
|
||||
{
|
||||
if (*cur != *check) return false;
|
||||
|
||||
cur ++; check ++;
|
||||
}
|
||||
|
||||
if (cur == this->m_content.end ())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (check != str.end ())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
it = cur;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool compiler::expectSemicolon (std::string::const_iterator& it)
|
||||
{
|
||||
if (*it != ';')
|
||||
{
|
||||
this->m_error = true;
|
||||
this->m_errorInfo = "Expected semicolon but got " + *it;
|
||||
return false;
|
||||
}
|
||||
|
||||
it ++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void compiler::ignoreSpaces(std::string::const_iterator &it)
|
||||
{
|
||||
while (it != this->m_content.end() && (*it == ' ' || *it == '\t')) it ++;
|
||||
}
|
||||
|
||||
void compiler::ignoreUpToNextLineFeed (std::string::const_iterator& it)
|
||||
{
|
||||
while (it != this->m_content.end() && *it != '\n') it ++;
|
||||
}
|
||||
|
||||
void compiler::ignoreUpToBlockCommentEnd (std::string::const_iterator& it)
|
||||
{
|
||||
while (it != this->m_content.end() && this->peekString ("*/", it) == false) it ++;
|
||||
}
|
||||
|
||||
std::string compiler::extractType (std::string::const_iterator& it)
|
||||
{
|
||||
std::vector<std::string>::const_iterator cur = sTypes.begin ();
|
||||
std::vector<std::string>::const_iterator end = sTypes.end ();
|
||||
|
||||
while (cur != end)
|
||||
{
|
||||
if (this->peekString (*cur, it) == true)
|
||||
{
|
||||
return *cur;
|
||||
}
|
||||
|
||||
cur ++;
|
||||
}
|
||||
|
||||
this->m_error = true;
|
||||
this->m_errorInfo = "Expected type";
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string compiler::extractName (std::string::const_iterator& it)
|
||||
{
|
||||
std::string::const_iterator cur = it;
|
||||
std::string::const_iterator begin = cur;
|
||||
|
||||
// first character has to be a valid alphabetic characer
|
||||
if (this->isChar (cur) == false && *cur != '_')
|
||||
{
|
||||
this->m_error = true;
|
||||
this->m_errorInfo = "Expected name doesn't start with a valid character";
|
||||
return "";
|
||||
}
|
||||
|
||||
cur ++;
|
||||
|
||||
while (cur != this->m_content.end () && (this->isChar (cur) == true || *cur == '_' || this->isNumeric (cur) == true)) cur ++;
|
||||
|
||||
it = cur;
|
||||
|
||||
return std::string (begin, cur);
|
||||
}
|
||||
|
||||
bool compiler::isChar (std::string::const_iterator& it)
|
||||
{
|
||||
return ((*it) >= 'A' && (*it) <= 'Z') || ((*it) >= 'a' && (*it) <= 'z');
|
||||
}
|
||||
|
||||
bool compiler::isNumeric (std::string::const_iterator& it)
|
||||
{
|
||||
return (*it) >= '0' && (*it) <= '9';
|
||||
}
|
||||
|
||||
std::string compiler::extractQuotedValue(std::string::const_iterator& it)
|
||||
{
|
||||
std::string::const_iterator cur = it;
|
||||
|
||||
if (*cur != '"')
|
||||
{
|
||||
m_error = true;
|
||||
m_errorInfo = "Expected opening \" but got " + (*cur);
|
||||
return "";
|
||||
}
|
||||
|
||||
cur ++;
|
||||
|
||||
while (cur != this->m_content.end () && *cur != '\n' && *cur != '"') cur ++;
|
||||
|
||||
if (cur == this->m_content.end ())
|
||||
{
|
||||
m_error = true;
|
||||
m_errorInfo = "Expected closing \" not found";
|
||||
it = cur;
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string filename = std::string (++it, cur);
|
||||
|
||||
it = ++cur;
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
std::string compiler::lookupShaderFile (std::string filename)
|
||||
{
|
||||
irr::io::path shader = this->m_resolver.resolve (filename.c_str ());
|
||||
irr::io::IFileSystem *fs = wp::irrlicht::device->getFileSystem ();
|
||||
|
||||
// by default try to load from current folder
|
||||
// we might want, in the future, to load things from different folders
|
||||
// to provide standard functionality
|
||||
if (fs->existFile (shader) == false)
|
||||
{
|
||||
this->m_error = true;
|
||||
this->m_errorInfo = "Cannot find file " + filename + " to include";
|
||||
return "";
|
||||
}
|
||||
|
||||
// now compile the new shader
|
||||
// do not include the default header (as it's already included in the parent)
|
||||
compiler loader (shader, this->m_type, true);
|
||||
|
||||
return loader.precompile ();
|
||||
}
|
||||
|
||||
std::string compiler::lookupReplaceSymbol (std::string symbol)
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator cur = sVariableReplacement.begin ();
|
||||
std::map<std::string, std::string>::const_iterator end = sVariableReplacement.end ();
|
||||
|
||||
while (cur != end)
|
||||
{
|
||||
if (cur->first == symbol)
|
||||
{
|
||||
return cur->second;
|
||||
}
|
||||
|
||||
cur ++;
|
||||
}
|
||||
|
||||
// if there is no replacement, return the original
|
||||
return symbol;
|
||||
}
|
||||
|
||||
std::string compiler::precompile()
|
||||
{
|
||||
#define BREAK_IF_ERROR if (this->m_error == true) { wp::irrlicht::device->getLogger ()->log ("ERROR COMPILING SHADER"); wp::irrlicht::device->getLogger ()->log (this->m_errorInfo.c_str ()); return ""; }
|
||||
// parse the shader and find #includes and such things and translate them to the correct name
|
||||
// also remove any #version definition to prevent errors
|
||||
std::string::const_iterator it = this->m_content.begin ();
|
||||
|
||||
// reset error indicator
|
||||
this->m_error = false;
|
||||
this->m_errorInfo = "";
|
||||
|
||||
// search preprocessor macros and parse them
|
||||
while (it != this->m_content.end () && this->m_error == false)
|
||||
{
|
||||
if (*it == ' ' || *it == '\t' || *it == '\n' || *it == '\r' || *it == '\0' || *it == '{' || *it == '}' || *it == '[' || *it == ']' || *it == '.')
|
||||
{
|
||||
this->m_compiledContent += *it;
|
||||
it ++;
|
||||
}
|
||||
else if (*it == '#')
|
||||
{
|
||||
if (this->peekString ("#include", it) == true)
|
||||
{
|
||||
std::string filename = "";
|
||||
|
||||
// ignore whitespaces
|
||||
this->ignoreSpaces (it); BREAK_IF_ERROR
|
||||
// extract value between quotes
|
||||
filename = this->extractQuotedValue (it); BREAK_IF_ERROR
|
||||
|
||||
// try to find the file first
|
||||
this->m_compiledContent += "// begin of included from file " + filename + "\r\n";
|
||||
this->m_compiledContent += this->lookupShaderFile (filename);
|
||||
this->m_compiledContent += "\r\n// end of included from file " + filename + "\r\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_compiledContent += '#';
|
||||
it ++;
|
||||
}
|
||||
}
|
||||
else if (*it == 'a')
|
||||
{
|
||||
// find attribute definitions
|
||||
if (this->peekString ("attribute", it) == true)
|
||||
{
|
||||
this->ignoreSpaces (it);
|
||||
std::string type = this->extractType (it); BREAK_IF_ERROR
|
||||
this->ignoreSpaces (it);
|
||||
std::string name = this->extractName (it); BREAK_IF_ERROR
|
||||
this->ignoreSpaces (it);
|
||||
this->expectSemicolon (it); BREAK_IF_ERROR
|
||||
|
||||
this->m_compiledContent += "// attribute";
|
||||
this->m_compiledContent += " " + type + " ";
|
||||
this->m_compiledContent += name;
|
||||
this->m_compiledContent += "; /* replaced by " + this->lookupReplaceSymbol (name) + " */";
|
||||
}
|
||||
else
|
||||
{
|
||||
// check for types first
|
||||
std::string type = this->extractType (it);
|
||||
|
||||
// types not found, try names
|
||||
if (this->m_error == false)
|
||||
{
|
||||
this->m_compiledContent += type;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_error = false;
|
||||
std::string name = this->extractName (it);
|
||||
|
||||
if (this->m_error == false)
|
||||
{
|
||||
// check if the name is a translated one or not
|
||||
this->m_compiledContent += this->lookupReplaceSymbol (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_error = false;
|
||||
this->m_compiledContent += *it;
|
||||
it ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*it == '/')
|
||||
{
|
||||
if (this->peekString ("//", it) == true)
|
||||
{
|
||||
std::string::const_iterator begin = it - 2;
|
||||
this->ignoreUpToNextLineFeed (it);
|
||||
this->m_compiledContent.append (begin, it);
|
||||
}
|
||||
else if (this->peekString ("/*", it) == true)
|
||||
{
|
||||
std::string::const_iterator begin = it - 2;
|
||||
this->ignoreUpToBlockCommentEnd (it);
|
||||
this->m_compiledContent.append (begin, it);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_compiledContent += *it;
|
||||
it ++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// check for types first
|
||||
std::string type = this->extractType (it);
|
||||
|
||||
// types not found, try names
|
||||
if (this->m_error == false)
|
||||
{
|
||||
this->m_compiledContent += type;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_error = false;
|
||||
std::string name = this->extractName (it);
|
||||
|
||||
if (this->m_error == false)
|
||||
{
|
||||
// check if the name is a translated one or not
|
||||
this->m_compiledContent += this->lookupReplaceSymbol (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_error = false;
|
||||
this->m_compiledContent += *it;
|
||||
it ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wp::irrlicht::device->getLogger ()->log ("Compiled shader output for", this->m_file.c_str ());
|
||||
wp::irrlicht::device->getLogger ()->log (this->m_compiledContent.c_str ());
|
||||
|
||||
return this->m_compiledContent;
|
||||
#undef BREAK_IF_ERROR
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> compiler::sVariableReplacement =
|
||||
{
|
||||
// attribute vec3 a_position
|
||||
{"a_Position", "gl_Vertex.xyz"},
|
||||
// attribute vec2 a_TexCoord
|
||||
{"a_TexCoord", "gl_MultiTexCoord0.xy"},
|
||||
// attribute vec3 a_Normal
|
||||
{"a_Normal", "gl_Normal.xyz"}
|
||||
};
|
||||
|
||||
std::vector<std::string> compiler::sTypes =
|
||||
{
|
||||
"vec4", "vec3", "vec2", "float"
|
||||
};
|
||||
}
|
||||
}
|
71
wallpaperengine/shaders/compiler.h
Normal file
71
wallpaperengine/shaders/compiler.h
Normal file
@ -0,0 +1,71 @@
|
||||
#ifndef __BASIC_SHADER_LOADER_H__
|
||||
#define __BASIC_SHADER_LOADER_H__
|
||||
|
||||
#include <irrlicht/irrlicht.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "../fs/fileResolver.h"
|
||||
|
||||
namespace wp
|
||||
{
|
||||
namespace shaders
|
||||
{
|
||||
/**
|
||||
* A basic shader loader that adds basic function definitions to every loaded shader
|
||||
*/
|
||||
class compiler
|
||||
{
|
||||
public:
|
||||
struct VariableReplacement
|
||||
{
|
||||
const char* original;
|
||||
const char* replacement;
|
||||
};
|
||||
|
||||
struct TypeName
|
||||
{
|
||||
const char* name;
|
||||
int size;
|
||||
};
|
||||
|
||||
enum Type
|
||||
{
|
||||
Type_Vertex = 0,
|
||||
Type_Pixel = 1,
|
||||
};
|
||||
|
||||
static std::map<std::string, std::string> sVariableReplacement;
|
||||
static std::vector<std::string> sTypes;
|
||||
|
||||
compiler (irr::io::path file, Type type, bool recursive = false);
|
||||
std::string precompile();
|
||||
|
||||
private:
|
||||
bool peekString (std::string str, std::string::const_iterator& it);
|
||||
bool expectSemicolon (std::string::const_iterator& it);
|
||||
void ignoreSpaces (std::string::const_iterator& it);
|
||||
void ignoreUpToNextLineFeed (std::string::const_iterator& it);
|
||||
void ignoreUpToBlockCommentEnd (std::string::const_iterator& it);
|
||||
std::string extractType (std::string::const_iterator& it);
|
||||
std::string extractName (std::string::const_iterator& it);
|
||||
std::string extractQuotedValue (std::string::const_iterator& it);
|
||||
std::string lookupShaderFile (std::string filename);
|
||||
std::string lookupReplaceSymbol (std::string symbol);
|
||||
|
||||
bool isChar (std::string::const_iterator& it);
|
||||
bool isNumeric (std::string::const_iterator& it);
|
||||
|
||||
irr::io::path m_file;
|
||||
std::string m_content;
|
||||
std::string m_compiledContent;
|
||||
bool m_error;
|
||||
std::string m_errorInfo;
|
||||
Type m_type;
|
||||
wp::fs::fileResolver m_resolver;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !__BASIC_SHADER_LOADER_H__ */
|
Loading…
Reference in New Issue
Block a user