diff --git a/build/config.lua b/build/config.lua index 8370331c7..8ecc7c24e 100644 --- a/build/config.lua +++ b/build/config.lua @@ -7,6 +7,9 @@ BuildDependencies = true -- Builds Nazara examples BuildExamples = true +-- Setup configurations array (valid values: Debug, Release, ReleaseWithDebug) +Configurations = "Debug,Release" -- "Debug,Release,ReleaseWithDebug" + -- Setup additionnals install directories, separated by a semi-colon ; (library binaries will be copied there) --InstallDir = "/usr/local/lib64" diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 01b51562d..e3ea13d62 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -104,7 +104,7 @@ function NazaraBuild:Execute() filter({}) end end - + -- Start defining projects workspace("NazaraEngine") platforms(platformData) @@ -114,12 +114,17 @@ function NazaraBuild:Execute() -- Add lib/conf/arch to library search path self:FilterLibDirectory("../lib/", libdirs) - configurations({ - -- "DebugStatic", - -- "ReleaseStatic", - "DebugDynamic", - "ReleaseDynamic" - }) + do + local linkTypes = {"Dynamic"} -- {"Static", "Dynamic"} + local configs = {} + for k,linkType in pairs(linkTypes) do + for k,config in pairs(self.Config["Configurations"]) do + table.insert(configs, config .. linkType) + end + end + + configurations(configs) + end language("C++") location(_ACTION) @@ -169,7 +174,7 @@ function NazaraBuild:Execute() for k,v in pairs(moduleTable.ConfigurationLibraries) do filter(k) - links(v) + links(v) end filter({}) @@ -236,7 +241,7 @@ function NazaraBuild:Execute() for k,v in pairs(toolTable.ConfigurationLibraries) do filter(k) - links(v) + links(v) end filter({}) @@ -282,7 +287,7 @@ function NazaraBuild:Execute() for k,v in pairs(exampleTable.ConfigurationLibraries) do filter(k) - links(v) + links(v) end filter({}) @@ -505,21 +510,56 @@ function NazaraBuild:LoadConfig() AddBoolOption("ServerMode", "server", "Excludes client-only modules/tools/examples") AddBoolOption("UniteModules", "united", "Builds all the modules as one united library") - -- InstallDir - newoption({ - trigger = "install-path", - description = "Setup additionnals install directories (library binaries will be copied there)" - }) + -- Configurations + do + newoption({ + trigger = "configurations", + description = "Override configurations target by a new set, separated by commas." + }) - self.Config["InstallDir"] = self.Config["InstallDir"] or "" - if (_OPTIONS["install-path"] ~= nil) then - self.Config["InstallDir"] = self.Config["InstallDir"] .. ";" .. _OPTIONS["install-path"] + configTable["Configurations"] = configTable["Configurations"] or "" + if (_OPTIONS["configurations"] ~= nil) then + configTable["Configurations"] = _OPTIONS["configurations"] + end + + local configs = {} + local validConfigs = {"Debug", "Release", "ReleaseWithDebug"} + local paths = string.explode(configTable["Configurations"], ",") + for k,v in pairs(paths) do + v = v:match("^%s*(.-)%s*$") -- Trim + if (#v > 0) then + if (table.contains(validConfigs, v)) then + table.insert(configs, v) + else + error("Invalid entry for configurations option: \"" .. v .. "\"") + end + end + end + + if (#configs == 0) then + error("Invalid entry for configurations option: no option") + end + + configTable["Configurations"] = configs end - local paths = string.explode(self.Config["InstallDir"], ";") - for k,v in pairs(paths) do - if (#v > 0) then - self:AddInstallPath(v) + -- InstallDir + do + newoption({ + trigger = "install-path", + description = "Setup additionnals install directories (library binaries will be copied there), separated by commas" + }) + + configTable["InstallDir"] = configTable["InstallDir"] or "" + if (_OPTIONS["install-path"] ~= nil) then + configTable["InstallDir"] = configTable["InstallDir"] .. ";" .. _OPTIONS["install-path"] + end + + local paths = string.explode(configTable["InstallDir"], ";") + for k,v in pairs(paths) do + if (#v > 0) then + self:AddInstallPath(v) + end end end end @@ -598,16 +638,20 @@ function NazaraBuild:Process(infoTable) if (not self.Config["UniteModules"] or infoTable.Type ~= "Module") then table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s") + table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugStatic, library .. "-s") table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-d") table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library) + table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugDynamic, library) end elseif (libraryTable.Type == "ExternLib") then library = libraryTable.Name table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s") + table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugStatic, library .. "-s") table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-s-d") table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library .. "-s") + table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugDynamic, library .. "-s") elseif (libraryTable.Type == "Tool") then library = "Nazara" .. libraryTable.Name @@ -629,8 +673,10 @@ function NazaraBuild:Process(infoTable) table.insert(infoTable.ConfigurationLibraries.DebugStatic, library .. "-s-d") table.insert(infoTable.ConfigurationLibraries.ReleaseStatic, library .. "-s") + table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugStatic, library .. "-s") table.insert(infoTable.ConfigurationLibraries.DebugDynamic, library .. "-d") table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library) + table.insert(infoTable.ConfigurationLibraries.ReleaseWithDebugDynamic, library) else infoTable.Excluded = true infoTable.ExcludeReason = "dependency " .. library .. " has invalid type \"" .. libraryTable.Type .. "\"" @@ -723,12 +769,14 @@ function NazaraBuild:PrepareGeneric() filter({"kind:*Lib", "configurations:DebugDynamic"}) targetsuffix("-d") - filter("configurations:Debug*") + filter("configurations:*Debug*") symbols("On") + filter("configurations:not *Debug*") + flags("NoFramePointer") + -- Setup some optimizations for release filter("configurations:Release*") - flags("NoFramePointer") optimize("Speed") vectorextensions("SSE2") @@ -950,8 +998,10 @@ function NazaraBuild:SetupInfoTable(infoTable) infoTable.ConfigurationLibraries = {} infoTable.ConfigurationLibraries.DebugStatic = {} infoTable.ConfigurationLibraries.ReleaseStatic = {} + infoTable.ConfigurationLibraries.ReleaseWithDebugStatic = {} infoTable.ConfigurationLibraries.DebugDynamic = {} infoTable.ConfigurationLibraries.ReleaseDynamic = {} + infoTable.ConfigurationLibraries.ReleaseWithDebugDynamic = {} infoTable.Excludable = true infoTable.LibraryPaths = {} infoTable.LibraryPaths.x86 = {} diff --git a/include/Nazara/Utility/AbstractBuffer.hpp b/include/Nazara/Utility/AbstractBuffer.hpp index dd214c70f..ff264d6b9 100644 --- a/include/Nazara/Utility/AbstractBuffer.hpp +++ b/include/Nazara/Utility/AbstractBuffer.hpp @@ -7,7 +7,8 @@ #ifndef NAZARA_ABSTRACTBUFFER_HPP #define NAZARA_ABSTRACTBUFFER_HPP -#include +#include +#include namespace Nz { @@ -17,14 +18,13 @@ namespace Nz AbstractBuffer() = default; virtual ~AbstractBuffer(); - virtual bool Create(unsigned int size, BufferUsage usage = BufferUsage_Static) = 0; - virtual void Destroy() = 0; + virtual bool Fill(const void* data, UInt32 offset, UInt32 size) = 0; - virtual bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false) = 0; + virtual bool Initialize(UInt32 size, BufferUsageFlags usage) = 0; - virtual bool IsHardware() const = 0; + virtual DataStorage GetStorage() const = 0; - virtual void* Map(BufferAccess access, unsigned int offset = 0, unsigned int size = 0) = 0; + virtual void* Map(BufferAccess access, UInt32 offset = 0, UInt32 size = 0) = 0; virtual bool Unmap() = 0; }; } diff --git a/include/Nazara/Utility/Buffer.hpp b/include/Nazara/Utility/Buffer.hpp index 5ee866ae2..3655de53c 100644 --- a/include/Nazara/Utility/Buffer.hpp +++ b/include/Nazara/Utility/Buffer.hpp @@ -11,8 +11,10 @@ #include #include #include +#include #include #include +#include namespace Nz { @@ -21,8 +23,6 @@ namespace Nz using BufferConstRef = ObjectRef; using BufferRef = ObjectRef; - class AbstractBuffer; - class NAZARA_UTILITY_API Buffer : public RefCounted { friend class Utility; @@ -31,40 +31,41 @@ namespace Nz using BufferFactory = AbstractBuffer* (*)(Buffer* parent, BufferType type); Buffer(BufferType type); - Buffer(BufferType type, unsigned int size, UInt32 storage = DataStorage_Software, BufferUsage usage = BufferUsage_Static); + Buffer(BufferType type, UInt32 size, DataStorage storage = DataStorage_Software, BufferUsageFlags usage = 0); Buffer(const Buffer&) = delete; - Buffer(Buffer&&) = delete; + Buffer(Buffer&&) = default; ~Buffer(); - bool CopyContent(const Buffer& buffer); + bool CopyContent(const BufferRef& buffer); - bool Create(unsigned int size, UInt32 storage = DataStorage_Software, BufferUsage usage = BufferUsage_Static); + bool Create(UInt32 size, DataStorage storage = DataStorage_Software, BufferUsageFlags usage = 0); void Destroy(); - bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false); + bool Fill(const void* data, UInt32 offset, UInt32 size); - AbstractBuffer* GetImpl() const; - unsigned int GetSize() const; - UInt32 GetStorage() const; - BufferType GetType() const; - BufferUsage GetUsage() const; + inline AbstractBuffer* GetImpl() const; + inline UInt32 GetSize() const; + inline DataStorage GetStorage() const; + inline BufferType GetType() const; + inline BufferUsageFlags GetUsage() const; - bool IsHardware() const; - bool IsValid() const; + inline bool HasStorage(DataStorage storage) const; - void* Map(BufferAccess access, unsigned int offset = 0, unsigned int size = 0); - void* Map(BufferAccess access, unsigned int offset = 0, unsigned int size = 0) const; + inline bool IsValid() const; - bool SetStorage(UInt32 storage); + void* Map(BufferAccess access, UInt32 offset = 0, UInt32 size = 0); + void* Map(BufferAccess access, UInt32 offset = 0, UInt32 size = 0) const; + + bool SetStorage(DataStorage storage); void Unmap() const; Buffer& operator=(const Buffer&) = delete; - Buffer& operator=(Buffer&&) = delete; + Buffer& operator=(Buffer&&) = default; - static bool IsStorageSupported(UInt32 storage); + static bool IsStorageSupported(DataStorage storage); template static BufferRef New(Args&&... args); - static void SetBufferFactory(UInt32 storage, BufferFactory func); + static void SetBufferFactory(DataStorage storage, BufferFactory func); // Signals: NazaraSignal(OnBufferDestroy, const Buffer* /*buffer*/); @@ -74,13 +75,12 @@ namespace Nz static bool Initialize(); static void Uninitialize(); + std::unique_ptr m_impl; BufferType m_type; - BufferUsage m_usage; - UInt32 m_storage; - AbstractBuffer* m_impl; - unsigned int m_size; + BufferUsageFlags m_usage; + UInt32 m_size; - static BufferFactory s_bufferFactories[DataStorage_Max+1]; + static std::array s_bufferFactories; }; } diff --git a/include/Nazara/Utility/Buffer.inl b/include/Nazara/Utility/Buffer.inl index 8703fd82c..df54a3987 100644 --- a/include/Nazara/Utility/Buffer.inl +++ b/include/Nazara/Utility/Buffer.inl @@ -7,6 +7,41 @@ namespace Nz { + inline AbstractBuffer* Buffer::GetImpl() const + { + return m_impl.get(); + } + + inline UInt32 Buffer::GetSize() const + { + return m_size; + } + + inline DataStorage Buffer::GetStorage() const + { + return m_impl->GetStorage(); + } + + inline BufferType Buffer::GetType() const + { + return m_type; + } + + inline BufferUsageFlags Buffer::GetUsage() const + { + return m_usage; + } + + inline bool Buffer::HasStorage(DataStorage storage) const + { + return GetStorage() == storage; + } + + inline bool Buffer::IsValid() const + { + return m_impl != nullptr; + } + template BufferRef Buffer::New(Args&&... args) { diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index 2c162cd7d..4edce5fef 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -56,11 +56,19 @@ namespace Nz enum BufferUsage { BufferUsage_Dynamic, - BufferUsage_Static, + BufferUsage_FastRead, - BufferUsage_Max = BufferUsage_Static + BufferUsage_Max = BufferUsage_FastRead }; + template<> + struct EnableFlagsOperators + { + static constexpr bool value = true; + }; + + using BufferUsageFlags = Flags; + enum ComponentType { ComponentType_Color, @@ -95,14 +103,12 @@ namespace Nz CubemapFace_Max = CubemapFace_NegativeZ }; - enum DataStorageFlags + enum DataStorage { - DataStorage_Hardware = 0x1, - DataStorage_Software = 0x2, + DataStorage_Hardware, + DataStorage_Software, - DataStorage_Both = DataStorage_Hardware | DataStorage_Software, - - DataStorage_Max = DataStorage_Software*2-1 + DataStorage_Max = DataStorage_Software }; enum FaceFilling diff --git a/include/Nazara/Utility/IndexBuffer.hpp b/include/Nazara/Utility/IndexBuffer.hpp index 601e705c9..75010bdc0 100644 --- a/include/Nazara/Utility/IndexBuffer.hpp +++ b/include/Nazara/Utility/IndexBuffer.hpp @@ -23,46 +23,46 @@ namespace Nz { public: IndexBuffer() = default; - IndexBuffer(bool largeIndices, Buffer* buffer); - IndexBuffer(bool largeIndices, Buffer* buffer, unsigned int startOffset, unsigned int endOffset); - IndexBuffer(bool largeIndices, unsigned int length, UInt32 storage = DataStorage_Software, BufferUsage usage = BufferUsage_Static); + IndexBuffer(bool largeIndices, BufferRef buffer); + IndexBuffer(bool largeIndices, BufferRef buffer, UInt32 offset, UInt32 size); + IndexBuffer(bool largeIndices, UInt32 length, DataStorage storage, BufferUsageFlags usage); IndexBuffer(const IndexBuffer& indexBuffer); + IndexBuffer(IndexBuffer&&) = delete; ~IndexBuffer(); unsigned int ComputeCacheMissCount() const; - bool Fill(const void* data, unsigned int startIndex, unsigned int length, bool forceDiscard = false); - bool FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false); + bool Fill(const void* data, UInt32 startIndex, UInt32 length); + bool FillRaw(const void* data, UInt32 offset, UInt32 size); - Buffer* GetBuffer() const; - unsigned int GetEndOffset() const; - unsigned int GetIndexCount() const; - unsigned int GetStride() const; - unsigned int GetStartOffset() const; + inline const BufferRef& GetBuffer() const; + inline UInt32 GetEndOffset() const; + inline UInt32 GetIndexCount() const; + inline DataStorage GetStorage() const; + inline UInt32 GetStride() const; + inline UInt32 GetStartOffset() const; - bool HasLargeIndices() const; + inline bool HasLargeIndices() const; - bool IsHardware() const; - bool IsValid() const; + inline bool IsValid() const; - void* Map(BufferAccess access, unsigned int startVertex = 0, unsigned int length = 0); - void* Map(BufferAccess access, unsigned int startVertex = 0, unsigned int length = 0) const; - void* MapRaw(BufferAccess access, unsigned int offset = 0, unsigned int size = 0); - void* MapRaw(BufferAccess access, unsigned int offset = 0, unsigned int size = 0) const; + inline void* Map(BufferAccess access, UInt32 startVertex = 0, UInt32 length = 0); + inline void* Map(BufferAccess access, UInt32 startVertex = 0, UInt32 length = 0) const; + void* MapRaw(BufferAccess access, UInt32 offset = 0, UInt32 size = 0); + void* MapRaw(BufferAccess access, UInt32 offset = 0, UInt32 size = 0) const; void Optimize(); void Reset(); - void Reset(bool largeIndices, Buffer* buffer); - void Reset(bool largeIndices, Buffer* buffer, unsigned int startOffset, unsigned int endOffset); - void Reset(bool largeIndices, unsigned int length, UInt32 storage = DataStorage_Software, BufferUsage usage = BufferUsage_Static); + void Reset(bool largeIndices, BufferRef buffer); + void Reset(bool largeIndices, BufferRef buffer, UInt32 offset, UInt32 size); + void Reset(bool largeIndices, UInt32 length, DataStorage storage, BufferUsageFlags usage); void Reset(const IndexBuffer& indexBuffer); - bool SetStorage(UInt32 storage); - void Unmap() const; IndexBuffer& operator=(const IndexBuffer& indexBuffer); + IndexBuffer& operator=(IndexBuffer&&) = delete; template static IndexBufferRef New(Args&&... args); @@ -71,10 +71,10 @@ namespace Nz private: BufferRef m_buffer; + UInt32 m_endOffset; + UInt32 m_indexCount; + UInt32 m_startOffset; bool m_largeIndices; - unsigned int m_endOffset; - unsigned int m_indexCount; - unsigned int m_startOffset; }; } diff --git a/include/Nazara/Utility/IndexBuffer.inl b/include/Nazara/Utility/IndexBuffer.inl index 1c1d16a18..f598c5291 100644 --- a/include/Nazara/Utility/IndexBuffer.inl +++ b/include/Nazara/Utility/IndexBuffer.inl @@ -2,11 +2,64 @@ // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include #include namespace Nz { + inline const BufferRef& IndexBuffer::GetBuffer() const + { + return m_buffer; + } + + inline UInt32 IndexBuffer::GetEndOffset() const + { + return m_endOffset; + } + + inline UInt32 IndexBuffer::GetIndexCount() const + { + return m_indexCount; + } + + inline DataStorage IndexBuffer::GetStorage() const + { + return DataStorage(); + } + + inline UInt32 IndexBuffer::GetStride() const + { + return static_cast((m_largeIndices) ? sizeof(UInt32) : sizeof(UInt16)); + } + + inline UInt32 IndexBuffer::GetStartOffset() const + { + return m_startOffset; + } + + inline bool IndexBuffer::HasLargeIndices() const + { + return m_largeIndices; + } + + inline bool IndexBuffer::IsValid() const + { + return m_buffer; + } + + inline void* IndexBuffer::Map(BufferAccess access, UInt32 startIndex, UInt32 length) + { + UInt32 stride = GetStride(); + return MapRaw(access, startIndex*stride, length*stride); + } + + inline void* IndexBuffer::Map(BufferAccess access, UInt32 startIndex, UInt32 length) const + { + UInt32 stride = GetStride(); + return MapRaw(access, startIndex*stride, length*stride); + } + template IndexBufferRef IndexBuffer::New(Args&&... args) { diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 38067ce81..8cbbaf70b 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -30,13 +30,13 @@ namespace Nz { MeshParams(); - Matrix4f matrix = Matrix4f::Identity(); ///< A matrix which will transform every vertex position - UInt32 storage = DataStorage_Hardware; ///< The place where the buffers will be allocated - Vector2f texCoordOffset = {0.f, 0.f}; ///< Offset to apply on the texture coordinates (not scaled) - Vector2f texCoordScale = {1.f, 1.f}; ///< Scale to apply on the texture coordinates - bool animated = true; ///< If true, will load an animated version of the model if possible - bool center = false; ///< If true, will center the mesh vertices around the origin - bool optimizeIndexBuffers = true; ///< Optimize the index buffers after loading, improve cache locality (and thus rendering speed) but increase loading time. + Matrix4f matrix = Matrix4f::Identity(); ///< A matrix which will transform every vertex position + DataStorage storage = DataStorage_Hardware; ///< The place where the buffers will be allocated + Vector2f texCoordOffset = {0.f, 0.f}; ///< Offset to apply on the texture coordinates (not scaled) + Vector2f texCoordScale = {1.f, 1.f}; ///< Scale to apply on the texture coordinates + bool animated = true; ///< If true, will load an animated version of the model if possible + bool center = false; ///< If true, will center the mesh vertices around the origin + bool optimizeIndexBuffers = true; ///< Optimize the index buffers after loading, improve cache locality (and thus rendering speed) but increase loading time. bool IsValid() const; }; diff --git a/include/Nazara/Utility/VertexBuffer.hpp b/include/Nazara/Utility/VertexBuffer.hpp index 270d6be9b..12614355e 100644 --- a/include/Nazara/Utility/VertexBuffer.hpp +++ b/include/Nazara/Utility/VertexBuffer.hpp @@ -25,42 +25,42 @@ namespace Nz { public: VertexBuffer() = default; - VertexBuffer(const VertexDeclaration* vertexDeclaration, Buffer* buffer); - VertexBuffer(const VertexDeclaration* vertexDeclaration, Buffer* buffer, unsigned int startOffset, unsigned int endOffset); - VertexBuffer(const VertexDeclaration* vertexDeclaration, unsigned int length, UInt32 storage = DataStorage_Software, BufferUsage usage = BufferUsage_Static); + VertexBuffer(VertexDeclarationConstRef vertexDeclaration, BufferRef buffer); + VertexBuffer(VertexDeclarationConstRef vertexDeclaration, BufferRef buffer, UInt32 offset, UInt32 size); + VertexBuffer(VertexDeclarationConstRef vertexDeclaration, UInt32 length, DataStorage storage, BufferUsageFlags usage); VertexBuffer(const VertexBuffer& vertexBuffer); + VertexBuffer(VertexBuffer&&) = delete; ~VertexBuffer(); - bool Fill(const void* data, unsigned int startVertex, unsigned int length, bool forceDiscard = false); - bool FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false); + bool Fill(const void* data, UInt32 startVertex, UInt32 length); + bool FillRaw(const void* data, UInt32 offset, UInt32 size); - Buffer* GetBuffer() const; - unsigned int GetEndOffset() const; - unsigned int GetStartOffset() const; - unsigned int GetStride() const; - unsigned int GetVertexCount() const; - const VertexDeclaration* GetVertexDeclaration() const; + inline const BufferRef& GetBuffer() const; + inline UInt32 GetEndOffset() const; + inline UInt32 GetStartOffset() const; + inline UInt32 GetStride() const; + inline UInt32 GetVertexCount() const; + inline const VertexDeclarationConstRef& GetVertexDeclaration() const; - bool IsHardware() const; - bool IsValid() const; + inline bool IsValid() const; - void* Map(BufferAccess access, unsigned int startVertex = 0, unsigned int length = 0); - void* Map(BufferAccess access, unsigned int startVertex = 0, unsigned int length = 0) const; - void* MapRaw(BufferAccess access, unsigned int offset = 0, unsigned int size = 0); - void* MapRaw(BufferAccess access, unsigned int offset = 0, unsigned int size = 0) const; + void* Map(BufferAccess access, UInt32 startVertex = 0, UInt32 length = 0); + void* Map(BufferAccess access, UInt32 startVertex = 0, UInt32 length = 0) const; + void* MapRaw(BufferAccess access, UInt32 offset = 0, UInt32 size = 0); + void* MapRaw(BufferAccess access, UInt32 offset = 0, UInt32 size = 0) const; void Reset(); - void Reset(const VertexDeclaration* vertexDeclaration, Buffer* buffer); - void Reset(const VertexDeclaration* vertexDeclaration, Buffer* buffer, unsigned int startOffset, unsigned int endOffset); - void Reset(const VertexDeclaration* vertexDeclaration, unsigned int length, UInt32 storage = DataStorage_Software, BufferUsage usage = BufferUsage_Static); + void Reset(VertexDeclarationConstRef vertexDeclaration, BufferRef buffer); + void Reset(VertexDeclarationConstRef vertexDeclaration, BufferRef buffer, UInt32 offset, UInt32 size); + void Reset(VertexDeclarationConstRef vertexDeclaration, UInt32 length, DataStorage storage, BufferUsageFlags usage); void Reset(const VertexBuffer& vertexBuffer); - bool SetStorage(UInt32 storage); - void SetVertexDeclaration(const VertexDeclaration* vertexDeclaration); + void SetVertexDeclaration(VertexDeclarationConstRef vertexDeclaration); void Unmap() const; VertexBuffer& operator=(const VertexBuffer& vertexBuffer); + VertexBuffer& operator=(VertexBuffer&&) = delete; template static VertexBufferRef New(Args&&... args); @@ -69,10 +69,10 @@ namespace Nz private: BufferRef m_buffer; + UInt32 m_endOffset; + UInt32 m_startOffset; + UInt32 m_vertexCount; VertexDeclarationConstRef m_vertexDeclaration; - unsigned int m_endOffset; - unsigned int m_startOffset; - unsigned int m_vertexCount; }; } diff --git a/include/Nazara/Utility/VertexBuffer.inl b/include/Nazara/Utility/VertexBuffer.inl index 24268e9cb..45dc75ea7 100644 --- a/include/Nazara/Utility/VertexBuffer.inl +++ b/include/Nazara/Utility/VertexBuffer.inl @@ -7,6 +7,41 @@ namespace Nz { + inline const BufferRef& VertexBuffer::GetBuffer() const + { + return m_buffer; + } + + inline UInt32 VertexBuffer::GetEndOffset() const + { + return m_endOffset; + } + + inline UInt32 VertexBuffer::GetStride() const + { + return static_cast(m_vertexDeclaration->GetStride()); + } + + inline UInt32 VertexBuffer::GetStartOffset() const + { + return m_startOffset; + } + + inline UInt32 VertexBuffer::GetVertexCount() const + { + return m_vertexCount; + } + + inline const VertexDeclarationConstRef& VertexBuffer::GetVertexDeclaration() const + { + return m_vertexDeclaration; + } + + inline bool VertexBuffer::IsValid() const + { + return m_buffer && m_vertexDeclaration; + } + template VertexBufferRef VertexBuffer::New(Args&&... args) { diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index e95bf250b..c6c6c59ed 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -169,7 +169,7 @@ namespace Nz instanceCount -= renderedInstanceCount; // We fill the instancing buffer with our world matrices - instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); + instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount); instanceMatrices += renderedInstanceCount; // And we show diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index 60d344fb7..542b180a7 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -141,7 +141,7 @@ namespace Nz { ErrorFlags flags(ErrorFlag_ThrowException, true); - s_quadIndexBuffer.Reset(false, s_maxQuads * 6, DataStorage_Hardware, BufferUsage_Static); + s_quadIndexBuffer.Reset(false, s_maxQuads * 6, DataStorage_Hardware, 0); BufferMapper mapper(s_quadIndexBuffer, BufferAccess_WriteOnly); UInt16* indices = static_cast(mapper.GetPointer()); @@ -161,7 +161,7 @@ namespace Nz // Quad buffer (utilisé pour l'instancing de billboard et de sprites) //Note: Les UV sont calculés dans le shader - s_quadVertexBuffer.Reset(VertexDeclaration::Get(VertexLayout_XY), 4, DataStorage_Hardware, BufferUsage_Static); + s_quadVertexBuffer.Reset(VertexDeclaration::Get(VertexLayout_XY), 4, DataStorage_Hardware, 0); float vertices[2 * 4] = { -0.5f, -0.5f, @@ -202,7 +202,7 @@ namespace Nz s_quadIndexBuffer.Reset(); s_quadVertexBuffer.Reset(); } - + /*! * \brief Draws basic sprites * @@ -327,7 +327,7 @@ namespace Nz * \param sceneData Data of the scene * \param layer Layer of the rendering */ - + void DepthRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -386,7 +386,7 @@ namespace Nz std::size_t renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); billboardCount -= renderedBillboardCount; - instanceBuffer->Fill(data, 0, renderedBillboardCount, true); + instanceBuffer->Fill(data, 0, renderedBillboardCount); data += renderedBillboardCount; Renderer::DrawPrimitivesInstanced(renderedBillboardCount, PrimitiveMode_TriangleStrip, 0, 4); @@ -498,7 +498,7 @@ namespace Nz * \param sceneData Data of the scene * \param layer Layer of the rendering */ - + void DepthRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -594,7 +594,7 @@ namespace Nz instanceCount -= renderedInstanceCount; // We fill the instancing buffer with our world matrices - instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); + instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount); instanceMatrices += renderedInstanceCount; // And we draw @@ -665,4 +665,4 @@ namespace Nz VertexBuffer DepthRenderTechnique::s_quadVertexBuffer; VertexDeclaration DepthRenderTechnique::s_billboardInstanceDeclaration; VertexDeclaration DepthRenderTechnique::s_billboardVertexDeclaration; -} \ No newline at end of file +} diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 76541c982..22961b157 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -171,7 +171,7 @@ namespace Nz { ErrorFlags flags(ErrorFlag_ThrowException, true); - s_quadIndexBuffer.Reset(false, s_maxQuads * 6, DataStorage_Hardware, BufferUsage_Static); + s_quadIndexBuffer.Reset(false, s_maxQuads * 6, DataStorage_Hardware, 0); BufferMapper mapper(s_quadIndexBuffer, BufferAccess_WriteOnly); UInt16* indices = static_cast(mapper.GetPointer()); @@ -191,7 +191,7 @@ namespace Nz // Quad buffer (used for instancing of billboards and sprites) //Note: UV are computed in the shader - s_quadVertexBuffer.Reset(VertexDeclaration::Get(VertexLayout_XY), 4, DataStorage_Hardware, BufferUsage_Static); + s_quadVertexBuffer.Reset(VertexDeclaration::Get(VertexLayout_XY), 4, DataStorage_Hardware, 0); float vertices[2 * 4] = { -0.5f, -0.5f, @@ -463,7 +463,7 @@ namespace Nz std::size_t renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); billboardCount -= renderedBillboardCount; - instanceBuffer->Fill(data, 0, renderedBillboardCount, true); + instanceBuffer->Fill(data, 0, renderedBillboardCount); data += renderedBillboardCount; Renderer::DrawPrimitivesInstanced(renderedBillboardCount, PrimitiveMode_TriangleStrip, 0, 4); @@ -703,7 +703,7 @@ namespace Nz instanceCount -= renderedInstanceCount; // We fill the instancing buffer with our world matrices - instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); + instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount); instanceMatrices += renderedInstanceCount; // And we draw diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 6e1c3ee5f..8f5427718 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -194,7 +194,7 @@ namespace Nz // Free of atlas if it is ours std::shared_ptr defaultAtlas = Font::GetDefaultAtlas(); - if (defaultAtlas && defaultAtlas->GetStorage() & DataStorage_Hardware) + if (defaultAtlas && defaultAtlas->GetStorage() == DataStorage_Hardware) { Font::SetDefaultAtlas(nullptr); @@ -235,7 +235,7 @@ namespace Nz DepthRenderTechnique::Uninitialize(); ForwardRenderTechnique::Uninitialize(); SkinningManager::Uninitialize(); - + // Materials Material::Uninitialize(); MaterialPipeline::Uninitialize(); diff --git a/src/Nazara/Graphics/SkyboxBackground.cpp b/src/Nazara/Graphics/SkyboxBackground.cpp index fa7faefac..4a646bdbe 100644 --- a/src/Nazara/Graphics/SkyboxBackground.cpp +++ b/src/Nazara/Graphics/SkyboxBackground.cpp @@ -162,11 +162,11 @@ namespace Nz ErrorFlags flags(ErrorFlag_ThrowException, true); // Index buffer - IndexBufferRef indexBuffer = IndexBuffer::New(false, 36, DataStorage_Hardware, BufferUsage_Static); + IndexBufferRef indexBuffer = IndexBuffer::New(false, 36, DataStorage_Hardware, 0); indexBuffer->Fill(indices, 0, 36); // Vertex buffer - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ), 8, DataStorage_Hardware, BufferUsage_Static); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ), 8, DataStorage_Hardware, 0); vertexBuffer->Fill(vertices, 0, 8); // Shader diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 7e8402e20..5b3eb2cf6 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -69,7 +69,7 @@ namespace Nz { Font* font = drawer.GetFont(i); const AbstractAtlas* atlas = font->GetAtlas().get(); - NazaraAssert(atlas->GetStorage() & DataStorage_Hardware, "Font uses a non-hardware atlas which cannot be used by text sprites"); + NazaraAssert(atlas->GetStorage() == DataStorage_Hardware, "Font uses a non-hardware atlas which cannot be used by text sprites"); auto it = m_atlases.find(atlas); if (it == m_atlases.end()) diff --git a/src/Nazara/Renderer/HardwareBuffer.cpp b/src/Nazara/Renderer/HardwareBuffer.cpp new file mode 100644 index 000000000..d7b5219b4 --- /dev/null +++ b/src/Nazara/Renderer/HardwareBuffer.cpp @@ -0,0 +1,138 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + HardwareBuffer::HardwareBuffer(Buffer* parent, BufferType type) : + m_buffer(0), + m_type(type), + m_parent(parent) + { + } + + HardwareBuffer::~HardwareBuffer() + { + if (m_buffer) + { + Context::EnsureContext(); + + OpenGL::DeleteBuffer(m_type, m_buffer); + } + } + + bool HardwareBuffer::Initialize(UInt32 size, BufferUsageFlags usage) + { + Context::EnsureContext(); + + m_buffer = 0; + glGenBuffers(1, &m_buffer); + + OpenGL::BindBuffer(m_type, m_buffer); + glBufferData(OpenGL::BufferTarget[m_type], size, nullptr, (usage & BufferUsage_Dynamic) ? GL_STREAM_DRAW : GL_STATIC_DRAW); + + return true; + } + + bool HardwareBuffer::Fill(const void* data, UInt32 offset, UInt32 size) + { + Context::EnsureContext(); + + UInt32 totalSize = m_parent->GetSize(); + + bool forceDiscard = (size == totalSize); + + OpenGL::BindBuffer(m_type, m_buffer); + + // It seems glBuffer(Sub)Data performs faster than glMapBuffer under a specific range + // http://www.stevestreeting.com/2007/03/17/glmapbuffer-vs-glbuffersubdata-the-return/ + if (size < 32*1024) + { + // http://www.opengl.org/wiki/Buffer_Object_Streaming + if (forceDiscard) + glBufferData(OpenGL::BufferTarget[m_type], totalSize, nullptr, (m_parent->GetUsage() & BufferUsage_Dynamic) ? GL_STREAM_DRAW : GL_STATIC_DRAW); // Discard + + glBufferSubData(OpenGL::BufferTarget[m_type], offset, size, data); + } + else + { + void* ptr = Map((forceDiscard) ? BufferAccess_DiscardAndWrite : BufferAccess_WriteOnly, offset, size); + if (!ptr) + { + NazaraError("Failed to map buffer"); + return false; + } + + std::memcpy(ptr, data, size); + + Unmap(); + } + + return true; + } + + DataStorage HardwareBuffer::GetStorage() const + { + return DataStorage_Hardware; + } + + void* HardwareBuffer::Map(BufferAccess access, UInt32 offset, UInt32 size) + { + Context::EnsureContext(); + + OpenGL::BindBuffer(m_type, m_buffer); + + if (glMapBufferRange) + return glMapBufferRange(OpenGL::BufferTarget[m_type], offset, size, OpenGL::BufferLockRange[access]); + else + { + // http://www.opengl.org/wiki/Buffer_Object_Streaming + if (access == BufferAccess_DiscardAndWrite) + glBufferData(OpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, (m_parent->GetUsage() & BufferUsage_Dynamic) ? GL_STREAM_DRAW : GL_STATIC_DRAW); // Discard + + UInt8* ptr = static_cast(glMapBuffer(OpenGL::BufferTarget[m_type], OpenGL::BufferLock[access])); + if (ptr) + ptr += offset; + + return ptr; + } + } + + bool HardwareBuffer::Unmap() + { + Context::EnsureContext(); + + OpenGL::BindBuffer(m_type, m_buffer); + + if (glUnmapBuffer(OpenGL::BufferTarget[m_type]) != GL_TRUE) + { + // An error occured, we have to reset the buffer + glBufferData(OpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, (m_parent->GetUsage() & BufferUsage_Dynamic) ? GL_STREAM_DRAW : GL_STATIC_DRAW); + + NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error: 0x" + String::Number(glGetError(), 16) + ')'); + return false; + } + + return true; + } + + void HardwareBuffer::Bind() const + { + OpenGL::BindBuffer(m_type, m_buffer); + } + + GLuint HardwareBuffer::GetOpenGLID() const + { + return m_buffer; + } +} diff --git a/src/Nazara/Renderer/HardwareBuffer.hpp b/src/Nazara/Renderer/HardwareBuffer.hpp new file mode 100644 index 000000000..15a629c8b --- /dev/null +++ b/src/Nazara/Renderer/HardwareBuffer.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Renderer module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_HARDWAREBUFFER_HPP +#define NAZARA_HARDWAREBUFFER_HPP + +#include +#include +#include + +namespace Nz +{ + class Buffer; + + class HardwareBuffer : public AbstractBuffer + { + public: + HardwareBuffer(Buffer* parent, BufferType type); + ~HardwareBuffer(); + + bool Fill(const void* data, UInt32 offset, UInt32 size) override; + + bool Initialize(unsigned int size, BufferUsageFlags usage) override; + + DataStorage GetStorage() const override; + + void* Map(BufferAccess access, UInt32 offset = 0, UInt32 size = 0) override; + bool Unmap() override; + + // Fonctions OpenGL + void Bind() const; + GLuint GetOpenGLID() const; + + private: + GLuint m_buffer; + BufferType m_type; + Buffer* m_parent; + }; +} + +#endif // NAZARA_HARDWAREBUFFER_HPP diff --git a/src/Nazara/Utility/Buffer.cpp b/src/Nazara/Utility/Buffer.cpp index 503d6619b..4e589b938 100644 --- a/src/Nazara/Utility/Buffer.cpp +++ b/src/Nazara/Utility/Buffer.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -17,26 +16,18 @@ namespace Nz { - namespace - { - AbstractBuffer* SoftwareBufferFactory(Buffer* parent, BufferType type) - { - return new SoftwareBuffer(parent, type); - } - } - Buffer::Buffer(BufferType type) : m_type(type), - m_impl(nullptr), + m_usage(0), m_size(0) { } - Buffer::Buffer(BufferType type, unsigned int size, UInt32 storage, BufferUsage usage) : - m_type(type), - m_impl(nullptr) + Buffer::Buffer(BufferType type, UInt32 size, DataStorage storage, BufferUsageFlags usage) : + Buffer(type) { ErrorFlags flags(ErrorFlag_ThrowException, true); + Create(size, storage, usage); } @@ -47,27 +38,16 @@ namespace Nz Destroy(); } - bool Buffer::CopyContent(const Buffer& buffer) + bool Buffer::CopyContent(const BufferRef& buffer) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Buffer must be valid"); - return false; - } + NazaraAssert(m_impl, "Invalid buffer"); + NazaraAssert(!buffer && !buffer->IsValid(), "Invalid source buffer"); - if (!buffer.IsValid()) - { - NazaraError("Source buffer must be valid"); - return false; - } - #endif - - BufferMapper mapper(buffer, BufferAccess_ReadOnly); - return Fill(mapper.GetPointer(), 0, buffer.GetSize()); + BufferMapper mapper(*buffer, BufferAccess_ReadOnly); + return Fill(mapper.GetPointer(), 0, buffer->GetSize()); } - bool Buffer::Create(unsigned int size, UInt32 storage, BufferUsage usage) + bool Buffer::Create(UInt32 size, DataStorage storage, BufferUsageFlags usage) { Destroy(); @@ -79,15 +59,14 @@ namespace Nz } std::unique_ptr impl(s_bufferFactories[storage](this, m_type)); - if (!impl->Create(size, usage)) + if (!impl->Initialize(size, usage)) { NazaraError("Failed to create buffer"); return false; } - m_impl = impl.release(); + m_impl = std::move(impl); m_size = size; - m_storage = storage; m_usage = usage; return true; // Si on arrive ici c'est que tout s'est bien passé. @@ -95,125 +74,44 @@ namespace Nz void Buffer::Destroy() { - if (m_impl) + if (!m_impl) { OnBufferDestroy(this); - m_impl->Destroy(); - delete m_impl; - m_impl = nullptr; + m_impl.reset(); } } - bool Buffer::Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) + bool Buffer::Fill(const void* data, UInt32 offset, UInt32 size) { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Buffer not valid"); - return false; - } + NazaraAssert(m_impl, "Invalid buffer"); + NazaraAssert(offset + size <= m_size, "Exceeding buffer size"); - if (offset+size > m_size) - { - NazaraError("Exceeding buffer size (" + String::Number(offset+size) + " > " + String::Number(m_size) + ')'); - return false; - } - #endif - - return m_impl->Fill(data, offset, (size == 0) ? m_size-offset : size, forceDiscard); + return m_impl->Fill(data, offset, (size == 0) ? m_size - offset : size); } - AbstractBuffer* Buffer::GetImpl() const + void* Buffer::Map(BufferAccess access, UInt32 offset, UInt32 size) { - return m_impl; + NazaraAssert(m_impl, "Invalid buffer"); + NazaraAssert(offset + size <= m_size, "Exceeding buffer size"); + + return m_impl->Map(access, offset, (size == 0) ? m_size - offset : size); } - unsigned int Buffer::GetSize() const + void* Buffer::Map(BufferAccess access, UInt32 offset, UInt32 size) const { - return m_size; + NazaraAssert(m_impl, "Invalid buffer"); + NazaraAssert(access == BufferAccess_ReadOnly, "Buffer access must be read-only when used const"); + NazaraAssert(offset + size <= m_size, "Exceeding buffer size"); + + return m_impl->Map(access, offset, (size == 0) ? m_size - offset : size); } - UInt32 Buffer::GetStorage() const + bool Buffer::SetStorage(DataStorage storage) { - return m_storage; - } + NazaraAssert(m_impl, "Invalid buffer"); - BufferType Buffer::GetType() const - { - return m_type; - } - - BufferUsage Buffer::GetUsage() const - { - return m_usage; - } - - bool Buffer::IsHardware() const - { - return m_storage & DataStorage_Hardware; - } - - bool Buffer::IsValid() const - { - return m_impl != nullptr; - } - - void* Buffer::Map(BufferAccess access, unsigned int offset, unsigned int size) - { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Buffer not valid"); - return nullptr; - } - - if (offset+size > m_size) - { - NazaraError("Exceeding buffer size"); - return nullptr; - } - #endif - - return m_impl->Map(access, offset, (size == 0) ? m_size-offset : size); - } - - void* Buffer::Map(BufferAccess access, unsigned int offset, unsigned int size) const - { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Buffer not valid"); - return nullptr; - } - - if (access != BufferAccess_ReadOnly) - { - NazaraError("Buffer access must be read-only when used const"); - return nullptr; - } - - if (offset+size > m_size) - { - NazaraError("Exceeding buffer size"); - return nullptr; - } - #endif - - return m_impl->Map(access, offset, (size == 0) ? m_size-offset : size); - } - - bool Buffer::SetStorage(UInt32 storage) - { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Buffer not valid"); - return false; - } - #endif - - if (m_storage == storage) + if (HasStorage(storage)) return true; if (!IsStorageSupported(storage)) @@ -235,70 +133,57 @@ namespace Nz }); std::unique_ptr impl(s_bufferFactories[storage](this, m_type)); - if (!impl->Create(m_size, m_usage)) + if (!impl->Initialize(m_size, m_usage)) { NazaraError("Failed to create buffer"); return false; } - CallOnExit destroyImpl([&impl]() - { - impl->Destroy(); - }); - if (!impl->Fill(ptr, 0, m_size)) { NazaraError("Failed to fill buffer"); return false; } - destroyImpl.Reset(); - unmapMyImpl.CallAndReset(); - m_impl->Destroy(); - delete m_impl; - m_impl = impl.release(); - m_storage = storage; + m_impl = std::move(impl); return true; } void Buffer::Unmap() const { - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Buffer not valid"); - return; - } - #endif + NazaraAssert(m_impl, "Invalid buffer"); if (!m_impl->Unmap()) NazaraWarning("Failed to unmap buffer (it's content may be undefined)"); ///TODO: Unexpected ? } - bool Buffer::IsStorageSupported(UInt32 storage) + bool Buffer::IsStorageSupported(DataStorage storage) { return s_bufferFactories[storage] != nullptr; } - void Buffer::SetBufferFactory(UInt32 storage, BufferFactory func) + void Buffer::SetBufferFactory(DataStorage storage, BufferFactory func) { s_bufferFactories[storage] = func; } bool Buffer::Initialize() { - s_bufferFactories[DataStorage_Software] = SoftwareBufferFactory; + SetBufferFactory(DataStorage_Software, [](Buffer* parent, BufferType type) -> AbstractBuffer* + { + return new SoftwareBuffer(parent, type); + }); return true; } void Buffer::Uninitialize() { - std::memset(s_bufferFactories, 0, (DataStorage_Max+1)*sizeof(Buffer::BufferFactory)); + std::fill(s_bufferFactories.begin(), s_bufferFactories.end(), nullptr); } - Buffer::BufferFactory Buffer::s_bufferFactories[DataStorage_Max+1] = {nullptr}; + std::array Buffer::s_bufferFactories; } diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index 04628ba90..c28a12de0 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -108,7 +108,7 @@ namespace Nz } } - IndexBufferRef indexBuffer = IndexBuffer::New(false, header.num_tris*3, parameters.storage, BufferUsage_Static); + IndexBufferRef indexBuffer = IndexBuffer::New(false, header.num_tris*3, parameters.storage, 0); // Extract triangles data std::vector triangles(header.num_tris); @@ -159,7 +159,7 @@ namespace Nz } #endif - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), header.num_vertices, parameters.storage, BufferUsage_Static); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), header.num_vertices, parameters.storage, 0); StaticMeshRef subMesh = StaticMesh::New(mesh); if (!subMesh->Create(vertexBuffer)) { diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index bccf17568..26aef0a1f 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -91,8 +91,8 @@ namespace Nz bool largeIndices = (vertexCount > std::numeric_limits::max()); - IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, indexCount, parameters.storage); - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent_Skinning), vertexCount, parameters.storage, BufferUsage_Static); + IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, indexCount, parameters.storage, 0); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent_Skinning), vertexCount, parameters.storage, 0); // Index buffer IndexMapper indexMapper(indexBuffer, BufferAccess_DiscardAndWrite); @@ -236,7 +236,7 @@ namespace Nz // Index buffer bool largeIndices = (vertexCount > std::numeric_limits::max()); - IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, indexCount, parameters.storage); + IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, indexCount, parameters.storage, 0); IndexMapper indexMapper(indexBuffer, BufferAccess_DiscardAndWrite); IndexIterator index = indexMapper.begin(); @@ -251,7 +251,7 @@ namespace Nz indexMapper.Unmap(); // Vertex buffer - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage, 0); BufferMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); MeshVertex* vertices = static_cast(vertexMapper.GetPointer()); diff --git a/src/Nazara/Utility/Formats/OBJLoader.cpp b/src/Nazara/Utility/Formats/OBJLoader.cpp index d65d3e913..2371e18fd 100644 --- a/src/Nazara/Utility/Formats/OBJLoader.cpp +++ b/src/Nazara/Utility/Formats/OBJLoader.cpp @@ -233,8 +233,8 @@ namespace Nz } // Création des buffers - IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indices.size(), parameters.storage, BufferUsage_Static); - VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage, BufferUsage_Static); + IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indices.size(), parameters.storage, 0); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage, 0); // Remplissage des indices IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly); diff --git a/src/Nazara/Utility/IndexBuffer.cpp b/src/Nazara/Utility/IndexBuffer.cpp index 2f1a46515..90090aabe 100644 --- a/src/Nazara/Utility/IndexBuffer.cpp +++ b/src/Nazara/Utility/IndexBuffer.cpp @@ -14,19 +14,19 @@ namespace Nz { - IndexBuffer::IndexBuffer(bool largeIndices, Buffer* buffer) + IndexBuffer::IndexBuffer(bool largeIndices, BufferRef buffer) { ErrorFlags(ErrorFlag_ThrowException, true); - Reset(largeIndices, buffer); + Reset(largeIndices, std::move(buffer)); } - IndexBuffer::IndexBuffer(bool largeIndices, Buffer* buffer, unsigned int startOffset, unsigned int endOffset) + IndexBuffer::IndexBuffer(bool largeIndices, BufferRef buffer, UInt32 offset, UInt32 size) { ErrorFlags(ErrorFlag_ThrowException, true); - Reset(largeIndices, buffer, startOffset, endOffset); + Reset(largeIndices, std::move(buffer), offset, size); } - IndexBuffer::IndexBuffer(bool largeIndices, unsigned int length, UInt32 storage, BufferUsage usage) + IndexBuffer::IndexBuffer(bool largeIndices, UInt32 length, DataStorage storage, BufferUsageFlags usage) { ErrorFlags(ErrorFlag_ThrowException, true); Reset(largeIndices, length, storage, usage); @@ -54,105 +54,33 @@ namespace Nz return Nz::ComputeCacheMissCount(mapper.begin(), m_indexCount); } - bool IndexBuffer::Fill(const void* data, unsigned int startIndex, unsigned int length, bool forceDiscard) + bool IndexBuffer::Fill(const void* data, UInt32 startIndex, UInt32 length) { - unsigned int stride = GetStride(); - return FillRaw(data, startIndex*stride, length*stride, forceDiscard); + UInt32 stride = GetStride(); + + return FillRaw(data, startIndex*stride, length*stride); } - bool IndexBuffer::FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) + bool IndexBuffer::FillRaw(const void* data, UInt32 offset, UInt32 size) { - #if NAZARA_UTILITY_SAFE - if (m_startOffset + offset + size > m_endOffset) - { - NazaraError("Exceeding virtual buffer size"); - return false; - } - #endif + NazaraAssert(m_buffer && m_buffer->IsValid(), "Invalid buffer"); + NazaraAssert(m_startOffset + offset + size <= m_endOffset, "Exceeding virtual buffer size"); - return m_buffer->Fill(data, m_startOffset+offset, size, forceDiscard); + return m_buffer->Fill(data, m_startOffset+offset, size); } - Buffer* IndexBuffer::GetBuffer() const + void* IndexBuffer::MapRaw(BufferAccess access, UInt32 offset, UInt32 size) { - return m_buffer; - } - - unsigned int IndexBuffer::GetEndOffset() const - { - return m_endOffset; - } - - unsigned int IndexBuffer::GetIndexCount() const - { - return m_indexCount; - } - - unsigned int IndexBuffer::GetStride() const - { - return (m_largeIndices) ? sizeof(UInt32) : sizeof(UInt16); - } - - unsigned int IndexBuffer::GetStartOffset() const - { - return m_startOffset; - } - - bool IndexBuffer::HasLargeIndices() const - { - return m_largeIndices; - } - - bool IndexBuffer::IsHardware() const - { - return m_buffer->IsHardware(); - } - - bool IndexBuffer::IsValid() const - { - return m_buffer; - } - - void* IndexBuffer::Map(BufferAccess access, unsigned int startIndex, unsigned int length) - { - unsigned int stride = GetStride(); - return MapRaw(access, startIndex*stride, length*stride); - } - - void* IndexBuffer::Map(BufferAccess access, unsigned int startIndex, unsigned int length) const - { - unsigned int stride = GetStride(); - return MapRaw(access, startIndex*stride, length*stride); - } - - void* IndexBuffer::MapRaw(BufferAccess access, unsigned int offset, unsigned int size) - { - #if NAZARA_UTILITY_SAFE - if (!m_buffer) - { - NazaraError("No buffer"); - return nullptr; - } - - if (m_startOffset + offset + size > m_endOffset) - { - NazaraError("Exceeding virtual buffer size"); - return nullptr; - } - #endif + NazaraAssert(m_buffer && m_buffer->IsValid(), "Invalid buffer"); + NazaraAssert(m_startOffset + offset + size <= m_endOffset, "Exceeding virtual buffer size"); return m_buffer->Map(access, offset, size); } - void* IndexBuffer::MapRaw(BufferAccess access, unsigned int offset, unsigned int size) const + void* IndexBuffer::MapRaw(BufferAccess access, UInt32 offset, UInt32 size) const { - #if NAZARA_UTILITY_SAFE - if (m_startOffset + offset + size > m_endOffset) - { - NazaraError("Exceeding virtual buffer size"); - return nullptr; - } - #endif + NazaraAssert(m_buffer && m_buffer->IsValid(), "Invalid buffer"); + NazaraAssert(m_startOffset + offset + size <= m_endOffset, "Exceeding virtual buffer size"); return m_buffer->Map(access, offset, size); } @@ -169,52 +97,31 @@ namespace Nz m_buffer.Reset(); } - void IndexBuffer::Reset(bool largeIndices, Buffer* buffer) + void IndexBuffer::Reset(bool largeIndices, BufferRef buffer) { - Reset(largeIndices, buffer, 0, buffer->GetSize()-1); + NazaraAssert(buffer && buffer->IsValid(), "Invalid buffer"); + + Reset(largeIndices, buffer, 0, buffer->GetSize()); } - void IndexBuffer::Reset(bool largeIndices, Buffer* buffer, unsigned int startOffset, unsigned int endOffset) + void IndexBuffer::Reset(bool largeIndices, BufferRef buffer, UInt32 offset, UInt32 size) { - #if NAZARA_UTILITY_SAFE - if (!buffer || !buffer->IsValid()) - { - NazaraError("Buffer is invalid"); - return; - } + NazaraAssert(buffer && buffer->IsValid(), "Invalid buffer"); + NazaraAssert(size > 0, "Invalid size"); + NazaraAssert(offset + size > buffer->GetSize(), "Virtual buffer exceed buffer bounds"); - if (startOffset > endOffset) - { - NazaraError("Start offset cannot be over end offset"); - return; - } - - unsigned int bufferSize = buffer->GetSize(); - if (startOffset >= bufferSize) - { - NazaraError("Start offset is over buffer size"); - return; - } - - if (endOffset >= bufferSize) - { - NazaraError("End offset is over buffer size"); - return; - } - #endif - - unsigned int stride = (largeIndices) ? sizeof(UInt32) : sizeof(UInt16); + UInt32 stride = static_cast((largeIndices) ? sizeof(UInt32) : sizeof(UInt16)); m_buffer = buffer; - m_endOffset = endOffset; - m_indexCount = (endOffset - startOffset) / stride; + m_endOffset = offset + size; + m_indexCount = size / stride; m_largeIndices = largeIndices; - m_startOffset = startOffset; + m_startOffset = offset; } - void IndexBuffer::Reset(bool largeIndices, unsigned int length, UInt32 storage, BufferUsage usage) + void IndexBuffer::Reset(bool largeIndices, UInt32 length, DataStorage storage, BufferUsageFlags usage) { - unsigned int stride = (largeIndices) ? sizeof(UInt32) : sizeof(UInt16); + UInt32 stride = static_cast((largeIndices) ? sizeof(UInt32) : sizeof(UInt16)); m_endOffset = length * stride; m_indexCount = length; @@ -233,11 +140,6 @@ namespace Nz m_startOffset = indexBuffer.m_startOffset; } - bool IndexBuffer::SetStorage(UInt32 storage) - { - return m_buffer->SetStorage(storage); - } - void IndexBuffer::Unmap() const { m_buffer->Unmap(); diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index 363be074d..32db98e24 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -123,8 +123,8 @@ namespace Nz unsigned int vertexCount; ComputeBoxIndexVertexCount(primitive.box.subdivision, &indexCount, &vertexCount); - indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, BufferUsage_Static); - vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static); + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, 0); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, 0); VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); @@ -145,8 +145,8 @@ namespace Nz unsigned int vertexCount; ComputeConeIndexVertexCount(primitive.cone.subdivision, &indexCount, &vertexCount); - indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, BufferUsage_Static); - vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static); + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, 0); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, 0); VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); @@ -167,8 +167,8 @@ namespace Nz unsigned int vertexCount; ComputePlaneIndexVertexCount(primitive.plane.subdivision, &indexCount, &vertexCount); - indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, BufferUsage_Static); - vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static); + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, 0); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, 0); VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); @@ -193,8 +193,8 @@ namespace Nz unsigned int vertexCount; ComputeCubicSphereIndexVertexCount(primitive.sphere.cubic.subdivision, &indexCount, &vertexCount); - indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, BufferUsage_Static); - vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static); + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, 0); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, 0); VertexMapper vertexMapper(vertexBuffer, BufferAccess_ReadWrite); @@ -215,8 +215,8 @@ namespace Nz unsigned int vertexCount; ComputeIcoSphereIndexVertexCount(primitive.sphere.ico.recursionLevel, &indexCount, &vertexCount); - indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, BufferUsage_Static); - vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static); + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, 0); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, 0); VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); @@ -237,8 +237,8 @@ namespace Nz unsigned int vertexCount; ComputeUvSphereIndexVertexCount(primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, &indexCount, &vertexCount); - indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, BufferUsage_Static); - vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static); + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, 0); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, 0); VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); diff --git a/src/Nazara/Utility/SoftwareBuffer.cpp b/src/Nazara/Utility/SoftwareBuffer.cpp index 040017c1e..2f69e02ac 100644 --- a/src/Nazara/Utility/SoftwareBuffer.cpp +++ b/src/Nazara/Utility/SoftwareBuffer.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -19,14 +18,20 @@ namespace Nz { } - bool SoftwareBuffer::Create(unsigned int size, BufferUsage usage) + bool SoftwareBuffer::Fill(const void* data, UInt32 offset, UInt32 size) { - NazaraUnused(usage); + NazaraAssert(!m_mapped, "Buffer is already mapped"); + std::memcpy(&m_buffer[offset], data, size); + return true; + } + + bool SoftwareBuffer::Initialize(UInt32 size, BufferUsageFlags /*usage*/) + { // Protect the allocation to prevent a memory exception to escape the function try { - m_buffer = new UInt8[size]; + m_buffer.resize(size); } catch (const std::exception& e) { @@ -39,25 +44,12 @@ namespace Nz return true; } - void SoftwareBuffer::Destroy() + DataStorage SoftwareBuffer::GetStorage() const { - delete[] m_buffer; + return DataStorage_Software; } - bool SoftwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size, bool /*forceDiscard*/) - { - NazaraAssert(!m_mapped, "Buffer is already mapped"); - - std::memcpy(&m_buffer[offset], data, size); - return true; - } - - bool SoftwareBuffer::IsHardware() const - { - return false; - } - - void* SoftwareBuffer::Map(BufferAccess /*access*/, unsigned int offset, unsigned int /*size*/) + void* SoftwareBuffer::Map(BufferAccess /*access*/, UInt32 offset, UInt32 /*size*/) { NazaraAssert(!m_mapped, "Buffer is already mapped"); diff --git a/src/Nazara/Utility/SoftwareBuffer.hpp b/src/Nazara/Utility/SoftwareBuffer.hpp index 1e074257a..4e48dd29e 100644 --- a/src/Nazara/Utility/SoftwareBuffer.hpp +++ b/src/Nazara/Utility/SoftwareBuffer.hpp @@ -9,27 +9,29 @@ #include #include +#include namespace Nz { + class Buffer; + class SoftwareBuffer : public AbstractBuffer { public: SoftwareBuffer(Buffer* parent, BufferType type); ~SoftwareBuffer(); - bool Create(unsigned int size, BufferUsage usage = BufferUsage_Static); - void Destroy(); + bool Fill(const void* data, UInt32 offset, UInt32 size) override; - bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard); + bool Initialize(UInt32 size, BufferUsageFlags usage) override; - bool IsHardware() const; + DataStorage GetStorage() const override; - void* Map(BufferAccess access, unsigned int offset = 0, unsigned int size = 0); - bool Unmap(); + void* Map(BufferAccess access, UInt32 offset = 0, UInt32 size = 0) override; + bool Unmap() override; private: - UInt8* m_buffer; + std::vector m_buffer; bool m_mapped; }; } diff --git a/src/Nazara/Utility/VertexBuffer.cpp b/src/Nazara/Utility/VertexBuffer.cpp index b196d723a..bd3073427 100644 --- a/src/Nazara/Utility/VertexBuffer.cpp +++ b/src/Nazara/Utility/VertexBuffer.cpp @@ -10,22 +10,22 @@ namespace Nz { - VertexBuffer::VertexBuffer(const VertexDeclaration* vertexDeclaration, Buffer* buffer) + VertexBuffer::VertexBuffer(VertexDeclarationConstRef vertexDeclaration, BufferRef buffer) { ErrorFlags(ErrorFlag_ThrowException, true); - Reset(vertexDeclaration, buffer); + Reset(std::move(vertexDeclaration), std::move(buffer)); } - VertexBuffer::VertexBuffer(const VertexDeclaration* vertexDeclaration, Buffer* buffer, unsigned int startOffset, unsigned int endOffset) + VertexBuffer::VertexBuffer(VertexDeclarationConstRef vertexDeclaration, BufferRef buffer, UInt32 offset, UInt32 size) { ErrorFlags(ErrorFlag_ThrowException, true); - Reset(vertexDeclaration, buffer, startOffset, endOffset); + Reset(std::move(vertexDeclaration), std::move(buffer), offset, size); } - VertexBuffer::VertexBuffer(const VertexDeclaration* vertexDeclaration, unsigned int length, UInt32 storage, BufferUsage usage) + VertexBuffer::VertexBuffer(VertexDeclarationConstRef vertexDeclaration, UInt32 length, DataStorage storage, BufferUsageFlags usage) { ErrorFlags(ErrorFlag_ThrowException, true); - Reset(vertexDeclaration, length, storage, usage); + Reset(std::move(vertexDeclaration), length, storage, usage); } VertexBuffer::VertexBuffer(const VertexBuffer& vertexBuffer) : @@ -43,135 +43,49 @@ namespace Nz OnVertexBufferRelease(this); } - bool VertexBuffer::Fill(const void* data, unsigned int startVertex, unsigned int length, bool forceDiscard) + bool VertexBuffer::Fill(const void* data, UInt32 startVertex, UInt32 length) { - std::size_t stride = m_vertexDeclaration->GetStride(); - return FillRaw(data, startVertex*stride, length*stride, forceDiscard); + UInt32 stride = static_cast(m_vertexDeclaration->GetStride()); + return FillRaw(data, startVertex*stride, length*stride); } - bool VertexBuffer::FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) + bool VertexBuffer::FillRaw(const void* data, UInt32 offset, UInt32 size) { - #if NAZARA_UTILITY_SAFE - if (!m_buffer) - { - NazaraError("No buffer"); - return false; - } + NazaraAssert(m_buffer && m_buffer->IsValid(), "Invalid buffer"); + NazaraAssert(m_startOffset + offset + size <= m_endOffset, "Exceeding virtual buffer size"); - if (m_startOffset + offset + size > m_endOffset) - { - NazaraError("Exceeding virtual buffer size"); - return false; - } - #endif - - return m_buffer->Fill(data, m_startOffset+offset, size, forceDiscard); + return m_buffer->Fill(data, m_startOffset + offset, size); } - Buffer* VertexBuffer::GetBuffer() const + void* VertexBuffer::Map(BufferAccess access, UInt32 startVertex, UInt32 length) { - return m_buffer; - } - - unsigned int VertexBuffer::GetEndOffset() const - { - return m_endOffset; - } - - unsigned int VertexBuffer::GetStartOffset() const - { - return m_startOffset; - } - - unsigned int VertexBuffer::GetStride() const - { - return m_vertexDeclaration->GetStride(); - } - - unsigned int VertexBuffer::GetVertexCount() const - { - return m_vertexCount; - } - - const VertexDeclaration* VertexBuffer::GetVertexDeclaration() const - { - return m_vertexDeclaration; - } - - bool VertexBuffer::IsHardware() const - { - return m_buffer->IsHardware(); - } - - bool VertexBuffer::IsValid() const - { - return m_buffer && m_vertexDeclaration; - } - - void* VertexBuffer::Map(BufferAccess access, unsigned int startVertex, unsigned int length) - { - #if NAZARA_UTILITY_SAFE - if (!m_vertexDeclaration) - { - NazaraError("No vertex declaration"); - return nullptr; - } - #endif - - unsigned int stride = m_vertexDeclaration->GetStride(); + UInt32 stride = static_cast(m_vertexDeclaration->GetStride()); return MapRaw(access, startVertex*stride, length*stride); } - void* VertexBuffer::Map(BufferAccess access, unsigned int startVertex, unsigned int length) const + void* VertexBuffer::Map(BufferAccess access, UInt32 startVertex, UInt32 length) const { - #if NAZARA_UTILITY_SAFE - if (!m_buffer) - { - NazaraError("No buffer"); - return nullptr; - } + NazaraAssert(m_buffer && m_buffer->IsValid(), "Invalid buffer"); + NazaraAssert(m_vertexDeclaration, "Invalid vertex declaration"); - if (!m_vertexDeclaration) - { - NazaraError("No vertex declaration"); - return nullptr; - } - #endif - - unsigned int stride = m_vertexDeclaration->GetStride(); + UInt32 stride = static_cast(m_vertexDeclaration->GetStride()); return MapRaw(access, startVertex*stride, length*stride); } - void* VertexBuffer::MapRaw(BufferAccess access, unsigned int offset, unsigned int size) + void* VertexBuffer::MapRaw(BufferAccess access, UInt32 offset, UInt32 size) { - #if NAZARA_UTILITY_SAFE - if (!m_buffer) - { - NazaraError("No buffer"); - return nullptr; - } - - if (m_startOffset + offset + size > m_endOffset) - { - NazaraError("Exceeding virtual buffer size"); - return nullptr; - } - #endif + NazaraAssert(m_buffer && m_buffer->IsValid(), "Invalid buffer"); + NazaraAssert(m_startOffset + offset + size <= m_endOffset, "Exceeding virtual buffer size"); return m_buffer->Map(access, offset, size); } - void* VertexBuffer::MapRaw(BufferAccess access, unsigned int offset, unsigned int size) const + void* VertexBuffer::MapRaw(BufferAccess access, UInt32 offset, UInt32 size) const { - #if NAZARA_UTILITY_SAFE - if (m_startOffset + offset + size > m_endOffset) - { - NazaraError("Exceeding virtual buffer size"); - return nullptr; - } - #endif + NazaraAssert(m_buffer && m_buffer->IsValid(), "Invalid buffer"); + NazaraAssert(m_startOffset + offset + size <= m_endOffset, "Exceeding virtual buffer size"); return m_buffer->Map(access, offset, size); } @@ -182,55 +96,35 @@ namespace Nz m_vertexDeclaration.Reset(); } - void VertexBuffer::Reset(const VertexDeclaration* vertexDeclaration, Buffer* buffer) + void VertexBuffer::Reset(VertexDeclarationConstRef vertexDeclaration, BufferRef buffer) { - Reset(vertexDeclaration, buffer, 0, buffer->GetSize()-1); + NazaraAssert(buffer && buffer->IsValid(), "Invalid buffer"); + + UInt32 size = buffer->GetSize(); + Reset(std::move(vertexDeclaration), std::move(buffer), 0, size); } - void VertexBuffer::Reset(const VertexDeclaration* vertexDeclaration, Buffer* buffer, unsigned int startOffset, unsigned int endOffset) + void VertexBuffer::Reset(VertexDeclarationConstRef vertexDeclaration, BufferRef buffer, UInt32 offset, UInt32 size) { - #if NAZARA_UTILITY_SAFE - if (!buffer || !buffer->IsValid()) - { - NazaraError("Invalid buffer"); - return; - } - - if (startOffset > endOffset) - { - NazaraError("Start offset cannot be over end offset"); - return; - } - - unsigned int bufferSize = buffer->GetSize(); - if (startOffset >= bufferSize) - { - NazaraError("Start offset is over buffer size"); - return; - } - - if (endOffset >= bufferSize) - { - NazaraError("End offset is over buffer size"); - return; - } - #endif + NazaraAssert(buffer && buffer->IsValid(), "Invalid buffer"); + NazaraAssert(size > 0, "Invalid size"); + NazaraAssert(offset + size <= buffer->GetSize(), "Virtual buffer exceed buffer bounds"); m_buffer = buffer; - m_endOffset = endOffset; - m_startOffset = startOffset; - m_vertexCount = (vertexDeclaration) ? ((endOffset - startOffset) / vertexDeclaration->GetStride()) : 0; + m_endOffset = offset + size; + m_startOffset = offset; + m_vertexCount = (vertexDeclaration) ? (size / static_cast(vertexDeclaration->GetStride())) : 0; m_vertexDeclaration = vertexDeclaration; } - void VertexBuffer::Reset(const VertexDeclaration* vertexDeclaration, unsigned int length, UInt32 storage, BufferUsage usage) + void VertexBuffer::Reset(VertexDeclarationConstRef vertexDeclaration, UInt32 length, DataStorage storage, BufferUsageFlags usage) { - m_endOffset = length * ((vertexDeclaration) ? vertexDeclaration->GetStride() : 1); + m_endOffset = length * ((vertexDeclaration) ? static_cast(vertexDeclaration->GetStride()) : 1); m_startOffset = 0; m_vertexCount = length; + m_vertexDeclaration = std::move(vertexDeclaration); m_buffer = Buffer::New(BufferType_Vertex, m_endOffset, storage, usage); - m_vertexDeclaration = vertexDeclaration; } void VertexBuffer::Reset(const VertexBuffer& vertexBuffer) @@ -242,23 +136,12 @@ namespace Nz m_vertexDeclaration = vertexBuffer.m_vertexDeclaration; } - bool VertexBuffer::SetStorage(UInt32 storage) + void VertexBuffer::SetVertexDeclaration(VertexDeclarationConstRef vertexDeclaration) { - return m_buffer->SetStorage(storage); - } + NazaraAssert(vertexDeclaration, "Invalid vertex declaration"); - void VertexBuffer::SetVertexDeclaration(const VertexDeclaration* vertexDeclaration) - { - #if NAZARA_UTILITY_SAFE - if (!vertexDeclaration) - { - NazaraError("Vertex declaration is invalid"); - return; - } - #endif - - m_vertexCount = (m_endOffset - m_startOffset)/vertexDeclaration->GetStride(); - m_vertexDeclaration = vertexDeclaration; + m_vertexCount = (m_endOffset - m_startOffset) / static_cast(vertexDeclaration->GetStride()); + m_vertexDeclaration = std::move(vertexDeclaration); } void VertexBuffer::Unmap() const