include/gltexturebuffer.hpp
694871da
 #ifndef GLTEXTUREBUFFER_HPP_
 #define GLTEXTUREBUFFER_HPP_
 
 
 #include <string>
 #include <utility>
 
 #include <gltexturend.hpp>
 
 
 /// Class
 
 template<typename Data>
 class GLTextureBuffer : public GLTextureND<1>
 {
 public:
 
     /// Special member functions
 
     explicit GLTextureBuffer(
         std::string object_label,
         Size        size,
         GLenum      usage           = GL_STATIC_DRAW,
         GLenum      internal_format = DataTraits<Data>::internal_format
     );
     GLTextureBuffer(GLTextureBuffer && other) noexcept;
     virtual ~GLTextureBuffer();
 
     /// Core
 
     GLTextureBuffer static const & empty();
 
     GLOBJECT_GET(GLuint, buffer)
 
 protected:
 
     /// Core
 
     void data_(
         void const * data,
         GLenum       target,
         GLenum       format,
         GLenum       type
     ) override;
 
     GLsizeiptr buffer_size_() const;
 
 private:
 
     /// Core
 
     GLuint buffer_;
 };
 
 
 /// Special member functions
 
 template<typename Data>
 inline GLTextureBuffer<Data>::GLTextureBuffer(
     std::string object_label,
     Size        size,
     GLenum      usage,
     GLenum      internal_format
 )
 :
     GLTextureND(
         std::move(object_label),
         GL_TEXTURE_BUFFER,
         GL_TEXTURE_BINDING_BUFFER,
         GL_MAX_TEXTURE_BUFFER_SIZE,
         size,
         internal_format
     ),
     buffer_{0}
 {
     try
     {
         check_supported_({3, 1}, "GL_ARB_texture_buffer_object");
         switch (internal_format)
         {
             case GL_RGB32F:
             case GL_RGB32I:
             case GL_RGB32UI:
                 check_supported_({4, 0}, "GL_ARB_texture_buffer_object_rgb32");
         }
         glGenBuffers(1, &buffer_);
         glBindBuffer(GL_TEXTURE_BUFFER, buffer_);
         glBufferData(
             GL_TEXTURE_BUFFER,
             buffer_size_(),
             nullptr,
             usage
         );
         glTexBuffer(target_, internal_format, buffer_);
         check_error_(glGetError());
     }
     catch (...)
     {
         glDeleteBuffers(1, &buffer_);
         fail_action_("create");
     }
 }
 
 template<typename Data>
 inline GLTextureBuffer<Data>::GLTextureBuffer(
     GLTextureBuffer && other
 ) noexcept
 :
     buffer_{other.buffer_}
 {
     other.buffer_ = 0;
 }
 
 template<typename Data>
 inline GLTextureBuffer<Data>::~GLTextureBuffer()
 {
     glDeleteBuffers(1, &buffer_);
 }
 
 /// Core
 
 template<typename Data>
 inline GLTextureBuffer<Data> const & GLTextureBuffer<Data>::empty()
 {
     return empty_<GLTextureBuffer>();
 }
 
 template<typename Data>
 inline void GLTextureBuffer<Data>::data_(
     void const * data,
     GLenum       target,
     GLenum       format,
     GLenum       type
 )
 {
     check_format_(format, DataTraits<Data>::format);
     check_type_  (type,   DataTraits<Data>::type);
     glBufferSubData(
         target,
         0,
         buffer_size_(),
         data
     );
 }
 
 template<typename Data>
 inline GLsizeiptr GLTextureBuffer<Data>::buffer_size_() const
 {
     return (GLsizeiptr)(data_size_() * sizeof(Data));
 }
 
 
 #endif // GLTEXTUREBUFFER_HPP_