mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-14 19:59:59 +01:00
Improved Shader compilation
This commit is contained in:
167
Shader.cpp
167
Shader.cpp
@@ -73,74 +73,104 @@ GLenum blending_destination_function[9] = {GL_ONE_MINUS_SRC_ALPHA,// normal
|
|||||||
GL_ZERO};
|
GL_ZERO};
|
||||||
|
|
||||||
ShadingProgram::ShadingProgram(const std::string& vertex, const std::string& fragment) :
|
ShadingProgram::ShadingProgram(const std::string& vertex, const std::string& fragment) :
|
||||||
vertex_id_(0), fragment_id_(0), id_(0)
|
id_(0), need_compile_(true), vertex_(vertex), fragment_(fragment)
|
||||||
{
|
{
|
||||||
if (Resource::hasPath(vertex))
|
|
||||||
vertex_file_ = vertex;
|
|
||||||
else
|
|
||||||
vertex_code_ = vertex;
|
|
||||||
|
|
||||||
if (Resource::hasPath(fragment))
|
|
||||||
fragment_file_ = fragment;
|
|
||||||
else
|
|
||||||
fragment_code_ = fragment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadingProgram::init()
|
void ShadingProgram::setShaders(const std::string& vertex, const std::string& fragment)
|
||||||
{
|
{
|
||||||
if (vertex_code_.empty())
|
vertex_ = vertex;
|
||||||
vertex_code_ = Resource::getText(vertex_file_);
|
fragment_ = fragment;
|
||||||
|
need_compile_ = true;
|
||||||
if (fragment_code_.empty())
|
|
||||||
fragment_code_ = Resource::getText(fragment_file_);
|
|
||||||
|
|
||||||
if ( compile() )
|
|
||||||
link();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ShadingProgram::initialized()
|
|
||||||
{
|
|
||||||
return (id_ != 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShadingProgram::compile()
|
bool ShadingProgram::compile()
|
||||||
{
|
{
|
||||||
const char* vcode = vertex_code_.c_str();
|
char infoLog[1024];
|
||||||
vertex_id_ = glCreateShader(GL_VERTEX_SHADER);
|
int success = GL_FALSE;
|
||||||
|
|
||||||
|
std::string vertex_code = vertex_;
|
||||||
|
if (Resource::hasPath(vertex_))
|
||||||
|
vertex_code = Resource::getText(vertex_);
|
||||||
|
std::string fragment_code = fragment_;
|
||||||
|
if (Resource::hasPath(fragment_))
|
||||||
|
fragment_code = Resource::getText(fragment_);
|
||||||
|
|
||||||
|
// VERTEX SHADER
|
||||||
|
const char* vcode = vertex_code.c_str();
|
||||||
|
unsigned int vertex_id_ = glCreateShader(GL_VERTEX_SHADER);
|
||||||
glShaderSource(vertex_id_, 1, &vcode, NULL);
|
glShaderSource(vertex_id_, 1, &vcode, NULL);
|
||||||
glCompileShader(vertex_id_);
|
glCompileShader(vertex_id_);
|
||||||
|
|
||||||
const char* fcode = fragment_code_.c_str();
|
glGetShaderiv(vertex_id_, GL_COMPILE_STATUS, &success);
|
||||||
fragment_id_ = glCreateShader(GL_FRAGMENT_SHADER);
|
if (!success) {
|
||||||
glShaderSource(fragment_id_, 1, &fcode, NULL);
|
glGetShaderInfoLog(vertex_id_, 1024, NULL, infoLog);
|
||||||
glCompileShader(fragment_id_);
|
Log::Warning("Error compiling Vertex ShadingProgram:\n%s", infoLog);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// FRAGMENT SHADER
|
||||||
|
const char* fcode = fragment_code.c_str();
|
||||||
|
unsigned int fragment_id_ = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(fragment_id_, 1, &fcode, NULL);
|
||||||
|
glCompileShader(fragment_id_);
|
||||||
|
|
||||||
return checkCompileErr();
|
glGetShaderiv(fragment_id_, GL_COMPILE_STATUS, &success);
|
||||||
}
|
if (!success) {
|
||||||
|
glGetShaderInfoLog(fragment_id_, 1024, NULL, infoLog);
|
||||||
|
Log::Warning("Error compiling Fragment ShadingProgram:\n%s", infoLog);
|
||||||
|
glDeleteShader(vertex_id_);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// LINK PROGRAM
|
||||||
|
|
||||||
void ShadingProgram::link()
|
// create new GL Program only if not already done
|
||||||
{
|
if (id_ == 0)
|
||||||
id_ = glCreateProgram();
|
id_ = glCreateProgram();
|
||||||
glAttachShader(id_, vertex_id_);
|
|
||||||
glAttachShader(id_, fragment_id_);
|
// attach shaders and link
|
||||||
glLinkProgram(id_);
|
glAttachShader(id_, vertex_id_);
|
||||||
checkLinkingErr();
|
glAttachShader(id_, fragment_id_);
|
||||||
glUseProgram(id_);
|
glLinkProgram(id_);
|
||||||
glUniform1i(glGetUniformLocation(id_, "iChannel0"), 0);
|
|
||||||
glUniform1i(glGetUniformLocation(id_, "iChannel1"), 1);
|
glGetProgramiv(id_, GL_LINK_STATUS, &success);
|
||||||
glUseProgram(0);
|
if (!success) {
|
||||||
glDeleteShader(vertex_id_);
|
glGetProgramInfoLog(id_, 1024, NULL, infoLog);
|
||||||
vertex_id_ = 0;
|
Log::Warning("Error linking ShadingProgram:\n%s", infoLog);
|
||||||
glDeleteShader(fragment_id_);
|
glDeleteProgram(id_);
|
||||||
fragment_id_ = 0;
|
id_ = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// all good, set default uniforms
|
||||||
|
glUseProgram(id_);
|
||||||
|
glUniform1i(glGetUniformLocation(id_, "iChannel0"), 0);
|
||||||
|
glUniform1i(glGetUniformLocation(id_, "iChannel1"), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// done (no more need for shaders)
|
||||||
|
glUseProgram(0);
|
||||||
|
glDeleteShader(vertex_id_);
|
||||||
|
glDeleteShader(fragment_id_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do not compile indefinitely
|
||||||
|
need_compile_ = false;
|
||||||
|
|
||||||
|
// inform of success
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadingProgram::use()
|
void ShadingProgram::use()
|
||||||
{
|
{
|
||||||
if (currentProgram_ == nullptr || currentProgram_ != this)
|
if (currentProgram_ == nullptr || currentProgram_ != this)
|
||||||
{
|
{
|
||||||
currentProgram_ = this;
|
// first time use ; compile
|
||||||
|
if (need_compile_)
|
||||||
|
compile();
|
||||||
|
// use program
|
||||||
glUseProgram(id_); // NB: if not linked, use 0 as default
|
glUseProgram(id_); // NB: if not linked, use 0 as default
|
||||||
|
// remember (avoid switching program)
|
||||||
|
currentProgram_ = this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +180,15 @@ void ShadingProgram::enduse()
|
|||||||
currentProgram_ = nullptr ;
|
currentProgram_ = nullptr ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShadingProgram::reset()
|
||||||
|
{
|
||||||
|
if (id_ != 0) {
|
||||||
|
glDeleteProgram(id_);
|
||||||
|
id_ = 0;
|
||||||
|
}
|
||||||
|
ShadingProgram::enduse();
|
||||||
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void ShadingProgram::setUniform<int>(const std::string& name, int val) {
|
void ShadingProgram::setUniform<int>(const std::string& name, int val) {
|
||||||
glUniform1i(glGetUniformLocation(id_, name.c_str()), val);
|
glUniform1i(glGetUniformLocation(id_, name.c_str()), val);
|
||||||
@@ -205,34 +244,6 @@ void ShadingProgram::setUniform<glm::mat4>(const std::string& name, glm::mat4 va
|
|||||||
// glUniformMatrix4fv(glGetUniformLocation(id_, name.c_str()), 1, GL_FALSE, val);
|
// glUniformMatrix4fv(glGetUniformLocation(id_, name.c_str()), 1, GL_FALSE, val);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
bool ShadingProgram::checkCompileErr()
|
|
||||||
{
|
|
||||||
int success;
|
|
||||||
char infoLog[1024];
|
|
||||||
glGetShaderiv(vertex_id_, GL_COMPILE_STATUS, &success);
|
|
||||||
if (!success) {
|
|
||||||
glGetShaderInfoLog(vertex_id_, 1024, NULL, infoLog);
|
|
||||||
Log::Warning("Error compiling Vertex ShadingProgram:\n%s", infoLog);
|
|
||||||
}
|
|
||||||
glGetShaderiv(fragment_id_, GL_COMPILE_STATUS, &success);
|
|
||||||
if (!success) {
|
|
||||||
glGetShaderInfoLog(fragment_id_, 1024, NULL, infoLog);
|
|
||||||
Log::Warning("Error compiling Fragment ShadingProgram:\n%s", infoLog);
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShadingProgram::checkLinkingErr()
|
|
||||||
{
|
|
||||||
int success;
|
|
||||||
glGetProgramiv(id_, GL_LINK_STATUS, &success);
|
|
||||||
if (!success) {
|
|
||||||
char infoLog[1024];
|
|
||||||
glGetProgramInfoLog(id_, 1024, NULL, infoLog);
|
|
||||||
Log::Warning("Error linking ShadingProgram:\n%s", infoLog);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Shader::force_blending_opacity = false;
|
bool Shader::force_blending_opacity = false;
|
||||||
|
|
||||||
@@ -259,10 +270,6 @@ void Shader::accept(Visitor& v) {
|
|||||||
|
|
||||||
void Shader::use()
|
void Shader::use()
|
||||||
{
|
{
|
||||||
// initialization on first use
|
|
||||||
if (!program_->initialized())
|
|
||||||
program_->init();
|
|
||||||
|
|
||||||
// Use program
|
// Use program
|
||||||
program_->use();
|
program_->use();
|
||||||
|
|
||||||
|
|||||||
26
Shader.h
26
Shader.h
@@ -13,27 +13,23 @@ class ShadingProgram
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// create GLSL Program from resource file (if exist) or code of vertex and fragment shaders
|
// create GLSL Program from resource file (if exist) or code of vertex and fragment shaders
|
||||||
ShadingProgram(const std::string& vertex, const std::string& fragment);
|
ShadingProgram(const std::string& vertex = "", const std::string& fragment = "");
|
||||||
|
void setShaders(const std::string& vertex, const std::string& fragment);
|
||||||
|
|
||||||
void init();
|
|
||||||
bool initialized();
|
|
||||||
void use();
|
void use();
|
||||||
|
bool compile();
|
||||||
|
static void enduse();
|
||||||
|
void reset();
|
||||||
|
|
||||||
template<typename T> void setUniform(const std::string& name, T val);
|
template<typename T> void setUniform(const std::string& name, T val);
|
||||||
template<typename T> void setUniform(const std::string& name, T val1, T val2);
|
template<typename T> void setUniform(const std::string& name, T val1, T val2);
|
||||||
template<typename T> void setUniform(const std::string& name, T val1, T val2, T val3);
|
template<typename T> void setUniform(const std::string& name, T val1, T val2, T val3);
|
||||||
|
|
||||||
static void enduse();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool checkCompileErr();
|
unsigned int id_;
|
||||||
void checkLinkingErr();
|
bool need_compile_;
|
||||||
bool compile();
|
std::string vertex_;
|
||||||
void link();
|
std::string fragment_;
|
||||||
unsigned int vertex_id_, fragment_id_, id_;
|
|
||||||
std::string vertex_code_;
|
|
||||||
std::string fragment_code_;
|
|
||||||
std::string vertex_file_;
|
|
||||||
std::string fragment_file_;
|
|
||||||
|
|
||||||
static ShadingProgram *currentProgram_;
|
static ShadingProgram *currentProgram_;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user