diff options
Diffstat (limited to 'Runtime/Graphics/GPUDataBuffers.h')
-rw-r--r-- | Runtime/Graphics/GPUDataBuffers.h | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/Runtime/Graphics/GPUDataBuffers.h b/Runtime/Graphics/GPUDataBuffers.h new file mode 100644 index 0000000..62e0413 --- /dev/null +++ b/Runtime/Graphics/GPUDataBuffers.h @@ -0,0 +1,160 @@ +#pragma once + +#include <vector> + +#include "Runtime/Lua/LuaHelper.h" +#include "../Utilities/Type.h" +#include "../Utilities/Singleton.h" +#include "../Utilities/UtilMacros.h" +#include "../Utilities/Assert.h" +#include "OpenGL.h" + +template<typename T> +// GPU侧的通用缓冲区,最底层的实现 +class GPUDataBuffer +{ +public: + GPUDataBuffer(GLenum target, GLenum usage)/*throw GLException*/ + : m_Target(target) + , m_Usage(usage) + { + glGenBuffers(1, &m_Handle); + + CheckGLError( + glDeleteBuffers(1, &m_Handle); + throw GLException(error); + ); + } + virtual ~GPUDataBuffer() + { + glDeleteBuffers(1, &m_Handle); + } + + // 提交\更新缓冲区数据 + void Upload(int offset, int size, const T* data) + { + glBindBuffer(m_Target, m_Handle); + glBufferSubData(m_Target, offset, size, data); + glBindBuffer(m_Target, 0); + } + + // 更新缓冲区数据(性能优于Upload) + T* Map(uint32 access) + { + glBindBuffer(m_Target, m_Handle); + void* ptr = glMapBuffer(m_Target, access); + glBindBuffer(m_Target, 0); + return ptr; + } + T* MapRange(int offset, int size, uint32 access) // 性能最佳 + { + glBindBuffer(m_Target, m_Handle); + void* ptr = glMapBufferRange(m_Target, offset, size, access); + glBindBuffer(m_Target, 0); + return ptr; + } + void FlushMapedRange(int offset, int size) + { + glBindBuffer(m_Target, m_Handle); + glFlushMappedBufferRange(m_Target, offset, size); + glBindBuffer(m_Target, 0); + } + void UnMap() + { + glBindBuffer(m_Target, m_Handle); + glUnmapBuffer(m_Target); + glBindBuffer(m_Target, 0); + } + + // 重置缓冲区 + void Restore(int size, GLenum usage) + { + RestoreWithData(size, usage, 0); + } + void RestoreWithData(int size, GLenum usage, const T* data) + { + glBindBuffer(m_Target, m_Handle); + glBufferData(m_Target, size, data, usage); + glBindBuffer(m_Target, 0); + m_Size = size; + m_Usage = usage; + } + + void Orphan() + { + glBindBuffer(m_Target, m_Handle); + glBufferData(m_Target, 0, 0, GL_STREAM_DRAW); + glBindBuffer(m_Target, 0); + } + + int GetComponentSize() + { + return sizeof(T); + } + + GET(int, Size, m_Size); + GET(GLenum, Usage, m_Usage); + GET(GLuint, Handle, m_Handle); + +protected: + GLuint m_Handle; + + GLenum m_Target; + GLenum m_Usage; + + int m_Size; + +}; + +struct VertexAttributeDescriptor +{ + int index; // attribute layout index //glBindAttribLocation + int numOfComponents; // 1,2,3,4 + int stride; +}; + +struct VertexDataLayout +{ + std::vector<VertexAttributeDescriptor> attributes; +}; + +class DynamicVBO; +//顶点数据流 +class VBO : public GPUDataBuffer<float> +{ +public: + VBO(); + virtual ~VBO(); + + void AddVertexAttribute(int index, int numOfComps, int stride); + void AddVertexAttribute(VertexAttributeDescriptor& attribute); + int GetVertexAttributesCount(); + void ClearVertexAttribute(); + + static const GLenum componentType = GL_FLOAT; + +protected: + friend class DynamicVBO; + VBO(GLenum usage); + + VertexDataLayout m_Layout; + +}; + +// 频繁读写的共享vbo +class DynamicVBO : public VBO +{ +public: + DynamicVBO(); + ~DynamicVBO(); + +}; + +// 索引数据流 +class IBO : GPUDataBuffer<UInt16> +{ +public: + static const GLenum componentType = GL_UNSIGNED_SHORT; + + +};
\ No newline at end of file |