#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