Reworked IndexBuffer, Vertex[Buffer|Declaration|Structs]
Former-commit-id: e3f637f2680afda57a444f73b8f7ad681bb1b8a5
This commit is contained in:
parent
35d9a2fef7
commit
4abefc3e93
|
|
@ -40,7 +40,6 @@ class NAZARA_API NzResource
|
|||
{
|
||||
public:
|
||||
NzResource(bool persistent = true);
|
||||
NzResource(const NzResource& resource);
|
||||
virtual ~NzResource();
|
||||
|
||||
void AddResourceListener(NzResourceListener* listener, int index = 0) const;
|
||||
|
|
|
|||
|
|
@ -102,7 +102,8 @@ class NAZARA_API NzOpenGL
|
|||
static void Uninitialize();
|
||||
|
||||
static GLenum Attachment[nzAttachmentPoint_Max+1];
|
||||
static nzUInt8 AttributeIndex[nzElementUsage_Max+1];
|
||||
static nzUInt8 AttributeIndex[nzAttributeUsage_Max+1];
|
||||
static GLenum AttributeType[nzAttributeType_Max+1];
|
||||
static GLenum BlendFunc[nzBlendFunc_Max+1];
|
||||
static GLenum BufferLock[nzBufferAccess_Max+1];
|
||||
static GLenum BufferLockRange[nzBufferAccess_Max+1];
|
||||
|
|
@ -110,7 +111,6 @@ class NAZARA_API NzOpenGL
|
|||
static GLenum BufferTargetBinding[nzBufferType_Max+1];
|
||||
static GLenum BufferUsage[nzBufferUsage_Max+1];
|
||||
static GLenum CubemapFace[6]; // Un cube possède six faces et ça n'est pas prêt de changer
|
||||
static GLenum ElementType[nzElementType_Max+1];
|
||||
static GLenum FaceCulling[nzFaceCulling_Max+1];
|
||||
static GLenum FaceFilling[nzFaceFilling_Max+1];
|
||||
static GLenum PrimitiveMode[nzPrimitiveMode_Max+1];
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#include <Nazara/Renderer/RenderStates.hpp>
|
||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||
|
||||
class NzColor;
|
||||
class NzContext;
|
||||
|
|
@ -27,11 +28,6 @@ class NzVertexBuffer;
|
|||
class NAZARA_API NzRenderer
|
||||
{
|
||||
public:
|
||||
struct InstancingData
|
||||
{
|
||||
NzMatrix4f worldMatrix;
|
||||
};
|
||||
|
||||
NzRenderer() = delete;
|
||||
~NzRenderer() = delete;
|
||||
|
||||
|
|
@ -52,6 +48,7 @@ class NAZARA_API NzRenderer
|
|||
static nzUInt8 GetMaxAnisotropyLevel();
|
||||
static unsigned int GetMaxRenderTargets();
|
||||
static unsigned int GetMaxTextureUnits();
|
||||
static unsigned int GetMaxVertexAttribs();
|
||||
static float GetPointSize();
|
||||
static const NzRenderStates& GetRenderStates();
|
||||
static NzRectui GetScissorRect();
|
||||
|
|
@ -75,7 +72,8 @@ class NAZARA_API NzRenderer
|
|||
static void SetFaceCulling(nzFaceCulling cullingMode);
|
||||
static void SetFaceFilling(nzFaceFilling fillingMode);
|
||||
static void SetIndexBuffer(const NzIndexBuffer* indexBuffer);
|
||||
static void SetInstancingData(const InstancingData* instancingData, unsigned int instanceCount);
|
||||
static void SetInstancingData(const void* instancingDatainstancingData, unsigned int instanceCount);
|
||||
static void SetInstancingDeclaration(const NzVertexDeclaration* declaration, unsigned int* newMaxInstanceCount);
|
||||
static void SetLineWidth(float size);
|
||||
static void SetMatrix(nzMatrixType type, const NzMatrix4f& matrix);
|
||||
static void SetPointSize(float size);
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@ class NAZARA_API NzAbstractBuffer
|
|||
|
||||
virtual bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false) = 0;
|
||||
|
||||
virtual void* GetPointer() = 0;
|
||||
|
||||
virtual bool IsHardware() const = 0;
|
||||
|
||||
virtual void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) = 0;
|
||||
|
|
|
|||
|
|
@ -28,31 +28,27 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable
|
|||
using BufferFunction = NzAbstractBuffer* (*)(NzBuffer* parent, nzBufferType type);
|
||||
|
||||
NzBuffer(nzBufferType type);
|
||||
NzBuffer(nzBufferType type, unsigned int length, nzUInt8 typeSize, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static);
|
||||
NzBuffer(nzBufferType type, unsigned int size, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static);
|
||||
~NzBuffer();
|
||||
|
||||
bool CopyContent(const NzBuffer& buffer);
|
||||
|
||||
bool Create(unsigned int length, nzUInt8 typeSize, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static);
|
||||
bool Create(unsigned int size, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static);
|
||||
void Destroy();
|
||||
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int length, bool forceDiscard = false);
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false);
|
||||
|
||||
NzAbstractBuffer* GetImpl() const;
|
||||
unsigned int GetLength() const;
|
||||
void* GetPointer();
|
||||
const void* GetPointer() const;
|
||||
unsigned int GetSize() const;
|
||||
nzBufferStorage GetStorage() const;
|
||||
nzBufferType GetType() const;
|
||||
nzUInt8 GetTypeSize() const;
|
||||
nzBufferUsage GetUsage() const;
|
||||
|
||||
bool IsHardware() const;
|
||||
bool IsValid() const;
|
||||
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0);
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0) const;
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0);
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) const;
|
||||
|
||||
bool SetStorage(nzBufferStorage storage);
|
||||
|
||||
|
|
@ -68,9 +64,8 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable
|
|||
nzBufferStorage m_storage;
|
||||
nzBufferType m_type;
|
||||
nzBufferUsage m_usage;
|
||||
nzUInt8 m_typeSize;
|
||||
NzAbstractBuffer* m_impl;
|
||||
unsigned int m_length;
|
||||
unsigned int m_size;
|
||||
|
||||
static BufferFunction s_bufferFunctions[nzBufferStorage_Max+1];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,6 +15,48 @@ enum nzAnimationType
|
|||
nzAnimationType_Max = nzAnimationType_Static
|
||||
};
|
||||
|
||||
enum nzAttributeType
|
||||
{
|
||||
nzAttributeType_Color,
|
||||
nzAttributeType_Double1,
|
||||
nzAttributeType_Double2,
|
||||
nzAttributeType_Double3,
|
||||
nzAttributeType_Double4,
|
||||
nzAttributeType_Float1,
|
||||
nzAttributeType_Float2,
|
||||
nzAttributeType_Float3,
|
||||
nzAttributeType_Float4,
|
||||
|
||||
nzAttributeType_Max = nzAttributeType_Float4
|
||||
};
|
||||
|
||||
enum nzAttributeUsage
|
||||
{
|
||||
nzAttributeUsage_InstanceData0,
|
||||
nzAttributeUsage_InstanceData1,
|
||||
nzAttributeUsage_InstanceData2,
|
||||
nzAttributeUsage_InstanceData3,
|
||||
nzAttributeUsage_InstanceData4,
|
||||
nzAttributeUsage_InstanceData5,
|
||||
nzAttributeUsage_Normal,
|
||||
nzAttributeUsage_Position,
|
||||
nzAttributeUsage_Tangent,
|
||||
nzAttributeUsage_TexCoord,
|
||||
nzAttributeUsage_Userdata0,
|
||||
nzAttributeUsage_Userdata1,
|
||||
nzAttributeUsage_Userdata2,
|
||||
nzAttributeUsage_Userdata3,
|
||||
nzAttributeUsage_Userdata4,
|
||||
nzAttributeUsage_Userdata5,
|
||||
|
||||
nzAttributeUsage_FirstInstanceData = nzAttributeUsage_InstanceData0,
|
||||
nzAttributeUsage_FirstVertexData = nzAttributeUsage_Normal,
|
||||
nzAttributeUsage_LastInstanceData = nzAttributeUsage_InstanceData5,
|
||||
nzAttributeUsage_LastVertexData = nzAttributeUsage_Userdata5,
|
||||
|
||||
nzAttributeUsage_Max = nzAttributeUsage_Userdata5
|
||||
};
|
||||
|
||||
enum nzBufferAccess
|
||||
{
|
||||
nzBufferAccess_DiscardAndWrite,
|
||||
|
|
@ -27,7 +69,7 @@ enum nzBufferAccess
|
|||
|
||||
enum nzBufferStorage
|
||||
{
|
||||
//nzBufferStorage_Both,
|
||||
//nzBufferStorage_Both, ///TODO
|
||||
nzBufferStorage_Hardware,
|
||||
nzBufferStorage_Software,
|
||||
|
||||
|
|
@ -64,40 +106,6 @@ enum nzCubemapFace
|
|||
nzCubemapFace_Max = nzCubemapFace_NegativeZ
|
||||
};
|
||||
|
||||
enum nzElementStream
|
||||
{
|
||||
nzElementStream_VertexData,
|
||||
nzElementStream_InstancedData,
|
||||
|
||||
nzElementStream_Max = nzElementStream_InstancedData
|
||||
};
|
||||
|
||||
enum nzElementType
|
||||
{
|
||||
nzElementType_Color,
|
||||
nzElementType_Double1,
|
||||
nzElementType_Double2,
|
||||
nzElementType_Double3,
|
||||
nzElementType_Double4,
|
||||
nzElementType_Float1,
|
||||
nzElementType_Float2,
|
||||
nzElementType_Float3,
|
||||
nzElementType_Float4,
|
||||
|
||||
nzElementType_Max = nzElementType_Float4
|
||||
};
|
||||
|
||||
enum nzElementUsage
|
||||
{
|
||||
nzElementUsage_Diffuse,
|
||||
nzElementUsage_Normal,
|
||||
nzElementUsage_Position,
|
||||
nzElementUsage_Tangent,
|
||||
nzElementUsage_TexCoord,
|
||||
|
||||
nzElementUsage_Max = nzElementUsage_TexCoord
|
||||
};
|
||||
|
||||
enum nzEventType
|
||||
{
|
||||
nzEventType_GainedFocus,
|
||||
|
|
@ -209,6 +217,23 @@ enum nzPrimitiveMode
|
|||
nzPrimitiveMode_Max = nzPrimitiveMode_TriangleFan
|
||||
};
|
||||
|
||||
enum nzVertexLayout
|
||||
{
|
||||
// Déclarations destinées au rendu
|
||||
nzVertexLayout_XY,
|
||||
nzVertexLayout_XY_UV,
|
||||
nzVertexLayout_XYZ,
|
||||
nzVertexLayout_XYZ_Normal,
|
||||
nzVertexLayout_XYZ_Normal_UV,
|
||||
nzVertexLayout_XYZ_Normal_UV_Tangent,
|
||||
nzVertexLayout_XYZ_UV,
|
||||
|
||||
// Déclarations destinées à l'instancing
|
||||
nzVertexLayout_Matrix4,
|
||||
|
||||
nzVertexLayout_Max = nzVertexLayout_Matrix4
|
||||
};
|
||||
|
||||
enum nzWindowCursor
|
||||
{
|
||||
nzWindowCursor_None,
|
||||
|
|
|
|||
|
|
@ -20,28 +20,30 @@ using NzIndexBufferRef = NzResourceRef<NzIndexBuffer>;
|
|||
class NAZARA_API NzIndexBuffer : public NzResource
|
||||
{
|
||||
public:
|
||||
NzIndexBuffer(NzBuffer* buffer, unsigned int startIndex, unsigned int indexCount);
|
||||
NzIndexBuffer(unsigned int length, bool largeIndices = false, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static);
|
||||
NzIndexBuffer(const NzIndexBuffer& indexBuffer);
|
||||
~NzIndexBuffer();
|
||||
NzIndexBuffer(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset);
|
||||
NzIndexBuffer(bool largeIndices, unsigned int length, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static);
|
||||
NzIndexBuffer(const NzIndexBuffer& vertexBuffer);
|
||||
~NzIndexBuffer() = default;
|
||||
|
||||
unsigned int ComputeCacheMissCount() const;
|
||||
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int length, bool forceDiscard = false);
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false);
|
||||
bool FillIndices(const void* data, unsigned int startIndex, unsigned int length, bool forceDiscard = false);
|
||||
|
||||
NzBuffer* GetBuffer() const;
|
||||
unsigned int GetEndOffset() const;
|
||||
unsigned int GetIndexCount() const;
|
||||
void* GetPointer();
|
||||
const void* GetPointer() const;
|
||||
unsigned int GetStartIndex() const;
|
||||
unsigned int GetStride() const;
|
||||
unsigned int GetStartOffset() const;
|
||||
|
||||
bool HasLargeIndices() const;
|
||||
|
||||
bool IsHardware() const;
|
||||
bool IsSequential() const;
|
||||
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0);
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0) const;
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0);
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) const;
|
||||
void* MapIndices(nzBufferAccess access, unsigned int startVertex = 0, unsigned int length = 0);
|
||||
void* MapIndices(nzBufferAccess access, unsigned int startVertex = 0, unsigned int length = 0) const;
|
||||
|
||||
void Optimize();
|
||||
|
||||
|
|
@ -51,9 +53,10 @@ class NAZARA_API NzIndexBuffer : public NzResource
|
|||
|
||||
private:
|
||||
NzBufferRef m_buffer;
|
||||
bool m_ownsBuffer;
|
||||
bool m_largeIndices;
|
||||
unsigned int m_endOffset;
|
||||
unsigned int m_indexCount;
|
||||
unsigned int m_startIndex;
|
||||
unsigned int m_startOffset;
|
||||
};
|
||||
|
||||
#endif // NAZARA_INDEXBUFFER_HPP
|
||||
|
|
|
|||
|
|
@ -113,8 +113,6 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener
|
|||
|
||||
void Transform(const NzMatrix4f& matrix);
|
||||
|
||||
static const NzVertexDeclaration* GetDeclaration();
|
||||
|
||||
private:
|
||||
void OnResourceReleased(const NzResource* resource, int index) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,35 +21,38 @@ using NzVertexBufferRef = NzResourceRef<NzVertexBuffer>;
|
|||
class NAZARA_API NzVertexBuffer : public NzResource
|
||||
{
|
||||
public:
|
||||
NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startVertex, unsigned int vertexCount);
|
||||
NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset);
|
||||
NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static);
|
||||
NzVertexBuffer(const NzVertexBuffer& vertexBuffer);
|
||||
~NzVertexBuffer();
|
||||
~NzVertexBuffer() = default;
|
||||
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int length, bool forceDiscard = false);
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false);
|
||||
bool FillVertices(const void* data, unsigned int startVertex, unsigned int length, bool forceDiscard = false);
|
||||
|
||||
NzBuffer* GetBuffer() const;
|
||||
void* GetPointer();
|
||||
const void* GetPointer() const;
|
||||
unsigned int GetStartVertex() const;
|
||||
nzUInt8 GetTypeSize() const;
|
||||
unsigned int GetEndOffset() const;
|
||||
unsigned int GetStartOffset() const;
|
||||
unsigned int GetStride() const;
|
||||
unsigned int GetVertexCount() const;
|
||||
const NzVertexDeclaration* GetVertexDeclaration() const;
|
||||
|
||||
bool IsHardware() const;
|
||||
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0);
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0) const;
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0);
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) const;
|
||||
void* MapVertices(nzBufferAccess access, unsigned int startVertex = 0, unsigned int length = 0);
|
||||
void* MapVertices(nzBufferAccess access, unsigned int startVertex = 0, unsigned int length = 0) const;
|
||||
|
||||
bool SetStorage(nzBufferStorage storage);
|
||||
void SetVertexDeclaration(const NzVertexDeclaration* vertexDeclaration);
|
||||
|
||||
void Unmap() const;
|
||||
|
||||
private:
|
||||
NzBufferRef m_buffer;
|
||||
NzVertexDeclarationConstRef m_vertexDeclaration;
|
||||
bool m_ownsBuffer;
|
||||
unsigned int m_startVertex;
|
||||
unsigned int m_endOffset;
|
||||
unsigned int m_startOffset;
|
||||
unsigned int m_vertexCount;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,15 +12,6 @@
|
|||
#include <Nazara/Core/ResourceRef.hpp>
|
||||
#include <Nazara/Utility/Enums.hpp>
|
||||
|
||||
struct NzVertexElement
|
||||
{
|
||||
unsigned int offset;
|
||||
unsigned int usageIndex = 0;
|
||||
nzElementStream stream = nzElementStream_VertexData;
|
||||
nzElementType type;
|
||||
nzElementUsage usage;
|
||||
};
|
||||
|
||||
class NzVertexDeclaration;
|
||||
|
||||
using NzVertexDeclarationConstRef = NzResourceRef<const NzVertexDeclaration>;
|
||||
|
|
@ -30,38 +21,45 @@ struct NzVertexDeclarationImpl;
|
|||
|
||||
class NAZARA_API NzVertexDeclaration : public NzResource
|
||||
{
|
||||
friend class NzUtility;
|
||||
|
||||
public:
|
||||
NzVertexDeclaration() = default;
|
||||
NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount);
|
||||
NzVertexDeclaration(const NzVertexDeclaration& declaration);
|
||||
NzVertexDeclaration(NzVertexDeclaration&& declaration) noexcept;
|
||||
~NzVertexDeclaration();
|
||||
NzVertexDeclaration();
|
||||
NzVertexDeclaration(NzVertexDeclaration& declaration);
|
||||
~NzVertexDeclaration() = default;
|
||||
|
||||
bool Create(const NzVertexElement* elements, unsigned int elementCount);
|
||||
void Destroy();
|
||||
void DisableAttribute(nzAttributeUsage usage);
|
||||
void EnableAttribute(nzAttributeUsage usage, nzAttributeType type, unsigned int offset);
|
||||
|
||||
const NzVertexElement* GetElement(unsigned int i) const;
|
||||
const NzVertexElement* GetElement(nzElementStream stream, unsigned int i) const;
|
||||
const NzVertexElement* GetElement(nzElementStream stream, nzElementUsage usage, unsigned int usageIndex = 0) const;
|
||||
unsigned int GetElementCount() const;
|
||||
unsigned int GetElementCount(nzElementStream stream) const;
|
||||
unsigned int GetStride(nzElementStream stream) const;
|
||||
void GetAttribute(nzAttributeUsage usage, bool* enabled, nzAttributeType* type, unsigned int* offset) const;
|
||||
unsigned int GetStride() const;
|
||||
|
||||
bool HasElement(unsigned int i) const;
|
||||
bool HasElement(nzElementStream stream, unsigned int i) const;
|
||||
bool HasElement(nzElementStream stream, nzElementUsage usage, unsigned int usageIndex = 0) const;
|
||||
bool HasStream(nzElementStream stream) const;
|
||||
|
||||
bool IsValid() const;
|
||||
void SetStride(unsigned int stride);
|
||||
|
||||
NzVertexDeclaration& operator=(const NzVertexDeclaration& declaration);
|
||||
NzVertexDeclaration& operator=(NzVertexDeclaration&& declaration) noexcept;
|
||||
|
||||
static unsigned int GetElementCount(nzElementType type);
|
||||
static unsigned int GetElementSize(nzElementType type);
|
||||
static NzVertexDeclaration* Get(nzVertexLayout layout);
|
||||
static unsigned int GetAttributeSize(nzAttributeType type);
|
||||
|
||||
private:
|
||||
NzVertexDeclarationImpl* m_sharedImpl = nullptr;
|
||||
static bool Initialize();
|
||||
static void Uninitialize();
|
||||
|
||||
struct Attribute
|
||||
{
|
||||
nzAttributeType type;
|
||||
bool enabled = false;
|
||||
unsigned int offset;
|
||||
// Il serait aussi possible de préciser le stride de façon indépendante, ce que je ne permets pas
|
||||
// pour décomplexifier l'interface en enlevant quelque chose d'inutile.
|
||||
// Si vous pensez que ça peut être utile, n'hésitez pas à me le faire savoir !
|
||||
// PS: Même cas pour le diviseur (instancing)
|
||||
};
|
||||
|
||||
Attribute m_attributes[nzAttributeUsage_Max+1];
|
||||
unsigned int m_stride;
|
||||
|
||||
static NzVertexDeclaration s_declarations[nzVertexLayout_Max+1];
|
||||
};
|
||||
|
||||
#endif // NAZARA_VERTEXDECLARATION_HPP
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ struct NzVertexStruct_XY
|
|||
NzVector2f position;
|
||||
};
|
||||
|
||||
struct NzVertexStruct_XY_Color : public NzVertexStruct_XY
|
||||
struct NzVertexStruct_XY_UV : public NzVertexStruct_XY
|
||||
{
|
||||
NzVector3f color;
|
||||
NzVector2f uv;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
|
@ -27,87 +27,24 @@ struct NzVertexStruct_XYZ
|
|||
NzVector3f position;
|
||||
};
|
||||
|
||||
struct NzVertexStruct_XYZ_Color : public NzVertexStruct_XYZ
|
||||
{
|
||||
NzVector3f color;
|
||||
};
|
||||
|
||||
struct NzVertexStruct_XYZ_Normal : public NzVertexStruct_XYZ
|
||||
{
|
||||
NzVector3f normal;
|
||||
};
|
||||
|
||||
struct NzVertexStruct_XYZ_Normal_Color : public NzVertexStruct_XYZ_Normal
|
||||
{
|
||||
NzVector3f color;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
||||
struct NzVertexStruct_XYZ_UV : public NzVertexStruct_XYZ
|
||||
{
|
||||
NzVector2f uv;
|
||||
};
|
||||
|
||||
struct NzVertexStruct_XYZ_UV_Color : public NzVertexStruct_XYZ_UV
|
||||
{
|
||||
NzVector3f color;
|
||||
};
|
||||
|
||||
struct NzVertexStruct_XYZ_Normal_UV : public NzVertexStruct_XYZ_Normal
|
||||
{
|
||||
NzVector2f uv;
|
||||
};
|
||||
|
||||
struct NzVertexStruct_XYZ_Normal_UV_Color : public NzVertexStruct_XYZ_Normal_UV
|
||||
{
|
||||
NzVector3f color;
|
||||
};
|
||||
|
||||
struct NzVertexStruct_XYZ_Normal_UV_Tangent : public NzVertexStruct_XYZ_Normal_UV
|
||||
{
|
||||
NzVector3f tangent;
|
||||
};
|
||||
|
||||
struct NzVertexStruct_XYZ_Normal_UV_Tangent_Color : public NzVertexStruct_XYZ_Normal_UV_Tangent
|
||||
struct NzVertexStruct_XYZ_UV : public NzVertexStruct_XYZ
|
||||
{
|
||||
NzVector3f color;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
||||
struct NzVertexStruct_XYZ_UV_UV2 : public NzVertexStruct_XYZ_UV
|
||||
{
|
||||
NzVector2f uv2;
|
||||
};
|
||||
|
||||
struct NzVertexStruct_XYZ_UV_UV2_Color : public NzVertexStruct_XYZ_UV_UV2
|
||||
{
|
||||
NzVector3f color;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
||||
struct NzVertexStruct_XYZ_Normal_UV_UV2 : public NzVertexStruct_XYZ_Normal_UV
|
||||
{
|
||||
NzVector2f uv2;
|
||||
};
|
||||
|
||||
struct NzVertexStruct_XYZ_Normal_UV_UV2_Color : public NzVertexStruct_XYZ_Normal_UV_UV2
|
||||
{
|
||||
NzVector3f color;
|
||||
};
|
||||
|
||||
struct NzVertexStruct_XYZ_Normal_UV_UV2_Tangent : public NzVertexStruct_XYZ_Normal_UV_UV2
|
||||
{
|
||||
NzVector3f tangent;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
||||
struct NzVertexStruct_XYZ_Normal_UV_UV2_Tangent_Color : public NzVertexStruct_XYZ_Normal_UV_UV2_Tangent
|
||||
{
|
||||
NzVector3f color;
|
||||
NzVector2f uv;
|
||||
};
|
||||
|
||||
#endif // NAZARA_VERTEXSTRUCT_HPP
|
||||
|
|
|
|||
|
|
@ -16,12 +16,6 @@ m_resourceReferenceCount(0)
|
|||
{
|
||||
}
|
||||
|
||||
NzResource::NzResource(const NzResource& resource) :
|
||||
m_resourcePersistent(resource.m_resourcePersistent.load()),
|
||||
m_resourceReferenceCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
NzResource::~NzResource()
|
||||
{
|
||||
EnsureResourceListenerUpdate();
|
||||
|
|
|
|||
|
|
@ -97,10 +97,10 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<NzIndexBuffer> indexBuffer(new NzIndexBuffer(indices.size(), vertexCount > std::numeric_limits<nzUInt16>::max(), parameters.mesh.storage, nzBufferUsage_Static));
|
||||
std::unique_ptr<NzIndexBuffer> indexBuffer(new NzIndexBuffer(vertexCount > std::numeric_limits<nzUInt16>::max(), indices.size(), parameters.mesh.storage, nzBufferUsage_Static));
|
||||
indexBuffer->SetPersistent(false);
|
||||
|
||||
std::unique_ptr<NzVertexBuffer> vertexBuffer(new NzVertexBuffer(NzMesh::GetDeclaration(), vertexCount, parameters.mesh.storage, nzBufferUsage_Static));
|
||||
std::unique_ptr<NzVertexBuffer> vertexBuffer(new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.mesh.storage, nzBufferUsage_Static));
|
||||
vertexBuffer->SetPersistent(false);
|
||||
|
||||
// Remplissage des indices
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace
|
|||
{
|
||||
NzIndexBuffer* BuildIndexBuffer()
|
||||
{
|
||||
std::unique_ptr<NzIndexBuffer> indexBuffer(new NzIndexBuffer(36, false, nzBufferStorage_Hardware, nzBufferUsage_Static));
|
||||
std::unique_ptr<NzIndexBuffer> indexBuffer(new NzIndexBuffer(false, 36, nzBufferStorage_Hardware, nzBufferUsage_Static));
|
||||
indexBuffer->SetPersistent(false);
|
||||
|
||||
nzUInt16 indices[6*6] =
|
||||
|
|
@ -35,7 +35,7 @@ namespace
|
|||
1, 6, 2, 1, 5, 6
|
||||
};
|
||||
|
||||
if (!indexBuffer->Fill(indices, 0, 36))
|
||||
if (!indexBuffer->FillIndices(indices, 0, 36))
|
||||
{
|
||||
NazaraError("Failed to create vertex buffer");
|
||||
return nullptr;
|
||||
|
|
@ -125,22 +125,7 @@ namespace
|
|||
|
||||
NzVertexBuffer* BuildVertexBuffer()
|
||||
{
|
||||
std::unique_ptr<NzVertexDeclaration> declaration(new NzVertexDeclaration);
|
||||
declaration->SetPersistent(false);
|
||||
|
||||
NzVertexElement elements;
|
||||
elements.offset = 0;
|
||||
elements.type = nzElementType_Float3;
|
||||
elements.usage = nzElementUsage_Position;
|
||||
|
||||
if (!declaration->Create(&elements, 1))
|
||||
{
|
||||
NazaraError("Failed to create declaration");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<NzVertexBuffer> vertexBuffer(new NzVertexBuffer(declaration.get(), 8, nzBufferStorage_Hardware, nzBufferUsage_Static));
|
||||
declaration.release();
|
||||
std::unique_ptr<NzVertexBuffer> vertexBuffer(new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ), 8, nzBufferStorage_Hardware, nzBufferUsage_Static));
|
||||
vertexBuffer->SetPersistent(false);
|
||||
|
||||
float vertices[8*(sizeof(float)*3)] =
|
||||
|
|
@ -155,7 +140,7 @@ namespace
|
|||
1.0, 1.0, -1.0,
|
||||
};
|
||||
|
||||
if (!vertexBuffer->Fill(vertices, 0, 8))
|
||||
if (!vertexBuffer->FillVertices(vertices, 0, 8))
|
||||
{
|
||||
NazaraError("Failed to create vertex buffer");
|
||||
return nullptr;
|
||||
|
|
|
|||
|
|
@ -539,26 +539,9 @@ bool NzDebugDrawer::Initialize()
|
|||
colorLocation = shader->GetUniformLocation(nzShaderUniform_MaterialDiffuse);
|
||||
}
|
||||
|
||||
// VertexDeclaration
|
||||
{
|
||||
NzVertexElement element;
|
||||
element.offset = 0;
|
||||
element.type = nzElementType_Float3;
|
||||
element.usage = nzElementUsage_Position;
|
||||
|
||||
vertexDeclaration = new NzVertexDeclaration;
|
||||
if (!vertexDeclaration->Create(&element, 1))
|
||||
{
|
||||
NazaraError("Failed to create declaration");
|
||||
Uninitialize();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// VertexBuffer (Nécessite la déclaration)
|
||||
{
|
||||
vertexBuffer = new NzVertexBuffer(vertexDeclaration, 65365, nzBufferStorage_Hardware, nzBufferUsage_Dynamic);
|
||||
vertexBuffer = new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), 65365, nzBufferStorage_Hardware, nzBufferUsage_Dynamic);
|
||||
if (!vertexBuffer->GetBuffer()->IsValid())
|
||||
{
|
||||
NazaraError("Failed to create buffer");
|
||||
|
|
|
|||
|
|
@ -123,26 +123,26 @@ bool NzGLSLShader::Create()
|
|||
return false;
|
||||
}
|
||||
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzElementUsage_TexCoord]+8, "InstanceMatrix");
|
||||
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzElementUsage_Position], "VertexPosition");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzElementUsage_Normal], "VertexNormal");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzElementUsage_Diffuse], "VertexDiffuse");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzElementUsage_Tangent], "VertexTangent");
|
||||
|
||||
char texCoordsUniform[] = "VertexTexCoord*";
|
||||
|
||||
unsigned int maxTexCoords = std::min(8U, NzRenderer::GetMaxTextureUnits());
|
||||
for (unsigned int i = 0; i < maxTexCoords; ++i)
|
||||
{
|
||||
texCoordsUniform[14] = '0' + i;
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzElementUsage_TexCoord]+i, texCoordsUniform);
|
||||
}
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_InstanceData0], "InstanceData0");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_InstanceData1], "InstanceData1");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_InstanceData2], "InstanceData2");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_InstanceData3], "InstanceData3");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_InstanceData4], "InstanceData4");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_InstanceData5], "InstanceData5");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_Normal], "VertexNormal");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_Position], "VertexPosition");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_Tangent], "VertexTangent");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_TexCoord], "VertexTexCoord");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_Userdata0], "VertexUserdata0");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_Userdata1], "VertexUserdata1");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_Userdata2], "VertexUserdata2");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_Userdata3], "VertexUserdata3");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_Userdata4], "VertexUserdata4");
|
||||
glBindAttribLocation(m_program, NzOpenGL::AttributeIndex[nzAttributeUsage_Userdata5], "VertexUserdata5");
|
||||
|
||||
if (NzRenderer::HasCapability(nzRendererCap_MultipleRenderTargets))
|
||||
{
|
||||
NzString uniform;
|
||||
uniform.Reserve(14); // 12 + 2
|
||||
uniform = "RenderTarget";
|
||||
|
||||
unsigned int maxRenderTargets = NzRenderer::GetMaxRenderTargets();
|
||||
|
|
|
|||
|
|
@ -143,11 +143,6 @@ bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
|
|||
return true;
|
||||
}
|
||||
|
||||
void* NzHardwareBuffer::GetPointer()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::IsHardware() const
|
||||
{
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ class NzHardwareBuffer : public NzAbstractBuffer
|
|||
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard);
|
||||
|
||||
void* GetPointer();
|
||||
|
||||
bool IsHardware() const;
|
||||
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0);
|
||||
|
|
|
|||
|
|
@ -1161,14 +1161,37 @@ GLenum NzOpenGL::Attachment[nzAttachmentPoint_Max+1] =
|
|||
GL_STENCIL_ATTACHMENT // nzAttachmentPoint_Stencil
|
||||
};
|
||||
|
||||
nzUInt8 NzOpenGL::AttributeIndex[nzElementUsage_Max+1] =
|
||||
nzUInt8 NzOpenGL::AttributeIndex[nzAttributeUsage_Max+1] =
|
||||
{
|
||||
2, // nzElementUsage_Diffuse
|
||||
1, // nzElementUsage_Normal
|
||||
0, // nzElementUsage_Position
|
||||
3, // nzElementUsage_Tangent
|
||||
10, // nzAttributeUsage_InstanceData0
|
||||
11, // nzAttributeUsage_InstanceData1
|
||||
12, // nzAttributeUsage_InstanceData2
|
||||
13, // nzAttributeUsage_InstanceData3
|
||||
14, // nzAttributeUsage_InstanceData4
|
||||
15, // nzAttributeUsage_InstanceData5
|
||||
2, // nzAttributeUsage_Normal
|
||||
0, // nzAttributeUsage_Position
|
||||
3, // nzAttributeUsage_Tangent
|
||||
1, // nzAttributeUsage_TexCoord
|
||||
4, // nzAttributeUsage_Userdata0
|
||||
5, // nzAttributeUsage_Userdata1
|
||||
6, // nzAttributeUsage_Userdata2
|
||||
7, // nzAttributeUsage_Userdata3
|
||||
8, // nzAttributeUsage_Userdata4
|
||||
9 // nzAttributeUsage_Userdata5
|
||||
};
|
||||
|
||||
4 // nzElementUsage_TexCoord (Doit être le dernier de la liste car extensible)
|
||||
GLenum NzOpenGL::AttributeType[nzAttributeType_Max+1] =
|
||||
{
|
||||
GL_UNSIGNED_BYTE, // nzAttributeType_Color
|
||||
GL_DOUBLE, // nzAttributeType_Double1
|
||||
GL_DOUBLE, // nzAttributeType_Double2
|
||||
GL_DOUBLE, // nzAttributeType_Double3
|
||||
GL_DOUBLE, // nzAttributeType_Double4
|
||||
GL_FLOAT, // nzAttributeType_Float1
|
||||
GL_FLOAT, // nzAttributeType_Float2
|
||||
GL_FLOAT, // nzAttributeType_Float3
|
||||
GL_FLOAT // nzAttributeType_Float4
|
||||
};
|
||||
|
||||
GLenum NzOpenGL::BlendFunc[nzBlendFunc_Max+1] =
|
||||
|
|
@ -1232,19 +1255,6 @@ GLenum NzOpenGL::CubemapFace[6] =
|
|||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z // nzCubemapFace_NegativeZ
|
||||
};
|
||||
|
||||
GLenum NzOpenGL::ElementType[nzElementType_Max+1] =
|
||||
{
|
||||
GL_UNSIGNED_BYTE, // nzElementType_Color
|
||||
GL_DOUBLE, // nzElementType_Double1
|
||||
GL_DOUBLE, // nzElementType_Double2
|
||||
GL_DOUBLE, // nzElementType_Double3
|
||||
GL_DOUBLE, // nzElementType_Double4
|
||||
GL_FLOAT, // nzElementType_Float1
|
||||
GL_FLOAT, // nzElementType_Float2
|
||||
GL_FLOAT, // nzElementType_Float3
|
||||
GL_FLOAT // nzElementType_Float4
|
||||
};
|
||||
|
||||
GLenum NzOpenGL::FaceCulling[nzFaceCulling_Max+1] =
|
||||
{
|
||||
GL_BACK, // nzFaceCulling_Back
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
|
|
@ -63,13 +64,13 @@ namespace
|
|||
return new NzHardwareBuffer(parent, type);
|
||||
}
|
||||
|
||||
using VAO_Key = std::tuple<const NzContext*, const NzIndexBuffer*, const NzVertexBuffer*, bool>;
|
||||
using VAO_Key = std::tuple<const NzIndexBuffer*, const NzVertexBuffer*, const NzVertexDeclaration*, const NzVertexDeclaration*>;
|
||||
|
||||
std::map<VAO_Key, unsigned int> s_vaos;
|
||||
std::unordered_map<NzContext*, std::map<VAO_Key, unsigned int>> s_vaos;
|
||||
std::set<unsigned int> s_dirtyTextureUnits;
|
||||
std::vector<TextureUnit> s_textureUnits;
|
||||
GLuint s_currentVAO = 0;
|
||||
NzBuffer* s_instancingBuffer = nullptr;
|
||||
NzVertexBuffer* s_instancingBuffer = nullptr;
|
||||
NzVertexBuffer* s_fullscreenQuadBuffer = nullptr;
|
||||
MatrixUnit s_matrices[nzMatrixType_Max+1];
|
||||
NzRenderStates s_states;
|
||||
|
|
@ -80,12 +81,14 @@ namespace
|
|||
const NzRenderTarget* s_target;
|
||||
const NzShader* s_shader;
|
||||
const NzVertexBuffer* s_vertexBuffer;
|
||||
const NzVertexDeclaration* s_instancingDeclaration;
|
||||
bool s_capabilities[nzRendererCap_Max+1];
|
||||
bool s_instancing;
|
||||
bool s_useSamplerObjects;
|
||||
bool s_useVertexArrayObjects;
|
||||
unsigned int s_maxRenderTarget;
|
||||
unsigned int s_maxTextureUnit;
|
||||
unsigned int s_maxVertexAttribs;
|
||||
}
|
||||
|
||||
void NzRenderer::Clear(unsigned long flags)
|
||||
|
|
@ -173,26 +176,21 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode mode, unsigned int firstI
|
|||
return;
|
||||
}
|
||||
|
||||
if (s_indexBuffer->IsSequential())
|
||||
glDrawArrays(NzOpenGL::PrimitiveMode[mode], s_indexBuffer->GetStartIndex(), s_indexBuffer->GetIndexCount());
|
||||
else
|
||||
{
|
||||
GLenum type;
|
||||
const nzUInt8* ptr = reinterpret_cast<const nzUInt8*>(s_indexBuffer->GetPointer());
|
||||
nzUInt8* offset = reinterpret_cast<nzUInt8*>(s_indexBuffer->GetStartOffset());
|
||||
|
||||
if (s_indexBuffer->HasLargeIndices())
|
||||
{
|
||||
ptr += firstIndex*sizeof(nzUInt32);
|
||||
offset += firstIndex*sizeof(nzUInt64);
|
||||
type = GL_UNSIGNED_INT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr += firstIndex*sizeof(nzUInt16);
|
||||
offset += firstIndex*sizeof(nzUInt32);
|
||||
type = GL_UNSIGNED_SHORT;
|
||||
}
|
||||
|
||||
glDrawElements(NzOpenGL::PrimitiveMode[mode], indexCount, type, ptr);
|
||||
}
|
||||
|
||||
glDrawElements(NzOpenGL::PrimitiveMode[mode], indexCount, type, offset);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
|
@ -246,27 +244,21 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr
|
|||
return;
|
||||
}
|
||||
|
||||
if (s_indexBuffer->IsSequential())
|
||||
glDrawArraysInstanced(NzOpenGL::PrimitiveMode[mode], s_indexBuffer->GetStartIndex(), s_indexBuffer->GetIndexCount(), instanceCount);
|
||||
else
|
||||
{
|
||||
GLenum type;
|
||||
const nzUInt8* ptr = reinterpret_cast<const nzUInt8*>(s_indexBuffer->GetPointer());
|
||||
nzUInt8* offset = reinterpret_cast<nzUInt8*>(s_indexBuffer->GetStartOffset());
|
||||
|
||||
if (s_indexBuffer->HasLargeIndices())
|
||||
{
|
||||
ptr += firstIndex*sizeof(nzUInt32);
|
||||
offset += firstIndex*sizeof(nzUInt64);
|
||||
type = GL_UNSIGNED_INT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr += firstIndex*sizeof(nzUInt16);
|
||||
offset += firstIndex*sizeof(nzUInt32);
|
||||
type = GL_UNSIGNED_SHORT;
|
||||
}
|
||||
|
||||
glDrawElementsInstanced(NzOpenGL::PrimitiveMode[mode], indexCount, type, ptr, instanceCount);
|
||||
}
|
||||
|
||||
glDrawElementsInstanced(NzOpenGL::PrimitiveMode[mode], indexCount, type, offset, instanceCount);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
|
@ -422,16 +414,13 @@ unsigned int NzRenderer::GetMaxTextureUnits()
|
|||
return s_maxTextureUnit;
|
||||
}
|
||||
|
||||
unsigned int NzRenderer::GetMaxVertexAttribs()
|
||||
{
|
||||
return s_maxVertexAttribs;
|
||||
}
|
||||
|
||||
float NzRenderer::GetPointSize()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return 0.f;
|
||||
}
|
||||
#endif
|
||||
|
||||
return s_states.pointSize;
|
||||
}
|
||||
|
||||
|
|
@ -551,20 +540,6 @@ bool NzRenderer::Initialize()
|
|||
else
|
||||
s_maxAnisotropyLevel = 1;
|
||||
|
||||
if (s_capabilities[nzRendererCap_Instancing])
|
||||
{
|
||||
s_instancingBuffer = new NzBuffer(nzBufferType_Vertex);
|
||||
if (!s_instancingBuffer->Create(NAZARA_RENDERER_MAX_INSTANCES, sizeof(InstancingData), nzBufferStorage_Hardware, nzBufferUsage_Dynamic))
|
||||
{
|
||||
s_capabilities[nzRendererCap_Instancing] = false;
|
||||
|
||||
delete s_instancingBuffer;
|
||||
s_instancingBuffer = nullptr;
|
||||
|
||||
NazaraWarning("Failed to create instancing buffer, disabled instancing.");
|
||||
}
|
||||
}
|
||||
|
||||
if (s_capabilities[nzRendererCap_MultipleRenderTargets])
|
||||
{
|
||||
GLint maxDrawBuffers;
|
||||
|
|
@ -580,15 +555,16 @@ bool NzRenderer::Initialize()
|
|||
GLint maxTextureUnits;
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
|
||||
|
||||
GLint maxVertexAttribs;
|
||||
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
|
||||
|
||||
// Impossible de binder plus de texcoords que d'attributes (en sachant qu'un certain nombre est déjà pris par les autres attributs)
|
||||
s_maxTextureUnit = static_cast<unsigned int>(std::min(maxTextureUnits, maxVertexAttribs-NzOpenGL::AttributeIndex[nzElementUsage_TexCoord]));
|
||||
s_maxTextureUnit = static_cast<unsigned int>(maxTextureUnits);
|
||||
}
|
||||
else
|
||||
s_maxTextureUnit = 1;
|
||||
|
||||
GLint maxVertexAttribs;
|
||||
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
|
||||
s_maxVertexAttribs = static_cast<unsigned int>(maxVertexAttribs);
|
||||
|
||||
s_states = NzRenderStates();
|
||||
|
||||
s_indexBuffer = nullptr;
|
||||
|
|
@ -600,25 +576,7 @@ bool NzRenderer::Initialize()
|
|||
s_vertexBuffer = nullptr;
|
||||
s_updateFlags = (Update_Matrices | Update_Shader | Update_VAO);
|
||||
|
||||
NzVertexElement element;
|
||||
element.offset = 0;
|
||||
element.type = nzElementType_Float2;
|
||||
element.usage = nzElementUsage_Position;
|
||||
|
||||
std::unique_ptr<NzVertexDeclaration> declaration(new NzVertexDeclaration);
|
||||
if (!declaration->Create(&element, 1))
|
||||
{
|
||||
NazaraError("Failed to create fullscreen quad declaration");
|
||||
Uninitialize();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
declaration->SetPersistent(false);
|
||||
|
||||
s_fullscreenQuadBuffer = new NzVertexBuffer(declaration.get(), 4, nzBufferStorage_Hardware, nzBufferUsage_Static);
|
||||
declaration.release();
|
||||
|
||||
s_fullscreenQuadBuffer = new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzBufferStorage_Hardware, nzBufferUsage_Static);
|
||||
float vertices[4*2] =
|
||||
{
|
||||
-1.f, -1.f,
|
||||
|
|
@ -627,7 +585,7 @@ bool NzRenderer::Initialize()
|
|||
1.f, 1.f,
|
||||
};
|
||||
|
||||
if (!s_fullscreenQuadBuffer->Fill(vertices, 0, 4))
|
||||
if (!s_fullscreenQuadBuffer->FillVertices(vertices, 0, 4))
|
||||
{
|
||||
NazaraError("Failed to fill fullscreen quad buffer");
|
||||
Uninitialize();
|
||||
|
|
@ -635,6 +593,22 @@ bool NzRenderer::Initialize()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (s_capabilities[nzRendererCap_Instancing])
|
||||
{
|
||||
try
|
||||
{
|
||||
s_instancingBuffer = new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_Matrix4), NAZARA_RENDERER_MAX_INSTANCES, nzBufferStorage_Hardware, nzBufferUsage_Dynamic);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
s_capabilities[nzRendererCap_Instancing] = false;
|
||||
s_instancingBuffer = nullptr;
|
||||
NazaraError("Failed to create instancing buffer: " + e.what()); ///TODO: Noexcept
|
||||
}
|
||||
}
|
||||
else
|
||||
s_instancingBuffer = nullptr;
|
||||
|
||||
if (!NzMaterial::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize materials");
|
||||
|
|
@ -670,12 +644,6 @@ bool NzRenderer::Initialize()
|
|||
bool NzRenderer::IsEnabled(nzRendererParameter parameter)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parameter > nzRendererParameter_Max)
|
||||
{
|
||||
NazaraError("Renderer parameter out of enum");
|
||||
|
|
@ -693,14 +661,6 @@ bool NzRenderer::IsInitialized()
|
|||
|
||||
void NzRenderer::SetBlendFunc(nzBlendFunc srcBlend, nzBlendFunc dstBlend)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
s_states.srcBlend = srcBlend;
|
||||
s_states.dstBlend = dstBlend;
|
||||
}
|
||||
|
|
@ -759,47 +719,23 @@ void NzRenderer::SetClearStencil(unsigned int value)
|
|||
|
||||
void NzRenderer::SetDepthFunc(nzRendererComparison compareFunc)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
s_states.depthFunc = compareFunc;
|
||||
}
|
||||
|
||||
void NzRenderer::SetFaceCulling(nzFaceCulling cullingMode)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
s_states.faceCulling = cullingMode;
|
||||
}
|
||||
|
||||
void NzRenderer::SetFaceFilling(nzFaceFilling fillingMode)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
s_states.faceFilling = fillingMode;
|
||||
}
|
||||
|
||||
void NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (indexBuffer && !indexBuffer->IsSequential() && !indexBuffer->IsHardware())
|
||||
if (indexBuffer && !indexBuffer->IsHardware())
|
||||
{
|
||||
NazaraError("Buffer must be hardware");
|
||||
return;
|
||||
|
|
@ -813,7 +749,7 @@ void NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer)
|
|||
}
|
||||
}
|
||||
|
||||
void NzRenderer::SetInstancingData(const NzRenderer::InstancingData* instancingData, unsigned int instanceCount)
|
||||
void NzRenderer::SetInstancingData(const void* instancingData, unsigned int instanceCount)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!s_capabilities[nzRendererCap_Instancing])
|
||||
|
|
@ -834,27 +770,42 @@ void NzRenderer::SetInstancingData(const NzRenderer::InstancingData* instancingD
|
|||
return;
|
||||
}
|
||||
|
||||
if (instanceCount > NAZARA_RENDERER_MAX_INSTANCES)
|
||||
unsigned int maxInstanceCount = s_instancingBuffer->GetVertexCount();
|
||||
if (instanceCount > maxInstanceCount)
|
||||
{
|
||||
NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")");
|
||||
NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " + NzString::Number(maxInstanceCount) + ")");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!s_instancingBuffer->Fill(instancingData, 0, instanceCount, true))
|
||||
if (!s_instancingBuffer->FillVertices(instancingData, 0, instanceCount, true))
|
||||
NazaraError("Failed to fill instancing buffer");
|
||||
}
|
||||
|
||||
void NzRenderer::SetInstancingDeclaration(const NzVertexDeclaration* declaration, unsigned int* newMaxInstanceCount)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!s_capabilities[nzRendererCap_Instancing])
|
||||
{
|
||||
NazaraError("Instancing not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!declaration)
|
||||
{
|
||||
NazaraError("Declaration must be valid");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
s_instancingBuffer->SetVertexDeclaration(declaration);
|
||||
|
||||
if (newMaxInstanceCount)
|
||||
*newMaxInstanceCount = s_instancingBuffer->GetVertexCount();
|
||||
}
|
||||
|
||||
void NzRenderer::SetLineWidth(float width)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (width <= 0.f)
|
||||
{
|
||||
|
|
@ -914,14 +865,6 @@ void NzRenderer::SetMatrix(nzMatrixType type, const NzMatrix4f& matrix)
|
|||
|
||||
void NzRenderer::SetPointSize(float size)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (size <= 0.f)
|
||||
{
|
||||
|
|
@ -1197,26 +1140,24 @@ void NzRenderer::Uninitialize()
|
|||
// Loaders
|
||||
NzLoaders_Texture_Unregister();
|
||||
|
||||
NzDebugDrawer::Uninitialize();
|
||||
NzMaterial::Uninitialize();
|
||||
NzShaderBuilder::Uninitialize();
|
||||
NzTextureSampler::Uninitialize();
|
||||
NzShaderBuilder::Uninitialize();
|
||||
NzMaterial::Uninitialize();
|
||||
NzDebugDrawer::Uninitialize();
|
||||
|
||||
// Libération des buffers
|
||||
delete s_fullscreenQuadBuffer;
|
||||
|
||||
if (s_instancingBuffer)
|
||||
{
|
||||
delete s_instancingBuffer;
|
||||
s_instancingBuffer = nullptr;
|
||||
}
|
||||
|
||||
// Libération des VAOs
|
||||
for (auto it = s_vaos.begin(); it != s_vaos.end(); ++it)
|
||||
for (auto pair : s_vaos)
|
||||
{
|
||||
GLuint vao = static_cast<GLuint>(it->second);
|
||||
for (auto pair2 : pair.second)
|
||||
{
|
||||
GLuint vao = static_cast<GLuint>(pair2.second);
|
||||
glDeleteVertexArrays(1, &vao);
|
||||
}
|
||||
}
|
||||
|
||||
NzOpenGL::Uninitialize();
|
||||
|
||||
|
|
@ -1355,20 +1296,22 @@ bool NzRenderer::EnsureStateUpdate()
|
|||
// Si les VAOs sont supportés, on entoure nos appels par ceux-ci
|
||||
if (s_useVertexArrayObjects)
|
||||
{
|
||||
// On recherche si un VAO existe déjà avec notre configuration
|
||||
// Note: Les VAOs ne sont pas partagés entre les contextes, ces derniers font donc partie de notre configuration
|
||||
// Note: Les VAOs ne sont pas partagés entre les contextes, nous avons donc un tableau de VAOs par contexte
|
||||
auto vaos = s_vaos[NzContext::GetCurrent()];
|
||||
|
||||
VAO_Key key(NzContext::GetCurrent(), s_indexBuffer, s_vertexBuffer, s_instancing);
|
||||
auto it = s_vaos.find(key);
|
||||
// Notre clé est composée de ce qui définit un VAO
|
||||
VAO_Key key(s_indexBuffer, s_vertexBuffer, s_vertexBuffer->GetVertexDeclaration(), (s_instancing) ? s_instancingDeclaration : nullptr);
|
||||
|
||||
if (it == s_vaos.end())
|
||||
// On recherche un VAO existant avec notre configuration
|
||||
auto it = vaos.find(key);
|
||||
if (it == vaos.end())
|
||||
{
|
||||
// On créé notre VAO
|
||||
glGenVertexArrays(1, &s_currentVAO);
|
||||
glBindVertexArray(s_currentVAO);
|
||||
|
||||
// On l'ajoute à notre liste
|
||||
s_vaos.insert(std::make_pair(key, static_cast<unsigned int>(s_currentVAO)));
|
||||
vaos.insert(std::make_pair(key, static_cast<unsigned int>(s_currentVAO)));
|
||||
|
||||
// Et on indique qu'on veut le programmer
|
||||
update = true;
|
||||
|
|
@ -1386,53 +1329,72 @@ bool NzRenderer::EnsureStateUpdate()
|
|||
|
||||
if (update)
|
||||
{
|
||||
const NzVertexDeclaration* vertexDeclaration;
|
||||
unsigned int bufferOffset;
|
||||
unsigned int stride;
|
||||
|
||||
NzHardwareBuffer* vertexBufferImpl = static_cast<NzHardwareBuffer*>(s_vertexBuffer->GetBuffer()->GetImpl());
|
||||
vertexBufferImpl->Bind();
|
||||
|
||||
const NzVertexDeclaration* vertexDeclaration = s_vertexBuffer->GetVertexDeclaration();
|
||||
|
||||
const nzUInt8* buffer = static_cast<const nzUInt8*>(s_vertexBuffer->GetPointer());
|
||||
unsigned int stride = vertexDeclaration->GetStride(nzElementStream_VertexData);
|
||||
for (unsigned int i = 0; i <= nzElementUsage_Max; ++i)
|
||||
bufferOffset = s_vertexBuffer->GetStartOffset();
|
||||
vertexDeclaration = s_vertexBuffer->GetVertexDeclaration();
|
||||
stride = vertexDeclaration->GetStride();
|
||||
for (unsigned int i = nzAttributeUsage_FirstVertexData; i <= nzAttributeUsage_LastVertexData; ++i)
|
||||
{
|
||||
nzElementUsage usage = static_cast<nzElementUsage>(i);
|
||||
if (vertexDeclaration->HasElement(nzElementStream_VertexData, usage))
|
||||
{
|
||||
const NzVertexElement* element = vertexDeclaration->GetElement(nzElementStream_VertexData, usage);
|
||||
nzAttributeType type;
|
||||
bool enabled;
|
||||
unsigned int offset;
|
||||
vertexDeclaration->GetAttribute(static_cast<nzAttributeUsage>(i), &enabled, &type, &offset);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
glEnableVertexAttribArray(NzOpenGL::AttributeIndex[i]);
|
||||
glVertexAttribPointer(NzOpenGL::AttributeIndex[i],
|
||||
NzVertexDeclaration::GetElementCount(element->type),
|
||||
NzOpenGL::ElementType[element->type],
|
||||
(element->type == nzElementType_Color) ? GL_TRUE : GL_FALSE,
|
||||
NzVertexDeclaration::GetAttributeSize(type),
|
||||
NzOpenGL::AttributeType[type],
|
||||
(type == nzAttributeType_Color) ? GL_TRUE : GL_FALSE,
|
||||
stride,
|
||||
&buffer[element->offset]);
|
||||
reinterpret_cast<void*>(bufferOffset + offset));
|
||||
}
|
||||
else
|
||||
glDisableVertexAttribArray(NzOpenGL::AttributeIndex[i]);
|
||||
}
|
||||
|
||||
unsigned int instanceMatrixIndex = NzOpenGL::AttributeIndex[nzElementUsage_TexCoord] + 8;
|
||||
if (s_instancing)
|
||||
/*if (s_instancing)
|
||||
{
|
||||
static_cast<NzHardwareBuffer*>(s_instancingBuffer->GetImpl())->Bind();
|
||||
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
bufferOffset = s_instancingBuffer->GetStartOffset();
|
||||
vertexDeclaration = s_instancingBuffer->GetVertexDeclaration();
|
||||
stride = vertexDeclaration->GetStride();
|
||||
for (unsigned int i = nzAttributeUsage_FirstInstanceData; i <= nzAttributeUsage_LastInstanceData; ++i)
|
||||
{
|
||||
glEnableVertexAttribArray(instanceMatrixIndex);
|
||||
glVertexAttribPointer(instanceMatrixIndex, 4, GL_FLOAT, GL_FALSE, sizeof(InstancingData), reinterpret_cast<GLvoid*>(offsetof(InstancingData, worldMatrix) + i*sizeof(float)*4));
|
||||
glVertexAttribDivisor(instanceMatrixIndex, 1);
|
||||
nzAttributeType type;
|
||||
bool enabled;
|
||||
unsigned int offset;
|
||||
vertexDeclaration->GetAttribute(static_cast<nzAttributeUsage>(i), &enabled, &offset, &type);
|
||||
|
||||
instanceMatrixIndex++;
|
||||
if (enabled)
|
||||
{
|
||||
glEnableVertexAttribArray(NzOpenGL::AttributeIndex[i]);
|
||||
glVertexAttribPointer(NzOpenGL::AttributeIndex[i],
|
||||
NzVertexDeclaration::GetElementCount(type),
|
||||
NzOpenGL::AttributeType[type],
|
||||
(type == nzAttributeType_Color) ? GL_TRUE : GL_FALSE,
|
||||
stride,
|
||||
reinterpret_cast<void*>(bufferOffset + offset));
|
||||
glVertexAttribDivisor(NzOpenGL::AttributeIndex[i], 1);
|
||||
}
|
||||
else
|
||||
glDisableVertexAttribArray(NzOpenGL::AttributeIndex[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
glDisableVertexAttribArray(instanceMatrixIndex++);
|
||||
}
|
||||
for (unsigned int i = nzAttributeUsage_FirstInstanceData; i <= nzAttributeUsage_LastInstanceData; ++i)
|
||||
glDisableVertexAttribArray(NzOpenGL::AttributeIndex[i]);
|
||||
}*/
|
||||
|
||||
if (s_indexBuffer && !s_indexBuffer->IsSequential())
|
||||
// Et on active l'index buffer (Un seul index buffer par VAO)
|
||||
if (s_indexBuffer)
|
||||
{
|
||||
NzHardwareBuffer* indexBufferImpl = static_cast<NzHardwareBuffer*>(s_indexBuffer->GetBuffer()->GetImpl());
|
||||
indexBufferImpl->Bind();
|
||||
|
|
@ -1453,7 +1415,7 @@ bool NzRenderer::EnsureStateUpdate()
|
|||
}
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (s_updateFlags != Update_None)
|
||||
if (s_updateFlags != Update_None && !s_useVertexArrayObjects && s_updateFlags != Update_VAO)
|
||||
NazaraWarning("Update flags not fully cleared");
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1463,6 +1425,8 @@ bool NzRenderer::EnsureStateUpdate()
|
|||
glBindVertexArray(s_currentVAO);
|
||||
|
||||
// On vérifie que les textures actuellement bindées sont bien nos textures
|
||||
// Ceci à cause du fait qu'il est possible que des opérations sur les textures ait eu lieu
|
||||
// entre le dernier rendu et maintenant
|
||||
for (unsigned int i = 0; i < s_maxTextureUnit; ++i)
|
||||
{
|
||||
const NzTexture* texture = s_textureUnits[i].texture;
|
||||
|
|
@ -1470,6 +1434,7 @@ bool NzRenderer::EnsureStateUpdate()
|
|||
NzOpenGL::BindTexture(i, texture->GetType(), texture->GetOpenGLID());
|
||||
}
|
||||
|
||||
// Et on termine par envoyer nos états à OpenGL
|
||||
NzOpenGL::ApplyStates(s_states);
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -22,17 +22,16 @@ namespace
|
|||
|
||||
NzBuffer::NzBuffer(nzBufferType type) :
|
||||
m_type(type),
|
||||
m_typeSize(0),
|
||||
m_impl(nullptr),
|
||||
m_length(0)
|
||||
m_size(0)
|
||||
{
|
||||
}
|
||||
|
||||
NzBuffer::NzBuffer(nzBufferType type, unsigned int length, nzUInt8 typeSize, nzBufferStorage storage, nzBufferUsage usage) :
|
||||
NzBuffer::NzBuffer(nzBufferType type, unsigned int size, nzBufferStorage storage, nzBufferUsage usage) :
|
||||
m_type(type),
|
||||
m_impl(nullptr)
|
||||
{
|
||||
Create(length, typeSize, storage, usage);
|
||||
Create(size, storage, usage);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
|
|
@ -62,20 +61,14 @@ bool NzBuffer::CopyContent(const NzBuffer& buffer)
|
|||
NazaraError("Source buffer must be valid");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!buffer.GetTypeSize() != m_typeSize)
|
||||
{
|
||||
NazaraError("Source buffer type size does not match buffer type size");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
NzBufferMapper<NzBuffer> mapper(buffer, nzBufferAccess_ReadOnly);
|
||||
|
||||
return Fill(mapper.GetPointer(), 0, buffer.GetLength());
|
||||
return Fill(mapper.GetPointer(), 0, buffer.GetSize());
|
||||
}
|
||||
|
||||
bool NzBuffer::Create(unsigned int length, nzUInt8 typeSize, nzBufferStorage storage, nzBufferUsage usage)
|
||||
bool NzBuffer::Create(unsigned int size, nzBufferStorage storage, nzBufferUsage usage)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
|
|
@ -87,7 +80,7 @@ bool NzBuffer::Create(unsigned int length, nzUInt8 typeSize, nzBufferStorage sto
|
|||
}
|
||||
|
||||
NzAbstractBuffer* impl = s_bufferFunctions[storage](this, m_type);
|
||||
if (!impl->Create(length*typeSize, usage))
|
||||
if (!impl->Create(size, usage))
|
||||
{
|
||||
NazaraError("Failed to create buffer");
|
||||
delete impl;
|
||||
|
|
@ -96,8 +89,7 @@ bool NzBuffer::Create(unsigned int length, nzUInt8 typeSize, nzBufferStorage sto
|
|||
}
|
||||
|
||||
m_impl = impl;
|
||||
m_length = length;
|
||||
m_typeSize = typeSize;
|
||||
m_size = size;
|
||||
m_storage = storage;
|
||||
m_usage = usage;
|
||||
|
||||
|
|
@ -117,7 +109,7 @@ void NzBuffer::Destroy()
|
|||
}
|
||||
}
|
||||
|
||||
bool NzBuffer::Fill(const void* data, unsigned int offset, unsigned int length, bool forceDiscard)
|
||||
bool NzBuffer::Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
|
|
@ -126,14 +118,14 @@ bool NzBuffer::Fill(const void* data, unsigned int offset, unsigned int length,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (offset+length > m_length)
|
||||
if (offset+size > m_size)
|
||||
{
|
||||
NazaraError("Exceeding buffer size");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->Fill(data, offset*m_typeSize, ((length == 0) ? m_length-offset : length)*m_typeSize, forceDiscard);
|
||||
return m_impl->Fill(data, offset, (size == 0) ? m_size-offset : size, forceDiscard);
|
||||
}
|
||||
|
||||
NzAbstractBuffer* NzBuffer::GetImpl() const
|
||||
|
|
@ -141,40 +133,9 @@ NzAbstractBuffer* NzBuffer::GetImpl() const
|
|||
return m_impl;
|
||||
}
|
||||
|
||||
unsigned int NzBuffer::GetLength() const
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
void* NzBuffer::GetPointer()
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->GetPointer();
|
||||
}
|
||||
|
||||
const void* NzBuffer::GetPointer() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Buffer not valid");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->GetPointer();
|
||||
}
|
||||
|
||||
unsigned int NzBuffer::GetSize() const
|
||||
{
|
||||
return m_length*m_typeSize;
|
||||
return m_size;
|
||||
}
|
||||
|
||||
nzBufferStorage NzBuffer::GetStorage() const
|
||||
|
|
@ -187,11 +148,6 @@ nzBufferType NzBuffer::GetType() const
|
|||
return m_type;
|
||||
}
|
||||
|
||||
nzUInt8 NzBuffer::GetTypeSize() const
|
||||
{
|
||||
return m_typeSize;
|
||||
}
|
||||
|
||||
nzBufferUsage NzBuffer::GetUsage() const
|
||||
{
|
||||
return m_usage;
|
||||
|
|
@ -207,7 +163,7 @@ bool NzBuffer::IsValid() const
|
|||
return m_impl != nullptr;
|
||||
}
|
||||
|
||||
void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
|
||||
void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
|
|
@ -216,17 +172,17 @@ void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int len
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (offset+length > m_length)
|
||||
if (offset+size > m_size)
|
||||
{
|
||||
NazaraError("Exceeding buffer size");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->Map(access, offset*m_typeSize, ((length == 0) ? m_length-offset : length)*m_typeSize);
|
||||
return m_impl->Map(access, offset, (size == 0) ? m_size-offset : size);
|
||||
}
|
||||
|
||||
void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length) const
|
||||
void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
|
|
@ -241,14 +197,14 @@ void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int len
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (offset+length > m_length)
|
||||
if (offset+size > m_size)
|
||||
{
|
||||
NazaraError("Exceeding buffer size");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->Map(access, offset*m_typeSize, ((length == 0) ? m_length-offset : length)*m_typeSize);
|
||||
return m_impl->Map(access, offset, (size == 0) ? m_size-offset : size);
|
||||
}
|
||||
|
||||
bool NzBuffer::SetStorage(nzBufferStorage storage)
|
||||
|
|
@ -272,7 +228,7 @@ bool NzBuffer::SetStorage(nzBufferStorage storage)
|
|||
}
|
||||
#endif
|
||||
|
||||
void* ptr = m_impl->Map(nzBufferAccess_ReadOnly, 0, m_length*m_typeSize);
|
||||
void* ptr = m_impl->Map(nzBufferAccess_ReadOnly, 0, m_size);
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map buffer");
|
||||
|
|
@ -280,7 +236,7 @@ bool NzBuffer::SetStorage(nzBufferStorage storage)
|
|||
}
|
||||
|
||||
NzAbstractBuffer* impl = s_bufferFunctions[storage](this, m_type);
|
||||
if (!impl->Create(m_length*m_typeSize, m_usage))
|
||||
if (!impl->Create(m_size, m_usage))
|
||||
{
|
||||
NazaraError("Failed to create buffer");
|
||||
delete impl;
|
||||
|
|
@ -289,7 +245,7 @@ bool NzBuffer::SetStorage(nzBufferStorage storage)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!impl->Fill(ptr, 0, m_length*m_typeSize))
|
||||
if (!impl->Fill(ptr, 0, m_size))
|
||||
{
|
||||
NazaraError("Failed to fill buffer");
|
||||
impl->Destroy();
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ m_sharedImage(&emptyImage)
|
|||
}
|
||||
|
||||
NzImage::NzImage(const NzImage& image) :
|
||||
NzResource(image),
|
||||
NzResource(),
|
||||
m_sharedImage(image.m_sharedImage)
|
||||
{
|
||||
if (m_sharedImage != &emptyImage)
|
||||
|
|
@ -63,6 +63,11 @@ m_sharedImage(image.m_sharedImage)
|
|||
image.m_sharedImage = &emptyImage;
|
||||
}
|
||||
|
||||
NzImage::NzImage(SharedImage* sharedImage) :
|
||||
m_sharedImage(sharedImage)
|
||||
{
|
||||
}
|
||||
|
||||
NzImage::~NzImage()
|
||||
{
|
||||
Destroy();
|
||||
|
|
|
|||
|
|
@ -11,62 +11,65 @@
|
|||
#include <stdexcept>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
///FIXME: Gérer efficacement les erreurs de création du buffer
|
||||
|
||||
NzIndexBuffer::NzIndexBuffer(NzBuffer* buffer, unsigned int startIndex, unsigned int indexCount) :
|
||||
NzIndexBuffer::NzIndexBuffer(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset) :
|
||||
m_buffer(buffer),
|
||||
m_ownsBuffer(false),
|
||||
m_indexCount(indexCount),
|
||||
m_startIndex(startIndex)
|
||||
m_largeIndices(largeIndices),
|
||||
m_endOffset(endOffset),
|
||||
m_startOffset(startOffset)
|
||||
{
|
||||
if (m_buffer)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
nzUInt8 indexSize = m_buffer->GetSize();
|
||||
if (indexSize != 2 && indexSize != 4)
|
||||
if (!m_buffer || !m_buffer->IsValid())
|
||||
{
|
||||
NazaraError("Invalid index size (" + NzString::Number(indexSize) + ')');
|
||||
m_buffer = nullptr;
|
||||
NazaraError("Buffer is invalid");
|
||||
throw std::invalid_argument("Buffer must be valid");
|
||||
}
|
||||
|
||||
throw std::runtime_error("Constructor failed");
|
||||
if (endOffset > startOffset)
|
||||
{
|
||||
NazaraError("End offset cannot be over start offset");
|
||||
throw std::invalid_argument("End offset cannot be over start offset");
|
||||
}
|
||||
|
||||
unsigned int bufferSize = m_buffer->GetSize();
|
||||
if (startOffset >= bufferSize)
|
||||
{
|
||||
NazaraError("Start offset is over buffer size");
|
||||
throw std::invalid_argument("Start offset is over buffer size");
|
||||
}
|
||||
|
||||
if (endOffset >= bufferSize)
|
||||
{
|
||||
NazaraError("End offset is over buffer size");
|
||||
throw std::invalid_argument("End offset is over buffer size");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int stride = (largeIndices) ? sizeof(nzUInt32) : sizeof(nzUInt16);
|
||||
|
||||
m_indexCount = (endOffset - startOffset) / stride;
|
||||
}
|
||||
|
||||
NzIndexBuffer::NzIndexBuffer(unsigned int length, bool largeIndices, nzBufferStorage storage, nzBufferUsage usage) :
|
||||
m_ownsBuffer(true),
|
||||
NzIndexBuffer::NzIndexBuffer(bool largeIndices, unsigned int length, nzBufferStorage storage, nzBufferUsage usage) :
|
||||
m_largeIndices(largeIndices),
|
||||
m_indexCount(length),
|
||||
m_startIndex(0)
|
||||
m_startOffset(0)
|
||||
{
|
||||
m_buffer = new NzBuffer(nzBufferType_Index, length, (largeIndices) ? 4 : 2, storage, usage);
|
||||
m_endOffset = length * ((largeIndices) ? sizeof(nzUInt32) : sizeof(nzUInt16));
|
||||
|
||||
m_buffer = new NzBuffer(nzBufferType_Index, m_endOffset, storage, usage);
|
||||
m_buffer->SetPersistent(false);
|
||||
}
|
||||
|
||||
NzIndexBuffer::NzIndexBuffer(const NzIndexBuffer& indexBuffer) :
|
||||
NzResource(true),
|
||||
NzResource(),
|
||||
m_buffer(indexBuffer.m_buffer),
|
||||
m_ownsBuffer(indexBuffer.m_ownsBuffer),
|
||||
m_largeIndices(indexBuffer.m_largeIndices),
|
||||
m_endOffset(indexBuffer.m_endOffset),
|
||||
m_indexCount(indexBuffer.m_indexCount),
|
||||
m_startIndex(indexBuffer.m_startIndex)
|
||||
m_startOffset(indexBuffer.m_startOffset)
|
||||
{
|
||||
if (m_buffer)
|
||||
{
|
||||
if (m_ownsBuffer)
|
||||
{
|
||||
NzBuffer* buffer = indexBuffer.m_buffer;
|
||||
|
||||
m_buffer = new NzBuffer(nzBufferType_Index, buffer->GetLength(), buffer->GetSize(), buffer->GetStorage(), buffer->GetUsage());
|
||||
m_buffer->SetPersistent(false);
|
||||
m_buffer->CopyContent(*indexBuffer.m_buffer);
|
||||
}
|
||||
else
|
||||
m_buffer = indexBuffer.m_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
NzIndexBuffer::~NzIndexBuffer() = default;
|
||||
|
||||
unsigned int NzIndexBuffer::ComputeCacheMissCount() const
|
||||
{
|
||||
NzIndexMapper mapper(this);
|
||||
|
|
@ -74,23 +77,23 @@ unsigned int NzIndexBuffer::ComputeCacheMissCount() const
|
|||
return NzComputeCacheMissCount(mapper.begin(), m_indexCount);
|
||||
}
|
||||
|
||||
bool NzIndexBuffer::Fill(const void* data, unsigned int offset, unsigned int length, bool forceDiscard)
|
||||
bool NzIndexBuffer::Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Impossible to fill sequential buffers");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (offset+length > m_indexCount)
|
||||
if (m_startOffset + offset + size > m_endOffset)
|
||||
{
|
||||
NazaraError("Exceeding virtual buffer size");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_buffer->Fill(data, m_startIndex+offset, length, forceDiscard);
|
||||
return m_buffer->Fill(data, m_startOffset+offset, size, forceDiscard);
|
||||
}
|
||||
|
||||
bool NzIndexBuffer::FillIndices(const void* data, unsigned int startIndex, unsigned int length, bool forceDiscard)
|
||||
{
|
||||
unsigned int stride = GetStride();
|
||||
return Fill(data, startIndex*stride, length*stride, forceDiscard);
|
||||
}
|
||||
|
||||
NzBuffer* NzIndexBuffer::GetBuffer() const
|
||||
|
|
@ -98,30 +101,9 @@ NzBuffer* NzIndexBuffer::GetBuffer() const
|
|||
return m_buffer;
|
||||
}
|
||||
|
||||
void* NzIndexBuffer::GetPointer()
|
||||
unsigned int NzIndexBuffer::GetEndOffset() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Sequential buffers have no pointer");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return reinterpret_cast<nzUInt8*>(m_buffer->GetPointer()) + m_startIndex*m_buffer->GetTypeSize();
|
||||
}
|
||||
|
||||
const void* NzIndexBuffer::GetPointer() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Sequential buffers have no pointer");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return reinterpret_cast<const nzUInt8*>(m_buffer->GetPointer()) + m_startIndex*m_buffer->GetTypeSize();
|
||||
return m_endOffset;
|
||||
}
|
||||
|
||||
unsigned int NzIndexBuffer::GetIndexCount() const
|
||||
|
|
@ -129,78 +111,64 @@ unsigned int NzIndexBuffer::GetIndexCount() const
|
|||
return m_indexCount;
|
||||
}
|
||||
|
||||
unsigned int NzIndexBuffer::GetStartIndex() const
|
||||
unsigned int NzIndexBuffer::GetStride() const
|
||||
{
|
||||
return m_startIndex;
|
||||
return (m_largeIndices) ? sizeof(nzUInt32) : sizeof(nzUInt16);
|
||||
}
|
||||
|
||||
unsigned int NzIndexBuffer::GetStartOffset() const
|
||||
{
|
||||
return m_startOffset;
|
||||
}
|
||||
|
||||
bool NzIndexBuffer::HasLargeIndices() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Sequential buffers have no index size");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (m_buffer->GetTypeSize() == 4);
|
||||
return m_largeIndices;
|
||||
}
|
||||
|
||||
bool NzIndexBuffer::IsHardware() const
|
||||
{
|
||||
return m_buffer->IsHardware();
|
||||
}
|
||||
|
||||
void* NzIndexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
if (m_startOffset + offset + size > m_endOffset)
|
||||
{
|
||||
NazaraWarning("Sequential index buffers are neither hardware or software");
|
||||
NazaraError("Exceeding virtual buffer size");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_buffer->IsHardware();
|
||||
return m_buffer->Map(access, offset, size);
|
||||
}
|
||||
|
||||
bool NzIndexBuffer::IsSequential() const
|
||||
{
|
||||
return m_buffer == nullptr;
|
||||
}
|
||||
|
||||
void* NzIndexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
|
||||
void* NzIndexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Impossible to map sequential buffers");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (offset+length > m_indexCount)
|
||||
if (m_startOffset + offset + size > m_endOffset)
|
||||
{
|
||||
NazaraError("Exceeding virtual buffer size");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_buffer->Map(access, m_startIndex+offset, (length) ? length : m_indexCount-offset);
|
||||
return m_buffer->Map(access, offset, size);
|
||||
}
|
||||
|
||||
void* NzIndexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length) const
|
||||
void* NzIndexBuffer::MapIndices(nzBufferAccess access, unsigned int startIndex, unsigned int length)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Impossible to map sequential buffers");
|
||||
return nullptr;
|
||||
}
|
||||
unsigned int stride = GetStride();
|
||||
|
||||
if (offset+length > m_indexCount)
|
||||
{
|
||||
NazaraError("Exceeding virtual buffer size");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
return Map(access, startIndex*stride, length*stride);
|
||||
}
|
||||
|
||||
return m_buffer->Map(access, m_startIndex+offset, (length) ? length : m_indexCount-offset);
|
||||
void* NzIndexBuffer::MapIndices(nzBufferAccess access, unsigned int startIndex, unsigned int length) const
|
||||
{
|
||||
unsigned int stride = GetStride();
|
||||
|
||||
return Map(access, startIndex*stride, length*stride);
|
||||
}
|
||||
|
||||
void NzIndexBuffer::Optimize()
|
||||
|
|
@ -212,26 +180,10 @@ void NzIndexBuffer::Optimize()
|
|||
|
||||
bool NzIndexBuffer::SetStorage(nzBufferStorage storage)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraWarning("Sequential buffers have no storage");
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_buffer->SetStorage(storage);
|
||||
}
|
||||
|
||||
void NzIndexBuffer::Unmap() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_buffer)
|
||||
{
|
||||
NazaraError("Impossible to unlock sequential buffers");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_buffer->Unmap();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,13 +22,6 @@ namespace
|
|||
return ptr[i];
|
||||
}
|
||||
|
||||
nzUInt32 GetterSequential(const void* buffer, unsigned int i)
|
||||
{
|
||||
NazaraUnused(buffer);
|
||||
|
||||
return static_cast<nzUInt32>(i);
|
||||
}
|
||||
|
||||
void Setter16(void* buffer, unsigned int i, nzUInt32 value)
|
||||
{
|
||||
nzUInt16* ptr = reinterpret_cast<nzUInt16*>(buffer);
|
||||
|
|
@ -50,8 +43,14 @@ namespace
|
|||
NzIndexMapper::NzIndexMapper(NzIndexBuffer* indexBuffer, nzBufferAccess access) :
|
||||
m_indexCount(indexBuffer->GetIndexCount())
|
||||
{
|
||||
if (indexBuffer && !indexBuffer->IsSequential())
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!indexBuffer)
|
||||
{
|
||||
NazaraError("Index buffer must be valid");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_mapper.Map(indexBuffer, access))
|
||||
NazaraError("Failed to map buffer"); ///TODO: Unexcepted
|
||||
|
||||
|
|
@ -71,20 +70,20 @@ m_indexCount(indexBuffer->GetIndexCount())
|
|||
else
|
||||
m_setter = SetterError;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_getter = GetterSequential;
|
||||
m_setter = SetterError;
|
||||
}
|
||||
}
|
||||
|
||||
NzIndexMapper::NzIndexMapper(const NzIndexBuffer* indexBuffer, nzBufferAccess access) :
|
||||
m_setter(SetterError),
|
||||
m_indexCount(indexBuffer->GetIndexCount())
|
||||
{
|
||||
if (indexBuffer && !indexBuffer->IsSequential())
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!indexBuffer)
|
||||
{
|
||||
NazaraError("Index buffer must be valid");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_mapper.Map(indexBuffer, access))
|
||||
NazaraError("Failed to map buffer"); ///TODO: Unexcepted
|
||||
|
||||
|
|
@ -92,9 +91,6 @@ m_indexCount(indexBuffer->GetIndexCount())
|
|||
m_getter = Getter32;
|
||||
else
|
||||
m_getter = Getter16;
|
||||
}
|
||||
else
|
||||
m_getter = GetterSequential;
|
||||
}
|
||||
|
||||
NzIndexMapper::NzIndexMapper(const NzSubMesh* subMesh) :
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ namespace
|
|||
|
||||
/// Chargement des submesh
|
||||
// Actuellement le loader ne charge qu'un submesh
|
||||
std::unique_ptr<NzIndexBuffer> indexBuffer(new NzIndexBuffer(header.num_tris * 3, false, parameters.storage, nzBufferUsage_Static));
|
||||
std::unique_ptr<NzIndexBuffer> indexBuffer(new NzIndexBuffer(false, header.num_tris * 3, parameters.storage, nzBufferUsage_Static));
|
||||
indexBuffer->SetPersistent(false);
|
||||
|
||||
/// Lecture des triangles
|
||||
|
|
@ -149,7 +149,7 @@ namespace
|
|||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<NzVertexBuffer> vertexBuffer(new NzVertexBuffer(NzMesh::GetDeclaration(), header.num_vertices, parameters.storage, nzBufferUsage_Static));
|
||||
std::unique_ptr<NzVertexBuffer> vertexBuffer(new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), header.num_vertices, parameters.storage, nzBufferUsage_Static));
|
||||
std::unique_ptr<NzStaticMesh> subMesh(new NzStaticMesh(mesh));
|
||||
if (!subMesh->Create(vertexBuffer.get()))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
|||
// Index buffer
|
||||
bool largeIndices = (vertexCount > std::numeric_limits<nzUInt16>::max());
|
||||
|
||||
std::unique_ptr<NzIndexBuffer> indexBuffer(new NzIndexBuffer(indexCount, largeIndices, m_parameters.storage));
|
||||
std::unique_ptr<NzIndexBuffer> indexBuffer(new NzIndexBuffer(largeIndices, indexCount, m_parameters.storage));
|
||||
indexBuffer->SetPersistent(false);
|
||||
|
||||
NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_DiscardAndWrite);
|
||||
|
|
@ -308,7 +308,7 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh)
|
|||
indexMapper.Unmap();
|
||||
|
||||
// Vertex buffer
|
||||
std::unique_ptr<NzVertexBuffer> vertexBuffer(new NzVertexBuffer(NzMesh::GetDeclaration(), vertexCount, m_parameters.storage));
|
||||
std::unique_ptr<NzVertexBuffer> vertexBuffer(new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), vertexCount, m_parameters.storage));
|
||||
NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
|
||||
|
||||
NzMeshVertex* vertex = reinterpret_cast<NzMeshVertex*>(vertexMapper.GetPointer());
|
||||
|
|
|
|||
|
|
@ -170,6 +170,8 @@ NzSubMesh* NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams
|
|||
NzMatrix4f matrix(primitive.matrix);
|
||||
matrix.ApplyScale(params.scale);
|
||||
|
||||
NzVertexDeclaration* declaration = NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent);
|
||||
|
||||
switch (primitive.type)
|
||||
{
|
||||
case nzPrimitiveType_Box:
|
||||
|
|
@ -181,7 +183,7 @@ NzSubMesh* NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams
|
|||
indexBuffer.reset(new NzIndexBuffer(indexCount, vertexCount > std::numeric_limits<nzUInt16>::max(), params.storage, nzBufferUsage_Static));
|
||||
indexBuffer->SetPersistent(false);
|
||||
|
||||
vertexBuffer.reset(new NzVertexBuffer(GetDeclaration(), vertexCount, params.storage, nzBufferUsage_Static));
|
||||
vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
|
||||
vertexBuffer->SetPersistent(false);
|
||||
|
||||
NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
|
||||
|
|
@ -200,7 +202,7 @@ NzSubMesh* NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams
|
|||
indexBuffer.reset(new NzIndexBuffer(indexCount, vertexCount > std::numeric_limits<nzUInt16>::max(), params.storage, nzBufferUsage_Static));
|
||||
indexBuffer->SetPersistent(false);
|
||||
|
||||
vertexBuffer.reset(new NzVertexBuffer(GetDeclaration(), vertexCount, params.storage, nzBufferUsage_Static));
|
||||
vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
|
||||
vertexBuffer->SetPersistent(false);
|
||||
|
||||
NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
|
||||
|
|
@ -223,7 +225,7 @@ NzSubMesh* NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams
|
|||
indexBuffer.reset(new NzIndexBuffer(indexCount, vertexCount > std::numeric_limits<nzUInt16>::max(), params.storage, nzBufferUsage_Static));
|
||||
indexBuffer->SetPersistent(false);
|
||||
|
||||
vertexBuffer.reset(new NzVertexBuffer(GetDeclaration(), vertexCount, params.storage, nzBufferUsage_Static));
|
||||
vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
|
||||
vertexBuffer->SetPersistent(false);
|
||||
|
||||
NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
|
||||
|
|
@ -242,7 +244,7 @@ NzSubMesh* NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams
|
|||
indexBuffer.reset(new NzIndexBuffer(indexCount, vertexCount > std::numeric_limits<nzUInt16>::max(), params.storage, nzBufferUsage_Static));
|
||||
indexBuffer->SetPersistent(false);
|
||||
|
||||
vertexBuffer.reset(new NzVertexBuffer(GetDeclaration(), vertexCount, params.storage, nzBufferUsage_Static));
|
||||
vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
|
||||
vertexBuffer->SetPersistent(false);
|
||||
|
||||
NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
|
||||
|
|
@ -261,7 +263,7 @@ NzSubMesh* NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams
|
|||
indexBuffer.reset(new NzIndexBuffer(indexCount, vertexCount > std::numeric_limits<nzUInt16>::max(), params.storage, nzBufferUsage_Static));
|
||||
indexBuffer->SetPersistent(false);
|
||||
|
||||
vertexBuffer.reset(new NzVertexBuffer(GetDeclaration(), vertexCount, params.storage, nzBufferUsage_Static));
|
||||
vertexBuffer.reset(new NzVertexBuffer(declaration, vertexCount, params.storage, nzBufferUsage_Static));
|
||||
vertexBuffer->SetPersistent(false);
|
||||
|
||||
NzBufferMapper<NzVertexBuffer> vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly);
|
||||
|
|
@ -979,36 +981,6 @@ void NzMesh::Transform(const NzMatrix4f& matrix)
|
|||
m_impl->aabbUpdated = false;
|
||||
}
|
||||
|
||||
const NzVertexDeclaration* NzMesh::GetDeclaration()
|
||||
{
|
||||
static NzVertexDeclaration declaration;
|
||||
|
||||
if (!declaration.IsValid())
|
||||
{
|
||||
// Déclaration correspondant à NzVertexStruct_XYZ_Normal_UV_Tangent
|
||||
NzVertexElement elements[4];
|
||||
elements[0].offset = 0;
|
||||
elements[0].type = nzElementType_Float3;
|
||||
elements[0].usage = nzElementUsage_Position;
|
||||
|
||||
elements[1].offset = 3*sizeof(float);
|
||||
elements[1].type = nzElementType_Float3;
|
||||
elements[1].usage = nzElementUsage_Normal;
|
||||
|
||||
elements[2].offset = 3*sizeof(float) + 3*sizeof(float);
|
||||
elements[2].type = nzElementType_Float2;
|
||||
elements[2].usage = nzElementUsage_TexCoord;
|
||||
|
||||
elements[3].offset = 3*sizeof(float) + 3*sizeof(float) + 2*sizeof(float);
|
||||
elements[3].type = nzElementType_Float3;
|
||||
elements[3].usage = nzElementUsage_Tangent;
|
||||
|
||||
declaration.Create(elements, 4);
|
||||
}
|
||||
|
||||
return &declaration;
|
||||
}
|
||||
|
||||
void NzMesh::OnResourceReleased(const NzResource* resource, int index)
|
||||
{
|
||||
NazaraUnused(resource);
|
||||
|
|
|
|||
|
|
@ -61,11 +61,6 @@ bool NzSoftwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
|
|||
return true;
|
||||
}
|
||||
|
||||
void* NzSoftwareBuffer::GetPointer()
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
bool NzSoftwareBuffer::IsHardware() const
|
||||
{
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ class NzSoftwareBuffer : public NzAbstractBuffer
|
|||
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard);
|
||||
|
||||
void* GetPointer();
|
||||
|
||||
bool IsHardware() const;
|
||||
|
||||
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <Nazara/Utility/Loaders/PCX.hpp>
|
||||
#include <Nazara/Utility/Loaders/STB.hpp>
|
||||
#include <Nazara/Utility/PixelFormat.hpp>
|
||||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||
#include <Nazara/Utility/Window.hpp>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
|
|
@ -60,6 +61,14 @@ bool NzUtility::Initialize()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!NzVertexDeclaration::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize vertex declarations");
|
||||
Uninitialize();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NzWindow::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize window's system");
|
||||
|
|
@ -117,6 +126,7 @@ void NzUtility::Uninitialize()
|
|||
NzLoaders_STB_Unregister();
|
||||
|
||||
NzWindow::Uninitialize();
|
||||
NzVertexDeclaration::Uninitialize();
|
||||
NzPixelFormat::Uninitialize();
|
||||
NzBuffer::Uninitialize();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,80 +7,95 @@
|
|||
#include <stdexcept>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
///FIXME: Gérer efficacement les erreurs de création du buffer
|
||||
|
||||
NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startVertex, unsigned int vertexCount) :
|
||||
NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset) :
|
||||
m_buffer(buffer),
|
||||
m_vertexDeclaration(vertexDeclaration),
|
||||
m_ownsBuffer(false),
|
||||
m_startVertex(startVertex),
|
||||
m_vertexCount(vertexCount)
|
||||
m_endOffset(endOffset),
|
||||
m_startOffset(startOffset)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_vertexDeclaration)
|
||||
{
|
||||
NazaraError("Vertex declaration is invalid");
|
||||
throw std::invalid_argument("Invalid vertex declaration");
|
||||
}
|
||||
|
||||
if (!m_buffer || !m_buffer->IsValid())
|
||||
{
|
||||
NazaraError("Buffer is invalid");
|
||||
throw std::invalid_argument("Buffer must be valid");
|
||||
}
|
||||
|
||||
if (!m_vertexDeclaration || !m_vertexDeclaration->IsValid())
|
||||
if (endOffset > startOffset)
|
||||
{
|
||||
NazaraError("Vertex declaration is invalid");
|
||||
throw std::invalid_argument("Invalid vertex declaration");
|
||||
NazaraError("End offset cannot be over start offset");
|
||||
throw std::invalid_argument("End offset cannot be over start offset");
|
||||
}
|
||||
|
||||
unsigned int bufferSize = m_buffer->GetSize();
|
||||
if (startOffset >= bufferSize)
|
||||
{
|
||||
NazaraError("Start offset is over buffer size");
|
||||
throw std::invalid_argument("Start offset is over buffer size");
|
||||
}
|
||||
|
||||
if (endOffset >= bufferSize)
|
||||
{
|
||||
NazaraError("End offset is over buffer size");
|
||||
throw std::invalid_argument("End offset is over buffer size");
|
||||
}
|
||||
#endif
|
||||
|
||||
m_vertexCount = (endOffset - startOffset) / m_vertexDeclaration->GetStride();
|
||||
}
|
||||
|
||||
NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzBufferStorage storage, nzBufferUsage usage) :
|
||||
m_vertexDeclaration(vertexDeclaration),
|
||||
m_ownsBuffer(true),
|
||||
m_startVertex(0),
|
||||
m_startOffset(0),
|
||||
m_vertexCount(length)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_vertexDeclaration || !m_vertexDeclaration->IsValid())
|
||||
if (!m_vertexDeclaration)
|
||||
{
|
||||
NazaraError("Vertex declaration is invalid");
|
||||
throw std::invalid_argument("Invalid vertex declaration");
|
||||
}
|
||||
#endif
|
||||
|
||||
m_buffer = new NzBuffer(nzBufferType_Vertex, length, vertexDeclaration->GetStride(nzElementStream_VertexData), storage, usage);
|
||||
m_endOffset = length*vertexDeclaration->GetStride();
|
||||
|
||||
m_buffer = new NzBuffer(nzBufferType_Vertex, m_endOffset, storage, usage);
|
||||
m_buffer->SetPersistent(false);
|
||||
}
|
||||
|
||||
NzVertexBuffer::NzVertexBuffer(const NzVertexBuffer& vertexBuffer) :
|
||||
NzResource(true),
|
||||
NzResource(),
|
||||
m_buffer(vertexBuffer.m_buffer),
|
||||
m_vertexDeclaration(vertexBuffer.m_vertexDeclaration),
|
||||
m_ownsBuffer(vertexBuffer.m_ownsBuffer),
|
||||
m_startVertex(vertexBuffer.m_startVertex),
|
||||
m_endOffset(vertexBuffer.m_endOffset),
|
||||
m_startOffset(vertexBuffer.m_startOffset),
|
||||
m_vertexCount(vertexBuffer.m_vertexCount)
|
||||
{
|
||||
if (m_ownsBuffer)
|
||||
{
|
||||
NzBuffer* buffer = vertexBuffer.m_buffer;
|
||||
|
||||
m_buffer = new NzBuffer(nzBufferType_Vertex, buffer->GetLength(), buffer->GetSize(), buffer->GetStorage(), buffer->GetUsage());
|
||||
m_buffer->SetPersistent(false);
|
||||
m_buffer->CopyContent(*vertexBuffer.m_buffer);
|
||||
}
|
||||
else
|
||||
m_buffer = vertexBuffer.m_buffer;
|
||||
}
|
||||
|
||||
NzVertexBuffer::~NzVertexBuffer() = default;
|
||||
|
||||
bool NzVertexBuffer::Fill(const void* data, unsigned int offset, unsigned int length, bool forceDiscard)
|
||||
bool NzVertexBuffer::Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (offset+length > m_vertexCount)
|
||||
if (m_startOffset + offset + size > m_endOffset)
|
||||
{
|
||||
NazaraError("Exceeding virtual buffer size");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_buffer->Fill(data, m_startVertex+offset, length, forceDiscard);
|
||||
return m_buffer->Fill(data, m_startOffset+offset, size, forceDiscard);
|
||||
}
|
||||
|
||||
bool NzVertexBuffer::FillVertices(const void* data, unsigned int startVertex, unsigned int length, bool forceDiscard)
|
||||
{
|
||||
unsigned int stride = m_vertexDeclaration->GetStride();
|
||||
|
||||
return Fill(data, startVertex*stride, length*stride, forceDiscard);
|
||||
}
|
||||
|
||||
NzBuffer* NzVertexBuffer::GetBuffer() const
|
||||
|
|
@ -88,24 +103,19 @@ NzBuffer* NzVertexBuffer::GetBuffer() const
|
|||
return m_buffer;
|
||||
}
|
||||
|
||||
void* NzVertexBuffer::GetPointer()
|
||||
unsigned int NzVertexBuffer::GetEndOffset() const
|
||||
{
|
||||
return reinterpret_cast<nzUInt8*>(m_buffer->GetPointer()) + m_startVertex*m_buffer->GetTypeSize();
|
||||
return m_endOffset;
|
||||
}
|
||||
|
||||
const void* NzVertexBuffer::GetPointer() const
|
||||
unsigned int NzVertexBuffer::GetStartOffset() const
|
||||
{
|
||||
return reinterpret_cast<const nzUInt8*>(m_buffer->GetPointer()) + m_startVertex*m_buffer->GetTypeSize();
|
||||
return m_startOffset;
|
||||
}
|
||||
|
||||
unsigned int NzVertexBuffer::GetStartVertex() const
|
||||
unsigned int NzVertexBuffer::GetStride() const
|
||||
{
|
||||
return m_startVertex;
|
||||
}
|
||||
|
||||
nzUInt8 NzVertexBuffer::GetTypeSize() const
|
||||
{
|
||||
return m_buffer->GetTypeSize();
|
||||
return m_vertexDeclaration->GetStride();
|
||||
}
|
||||
|
||||
unsigned int NzVertexBuffer::GetVertexCount() const
|
||||
|
|
@ -123,30 +133,44 @@ bool NzVertexBuffer::IsHardware() const
|
|||
return m_buffer->IsHardware();
|
||||
}
|
||||
|
||||
void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
|
||||
void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (offset+length > m_vertexCount)
|
||||
if (m_startOffset + offset + size > m_endOffset)
|
||||
{
|
||||
NazaraError("Exceeding virtual buffer size");
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_buffer->Map(access, m_startVertex+offset, (length) ? length : m_vertexCount-offset);
|
||||
return m_buffer->Map(access, offset, size);
|
||||
}
|
||||
|
||||
void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length) const
|
||||
void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (offset+length > m_vertexCount)
|
||||
if (m_startOffset + offset + size > m_endOffset)
|
||||
{
|
||||
NazaraError("Exceeding virtual buffer size");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_buffer->Map(access, m_startVertex+offset, (length) ? length : m_vertexCount-offset);
|
||||
return m_buffer->Map(access, offset, size);
|
||||
}
|
||||
|
||||
void* NzVertexBuffer::MapVertices(nzBufferAccess access, unsigned int startVertex, unsigned int length)
|
||||
{
|
||||
unsigned int stride = m_vertexDeclaration->GetStride();
|
||||
|
||||
return Map(access, startVertex*stride, length*stride);
|
||||
}
|
||||
|
||||
void* NzVertexBuffer::MapVertices(nzBufferAccess access, unsigned int startVertex, unsigned int length) const
|
||||
{
|
||||
unsigned int stride = m_vertexDeclaration->GetStride();
|
||||
|
||||
return Map(access, startVertex*stride, length*stride);
|
||||
}
|
||||
|
||||
bool NzVertexBuffer::SetStorage(nzBufferStorage storage)
|
||||
|
|
@ -154,6 +178,20 @@ bool NzVertexBuffer::SetStorage(nzBufferStorage storage)
|
|||
return m_buffer->SetStorage(storage);
|
||||
}
|
||||
|
||||
void NzVertexBuffer::SetVertexDeclaration(const NzVertexDeclaration* 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;
|
||||
}
|
||||
|
||||
void NzVertexBuffer::Unmap() const
|
||||
{
|
||||
m_buffer->Unmap();
|
||||
|
|
|
|||
|
|
@ -5,386 +5,192 @@
|
|||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Config.hpp>
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
const unsigned int elementCount[] =
|
||||
unsigned int attributeSize[nzAttributeType_Max+1] =
|
||||
{
|
||||
4, // nzElementType_Color
|
||||
1, // nzElementType_Double1
|
||||
2, // nzElementType_Double2
|
||||
3, // nzElementType_Double3
|
||||
4, // nzElementType_Double4
|
||||
1, // nzElementType_Float1
|
||||
2, // nzElementType_Float2
|
||||
3, // nzElementType_Float3
|
||||
4 // nzElementType_Float4
|
||||
4, // nzAttributeType_Color
|
||||
1, // nzAttributeType_Double1
|
||||
2, // nzAttributeType_Double2
|
||||
3, // nzAttributeType_Double3
|
||||
4, // nzAttributeType_Double4
|
||||
1, // nzAttributeType_Float1
|
||||
2, // nzAttributeType_Float2
|
||||
3, // nzAttributeType_Float3
|
||||
4 // nzAttributeType_Float4
|
||||
};
|
||||
|
||||
const unsigned int elementSize[] =
|
||||
unsigned int attributeStride[nzAttributeType_Max+1] =
|
||||
{
|
||||
4*sizeof(nzUInt8), // nzElementType_Color
|
||||
1*sizeof(double), // nzElementType_Double1
|
||||
2*sizeof(double), // nzElementType_Double2
|
||||
3*sizeof(double), // nzElementType_Double3
|
||||
4*sizeof(double), // nzElementType_Double4
|
||||
1*sizeof(float), // nzElementType_Float1
|
||||
2*sizeof(float), // nzElementType_Float2
|
||||
3*sizeof(float), // nzElementType_Float3
|
||||
4*sizeof(float) // nzElementType_Float4
|
||||
4*sizeof(nzUInt8), // nzAttributeType_Color
|
||||
1*sizeof(double), // nzAttributeType_Double1
|
||||
2*sizeof(double), // nzAttributeType_Double2
|
||||
3*sizeof(double), // nzAttributeType_Double3
|
||||
4*sizeof(double), // nzAttributeType_Double4
|
||||
1*sizeof(float), // nzAttributeType_Float1
|
||||
2*sizeof(float), // nzAttributeType_Float2
|
||||
3*sizeof(float), // nzAttributeType_Float3
|
||||
4*sizeof(float) // nzAttributeType_Float4
|
||||
};
|
||||
|
||||
bool VertexElementCompare(const NzVertexElement& elementA, const NzVertexElement& elementB)
|
||||
{
|
||||
// Nous classons d'abord par stream
|
||||
if (elementA.stream == elementB.stream)
|
||||
{
|
||||
// Ensuite par usage
|
||||
if (elementA.usage == elementB.usage)
|
||||
// Et finalement par usageIndex
|
||||
return elementA.usageIndex < elementB.usageIndex;
|
||||
else
|
||||
return elementA.usage < elementB.usage;
|
||||
}
|
||||
else
|
||||
return elementA.stream < elementB.stream;
|
||||
}
|
||||
}
|
||||
|
||||
struct NzVertexDeclarationImpl
|
||||
NzVertexDeclaration::NzVertexDeclaration() :
|
||||
m_stride(0)
|
||||
{
|
||||
NzVertexDeclarationImpl() :
|
||||
refCount(1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<NzVertexElement> elements;
|
||||
int elementPos[nzElementStream_Max+1][nzElementUsage_Max+1];
|
||||
int streamPos[nzElementStream_Max+1];
|
||||
unsigned int stride[nzElementStream_Max+1] = {0};
|
||||
NzVertexDeclaration::NzVertexDeclaration(NzVertexDeclaration& declaration) :
|
||||
NzResource(),
|
||||
m_stride(declaration.m_stride)
|
||||
{
|
||||
std::memcpy(m_attributes, declaration.m_attributes, sizeof(Attribute)*(nzAttributeUsage_Max+1));
|
||||
}
|
||||
|
||||
std::atomic_ushort refCount;
|
||||
};
|
||||
|
||||
NzVertexDeclaration::NzVertexDeclaration(const NzVertexElement* elements, unsigned int elementCount)
|
||||
void NzVertexDeclaration::DisableAttribute(nzAttributeUsage usage)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!Create(elements, elementCount))
|
||||
if (usage > nzAttributeUsage_Max)
|
||||
{
|
||||
NazaraError("Failed to create declaration");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#else
|
||||
Create(elements, elementCount);
|
||||
#endif
|
||||
}
|
||||
|
||||
NzVertexDeclaration::NzVertexDeclaration(const NzVertexDeclaration& declaration) :
|
||||
NzResource(),
|
||||
m_sharedImpl(declaration.m_sharedImpl)
|
||||
{
|
||||
if (m_sharedImpl)
|
||||
m_sharedImpl->refCount++;
|
||||
}
|
||||
|
||||
NzVertexDeclaration::NzVertexDeclaration(NzVertexDeclaration&& declaration) noexcept :
|
||||
m_sharedImpl(declaration.m_sharedImpl)
|
||||
{
|
||||
declaration.m_sharedImpl = nullptr;
|
||||
}
|
||||
|
||||
NzVertexDeclaration::~NzVertexDeclaration()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::Create(const NzVertexElement* elements, unsigned int elementCount)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!elements || elementCount == 0)
|
||||
{
|
||||
NazaraError("No element");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
NzVertexDeclarationImpl* impl = new NzVertexDeclarationImpl;
|
||||
std::memset(&impl->elementPos, -1, (nzElementStream_Max+1)*(nzElementUsage_Max+1)*sizeof(int));
|
||||
std::memset(&impl->streamPos, -1, (nzElementStream_Max+1)*sizeof(int));
|
||||
|
||||
// On copie et trions les éléments
|
||||
impl->elements.resize(elementCount);
|
||||
std::memcpy(&impl->elements[0], elements, elementCount*sizeof(NzVertexElement));
|
||||
std::sort(impl->elements.begin(), impl->elements.end(), VertexElementCompare);
|
||||
|
||||
for (unsigned int i = 0; i < elementCount; ++i)
|
||||
{
|
||||
NzVertexElement& current = impl->elements[i];
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
// Notre tableau étant trié, s'il y a collision, les deux éléments identiques se suivent...
|
||||
if (i > 0)
|
||||
{
|
||||
NzVertexElement& previous = impl->elements[i-1]; // On accède à l'élément précédent
|
||||
if (previous.usage == current.usage && previous.usageIndex == current.usageIndex && previous.stream == current.stream)
|
||||
{
|
||||
// Les deux éléments sont identiques là où ils ne devraient pas, nous avons une collision...
|
||||
NazaraError("Element usage 0x" + NzString::Number(current.usage, 16) + " collision with usage index " + NzString::Number(current.usageIndex) + " on stream 0x" + NzString::Number(current.stream, 16));
|
||||
delete impl;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (current.usageIndex == 0)
|
||||
impl->elementPos[current.stream][current.usage] = i;
|
||||
|
||||
if (impl->streamPos[current.stream] == -1)
|
||||
impl->streamPos[current.stream] = i; // Premier élément du stream (via le triage)
|
||||
|
||||
impl->stride[current.stream] += elementSize[current.type];
|
||||
}
|
||||
|
||||
#if NAZARA_UTILITY_FORCE_DECLARATION_STRIDE_MULTIPLE_OF_32
|
||||
for (unsigned int& stride : impl->stride)
|
||||
stride = ((static_cast<int>(stride)-1)/32+1)*32;
|
||||
#endif
|
||||
|
||||
m_sharedImpl = impl;
|
||||
|
||||
NotifyCreated();
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzVertexDeclaration::Destroy()
|
||||
{
|
||||
if (!m_sharedImpl)
|
||||
NazaraError("Attribute usage out of enum");
|
||||
return;
|
||||
|
||||
NotifyDestroy();
|
||||
|
||||
if (--m_sharedImpl->refCount == 0)
|
||||
delete m_sharedImpl;
|
||||
|
||||
m_sharedImpl = nullptr;
|
||||
}
|
||||
|
||||
const NzVertexElement* NzVertexDeclaration::GetElement(unsigned int i) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (i >= m_sharedImpl->elements.size())
|
||||
{
|
||||
NazaraError("Element index out of range (" + NzString::Number(i) + " >= " + NzString::Number(m_sharedImpl->elements.size()) + ')');
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_sharedImpl->elements[i];
|
||||
Attribute& attribute = m_attributes[usage];
|
||||
|
||||
if (attribute.enabled)
|
||||
{
|
||||
attribute.enabled = false;
|
||||
m_stride -= attributeStride[attribute.type];
|
||||
}
|
||||
}
|
||||
|
||||
const NzVertexElement* NzVertexDeclaration::GetElement(nzElementStream stream, unsigned int i) const
|
||||
void NzVertexDeclaration::EnableAttribute(nzAttributeUsage usage, nzAttributeType type, unsigned int offset)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (usage > nzAttributeUsage_Max)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int streamPos = m_sharedImpl->streamPos[stream];
|
||||
if (streamPos == -1)
|
||||
{
|
||||
NazaraError("Declaration has no stream 0x" + NzString::Number(stream, 16));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
unsigned int upperLimit = GetElementCount(stream);
|
||||
if (i >= upperLimit)
|
||||
{
|
||||
NazaraError("Element index out of range (" + NzString::Number(i) + " >= " + NzString::Number(upperLimit) + ')');
|
||||
return nullptr;
|
||||
NazaraError("Attribute usage out of enum");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &m_sharedImpl->elements[m_sharedImpl->streamPos[stream]+i];
|
||||
}
|
||||
Attribute& attribute = m_attributes[usage];
|
||||
|
||||
const NzVertexElement* NzVertexDeclaration::GetElement(nzElementStream stream, nzElementUsage usage, unsigned int usageIndex) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
int elementPos = m_sharedImpl->elementPos[stream][usage];
|
||||
if (elementPos == -1)
|
||||
return nullptr;
|
||||
|
||||
if (usageIndex == 0) // Si l'usage index vaut zéro, alors nous sommes certains d'être sur le bon élément (Majorité des cas)
|
||||
return &m_sharedImpl->elements[elementPos];
|
||||
if (attribute.enabled)
|
||||
m_stride -= attributeStride[attribute.type];
|
||||
else
|
||||
{
|
||||
elementPos += usageIndex;
|
||||
if (static_cast<unsigned int>(elementPos) >= m_sharedImpl->elements.size())
|
||||
return nullptr;
|
||||
attribute.enabled = true;
|
||||
|
||||
NzVertexElement& element = m_sharedImpl->elements[elementPos];
|
||||
if (element.stream != stream || element.usage != usage || element.usageIndex != usageIndex)
|
||||
return nullptr;
|
||||
attribute.offset = offset;
|
||||
attribute.type = type;
|
||||
|
||||
return &element;
|
||||
}
|
||||
m_stride += attributeStride[type];
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetElementCount() const
|
||||
void NzVertexDeclaration::GetAttribute(nzAttributeUsage usage, bool* enabled, nzAttributeType* type, unsigned int* offset) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (usage > nzAttributeUsage_Max)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return 0;
|
||||
NazaraError("Attribute usage out of enum");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_sharedImpl->elements.size();
|
||||
const Attribute& attribute = m_attributes[usage];
|
||||
|
||||
if (enabled)
|
||||
*enabled = attribute.enabled;
|
||||
|
||||
if (type)
|
||||
*type = attribute.type;
|
||||
|
||||
if (offset)
|
||||
*offset = attribute.offset;
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetElementCount(nzElementStream stream) const
|
||||
unsigned int NzVertexDeclaration::GetStride() const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int streamPos = m_sharedImpl->streamPos[stream];
|
||||
if (streamPos == -1)
|
||||
return 0;
|
||||
|
||||
unsigned int upperLimit = 0;
|
||||
if (stream == nzElementStream_Max)
|
||||
upperLimit = m_sharedImpl->elements.size();
|
||||
else
|
||||
{
|
||||
for (unsigned int upperStream = stream+1; upperStream <= nzElementStream_Max; ++upperStream)
|
||||
{
|
||||
if (m_sharedImpl->streamPos[upperStream] != -1)
|
||||
{
|
||||
upperLimit = m_sharedImpl->streamPos[upperStream];
|
||||
break;
|
||||
}
|
||||
else if (upperStream == nzElementStream_Max) // Dernier stream, toujours pas de limite
|
||||
upperLimit = m_sharedImpl->elements.size();
|
||||
}
|
||||
}
|
||||
|
||||
return upperLimit-streamPos;
|
||||
return m_stride;
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetStride(nzElementStream stream) const
|
||||
void NzVertexDeclaration::SetStride(unsigned int stride)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_sharedImpl->stride[stream];
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::HasElement(unsigned int i) const
|
||||
{
|
||||
return i < m_sharedImpl->elements.size();
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::HasElement(nzElementStream stream, unsigned int i) const
|
||||
{
|
||||
return i < GetElementCount(stream);
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::HasElement(nzElementStream stream, nzElementUsage usage, unsigned int usageIndex) const
|
||||
{
|
||||
int elementPos = m_sharedImpl->elementPos[stream][usage];
|
||||
if (elementPos == -1)
|
||||
return false;
|
||||
|
||||
elementPos += usageIndex;
|
||||
if (static_cast<unsigned int>(elementPos) >= m_sharedImpl->elements.size())
|
||||
return false;
|
||||
|
||||
NzVertexElement& element = m_sharedImpl->elements[elementPos];
|
||||
if (element.stream != stream || element.usage != usage || element.usageIndex != usageIndex)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::HasStream(nzElementStream stream) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_sharedImpl)
|
||||
{
|
||||
NazaraError("Declaration not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_sharedImpl->streamPos[stream] != -1;
|
||||
}
|
||||
|
||||
bool NzVertexDeclaration::IsValid() const
|
||||
{
|
||||
return m_sharedImpl != nullptr;
|
||||
m_stride = stride;
|
||||
}
|
||||
|
||||
NzVertexDeclaration& NzVertexDeclaration::operator=(const NzVertexDeclaration& declaration)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_sharedImpl = declaration.m_sharedImpl;
|
||||
if (m_sharedImpl)
|
||||
m_sharedImpl->refCount++;
|
||||
std::memcpy(m_attributes, declaration.m_attributes, sizeof(Attribute)*(nzAttributeUsage_Max+1));
|
||||
m_stride = declaration.m_stride;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
NzVertexDeclaration& NzVertexDeclaration::operator=(NzVertexDeclaration&& declaration) noexcept
|
||||
NzVertexDeclaration* NzVertexDeclaration::Get(nzVertexLayout layout)
|
||||
{
|
||||
Destroy();
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (layout > nzVertexLayout_Max)
|
||||
{
|
||||
NazaraError("Vertex layout out of enum");
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_sharedImpl = declaration.m_sharedImpl;
|
||||
declaration.m_sharedImpl = nullptr;
|
||||
|
||||
return *this;
|
||||
return &s_declarations[layout];
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetElementCount(nzElementType type)
|
||||
unsigned int NzVertexDeclaration::GetAttributeSize(nzAttributeType type)
|
||||
{
|
||||
return elementCount[type];
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (type > nzAttributeType_Max)
|
||||
{
|
||||
NazaraError("Attribute type out of enum");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return attributeSize[type];
|
||||
}
|
||||
|
||||
unsigned int NzVertexDeclaration::GetElementSize(nzElementType type)
|
||||
bool NzVertexDeclaration::Initialize()
|
||||
{
|
||||
return elementSize[type];
|
||||
s_declarations[nzVertexLayout_XY].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float2, 0);
|
||||
|
||||
s_declarations[nzVertexLayout_XY_UV].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float2, 0);
|
||||
s_declarations[nzVertexLayout_XY_UV].EnableAttribute(nzAttributeUsage_TexCoord, nzAttributeType_Float2, 2*sizeof(float));
|
||||
|
||||
s_declarations[nzVertexLayout_XYZ].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float3, 0);
|
||||
|
||||
s_declarations[nzVertexLayout_XYZ_Normal].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float3, 0);
|
||||
s_declarations[nzVertexLayout_XYZ_Normal].EnableAttribute(nzAttributeUsage_Normal, nzAttributeType_Float3, 3*sizeof(float));
|
||||
|
||||
s_declarations[nzVertexLayout_XYZ_Normal_UV].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float3, 0);
|
||||
s_declarations[nzVertexLayout_XYZ_Normal_UV].EnableAttribute(nzAttributeUsage_Normal, nzAttributeType_Float3, 3*sizeof(float));
|
||||
s_declarations[nzVertexLayout_XYZ_Normal_UV].EnableAttribute(nzAttributeUsage_TexCoord, nzAttributeType_Float2, (3+3)*sizeof(float));
|
||||
|
||||
s_declarations[nzVertexLayout_XYZ_Normal_UV_Tangent].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float3, 0);
|
||||
s_declarations[nzVertexLayout_XYZ_Normal_UV_Tangent].EnableAttribute(nzAttributeUsage_Normal, nzAttributeType_Float3, 3*sizeof(float));
|
||||
s_declarations[nzVertexLayout_XYZ_Normal_UV_Tangent].EnableAttribute(nzAttributeUsage_TexCoord, nzAttributeType_Float2, (3+3)*sizeof(float));
|
||||
s_declarations[nzVertexLayout_XYZ_Normal_UV_Tangent].EnableAttribute(nzAttributeUsage_Tangent, nzAttributeType_Float3, (3+3+2)*sizeof(float));
|
||||
|
||||
s_declarations[nzVertexLayout_XYZ_UV].EnableAttribute(nzAttributeUsage_Position, nzAttributeType_Float3, 0);
|
||||
s_declarations[nzVertexLayout_XYZ_UV].EnableAttribute(nzAttributeUsage_TexCoord, nzAttributeType_Float2, 3*sizeof(float));
|
||||
|
||||
s_declarations[nzVertexLayout_Matrix4].EnableAttribute(nzAttributeUsage_InstanceData0, nzAttributeType_Float4, 0*4*sizeof(float));
|
||||
s_declarations[nzVertexLayout_Matrix4].EnableAttribute(nzAttributeUsage_InstanceData1, nzAttributeType_Float4, 1*4*sizeof(float));
|
||||
s_declarations[nzVertexLayout_Matrix4].EnableAttribute(nzAttributeUsage_InstanceData2, nzAttributeType_Float4, 2*4*sizeof(float));
|
||||
s_declarations[nzVertexLayout_Matrix4].EnableAttribute(nzAttributeUsage_InstanceData3, nzAttributeType_Float4, 3*4*sizeof(float));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzVertexDeclaration::Uninitialize()
|
||||
{
|
||||
}
|
||||
|
||||
NzVertexDeclaration NzVertexDeclaration::s_declarations[nzVertexLayout_Max+1];
|
||||
|
|
|
|||
Loading…
Reference in New Issue