Port to Win32; Move sources to src/ subdir; Use precompiled headers
This commit is contained in:
99
src/render/ProgramProvider.cc
Normal file
99
src/render/ProgramProvider.cc
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "common.hh"
|
||||
|
||||
#include <glbinding/gl/gl.h>
|
||||
|
||||
#include "ProgramProvider.hh"
|
||||
#include "util.hh"
|
||||
|
||||
using namespace gl;
|
||||
|
||||
template<>
|
||||
std::unique_ptr<render::ProgramProvider> Singleton<render::ProgramProvider>::instance{nullptr};
|
||||
template<>
|
||||
std::once_flag Singleton<render::ProgramProvider>::instance_flag{};
|
||||
|
||||
namespace render {
|
||||
namespace {
|
||||
class ShaderException : public Exception {
|
||||
public:
|
||||
ShaderException(std::string const& msg)
|
||||
: Exception(msg)
|
||||
{
|
||||
}
|
||||
|
||||
std::string toString() const override {
|
||||
return "ShaderException: " + msg_;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ProgramProvider::ProgramProvider()
|
||||
{
|
||||
}
|
||||
|
||||
void shaderCompile_(std::string const& shaderName, ShaderResource& shader)
|
||||
{
|
||||
std::string prog = fileToString("shaders/" + shaderName);
|
||||
const char* const arr[] = {prog.c_str()};
|
||||
glShaderSource(shader, 1, arr, NULL);
|
||||
glCompileShader(shader);
|
||||
|
||||
int state;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &state);
|
||||
|
||||
if (state == 0) {
|
||||
int logLength;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
|
||||
|
||||
char *log = new char[logLength];
|
||||
glGetShaderInfoLog(shader, logLength, NULL, log);
|
||||
std::string msg(log);
|
||||
delete[] log;
|
||||
|
||||
throw ShaderException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
GLuint ProgramProvider::getProgram(std::string const& vertexShader, std::string const& fragShader)
|
||||
{
|
||||
auto key = make_tuple(vertexShader, fragShader);
|
||||
auto it = programCache_.find(key);
|
||||
if (it != programCache_.end())
|
||||
return it->second.get();
|
||||
|
||||
ShaderResource vs(glCreateShader(GL_VERTEX_SHADER)),
|
||||
fs(glCreateShader(GL_FRAGMENT_SHADER));
|
||||
|
||||
shaderCompile_(vertexShader + ".vs", vs);
|
||||
shaderCompile_(fragShader + ".fs", fs);
|
||||
|
||||
ProgramResource prog(glCreateProgram());
|
||||
glAttachShader(prog, vs);
|
||||
glAttachShader(prog, fs);
|
||||
|
||||
glLinkProgram(prog);
|
||||
|
||||
int state;
|
||||
glGetProgramiv(prog, GL_LINK_STATUS, &state);
|
||||
|
||||
if (state == 0) {
|
||||
int logLength;
|
||||
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
|
||||
|
||||
char *log = new char[logLength];
|
||||
glGetProgramInfoLog(prog, logLength, NULL, log);
|
||||
std::string msg(log);
|
||||
delete[] log;
|
||||
|
||||
throw ShaderException(msg);
|
||||
}
|
||||
|
||||
glDetachShader(prog, vs);
|
||||
glDetachShader(prog, fs);
|
||||
|
||||
std::tie(it, std::ignore) = programCache_.insert(make_pair(key, std::move(prog)));
|
||||
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user