#pragma once #include #include #include #include #include #include #include #include namespace mbgl { class ProgramParameters; namespace gfx { class Context { protected: Context(ContextType type_, uint32_t maximumVertexBindingCount_) : backend(type_), maximumVertexBindingCount(maximumVertexBindingCount_) { } public: const ContextType backend; static constexpr const uint32_t minimumRequiredVertexBindingCount = 8; const uint32_t maximumVertexBindingCount; public: Context(Context&&) = delete; Context(const Context&) = delete; Context& operator=(Context&& other) = delete; Context& operator=(const Context& other) = delete; virtual ~Context() = default; public: template VertexBuffer createVertexBuffer(VertexVector&& v, const BufferUsageType usage = BufferUsageType::StaticDraw) { return { v.elements(), createVertexBufferResource(v.data(), v.bytes(), usage) }; } template void updateVertexBuffer(VertexBuffer& buffer, VertexVector&& v) { assert(v.elements() == buffer.elements); updateVertexBufferResource(*buffer.resource, v.data(), v.bytes()); } template IndexBuffer createIndexBuffer(IndexVector&& v, const BufferUsageType usage = BufferUsageType::StaticDraw) { return { v.elements(), createIndexBufferResource(v.data(), v.bytes(), usage) }; } template void updateIndexBuffer(IndexBuffer& buffer, IndexVector&& v) { assert(v.elements() == buffer.elements); updateIndexBufferResource(*buffer.resource, v.data(), v.bytes()); } protected: virtual std::unique_ptr createVertexBufferResource(const void* data, std::size_t size, const BufferUsageType) = 0; virtual void updateVertexBufferResource(const VertexBufferResource&, const void* data, std::size_t size) = 0; virtual std::unique_ptr createIndexBufferResource(const void* data, std::size_t size, const BufferUsageType) = 0; virtual void updateIndexBufferResource(const IndexBufferResource&, const void* data, std::size_t size) = 0; public: // Create a texture from an image with data. template Texture createTexture(const Image& image, TextureChannelDataType type = TextureChannelDataType::UnsignedByte) { auto format = image.channels == 4 ? TexturePixelType::RGBA : TexturePixelType::Alpha; return { image.size, createTextureResource(image.size, image.data.get(), format, type) }; } // Creates an empty texture with the specified dimensions. Texture createTexture(const Size size, TexturePixelType format = TexturePixelType::RGBA, TextureChannelDataType type = TextureChannelDataType::UnsignedByte) { return { size, createTextureResource(size, nullptr, format, type) }; } template void updateTexture(Texture& texture, const Image& image, TextureChannelDataType type = TextureChannelDataType::UnsignedByte) { auto format = image.channels == 4 ? TexturePixelType::RGBA : TexturePixelType::Alpha; updateTextureResource(*texture.resource, image.size, image.data.get(), format, type); texture.size = image.size; } protected: virtual std::unique_ptr createTextureResource( Size, const void* data, TexturePixelType, TextureChannelDataType) = 0; virtual void updateTextureResource(const TextureResource&, Size, const void* data, TexturePixelType, TextureChannelDataType) = 0; public: DrawScope createDrawScope() { return { createDrawScopeResource() }; } protected: virtual std::unique_ptr createDrawScopeResource() = 0; public: template std::unique_ptr> createProgram(const ProgramParameters&); private: template std::unique_ptr> createProgram(const ProgramParameters&); }; } // namespace gfx } // namespace mbgl