#pragma once #include #include class FRenderState; #ifdef __ANDROID__ #define HW_MAX_PIPELINE_BUFFERS 4 #define HW_BLOCK_SSBO 1 #else // On desktop this is only useful fpr letting the GPU run in parallel with the playsim and for that 2 buffers are enough. #define HW_MAX_PIPELINE_BUFFERS 2 #endif // The low level code needs to know which attributes exist. // OpenGL needs to change the state of all of them per buffer binding. // VAOs are mostly useless for this because they lump buffer and binding state together which the model code does not want. enum { VATTR_VERTEX, VATTR_TEXCOORD, VATTR_COLOR, VATTR_VERTEX2, VATTR_NORMAL, VATTR_NORMAL2, VATTR_LIGHTMAP, VATTR_BONEWEIGHT, VATTR_BONESELECTOR, VATTR_MAX }; enum EVertexAttributeFormat { VFmt_Float4, VFmt_Float3, VFmt_Float2, VFmt_Float, VFmt_Byte4, VFmt_Packed_A2R10G10B10, VFmt_Byte4_UInt }; struct FVertexBufferAttribute { int binding; int location; int format; int offset; }; enum class BufferUsageType { Static, // initial data is not null, staticdata is true Stream, // initial data is not null, staticdata is false Persistent, // initial data is null, staticdata is false Mappable // initial data is null, staticdata is true }; class IBuffer { protected: size_t buffersize = 0; void *map = nullptr; public: IBuffer() = default; IBuffer(const IBuffer &) = delete; IBuffer &operator=(const IBuffer &) = delete; virtual ~IBuffer() = default; virtual void SetData(size_t size, const void *data, BufferUsageType type) = 0; virtual void SetSubData(size_t offset, size_t size, const void *data) = 0; virtual void *Lock(unsigned int size) = 0; virtual void Unlock() = 0; //virtual void Resize(size_t newsize) = 0; virtual void Upload(size_t start, size_t size) {} // For unmappable buffers virtual void Map() {} // Only needed by old OpenGL but this needs to be in the interface. virtual void Unmap() {} void *Memory() { return map; } size_t Size() { return buffersize; } };