allocate OpenGL object when C++ object is constructed; make create() a static factory function
This commit is contained in:
parent
22020958d5
commit
4096a53edc
@ -12,8 +12,6 @@ namespace glcxx
|
||||
|
||||
~Array();
|
||||
|
||||
void create();
|
||||
|
||||
void bind()
|
||||
{
|
||||
glBindVertexArray(m_id);
|
||||
@ -21,8 +19,6 @@ namespace glcxx
|
||||
|
||||
GLuint id() const { return m_id; }
|
||||
|
||||
bool valid() const { return m_id > 0u; }
|
||||
|
||||
protected:
|
||||
GLuint m_id;
|
||||
};
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define GLCXX_BUFFER_HPP
|
||||
|
||||
#include "glcxx/gl.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace glcxx
|
||||
{
|
||||
@ -12,18 +13,25 @@ namespace glcxx
|
||||
|
||||
~Buffer();
|
||||
|
||||
void create(GLenum target, GLenum usage, const void * ptr, size_t size);
|
||||
void set_buffer_data(GLenum target, GLenum usage, const void * ptr, size_t size);
|
||||
|
||||
GLuint id() const { return m_id; }
|
||||
|
||||
void bind() const { glBindBuffer(m_target, m_id); }
|
||||
|
||||
bool valid() const { return m_id > 0u; }
|
||||
static std::shared_ptr<Buffer> create(GLenum target, GLenum usage, const void * ptr, size_t size)
|
||||
{
|
||||
std::shared_ptr<Buffer> buffer = std::make_shared<Buffer>();
|
||||
buffer->set_buffer_data(target, usage, ptr, size);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
protected:
|
||||
GLuint m_id;
|
||||
|
||||
GLenum m_target;
|
||||
|
||||
void allocate();
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -18,13 +18,11 @@ namespace glcxx
|
||||
|
||||
void use() const { glUseProgram(m_id); }
|
||||
|
||||
bool valid() const { return m_id > 0u; }
|
||||
|
||||
template <typename... Shaders>
|
||||
void create(Shaders... shaders)
|
||||
void build(Shaders... shaders)
|
||||
{
|
||||
allocate();
|
||||
_create(shaders...);
|
||||
_build(shaders...);
|
||||
}
|
||||
|
||||
void attach_shader(const Shader & shader) const
|
||||
@ -42,45 +40,58 @@ namespace glcxx
|
||||
glAttachShader(m_id, shader->id());
|
||||
}
|
||||
|
||||
void link() const;
|
||||
|
||||
GLint get_uniform_location(const char * uniform_name)
|
||||
{
|
||||
return glGetUniformLocation(m_id, uniform_name);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static std::shared_ptr<Program> create(Args... args)
|
||||
{
|
||||
std::shared_ptr<Program> program = std::make_shared<Program>();
|
||||
program->build(args...);
|
||||
return program;
|
||||
}
|
||||
|
||||
protected:
|
||||
GLuint m_id;
|
||||
|
||||
void allocate();
|
||||
|
||||
void _create() const;
|
||||
|
||||
template <typename... Shaders>
|
||||
void _create(const Shader & shader, Shaders... args) const
|
||||
void _build() const
|
||||
{
|
||||
attach_shader(shader);
|
||||
_create(args...);
|
||||
link();
|
||||
}
|
||||
|
||||
template <typename... Shaders>
|
||||
void _create(std::unique_ptr<Shader> shader, Shaders... args) const
|
||||
void _build(const Shader & shader, Shaders... args) const
|
||||
{
|
||||
attach_shader(shader);
|
||||
_create(args...);
|
||||
_build(args...);
|
||||
}
|
||||
|
||||
template <typename... Shaders>
|
||||
void _create(std::shared_ptr<Shader> shader, Shaders... args) const
|
||||
void _build(std::unique_ptr<Shader> shader, Shaders... args) const
|
||||
{
|
||||
attach_shader(shader);
|
||||
_create(args...);
|
||||
_build(args...);
|
||||
}
|
||||
|
||||
template <typename... Shaders>
|
||||
void _create(const char * attribute_name, GLuint index, Shaders... args) const
|
||||
void _build(std::shared_ptr<Shader> shader, Shaders... args) const
|
||||
{
|
||||
attach_shader(shader);
|
||||
_build(args...);
|
||||
}
|
||||
|
||||
template <typename... Shaders>
|
||||
void _build(const char * attribute_name, GLuint index, Shaders... args) const
|
||||
{
|
||||
glBindAttribLocation(m_id, index, attribute_name);
|
||||
_create(args...);
|
||||
_build(args...);
|
||||
}
|
||||
|
||||
GLuint m_id;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -2,26 +2,43 @@
|
||||
#define GLCXX_SHADER_HPP
|
||||
|
||||
#include "glcxx/gl.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace glcxx
|
||||
{
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
Shader();
|
||||
Shader(GLenum shader_type);
|
||||
|
||||
~Shader();
|
||||
|
||||
void create(GLenum shader_type, const char * source, int length = -1);
|
||||
void set_source(const char * source, int length = -1);
|
||||
|
||||
void create_from_file(GLenum shader_type, const char * filename);
|
||||
void set_source_from_file(const char * filename);
|
||||
|
||||
GLuint id() const { return m_id; }
|
||||
|
||||
bool valid() const { return m_id > 0u; }
|
||||
static std::shared_ptr<Shader> create(GLenum shader_type, const char * source, int length = -1)
|
||||
{
|
||||
std::shared_ptr<Shader> shader = std::make_shared<Shader>(shader_type);
|
||||
shader->set_source(source, length);
|
||||
return shader;
|
||||
}
|
||||
|
||||
static std::shared_ptr<Shader> create_from_file(GLenum shader_type, const char * filename)
|
||||
{
|
||||
std::shared_ptr<Shader> shader = std::make_shared<Shader>(shader_type);
|
||||
shader->set_source_from_file(filename);
|
||||
return shader;
|
||||
}
|
||||
|
||||
protected:
|
||||
GLuint m_id;
|
||||
|
||||
GLenum m_shader_type;
|
||||
|
||||
void allocate();
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -6,18 +6,7 @@ namespace glcxx
|
||||
Array::Array()
|
||||
{
|
||||
m_id = 0u;
|
||||
}
|
||||
|
||||
Array::~Array()
|
||||
{
|
||||
if (m_id != 0u)
|
||||
{
|
||||
glDeleteVertexArrays(1, &m_id);
|
||||
}
|
||||
}
|
||||
|
||||
void Array::create()
|
||||
{
|
||||
glGenVertexArrays(1, &m_id);
|
||||
|
||||
if (m_id == 0u)
|
||||
@ -25,4 +14,9 @@ namespace glcxx
|
||||
throw Error("Failed to allocate an OpenGL array");
|
||||
}
|
||||
}
|
||||
|
||||
Array::~Array()
|
||||
{
|
||||
glDeleteVertexArrays(1, &m_id);
|
||||
}
|
||||
}
|
||||
|
@ -5,26 +5,28 @@ namespace glcxx
|
||||
{
|
||||
Buffer::Buffer()
|
||||
{
|
||||
m_id = 0u;
|
||||
allocate();
|
||||
}
|
||||
|
||||
Buffer::~Buffer()
|
||||
{
|
||||
if (m_id > 0u)
|
||||
{
|
||||
glDeleteBuffers(1, &m_id);
|
||||
}
|
||||
}
|
||||
|
||||
void Buffer::create(GLenum target, GLenum usage, const void * ptr, size_t size)
|
||||
void Buffer::set_buffer_data(GLenum target, GLenum usage, const void * ptr, size_t size)
|
||||
{
|
||||
m_target = target;
|
||||
bind();
|
||||
glBufferData(target, size, ptr, usage);
|
||||
}
|
||||
|
||||
void Buffer::allocate()
|
||||
{
|
||||
m_id = 0u;
|
||||
glGenBuffers(1, &m_id);
|
||||
if (m_id == 0u)
|
||||
{
|
||||
throw Error("Failed to allocate an OpenGL buffer");
|
||||
}
|
||||
bind();
|
||||
glBufferData(target, size, ptr, usage);
|
||||
}
|
||||
}
|
||||
|
@ -6,27 +6,15 @@ namespace glcxx
|
||||
{
|
||||
Program::Program()
|
||||
{
|
||||
m_id = 0u;
|
||||
allocate();
|
||||
}
|
||||
|
||||
Program::~Program()
|
||||
{
|
||||
if (m_id > 0u)
|
||||
{
|
||||
glDeleteProgram(m_id);
|
||||
}
|
||||
}
|
||||
|
||||
void Program::allocate()
|
||||
{
|
||||
m_id = glCreateProgram();
|
||||
if (m_id == 0u)
|
||||
{
|
||||
throw Error("Failed to allocate an OpenGL program");
|
||||
}
|
||||
}
|
||||
|
||||
void Program::_create() const
|
||||
void Program::link() const
|
||||
{
|
||||
glLinkProgram(m_id);
|
||||
|
||||
@ -49,4 +37,13 @@ namespace glcxx
|
||||
throw Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
void Program::allocate()
|
||||
{
|
||||
m_id = glCreateProgram();
|
||||
if (m_id == 0u)
|
||||
{
|
||||
throw Error("Failed to allocate an OpenGL program");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,29 +6,21 @@
|
||||
|
||||
namespace glcxx
|
||||
{
|
||||
Shader::Shader()
|
||||
Shader::Shader(GLenum shader_type)
|
||||
{
|
||||
m_id = 0u;
|
||||
m_shader_type = shader_type;
|
||||
allocate();
|
||||
}
|
||||
|
||||
Shader::~Shader()
|
||||
{
|
||||
if (m_id > 0u)
|
||||
{
|
||||
glDeleteShader(m_id);
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::create(GLenum shader_type, const char * source, int length)
|
||||
void Shader::set_source(const char * source, int length)
|
||||
{
|
||||
GLint status;
|
||||
|
||||
m_id = glCreateShader(shader_type);
|
||||
if (m_id == 0u)
|
||||
{
|
||||
throw Error("Failed to allocate an OpenGL shader");
|
||||
}
|
||||
|
||||
GLint lengths[1] = {length};
|
||||
glShaderSource(m_id, 1, &source, &lengths[0]);
|
||||
|
||||
@ -41,7 +33,7 @@ namespace glcxx
|
||||
}
|
||||
|
||||
std::string message = "Error compiling ";
|
||||
switch (shader_type)
|
||||
switch (m_shader_type)
|
||||
{
|
||||
case GL_VERTEX_SHADER:
|
||||
message += "vertex";
|
||||
@ -70,7 +62,7 @@ namespace glcxx
|
||||
throw Error(message);
|
||||
}
|
||||
|
||||
void Shader::create_from_file(GLenum shader_type, const char * filename)
|
||||
void Shader::set_source_from_file(const char * filename)
|
||||
{
|
||||
std::ifstream ifs;
|
||||
ifs.open(filename);
|
||||
@ -83,6 +75,15 @@ namespace glcxx
|
||||
ifs.seekg(0, ifs.beg);
|
||||
std::vector<char> file_contents(length);
|
||||
ifs.read(&file_contents[0], length);
|
||||
create(shader_type, &file_contents[0], length);
|
||||
set_source(&file_contents[0], length);
|
||||
}
|
||||
|
||||
void Shader::allocate()
|
||||
{
|
||||
m_id = glCreateShader(m_shader_type);
|
||||
if (m_id == 0u)
|
||||
{
|
||||
throw Error("Failed to allocate an OpenGL shader");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,28 +27,14 @@ bool init(void)
|
||||
{
|
||||
array1 = make_shared<glcxx::Array>();
|
||||
array2 = make_shared<glcxx::Array>();
|
||||
array1->create();
|
||||
array2->create();
|
||||
vs = make_shared<glcxx::Shader>();
|
||||
vs2 = make_shared<glcxx::Shader>();
|
||||
fs = make_shared<glcxx::Shader>();
|
||||
fs2 = make_shared<glcxx::Shader>();
|
||||
program = make_shared<glcxx::Program>();
|
||||
program2 = make_shared<glcxx::Program>();
|
||||
buffer = make_shared<glcxx::Buffer>();
|
||||
buffer2 = make_shared<glcxx::Buffer>();
|
||||
buffer3 = make_shared<glcxx::Buffer>();
|
||||
|
||||
vs->create_from_file(GL_VERTEX_SHADER, "test/vert.glsl");
|
||||
fs->create_from_file(GL_FRAGMENT_SHADER, "test/frag.glsl");
|
||||
program->create(vs, fs,
|
||||
"position", 0);
|
||||
vs = glcxx::Shader::create_from_file(GL_VERTEX_SHADER, "test/vert.glsl");
|
||||
fs = glcxx::Shader::create_from_file(GL_FRAGMENT_SHADER, "test/frag.glsl");
|
||||
program = glcxx::Program::create(vs, fs, "position", 0);
|
||||
|
||||
vs2->create_from_file(GL_VERTEX_SHADER, "test/vert2.glsl");
|
||||
fs2->create_from_file(GL_FRAGMENT_SHADER, "test/frag2.glsl");
|
||||
program2->create(vs2, fs2,
|
||||
"position", 0,
|
||||
"color", 1);
|
||||
vs2 = glcxx::Shader::create_from_file(GL_VERTEX_SHADER, "test/vert2.glsl");
|
||||
fs2 = glcxx::Shader::create_from_file(GL_FRAGMENT_SHADER, "test/frag2.glsl");
|
||||
program2 = glcxx::Program::create(vs2, fs2, "position", 0, "color", 1);
|
||||
|
||||
GLfloat coords[] = {
|
||||
-0.5, -0.5,
|
||||
@ -56,20 +42,20 @@ bool init(void)
|
||||
0.5, 0.5,
|
||||
-0.5, 0.5,
|
||||
};
|
||||
buffer->create(GL_ARRAY_BUFFER, GL_STATIC_DRAW, &coords, sizeof(coords));
|
||||
buffer = glcxx::Buffer::create(GL_ARRAY_BUFFER, GL_STATIC_DRAW, &coords, sizeof(coords));
|
||||
|
||||
GLfloat coords2[] = {
|
||||
0.2, 0.2,
|
||||
0.9, 0.2,
|
||||
0.9, 0.9,
|
||||
};
|
||||
buffer2->create(GL_ARRAY_BUFFER, GL_STATIC_DRAW, &coords2, sizeof(coords2));
|
||||
buffer2 = glcxx::Buffer::create(GL_ARRAY_BUFFER, GL_STATIC_DRAW, &coords2, sizeof(coords2));
|
||||
GLfloat colors[] = {
|
||||
1.0, 0.1, 0.1, 1.0,
|
||||
0.1, 1.0, 0.1, 1.0,
|
||||
0.1, 0.1, 1.0, 1.0,
|
||||
};
|
||||
buffer3->create(GL_ARRAY_BUFFER, GL_STATIC_DRAW, &colors, sizeof(colors));
|
||||
buffer3 = glcxx::Buffer::create(GL_ARRAY_BUFFER, GL_STATIC_DRAW, &colors, sizeof(colors));
|
||||
|
||||
array1->bind();
|
||||
glEnableVertexAttribArray(0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user