shader auto reload
This commit is contained in:
@@ -13,6 +13,10 @@ std::string Shader::read(const std::string& path)
|
||||
std::string ret;
|
||||
if (a.open(path.c_str()))
|
||||
{
|
||||
struct stat tmp_info;
|
||||
if (stat(path.c_str(), &tmp_info) == 0)
|
||||
m_deps[path] = tmp_info;
|
||||
|
||||
std::regex reg_include(R"!(#include "([^"]+)")!");
|
||||
std::string data((char*)a.read_all(), a.m_len);
|
||||
|
||||
@@ -105,18 +109,46 @@ bool Shader::load(const std::string& path)
|
||||
{
|
||||
*sections["vertex"] = SHADER_VERSION + *sections["vertex"];
|
||||
*sections["fragment"] = SHADER_VERSION + *sections["fragment"];
|
||||
return create(sections["vertex"]->c_str(), sections["fragment"]->c_str());
|
||||
if (create(sections["vertex"]->c_str(), sections["fragment"]->c_str()))
|
||||
{
|
||||
m_path = path;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("could not find [[vertex]] and [[fragment]] sections on %s", path.c_str());
|
||||
}
|
||||
|
||||
m_path = path;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Shader::reload()
|
||||
{
|
||||
if (m_path.empty())
|
||||
return false;
|
||||
|
||||
bool dirty = false;
|
||||
struct stat tmp_info;
|
||||
for (auto& d : m_deps)
|
||||
{
|
||||
if (stat(d.first.c_str(), &tmp_info) != 0)
|
||||
continue;
|
||||
if (tmp_info.st_mtime > d.second.st_mtime)
|
||||
{
|
||||
d.second = tmp_info;
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty)
|
||||
{
|
||||
LOG("reload shader %s", m_path.c_str());
|
||||
destroy();
|
||||
return load(m_path);
|
||||
}
|
||||
}
|
||||
|
||||
bool Shader::create(const char* vertex, const char* fragment)
|
||||
{
|
||||
GLint status;
|
||||
@@ -136,7 +168,7 @@ bool Shader::create(const char* vertex, const char* fragment)
|
||||
glGetShaderInfoLog(vs, sizeof(infolog), &infolen, infolog);
|
||||
if (infolen > 0)
|
||||
{
|
||||
LOG("\nVERTEX SHADER:");
|
||||
LOG("\nVERTEX SHADER: %s", m_path.c_str());
|
||||
parse_error(infolog, vertex);
|
||||
}
|
||||
if (status == 0)
|
||||
@@ -158,7 +190,7 @@ bool Shader::create(const char* vertex, const char* fragment)
|
||||
glGetShaderInfoLog(fs, sizeof(infolog), &infolen, infolog);
|
||||
if (infolen > 0)
|
||||
{
|
||||
LOG("\nFRAGMENT SHADER:");
|
||||
LOG("\nFRAGMENT SHADER: %s", m_path.c_str());
|
||||
parse_error(infolog, fragment);
|
||||
}
|
||||
if (status == 0)
|
||||
@@ -200,7 +232,7 @@ bool Shader::create(const char* vertex, const char* fragment)
|
||||
glGetProgramiv(ps, GL_LINK_STATUS, &status);
|
||||
glGetProgramInfoLog(ps, sizeof(infolog), &infolen, infolog);
|
||||
if (infolen > 0)
|
||||
LOG("LINK SHADER:\n%s", infolog);
|
||||
LOG("LINK SHADER: %s\n%s", m_path.c_str(), infolog);
|
||||
if (status == 0)
|
||||
{
|
||||
glDeleteProgram(ps);
|
||||
@@ -228,6 +260,18 @@ bool Shader::create(const char* vertex, const char* fragment)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Shader::destroy()
|
||||
{
|
||||
if (prog)
|
||||
{
|
||||
glUseProgram(0);
|
||||
glDeleteProgram(prog);
|
||||
prog = 0;
|
||||
}
|
||||
m_umap.clear();
|
||||
}
|
||||
|
||||
void Shader::use()
|
||||
{
|
||||
glUseProgram(prog);
|
||||
@@ -282,6 +326,14 @@ bool ShaderManager::load(kShader id, const std::string& path)
|
||||
return m_shaders[id].load(path);
|
||||
}
|
||||
|
||||
bool ShaderManager::reload()
|
||||
{
|
||||
bool success = true;
|
||||
for (auto& s : m_shaders)
|
||||
success &= s.second.reload();
|
||||
return success;
|
||||
}
|
||||
|
||||
bool ShaderManager::create(kShader id, const char* vertex, const char* fragment)
|
||||
{
|
||||
m_shaders[id].name = id;
|
||||
|
||||
Reference in New Issue
Block a user