diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ef4915..5800646 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,8 +18,8 @@ set(MATH quaternion.cpp vector.cpp matrix.cpp rayCaster.cpp) set(RENDER lineRenderer.cpp particleEmitter.cpp camera.cpp light.cpp material.cpp mesh.cpp meshData.cpp model.cpp node.cpp quad.cpp box.cpp root.cpp shader.cpp texture.cpp) set(ANIM animationController.cpp animationChannel.cpp animation.cpp animatable.cpp keyframeChannel.cpp driver.cpp) set(ARMATURE skeleton.cpp bone.cpp ikSolver.cpp) -set(ASSET_MANAGER assetManager.cpp textAsset.h imageAsset.h modelAsset.h fontAsset.h) -set(ASSET_READERS imageReader.cpp fontReader.cpp modelReader.cpp xmlModelReader.cpp) +set(ASSET_MANAGER assetManager.cpp shaderAsset.h textAsset.h imageAsset.h modelAsset.h fontAsset.h) +set(ASSET_READERS shaderReader.cpp imageReader.cpp fontReader.cpp modelReader.cpp xmlModelReader.cpp) if(BUILD_WITH_ASSIMP) set(ASSET_READERS ${ASSET_READERS} assimpModelReader.cpp) diff --git a/assetManager.cpp b/assetManager.cpp index 63b106b..8bdfdf8 100644 --- a/assetManager.cpp +++ b/assetManager.cpp @@ -1,8 +1,13 @@ #include "assetManager.h" #include "abstractAssetReader.h" #include "util.h" +#include "root.h" +#include "node.h" +#include "mesh.h" +#include "material.h" #include "imageReader.h" #include "fontReader.h" +#include "shaderReader.h" #include "xmlModelReader.h" #include @@ -71,6 +76,11 @@ namespace vb01{ if(find(modelFormats.begin(), modelFormats.end(), format) != modelFormats.end()) assetReader = XmlModelReader::getSingleton(); + vector shaderFormats = vector{"vert", "frag", "geo"}; + + if(find(shaderFormats.begin(), shaderFormats.end(), format) != shaderFormats.end()) + assetReader = ShaderReader::getSingleton(); + if(assetReader) assets.push_back(assetReader->readAsset(file)); else @@ -85,4 +95,28 @@ namespace vb01{ return nullptr; } + + void AssetManager::editAsset(string path, Asset &newAsset){ + ShaderAsset *oldAsset = (ShaderAsset*)getAsset(path); + + if(oldAsset){ + oldAsset->shaderString = ((ShaderAsset&)newAsset).shaderString; + + Root *root = Root::getSingleton(); + vector descendants; + root->getRootNode()->getDescendants(descendants); + root->getGuiNode()->getDescendants(descendants); + + for(Node *desc : descendants){ + vector meshes = desc->getMeshes(); + + for(Mesh *mesh : meshes){ + Material *mat = mesh->getMaterial(); + + if(mat) + mat->getShader()->loadShaders(); + } + } + } + } } diff --git a/assetManager.h b/assetManager.h index 262e9c1..d84e4f7 100644 --- a/assetManager.h +++ b/assetManager.h @@ -12,6 +12,7 @@ namespace vb01{ public: static AssetManager* getSingleton(); void load(std::string, bool = false); + void editAsset(std::string, Asset&); Asset* getAsset(std::string); inline Asset* getAsset(int i){return assets[i];} inline std::vector getAssets(){return assets;} diff --git a/shader.cpp b/shader.cpp index 79e6035..4a63f0c 100755 --- a/shader.cpp +++ b/shader.cpp @@ -1,20 +1,19 @@ #include "glad.h" #include #include -#include -#include -#include "shader.h" #include #include +#include "shader.h" +#include "assetManager.h" + using namespace std; using namespace glm; namespace vb01{ Shader::Shader(string shaderPath, bool geometry){ this->geometry = geometry; - this->path = shaderPath; initShaders(shaderPath + ".vert", shaderPath + ".frag", shaderPath + ".geo"); loadShaders(); @@ -22,7 +21,6 @@ namespace vb01{ Shader::Shader(string vertShader, string fragShader){ this->geometry = false; - this->path = vertShader; initShaders(vertShader, fragShader, ""); loadShaders(); @@ -30,88 +28,30 @@ namespace vb01{ Shader::Shader(string vertShader, string fragShader, string geoShader){ this->geometry = true; - this->path = vertShader; initShaders(vertShader, fragShader, geoShader); loadShaders(); } - Shader::~Shader(){} - string Shader::getName(){ - int dirId = path.find_last_of('/'); - string name = (dirId != -1 ? path.substr(dirId + 1) : path); + int dirId = vString->path.find_last_of('/'); + string name = (dirId != -1 ? vString->path.substr(dirId + 1) : vString->path); - int dotId = path.find_last_of('.'); + int dotId = name.find_last_of('.'); - if(dotId != -1) - name = name.substr(0, dotId); + if(dotId != -1) + name = name.substr(0, dotId); - return name; + return name; } void Shader::initShaders(string vertShaderPath, string fragShaderPath, string geoShaderPath){ - ifstream vertShaderFile, fragShaderFile; - vertShaderFile.open(vertShaderPath); - fragShaderFile.open(fragShaderPath); - - stringstream vertShaderStream, fragShaderStream; - vertShaderStream << vertShaderFile.rdbuf(); - fragShaderStream << fragShaderFile.rdbuf(); - - vertShaderFile.close(); - fragShaderFile.close(); - - vString = vertShaderStream.str(); - fString = fragShaderStream.str(); + AssetManager *am = AssetManager::getSingleton(); + vString = (ShaderAsset*)am->getAsset(vertShaderPath); + fString = (ShaderAsset*)am->getAsset(fragShaderPath); - if(geometry){ - ifstream geoShaderFile; - geoShaderFile.open(geoShaderPath); - - stringstream geoShaderStream; - geoShaderStream << geoShaderFile.rdbuf(); - - geoShaderFile.close(); - gString = geoShaderStream.str(); - } - } - - void Shader::editShader(ShaderType type, int line, string insertion){ - replaceLine(type, line, insertion); - loadShaders(); - } - - void Shader::replaceLine(ShaderType type, int line, string insertion){ - string *shaderString; - - switch(type){ - case VERTEX_SHADER: - shaderString = &vString; - break; - case FRAGMENT_SHADER: - shaderString = &fString; - break; - case GEOMETRY_SHADER: - shaderString = &gString; - break; - } - - int numPassedLines = 0, lineStart = -1, lineEnd = -1; - for(int i = 0; i < shaderString->length(); i++) - if(shaderString[0][i] == '\n'){ - if(numPassedLines == line - 1) - lineStart = i + 1; - - if(numPassedLines == line){ - lineEnd = i; - break; - } - - numPassedLines++; - } - - *shaderString = shaderString->substr(0, lineStart) + insertion + shaderString->substr(lineEnd); + if(geometry) + gString = (ShaderAsset*)am->getAsset(geoShaderPath); } void Shader::pushShader(u32 &type, string &sString, int glType, ErrorType errorType){ @@ -124,11 +64,11 @@ namespace vb01{ void Shader::loadShaders(){ u32 vert, geo, frag; - pushShader(vert, vString, GL_VERTEX_SHADER, VERTEX_ERROR); - pushShader(frag, fString, GL_FRAGMENT_SHADER, FRAGMENT_ERROR); + pushShader(vert, vString->shaderString, GL_VERTEX_SHADER, VERTEX_ERROR); + pushShader(frag, fString->shaderString, GL_FRAGMENT_SHADER, FRAGMENT_ERROR); if(geometry) - pushShader(geo, gString, GL_GEOMETRY_SHADER, GEOMETRY_ERROR); + pushShader(geo, gString->shaderString, GL_GEOMETRY_SHADER, GEOMETRY_ERROR); id = glCreateProgram(); glAttachShader(id, vert); diff --git a/shader.h b/shader.h index 7092516..15ea0a0 100755 --- a/shader.h +++ b/shader.h @@ -4,6 +4,7 @@ #include #include +#include "shaderAsset.h" #include "vector.h" #include "util.h" @@ -17,10 +18,10 @@ namespace vb01{ Shader(std::string, bool = false); Shader(std::string, std::string); Shader(std::string, std::string, std::string); - ~Shader(); + ~Shader(){} std::string getName(); - void setNumLights(int); void use(); + void loadShaders(); void setMat4(glm::mat4, std::string); void setVec4(Vector4, std::string); void setVec3(Vector3, std::string); @@ -29,17 +30,16 @@ namespace vb01{ void setBool(bool, std::string); void setInt(int, std::string); void setUnsignedInt(u32, std::string); - void editShader(ShaderType, int, std::string); + void editShader(ShaderType, int, std::string){} inline bool isGeometry(){return geometry;} private: void initShaders(std::string, std::string, std::string); void replaceLine(ShaderType, int, std::string); - void loadShaders(); void pushShader(u32&, std::string&, int, ErrorType); void checkCompileErrors(u32, ErrorType); u32 id; bool geometry = false; - std::string path, vString, fString, gString; + ShaderAsset *vString = nullptr, *fString = nullptr, *gString = nullptr; friend class ShaderTest; }; diff --git a/shaderAsset.h b/shaderAsset.h new file mode 100644 index 0000000..75fa384 --- /dev/null +++ b/shaderAsset.h @@ -0,0 +1,17 @@ +#ifndef SHADER_ASSET_H +#define SHADER_ASSET_H + +#include "asset.h" + +namespace vb01{ + struct ShaderAsset : public Asset{ + std::string shaderString = ""; + + ShaderAsset(std::string p, std::string str){ + path = p; + shaderString = str; + } + }; +} + +#endif diff --git a/shaderReader.cpp b/shaderReader.cpp new file mode 100644 index 0000000..48a6682 --- /dev/null +++ b/shaderReader.cpp @@ -0,0 +1,30 @@ +#include "shaderReader.h" +#include "shaderAsset.h" + +#include +#include + +namespace vb01{ + using namespace std; + + static ShaderReader *shaderReader = nullptr; + + ShaderReader* ShaderReader::getSingleton(){ + if(!shaderReader) + shaderReader = new ShaderReader(); + + return shaderReader; + } + + Asset* ShaderReader::readAsset(string path){ + ifstream shaderFile; + shaderFile.open(path); + + stringstream shaderStream; + shaderStream << shaderFile.rdbuf(); + + shaderFile.close(); + + return new ShaderAsset(path, shaderStream.str()); + } +} diff --git a/shaderReader.h b/shaderReader.h new file mode 100644 index 0000000..379b0a4 --- /dev/null +++ b/shaderReader.h @@ -0,0 +1,16 @@ +#ifndef SHADER_READER_H +#define SHADER_READER_H + +#include "abstractAssetReader.h" + +namespace vb01{ + class ShaderReader : public AbstractAssetReader{ + public: + static ShaderReader* getSingleton(); + Asset* readAsset(std::string); + private: + ShaderReader(){} + }; +} + +#endif