From 4096a53edc724411bc5b3760661c38a045899af3 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sat, 13 Jun 2015 23:33:23 -0400 Subject: [PATCH] allocate OpenGL object when C++ object is constructed; make create() a static factory function --- include/glcxx/Array.hpp | 4 ---- include/glcxx/Buffer.hpp | 12 ++++++++-- include/glcxx/Program.hpp | 47 ++++++++++++++++++++++++--------------- include/glcxx/Shader.hpp | 25 +++++++++++++++++---- src/glcxx/Array.cpp | 16 +++++-------- src/glcxx/Buffer.cpp | 18 ++++++++------- src/glcxx/Program.cpp | 27 ++++++++++------------ src/glcxx/Shader.cpp | 33 ++++++++++++++------------- test/test.cpp | 32 ++++++++------------------ 9 files changed, 113 insertions(+), 101 deletions(-) diff --git a/include/glcxx/Array.hpp b/include/glcxx/Array.hpp index 9734a96..97a3eeb 100644 --- a/include/glcxx/Array.hpp +++ b/include/glcxx/Array.hpp @@ -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; }; diff --git a/include/glcxx/Buffer.hpp b/include/glcxx/Buffer.hpp index da57562..04e607e 100644 --- a/include/glcxx/Buffer.hpp +++ b/include/glcxx/Buffer.hpp @@ -2,6 +2,7 @@ #define GLCXX_BUFFER_HPP #include "glcxx/gl.hpp" +#include 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 create(GLenum target, GLenum usage, const void * ptr, size_t size) + { + std::shared_ptr buffer = std::make_shared(); + buffer->set_buffer_data(target, usage, ptr, size); + return buffer; + } protected: GLuint m_id; GLenum m_target; + + void allocate(); }; }; diff --git a/include/glcxx/Program.hpp b/include/glcxx/Program.hpp index 990542b..17e02e5 100644 --- a/include/glcxx/Program.hpp +++ b/include/glcxx/Program.hpp @@ -18,13 +18,11 @@ namespace glcxx void use() const { glUseProgram(m_id); } - bool valid() const { return m_id > 0u; } - template - 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 + static std::shared_ptr create(Args... args) + { + std::shared_ptr program = std::make_shared(); + program->build(args...); + return program; + } + protected: + GLuint m_id; + void allocate(); - void _create() const; - - template - void _create(const Shader & shader, Shaders... args) const + void _build() const { - attach_shader(shader); - _create(args...); + link(); } template - void _create(std::unique_ptr shader, Shaders... args) const + void _build(const Shader & shader, Shaders... args) const { attach_shader(shader); - _create(args...); + _build(args...); } template - void _create(std::shared_ptr shader, Shaders... args) const + void _build(std::unique_ptr shader, Shaders... args) const { attach_shader(shader); - _create(args...); + _build(args...); } template - void _create(const char * attribute_name, GLuint index, Shaders... args) const + void _build(std::shared_ptr shader, Shaders... args) const + { + attach_shader(shader); + _build(args...); + } + + template + void _build(const char * attribute_name, GLuint index, Shaders... args) const { glBindAttribLocation(m_id, index, attribute_name); - _create(args...); + _build(args...); } - - GLuint m_id; }; }; diff --git a/include/glcxx/Shader.hpp b/include/glcxx/Shader.hpp index 5684d4e..554e13b 100644 --- a/include/glcxx/Shader.hpp +++ b/include/glcxx/Shader.hpp @@ -2,26 +2,43 @@ #define GLCXX_SHADER_HPP #include "glcxx/gl.hpp" +#include 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 create(GLenum shader_type, const char * source, int length = -1) + { + std::shared_ptr shader = std::make_shared(shader_type); + shader->set_source(source, length); + return shader; + } + + static std::shared_ptr create_from_file(GLenum shader_type, const char * filename) + { + std::shared_ptr shader = std::make_shared(shader_type); + shader->set_source_from_file(filename); + return shader; + } protected: GLuint m_id; + + GLenum m_shader_type; + + void allocate(); }; }; diff --git a/src/glcxx/Array.cpp b/src/glcxx/Array.cpp index f028bd6..cb168b5 100644 --- a/src/glcxx/Array.cpp +++ b/src/glcxx/Array.cpp @@ -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); + } } diff --git a/src/glcxx/Buffer.cpp b/src/glcxx/Buffer.cpp index 5440c8b..18a72d0 100644 --- a/src/glcxx/Buffer.cpp +++ b/src/glcxx/Buffer.cpp @@ -5,26 +5,28 @@ namespace glcxx { Buffer::Buffer() { - m_id = 0u; + allocate(); } 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; + 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); } } diff --git a/src/glcxx/Program.cpp b/src/glcxx/Program.cpp index 2a3ae1b..aaa222f 100644 --- a/src/glcxx/Program.cpp +++ b/src/glcxx/Program.cpp @@ -6,27 +6,15 @@ namespace glcxx { Program::Program() { - m_id = 0u; + allocate(); } Program::~Program() { - if (m_id > 0u) - { - glDeleteProgram(m_id); - } + 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"); + } + } } diff --git a/src/glcxx/Shader.cpp b/src/glcxx/Shader.cpp index a94ce3b..c9d0eb2 100644 --- a/src/glcxx/Shader.cpp +++ b/src/glcxx/Shader.cpp @@ -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); - } + 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 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"); + } } } diff --git a/test/test.cpp b/test/test.cpp index 0688522..712366f 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -27,28 +27,14 @@ bool init(void) { array1 = make_shared(); array2 = make_shared(); - array1->create(); - array2->create(); - vs = make_shared(); - vs2 = make_shared(); - fs = make_shared(); - fs2 = make_shared(); - program = make_shared(); - program2 = make_shared(); - buffer = make_shared(); - buffer2 = make_shared(); - buffer3 = make_shared(); - 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);