#ifndef BUFFER_H #define BUFFER_H #include "sparrowrenderer.h" #include #include #define BUFFER_OFFSET(i) ((char *)NULL + (i)) class Buffer { public: enum BufferType { VBO, EBO, UBO }; virtual ~Buffer() {} virtual void bind() = 0; virtual void unbind() = 0; }; template class TBuffer : public Buffer { public: class BufferEditor { GLenum m_typeEnum; T *ptr; public: BufferEditor(TBuffer *b) { if(b->isDynamic()) { GLenum m_typeEnum = b->getGLEnum(); glBindBuffer(m_typeEnum, b->getId()); ptr = (T*)glMapBuffer(m_typeEnum, GL_WRITE_ONLY); } else { fprintf(stderr, "Buffer data can't be edited, this buffer is static\n"); ptr = NULL; } } ~BufferEditor() { glUnmapBuffer(m_typeEnum); glBindBuffer(m_typeEnum, 0); } T* getPointer() { return ptr; } }; TBuffer(const std::vector &data, BufferType type, bool isDynamic = false) : m_type(type), m_isDynamic(isDynamic) { // TODO : allow stream draw GLenum draw_type = isDynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; GLenum typeEnum = getGLEnum(); glGenBuffers(1, &m_id); glBindBuffer(typeEnum, m_id); glBufferData(typeEnum, data.size() * sizeof(T), data.data(), draw_type); glBindBuffer(typeEnum, 0); } virtual ~TBuffer() { glDeleteBuffers(1, &m_id); } virtual void setVertexAttrib(int location, int nbComponents, int offset = 0, int instanceDivisor = 0) { if(m_type == VBO) { glBindBuffer(GL_ARRAY_BUFFER, m_id); glEnableVertexAttribArray(location); if(instanceDivisor) glVertexAttribDivisor(location, instanceDivisor); glVertexAttribPointer(location, nbComponents, GL_FLOAT, GL_FALSE, sizeof(T), BUFFER_OFFSET(offset)); glBindBuffer(GL_ARRAY_BUFFER, 0); } } virtual void bind() { glBindBuffer(getGLEnum(), m_id); } virtual void unbind() { glBindBuffer(getGLEnum(), 0); } GLuint getId() {return m_id;} BufferType getType() {return m_type;} bool isDynamic() {return m_isDynamic;} private: GLuint m_id; BufferType m_type; bool m_isDynamic; GLenum getGLEnum() { GLenum typeEnum; switch(m_type) { default: case VBO : typeEnum = GL_ARRAY_BUFFER; break; case EBO : typeEnum = GL_ELEMENT_ARRAY_BUFFER; break; case UBO : typeEnum = GL_UNIFORM_BUFFER; break; } return typeEnum; } }; #endif // BUFFER_H