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