#pragma once #include "GraphicsTags.hpp" #include "RcPtr.hpp" #include "SmallVector.hpp" #include #include #include #include struct GpuVertexBuffer : public RefCounted { GLuint handle; int sizeInBytes; GpuVertexBuffer(); ~GpuVertexBuffer(); void Upload(const std::byte* data, size_t sizeInBytes); }; struct GpuIndexBuffer : public RefCounted { GLuint handle; Tags::IndexType indexType; int count; GpuIndexBuffer(); ~GpuIndexBuffer(); Tags::IndexType GetIndexType() const { return indexType; } GLenum GetIndexTypeGL() const { return Tags::FindGLType(indexType); } void Upload(const std::byte* data, Tags::IndexType type, size_t count); }; struct BufferBindings { SmallVector, 4> bindings; int GetMaxBindingIndex() const; /// Safe. Returns nullptr if the index is not bound to any buffers. GpuVertexBuffer* GetBinding(int index) const; /// Adds or updates a buffer binding. Setting a binding to nullptr effectively removes the binding. void SetBinding(int index, GpuVertexBuffer* buffer); void Clear(); }; struct VertexElementFormat { /// NOTE: /// "Automatic" means it will be set inside VertexFormat::AddElement() /// "Parameter" means it must be set by the user /* Automatic */ int offset; /* Parameter */ int bindingIndex; /* Parameter */ Tags::VertexElementType type; /* Parameter */ Tags::VertexElementSemantic semantic; int GetStride() const; }; struct VertexFormat : public RefCounted { SmallVector elements; int vertexSize = 0; const decltype(elements)& GetElements() const { return elements; } void AddElement(VertexElementFormat element); void RemoveElement(int index); };