#pragma region CPL License
/*
Nuclex Native Framework
Copyright (C) 2002-2013 Nuclex Development Labs
This library is free software; you can redistribute it and/or
modify it under the terms of the IBM Common Public License as
published by the IBM Corporation; either version 1.0 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
IBM Common Public License for more details.
You should have received a copy of the IBM Common Public
License along with this library
*/
#pragma endregion // CPL License
#ifndef NUCLEX_GRAPHICS_RASTERIZATION_INDEXBUFFER_H
#define NUCLEX_GRAPHICS_RASTERIZATION_INDEXBUFFER_H
#include "GenericIndexBuffer.h"
namespace Nuclex { namespace Graphics { namespace Rasterization {
// ------------------------------------------------------------------------------------------- //
/// Stores strongly typed indices used to connect vertices to primitives
template class IndexBuffer;
// ------------------------------------------------------------------------------------------- //
/// Stores 16 bit indices used to connect vertices to primitives
template<>
class IndexBuffer : public GenericIndexBuffer {
///
/// Defines a range of vertices by the starting index and one past the last index
///
typedef std::pair VertexRange;
/// Initializes a new index buffer with the specified capacity
/// Number of indices the buffer will store
/// How the index buffer is going to be accessed
public: NUCLEX_GRAPHICS_API IndexBuffer(
std::size_t capacityInIndices, Usage::Enum usage = Usage::Immutable
) : GenericIndexBuffer(capacityInIndices * 2, usage) {}
/// Initializes an index buffer by copying an existing index buffer
/// Existing index buffer that will be copied
public: NUCLEX_GRAPHICS_API IndexBuffer(const IndexBuffer &other) :
GenericIndexBuffer(other) {}
/// Frees all resources owned by the index buffer
public: NUCLEX_GRAPHICS_API virtual ~IndexBuffer() {
OnDestroying();
}
/// Always returns false since this is a 16 bit index buffer
/// False
public: NUCLEX_GRAPHICS_API virtual bool Is32BitIndexBuffer() const { return false; }
/// Retrieves the total capacity of the index buffer in indices
/// The capacity of the index buffer in indices
public: NUCLEX_GRAPHICS_API std::size_t GetCapacityInIndices() const {
return this->CapacityBytes / 2;
}
/// Retrieves the number of indices that have been used
/// The number of used indices in the index buffer
public: NUCLEX_GRAPHICS_API std::size_t CountUsedIndices() const {
return CountUsedBytes() / 2;
}
/// Reads indices from the index buffer
/// Offset, in indices, from which on data will be read
/// Address at which the indices read will be deposited
/// Number of indices that will be read
public: NUCLEX_GRAPHICS_API void Read(
std::size_t offset, std::uint16_t *indices, std::size_t count
) const;
/// Writes indices into the index buffer
/// Offset, in indices, at which data will be written
/// Indices that will be written into the index buffer
/// Number of indices that will be written
public: NUCLEX_GRAPHICS_API void Write(
std::size_t offset, const std::uint16_t *indices, std::size_t count
);
/// Appends the specified index to the end of the index buffer
/// Index that will be appended
/// The index buffer itself to allow for method chaining
public: IndexBuffer &Append(std::uint16_t index) {
if(this->CapacityBytes - CountUsedBytes() < 2) {
throw std::runtime_error("No more space in index buffer");
}
Write(CountUsedIndices(), &index, 1);
return *this;
}
///
/// Determines the lowest and the highest vertex index present in the indices
///
/// First index that will be taken into consideration
/// Number of indices that will be checked
public: NUCLEX_GRAPHICS_API VertexRange GetLowestAndHighestVertexIndex(
std::size_t firstIndex = 0, std::size_t count = static_cast(-1)
) const;
/// Copies the contents of another buffer into this buffer
/// Other buffer whose contents will be copied
/// A reference to this buffer
public: NUCLEX_GRAPHICS_API IndexBuffer &operator =(const IndexBuffer &other) {
GenericIndexBuffer::operator=(other);
OnChanged(0, CountUsedBytes());
return *this;
}
/// Causes an exception if the specified range leaves the buffer
/// Index at which the range starts
/// Number of indices that will be considered
private: void enforceRangeStaysWithinBuffer(
std::size_t firstIndex, std::size_t count
) const;
};
// ------------------------------------------------------------------------------------------- //
/// Stores 32 bit indices used to connect vertices to primitives
template<>
class IndexBuffer : public GenericIndexBuffer {
///
/// Defines a range of vertices by the starting index and one past the last index
///
typedef std::pair VertexRange;
/// Initializes a new index buffer with the specified capacity
/// Number of indices the buffer will store
/// How the index buffer is going to be accessed
public: NUCLEX_GRAPHICS_API IndexBuffer(
std::size_t capacityInIndices, Usage::Enum usage = Usage::Immutable
) : GenericIndexBuffer(capacityInIndices * 4, usage) {}
/// Initializes an index buffer by copying an existing index buffer
/// Existing index buffer that will be copied
public: NUCLEX_GRAPHICS_API IndexBuffer(const IndexBuffer &other) :
GenericIndexBuffer(other) {}
/// Frees all resources owned by the index buffer
public: NUCLEX_GRAPHICS_API virtual ~IndexBuffer() {
OnDestroying();
}
/// Always returns true since this is a 32 bit index buffer
/// True
public: NUCLEX_GRAPHICS_API virtual bool Is32BitIndexBuffer() const { return false; }
/// Retrieves the total capacity of the index buffer in indices
/// The capacity of the index buffer in indices
public: NUCLEX_GRAPHICS_API std::size_t GetCapacityInIndices() const {
return this->CapacityBytes / 4;
}
/// Retrieves the number of indices that have been used
/// The number of used indices in the index buffer
public: NUCLEX_GRAPHICS_API std::size_t CountUsedIndices() const {
return CountUsedBytes() / 4;
}
/// Reads indices from the index buffer
/// Offset, in indices, from which on data will be read
/// Address at which the indices read will be deposited
/// Number of indices that will be read
public: NUCLEX_GRAPHICS_API void Read(
std::size_t offset, std::uint32_t *indices, std::size_t count
) const;
/// Writes indices into the index buffer
/// Offset, in indices, at which data will be written
/// Indices that will be written into the index buffer
/// Number of indices that will be written
public: NUCLEX_GRAPHICS_API void Write(
std::size_t offset, const std::uint32_t *indices, std::size_t count
);
/// Appends the specified index to the end of the index buffer
/// Index that will be appended
/// The index buffer itself to allow for method chaining
public: IndexBuffer &Append(std::uint32_t index) {
if(this->CapacityBytes - CountUsedBytes() < 2) {
throw std::runtime_error("No more space in index buffer");
}
Write(CountUsedIndices(), &index, 1);
return *this;
}
///
/// Determines the lowest and the highest vertex index present in the indices
///
/// First index that will be taken into consideration
/// Number of indices that will be checked
public: NUCLEX_GRAPHICS_API VertexRange GetLowestAndHighestVertexIndex(
std::size_t firstIndex = 0, std::size_t count = static_cast(-1)
) const;
/// Copies the contents of another buffer into this buffer
/// Other buffer whose contents will be copied
/// A reference to this buffer
public: NUCLEX_GRAPHICS_API IndexBuffer &operator =(const IndexBuffer &other) {
GenericIndexBuffer::operator=(other);
OnChanged(0, CountUsedBytes());
return *this;
}
/// Causes an exception if the specified range leaves the buffer
/// Index at which the range starts
/// Number of indices that will be considered
private: void enforceRangeStaysWithinBuffer(
std::size_t firstIndex, std::size_t count
) const;
};
// ------------------------------------------------------------------------------------------- //
}}} // namespace Nuclex::Graphics::Rasterization
#endif // NUCLEX_GRAPHICS_RASTERIZATION_INDEXBUFFER_H