#ifndef GLW_BUFFER_H #define GLW_BUFFER_H #include "./object.h" namespace glw { class BufferArguments : public ObjectArguments { public: typedef ObjectArguments BaseType; typedef BufferArguments ThisType; GLsizeiptr size; GLenum usage; const void * data; BufferArguments(void) : BaseType () , size (0) , usage (GL_STATIC_DRAW) , data (0) { this->clear(); } BufferArguments(GLsizeiptr aSize, GLenum aUsage = GL_STATIC_DRAW, const void * aData = 0) : BaseType () , size (aSize) , usage (aUsage) , data (aData) { ; } void clear(void) { BaseType::clear(); this->size = 0; this->usage = GL_STATIC_DRAW; this->data = 0; } }; class Buffer : public Object { friend class Context; public: typedef Object BaseType; typedef Buffer ThisType; virtual ~Buffer(void) { this->destroy(); } virtual Type type(void) const { return BufferType; } GLsizeiptr size(void) const { return this->m_size; } GLenum usage(void) const { return this->m_usage; } void setData(GLenum target, GLint unit, const GLsizeiptr size, GLenum usage, const GLvoid * data) { (void)unit; GLW_ASSERT(this->isValid()); glBufferData(target, size, data, usage); this->m_size = size; this->m_usage = usage; } void setSubData(GLenum target, GLint unit, GLintptr offset, GLsizeiptr size, const GLvoid * data) { (void)unit; GLW_ASSERT(this->isValid()); glBufferSubData(target, offset, size, data); } void getSubData(GLenum target, GLint unit, GLintptr offset, GLsizeiptr size, GLvoid * data) { (void)unit; GLW_ASSERT(this->isValid()); glGetBufferSubData(target, offset, size, data); } void * map(GLenum target, GLint unit, GLenum access) { (void)unit; GLW_ASSERT(this->isValid()); GLW_ASSERT(!this->isMapped(target, unit)); void * ptr = glMapBuffer(target, access); if (ptr == 0) return 0; this->m_mapAccess = access; this->m_mapPointer = ptr; return ptr; } void unmap(GLenum target, GLint unit) { (void)unit; GLW_ASSERT(this->isValid()); GLW_ASSERT(this->isMapped(target, unit)); glUnmapBuffer(target); this->m_mapAccess = GL_NONE; this->m_mapPointer = 0; } GLenum mapAccess(GLenum target, GLint unit) const { (void)target; (void)unit; return this->m_mapAccess; } bool isMapped(GLenum target, GLint unit) const { (void)target; (void)unit; return (this->m_mapAccess != GL_NONE); } void * mapPointer(GLenum target, GLint unit) const { (void)target; (void)unit; return this->m_mapPointer; } void vertexAttribPointer(GLenum target, GLint unit, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * offset) { (void)target; (void)unit; GLW_ASSERT(this->isValid()); glVertexAttribPointer(index, size, type, normalized, stride, offset); } void drawElements(GLenum target, GLint unit, GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) { (void)target; (void)unit; GLW_ASSERT(this->isValid()); glDrawElements(mode, count, type, indices); } protected: GLsizeiptr m_size; GLenum m_usage; GLenum m_mapAccess; void * m_mapPointer; Buffer(Context * ctx) : BaseType (ctx) , m_size (0) , m_usage (GL_NONE) , m_mapAccess (GL_NONE) , m_mapPointer (0) { ; } bool create(const BufferArguments & args) { this->destroy(); GLint boundName = 0; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundName); glGenBuffers(1, &(this->m_name)); glBindBuffer(GL_ARRAY_BUFFER, this->m_name); glBufferData(GL_ARRAY_BUFFER, args.size, args.data, args.usage); glBindBuffer(GL_ARRAY_BUFFER, boundName); this->m_size = args.size; this->m_usage = args.usage; return true; } virtual void doDestroy(void) { glDeleteBuffers(1, &(this->m_name)); this->m_size = 0; this->m_usage = GL_NONE; this->m_mapAccess = GL_NONE; this->m_mapPointer = 0; } virtual bool doIsValid(void) const { return (this->m_size > 0); } }; namespace detail { template <> struct BaseOf { typedef Object Type; }; }; typedef detail::ObjectSharedPointerTraits ::Type BufferPtr; class SafeBuffer : public SafeObject { friend class Context; friend class BoundBuffer; public: typedef SafeObject BaseType; typedef SafeBuffer ThisType; SafeBuffer(void) : BaseType() { ; } GLsizeiptr size(void) const { return this->object()->size(); } GLenum usage(void) const { return this->object()->usage(); } protected: SafeBuffer(const BufferPtr & buffer) : BaseType(buffer) { ; } const BufferPtr & object(void) const { return static_cast(BaseType::object()); } BufferPtr & object(void) { return static_cast(BaseType::object()); } }; namespace detail { template <> struct BaseOf { typedef SafeObject Type; }; }; namespace detail { template <> struct ObjectBase { typedef Buffer Type; }; }; namespace detail { template <> struct ObjectSafe { typedef SafeBuffer Type; }; }; typedef detail::ObjectSharedPointerTraits ::Type BufferHandle; class BufferBindingParams : public ObjectBindingParams { public: typedef ObjectBindingParams BaseType; typedef BufferBindingParams ThisType; BufferBindingParams(void) : BaseType() { ; } BufferBindingParams(GLenum aTarget, GLenum aUnit) : BaseType(aTarget, aUnit) { ; } }; class BoundBuffer : public BoundObject { friend class Context; public: typedef BoundObject BaseType; typedef BoundBuffer ThisType; BoundBuffer(void) : BaseType() { ; } const BufferHandle & handle(void) const { return static_cast(BaseType::handle()); } BufferHandle & handle(void) { return static_cast(BaseType::handle()); } void setData(const GLsizeiptr size, GLenum usage, const GLvoid * data) { this->object()->setData(this->m_target, this->m_unit, size, usage, data); } void setSubData(GLintptr offset, GLsizeiptr size, const GLvoid * data) { this->object()->setSubData(this->m_target, this->m_unit, offset, size, data); } void getSubData(GLintptr offset, GLsizeiptr size, GLvoid * data) { this->object()->getSubData(this->m_target, this->m_unit, offset, size, data); } void * map(GLenum access) { return this->object()->map(this->m_target, this->m_unit, access); } void unmap(void) { this->object()->unmap(this->m_target, this->m_unit); } GLenum mapAccess(void) const { return this->object()->mapAccess(this->m_target, this->m_unit); } bool isMapped(void) const { return this->object()->isMapped(this->m_target, this->m_unit); } void * mapPointer(void) const { return this->object()->mapPointer(this->m_target, this->m_unit); } protected: BoundBuffer(const BufferHandle & handle, const BufferBindingParams & params) : BaseType(handle, params) { ; } const BufferPtr & object(void) const { return this->handle()->object(); } BufferPtr & object(void) { return this->handle()->object(); } virtual void bind(void) { glBindBuffer(this->m_target, this->object()->name()); } virtual void unbind(void) { glBindBuffer(this->m_target, 0); } }; namespace detail { template <> struct ParamsOf { typedef BufferBindingParams Type; }; }; namespace detail { template <> struct BaseOf { typedef BoundObject Type; }; }; namespace detail { template <> struct ObjectBase { typedef Buffer Type; }; }; namespace detail { template <> struct ObjectBound { typedef BoundBuffer Type; }; }; typedef detail::ObjectSharedPointerTraits ::Type BoundBufferHandle; class VertexBufferBindingParams : public BufferBindingParams { public: typedef BufferBindingParams BaseType; typedef VertexBufferBindingParams ThisType; VertexBufferBindingParams(void) : BaseType(GL_ARRAY_BUFFER, 0) { ; } }; class BoundVertexBuffer : public BoundBuffer { friend class Context; public: typedef BoundBuffer BaseType; typedef BoundVertexBuffer ThisType; BoundVertexBuffer(void) : BaseType() { ; } void vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * offset) { this->object()->vertexAttribPointer(this->m_target, this->m_unit, index, size, type, normalized, stride, offset); } protected: BoundVertexBuffer(const BufferHandle & handle, const VertexBufferBindingParams & params) : BaseType(handle, params) { ; } }; namespace detail { template <> struct ParamsOf { typedef VertexBufferBindingParams Type; }; }; namespace detail { template <> struct BaseOf { typedef BoundBuffer Type; }; }; namespace detail { template <> struct ObjectBase { typedef Buffer Type; }; }; typedef detail::ObjectSharedPointerTraits ::Type BoundVertexBufferHandle; class IndexBufferBindingParams : public BufferBindingParams { public: typedef BufferBindingParams BaseType; typedef IndexBufferBindingParams ThisType; IndexBufferBindingParams(void) : BaseType(GL_ELEMENT_ARRAY_BUFFER, 0) { ; } }; class BoundIndexBuffer : public BoundBuffer { friend class Context; public: typedef BoundBuffer BaseType; typedef BoundIndexBuffer ThisType; BoundIndexBuffer(void) : BaseType() { ; } void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) { this->object()->drawElements(this->m_target, this->m_unit, mode, count, type, indices); } protected: BoundIndexBuffer(const BufferHandle & handle, const IndexBufferBindingParams & params) : BaseType(handle, params) { ; } }; namespace detail { template <> struct ParamsOf { typedef IndexBufferBindingParams Type; }; }; namespace detail { template <> struct BaseOf { typedef BoundBuffer Type; }; }; namespace detail { template <> struct ObjectBase { typedef Buffer Type; }; }; typedef detail::ObjectSharedPointerTraits ::Type BoundIndexBufferHandle; class PixelPackBufferBindingParams : public BufferBindingParams { public: typedef BufferBindingParams BaseType; typedef PixelPackBufferBindingParams ThisType; PixelPackBufferBindingParams(void) : BaseType(GL_PIXEL_PACK_BUFFER, 0) { ; } }; class BoundPixelPackBuffer : public BoundBuffer { friend class Context; public: typedef BoundBuffer BaseType; typedef BoundPixelPackBuffer ThisType; BoundPixelPackBuffer(void) : BaseType() { ; } protected: BoundPixelPackBuffer(const BufferHandle & handle, const PixelPackBufferBindingParams & params) : BaseType(handle, params) { ; } }; namespace detail { template <> struct ParamsOf { typedef PixelPackBufferBindingParams Type; }; }; namespace detail { template <> struct BaseOf { typedef BoundBuffer Type; }; }; namespace detail { template <> struct ObjectBase { typedef Buffer Type; }; }; typedef detail::ObjectSharedPointerTraits ::Type BoundPixelPackBufferHandle; class PixelUnpackBufferBindingParams : public BufferBindingParams { public: typedef BufferBindingParams BaseType; typedef PixelUnpackBufferBindingParams ThisType; PixelUnpackBufferBindingParams(void) : BaseType(GL_PIXEL_UNPACK_BUFFER, 0) { ; } }; class BoundPixelUnpackBuffer : public BoundBuffer { friend class Context; public: typedef BoundBuffer BaseType; typedef BoundPixelUnpackBuffer ThisType; BoundPixelUnpackBuffer(void) : BaseType() { ; } protected: BoundPixelUnpackBuffer(const BufferHandle & handle, const PixelUnpackBufferBindingParams & params) : BaseType(handle, params) { ; } }; namespace detail { template <> struct ParamsOf { typedef PixelUnpackBufferBindingParams Type; }; }; namespace detail { template <> struct BaseOf { typedef BoundBuffer Type; }; }; namespace detail { template <> struct ObjectBase { typedef Buffer Type; }; }; typedef detail::ObjectSharedPointerTraits ::Type BoundPixelUnpackBufferHandle; class UniformBufferBindingParams : public BufferBindingParams { public: typedef BufferBindingParams BaseType; typedef UniformBufferBindingParams ThisType; GLintptr offset; GLsizeiptr size; UniformBufferBindingParams(void) : BaseType (GL_UNIFORM_BUFFER, 0) , offset (0) , size (0) { ; } UniformBufferBindingParams(GLuint aIndex, GLintptr aOffset, GLsizeiptr aSize) : BaseType (GL_UNIFORM_BUFFER, GLint(aIndex)) , offset (aOffset) , size (aSize) { ; } }; class BoundUniformBuffer : public BoundBuffer { friend class Context; public: typedef BoundBuffer BaseType; typedef BoundUniformBuffer ThisType; BoundUniformBuffer(void) : BaseType() { ; } protected: BoundUniformBuffer(const BufferHandle & handle, const UniformBufferBindingParams & params) : BaseType(handle, params) { ; } virtual void bind(void) { glBindBufferRange(this->m_target, GLuint(this->m_unit), this->object()->name(), this->m_offset, this->m_size); } virtual void unbind(void) { glBindBufferRange(this->m_target, GLuint(this->m_unit), 0, 0, 0); } private: GLintptr m_offset; GLsizeiptr m_size; }; namespace detail { template <> struct ParamsOf { typedef UniformBufferBindingParams Type; }; }; namespace detail { template <> struct BaseOf { typedef BoundBuffer Type; }; }; namespace detail { template <> struct ObjectBase { typedef Buffer Type; }; }; typedef detail::ObjectSharedPointerTraits ::Type BoundUniformBufferHandle; class FeedbackBufferBindingParams : public BufferBindingParams { public: typedef BufferBindingParams BaseType; typedef FeedbackBufferBindingParams ThisType; GLintptr offset; GLsizeiptr size; FeedbackBufferBindingParams(void) : BaseType (GL_TRANSFORM_FEEDBACK_BUFFER, 0) , offset (0) , size (0) { ; } FeedbackBufferBindingParams(GLuint aIndex, GLintptr aOffset, GLsizeiptr aSize) : BaseType (GL_TRANSFORM_FEEDBACK_BUFFER, GLint(aIndex)) , offset (aOffset) , size (aSize) { ; } }; class BoundFeedbackBuffer : public BoundBuffer { friend class Context; public: typedef BoundBuffer BaseType; typedef BoundFeedbackBuffer ThisType; BoundFeedbackBuffer(void) : BaseType() { ; } protected: BoundFeedbackBuffer(const BufferHandle & handle, const FeedbackBufferBindingParams & params) : BaseType(handle, params) { ; } virtual void bind(void) { glBindBufferRange(this->m_target, GLuint(this->m_unit), this->object()->name(), this->m_offset, this->m_size); } virtual void unbind(void) { glBindBufferRange(this->m_target, GLuint(this->m_unit), 0, 0, 0); } private: GLintptr m_offset; GLsizeiptr m_size; }; namespace detail { template <> struct ParamsOf { typedef FeedbackBufferBindingParams Type; }; }; namespace detail { template <> struct BaseOf { typedef BoundBuffer Type; }; }; namespace detail { template <> struct ObjectBase { typedef Buffer Type; }; }; typedef detail::ObjectSharedPointerTraits ::Type BoundFeedbackBufferHandle; }; #endif // GLW_BUFFER_H