// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include #include #include #include namespace Nz { VertexBuffer::VertexBuffer(const VertexDeclaration* vertexDeclaration, Buffer* buffer) { ErrorFlags(ErrorFlag_ThrowException, true); Reset(vertexDeclaration, buffer); } VertexBuffer::VertexBuffer(const VertexDeclaration* vertexDeclaration, Buffer* buffer, unsigned int startOffset, unsigned int endOffset) { ErrorFlags(ErrorFlag_ThrowException, true); Reset(vertexDeclaration, buffer, startOffset, endOffset); } VertexBuffer::VertexBuffer(const VertexDeclaration* vertexDeclaration, unsigned int length, UInt32 storage, BufferUsage usage) { ErrorFlags(ErrorFlag_ThrowException, true); Reset(vertexDeclaration, length, storage, usage); } VertexBuffer::VertexBuffer(const VertexBuffer& vertexBuffer) : RefCounted(), m_buffer(vertexBuffer.m_buffer), m_vertexDeclaration(vertexBuffer.m_vertexDeclaration), m_endOffset(vertexBuffer.m_endOffset), m_startOffset(vertexBuffer.m_startOffset), m_vertexCount(vertexBuffer.m_vertexCount) { } VertexBuffer::~VertexBuffer() { OnVertexBufferRelease(this); } bool VertexBuffer::Fill(const void* data, unsigned int startVertex, unsigned int length, bool forceDiscard) { unsigned int stride = m_vertexDeclaration->GetStride(); return FillRaw(data, startVertex*stride, length*stride, forceDiscard); } bool VertexBuffer::FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) { #if NAZARA_UTILITY_SAFE if (!m_buffer) { NazaraError("No buffer"); return false; } if (m_startOffset + offset + size > m_endOffset) { NazaraError("Exceeding virtual buffer size"); return false; } #endif return m_buffer->Fill(data, m_startOffset+offset, size, forceDiscard); } Buffer* VertexBuffer::GetBuffer() const { return m_buffer; } unsigned int VertexBuffer::GetEndOffset() const { return m_endOffset; } unsigned int VertexBuffer::GetStartOffset() const { return m_startOffset; } unsigned int VertexBuffer::GetStride() const { return m_vertexDeclaration->GetStride(); } unsigned int VertexBuffer::GetVertexCount() const { return m_vertexCount; } const VertexDeclaration* VertexBuffer::GetVertexDeclaration() const { return m_vertexDeclaration; } bool VertexBuffer::IsHardware() const { return m_buffer->IsHardware(); } bool VertexBuffer::IsValid() const { return m_buffer && m_vertexDeclaration; } void* VertexBuffer::Map(BufferAccess access, unsigned int startVertex, unsigned int length) { #if NAZARA_UTILITY_SAFE if (!m_vertexDeclaration) { NazaraError("No vertex declaration"); return nullptr; } #endif unsigned int stride = m_vertexDeclaration->GetStride(); return MapRaw(access, startVertex*stride, length*stride); } void* VertexBuffer::Map(BufferAccess access, unsigned int startVertex, unsigned int length) const { #if NAZARA_UTILITY_SAFE if (!m_buffer) { NazaraError("No buffer"); return nullptr; } if (!m_vertexDeclaration) { NazaraError("No vertex declaration"); return nullptr; } #endif unsigned int stride = m_vertexDeclaration->GetStride(); return MapRaw(access, startVertex*stride, length*stride); } void* VertexBuffer::MapRaw(BufferAccess access, unsigned int offset, unsigned int size) { #if NAZARA_UTILITY_SAFE if (!m_buffer) { NazaraError("No buffer"); return nullptr; } if (m_startOffset + offset + size > m_endOffset) { NazaraError("Exceeding virtual buffer size"); return nullptr; } #endif return m_buffer->Map(access, offset, size); } void* VertexBuffer::MapRaw(BufferAccess access, unsigned int offset, unsigned int size) const { #if NAZARA_UTILITY_SAFE if (m_startOffset + offset + size > m_endOffset) { NazaraError("Exceeding virtual buffer size"); return nullptr; } #endif return m_buffer->Map(access, offset, size); } void VertexBuffer::Reset() { m_buffer.Reset(); m_vertexDeclaration.Reset(); } void VertexBuffer::Reset(const VertexDeclaration* vertexDeclaration, Buffer* buffer) { Reset(vertexDeclaration, buffer, 0, buffer->GetSize()-1); } void VertexBuffer::Reset(const VertexDeclaration* vertexDeclaration, Buffer* buffer, unsigned int startOffset, unsigned int endOffset) { #if NAZARA_UTILITY_SAFE if (!buffer || !buffer->IsValid()) { NazaraError("Invalid buffer"); return; } if (startOffset > endOffset) { NazaraError("Start offset cannot be over end offset"); return; } unsigned int bufferSize = buffer->GetSize(); if (startOffset >= bufferSize) { NazaraError("Start offset is over buffer size"); return; } if (endOffset >= bufferSize) { NazaraError("End offset is over buffer size"); return; } #endif m_buffer = buffer; m_endOffset = endOffset; m_startOffset = startOffset; m_vertexCount = (vertexDeclaration) ? ((endOffset - startOffset) / vertexDeclaration->GetStride()) : 0; m_vertexDeclaration = vertexDeclaration; } void VertexBuffer::Reset(const VertexDeclaration* vertexDeclaration, unsigned int length, UInt32 storage, BufferUsage usage) { m_endOffset = length * ((vertexDeclaration) ? vertexDeclaration->GetStride() : 1); m_startOffset = 0; m_vertexCount = length; m_buffer = Buffer::New(BufferType_Vertex, m_endOffset, storage, usage); m_vertexDeclaration = vertexDeclaration; } void VertexBuffer::Reset(const VertexBuffer& vertexBuffer) { m_buffer = vertexBuffer.m_buffer; m_endOffset = vertexBuffer.m_endOffset; m_startOffset = vertexBuffer.m_startOffset; m_vertexCount = vertexBuffer.m_vertexCount; m_vertexDeclaration = vertexBuffer.m_vertexDeclaration; } bool VertexBuffer::SetStorage(UInt32 storage) { return m_buffer->SetStorage(storage); } void VertexBuffer::SetVertexDeclaration(const VertexDeclaration* vertexDeclaration) { #if NAZARA_UTILITY_SAFE if (!vertexDeclaration) { NazaraError("Vertex declaration is invalid"); return; } #endif m_vertexCount = (m_endOffset - m_startOffset)/vertexDeclaration->GetStride(); m_vertexDeclaration = vertexDeclaration; } void VertexBuffer::Unmap() const { m_buffer->Unmap(); } VertexBuffer& VertexBuffer::operator=(const VertexBuffer& vertexBuffer) { Reset(vertexBuffer); return *this; } }