Files
NBEngine/engine/NBGraphics/include/NBGraphics/ProgramPipeline.hpp
T

147 lines
3.4 KiB
C++

#pragma once
#ifndef _NB_SHADER
#define _NB_SHADER
#include <NBGraphics/GLLoad.hpp>
#include <string>
#include <NBCore/Errors.hpp>
#include <NBCore/Utils.hpp>
#include <NBGraphics/Buffers.hpp>
#include <NBGraphics/OGLObjects.hpp>
namespace nb {
class ShaderError : public Error<ShaderError> {
using Base = Error<ShaderError>;
public:
using Base::Base;
enum Codes : unsigned int {
UNDEFINED
};
static const std::string type;
static const ErrorCodeMap ErrorMessages;
};
class ProgramError : public Error<ProgramError> {
using Base = Error<ProgramError>;
public:
using Base::Base;
enum Codes : unsigned int {
UNDEFINED, LINKING_ERROR
};
static const std::string type;
static const ErrorCodeMap ErrorMessages;
};
enum OpenGLProfiles {
Core,
Compatibility,
ES
};
class Shader : public OpenGLObject {
using Base = OpenGLObject;
public:
using Base::Base;
using Base::id;
Shader(GLenum, const std::string&);
Shader(GLenum, const std::vector<std::string>&);
Shader(Shader&&);
Shader& operator=(Shader&&) = delete;
~Shader() { remove(); }
operator bool();
virtual void bind() const override { /* TODO: Some warning of some kind perhaps*/ }
virtual void unbind() const override { /* TODO: Some warning of some kind perhaps*/ }
bool success() const;
GLint status(GLenum) const;
std::string log() const;
const GLenum target;
friend Base;
protected:
using Base::_id;
GLint _success;
std::vector<std::string> _sources;
virtual void compile() {
int num_srcs = _sources.size();
std::vector<char*> src_ptrs(num_srcs);
for (int i=0; i < num_srcs; ++i) {
src_ptrs[i] = _sources[i].data();
}
OPENGL_CALL(glShaderSource(_id, num_srcs, src_ptrs.data(), NULL));
OPENGL_CALL(glCompileShader(_id));
_success = status(GL_COMPILE_STATUS);
if (!_success) {
WARN(log(), 0x0FE);
}
}
virtual GLuint declare() override {
if (!_id) {
_id = _id = OPENGL_CALL(glCreateShader(target));
}
return _id;
}
virtual void remove() override {
if (_id) {
OPENGL_CALL(glDeleteShader(_id));
}
}
};
class Program : public OpenGLObject {
using Base = OpenGLObject;
public:
using Base::Base;
using Base::id;
Program(SharedVector<Shader>);
Program(Program&&);
Program& operator=(Program&&) = delete;
operator bool();
~Program() { remove(); }
void bind() const override {
OPENGL_CALL(glUseProgram(_id));
}
void unbind() const override { /* TODO: Some warning of some kind perhaps*/ }
GLint status(GLenum) const;
std::string log() const;
void setUniform(const std::string& blockname, std::shared_ptr<UniformBuffer>);
void setUniformBinding(const std::string& blockname, GLuint index);
GLuint getUniformBinding(const std::string& blockname) const;
friend Base;
protected:
using Base::_id;
GLint _success;
std::unordered_map<std::string, GLuint> _uniformBindings;
virtual GLuint declare() override {
if (!_id) {
_id = OPENGL_CALL(glCreateProgram());
}
return _id;
}
virtual void remove() override {
if (_id) {
OPENGL_CALL(glDeleteProgram(_id));
}
}
};
}
#endif