Merge pull request #66 from devZoGok/shader-asset-manager

Shader asset manager
This commit is contained in:
devZoGok
2024-09-26 17:26:24 +00:00
committed by GitHub
12 changed files with 153 additions and 109 deletions
+2 -2
View File
@@ -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)
+34
View File
@@ -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 <tinydir.h>
@@ -71,6 +76,11 @@ namespace vb01{
if(find(modelFormats.begin(), modelFormats.end(), format) != modelFormats.end())
assetReader = XmlModelReader::getSingleton();
vector<string> shaderFormats = vector<string>{"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<Node*> descendants;
root->getRootNode()->getDescendants(descendants);
root->getGuiNode()->getDescendants(descendants);
for(Node *desc : descendants){
vector<Mesh*> meshes = desc->getMeshes();
for(Mesh *mesh : meshes){
Material *mat = mesh->getMaterial();
if(mat)
mat->getShader()->loadShaders();
}
}
}
}
}
+1
View File
@@ -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<Asset*> getAssets(){return assets;}
+23 -21
View File
@@ -1,19 +1,24 @@
#include "root.h"
#include "bone.h"
#include "mesh.h"
#include "particleEmitter.h"
#include "light.h"
#include "text.h"
#include "material.h"
#include "light.h"
#include "matrix.h"
#include "material.h"
#include "skeleton.h"
#include "shaderAsset.h"
#include "particleEmitter.h"
#include "assetManager.h"
#include "animationController.h"
#include <boost/algorithm/string/find.hpp>
#include <glm.hpp>
#include <glm/gtc/matrix_inverse.hpp>
using namespace std;
using namespace glm;
using namespace boost;
namespace vb01{
Node::Node(Vector3 pos, Quaternion orientation, Vector3 scale, string name, Animatable::Type type) : Animatable(type, name){
@@ -245,6 +250,7 @@ namespace vb01{
lights.push_back(light);
light->onAttached(this);
updateShaders();
}
void Node::removeLight(int id){
@@ -439,27 +445,23 @@ namespace vb01{
void Node::updateShaders(){
Root *root = Root::getSingleton();
Node *rootNode = root->getRootNode();
vector<Node*> descendants;
rootNode->getDescendants(descendants);
descendants.push_back(rootNode);
for(Node *n : descendants){
vector<Mesh*> meshes = n->getMeshes();
for(Mesh *m : meshes){
Material *mat = m->getMaterial();
if(mat){
AssetManager *am = AssetManager::getSingleton();
ShaderAsset *sa = (ShaderAsset*)am->getAsset(root->getLibPath() + "texture.frag");
string shaderStr = sa->shaderString;
int numLights = root->getNumLights();
string str1 = "const int numLights = " + to_string(numLights > 0 ? numLights : 1) + ";";
mat->getShader()->editShader(Shader::FRAGMENT_SHADER, 1, str1);
int a1 = std::distance(shaderStr.begin(), find_nth(shaderStr, "\n", 0).begin());
int a2 = std::distance(shaderStr.begin(), find_nth(shaderStr, "\n", 1).begin());
shaderStr.replace(a1 + 1, a2 - a1 - 1, str1);
string str2 = "const bool checkLights = " + string(numLights > 0 ? "true" : "false") + ";";
mat->getShader()->editShader(Shader::FRAGMENT_SHADER, 2, str2);
}
}
}
a1 = std::distance(shaderStr.begin(), find_nth(shaderStr, "\n", 1).begin());
a2 = std::distance(shaderStr.begin(), find_nth(shaderStr, "\n", 2).begin());
shaderStr.replace(a1 + 1, a2 - a1 - 1, str2);
ShaderAsset sa2(sa->path, shaderStr);
am->editAsset(sa->path, sa2);
}
void Node::setOrientation(Quaternion q){
+4
View File
@@ -5,6 +5,7 @@
#include "box.h"
#include "quad.h"
#include "lineRenderer.h"
#include "assetManager.h"
#include "animationController.h"
#include "glad.h"
@@ -22,6 +23,7 @@ namespace vb01{
Root* Root::getSingleton(){
if(!root)
root = new Root();
return root;
}
@@ -47,6 +49,8 @@ namespace vb01{
this->height = height;
this->libPath = libPath;
AssetManager::getSingleton()->load(Root::getSingleton()->getLibPath());
initWindow(name);
brdfLutPlane = new Quad(Vector3(1, 1, 1) * 2);
+14 -74
View File
@@ -1,20 +1,19 @@
#include "glad.h"
#include <glfw3.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include "shader.h"
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#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,19 +28,16 @@ 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);
@@ -51,67 +46,12 @@ namespace vb01{
}
void Shader::initShaders(string vertShaderPath, string fragShaderPath, string geoShaderPath){
ifstream vertShaderFile, fragShaderFile;
vertShaderFile.open(vertShaderPath);
fragShaderFile.open(fragShaderPath);
AssetManager *am = AssetManager::getSingleton();
vString = (ShaderAsset*)am->getAsset(vertShaderPath);
fString = (ShaderAsset*)am->getAsset(fragShaderPath);
stringstream vertShaderStream, fragShaderStream;
vertShaderStream << vertShaderFile.rdbuf();
fragShaderStream << fragShaderFile.rdbuf();
vertShaderFile.close();
fragShaderFile.close();
vString = vertShaderStream.str();
fString = fragShaderStream.str();
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);
+5 -5
View File
@@ -4,6 +4,7 @@
#include <string>
#include <glm/mat4x4.hpp>
#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;
};
+17
View File
@@ -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
+30
View File
@@ -0,0 +1,30 @@
#include "shaderReader.h"
#include "shaderAsset.h"
#include <sstream>
#include <fstream>
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());
}
}
+16
View File
@@ -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
+1 -1
View File
@@ -133,10 +133,10 @@ void main(){
float shadow = getShadow(i);
diffuseCol *= (1.0 - shadow);
}
}
finalColor *= vec4(diffuseCol + specularCol, 1);
}
}
float brightness = dot(finalColor.rgb, vec3(0.2126, 0.7152, 0.0722));
+1 -1
View File
@@ -132,7 +132,7 @@ namespace vb01{
float biTanZ = atof(vertEl->Attribute("bz"));
Vector3 biTan = Vector3(biTanX, biTanY, biTanZ);
normals[i] = tan.cross(biTan);
normals[i] = biTan.cross(tan);
MeshData::Vertex vertex;
vertex.pos = &vertPos[id];