#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_TEXTURE_H #define NUCLEX_GRAPHICS_RASTERIZATION_TEXTURE_H #include "Resource.h" #include "PixelFormat.h" #include "Usage.h" #include "../Box.h" #include "../Helpers/ConcurrentObserverSet.h" #include namespace Nuclex { namespace Graphics { namespace Rasterization { // ------------------------------------------------------------------------------------------- // ///Multi-dimensional data used for image sampling and lookup tables class Texture : public Resource { #pragma region class Observer /// Receives notifications from the texture when it changes public: class Observer : public Resource::Observer { /// Frees the resources used by the observer public: virtual ~Observer() {} /// Called right before the texture is destroyed public: virtual void Destroying() = 0; /// Called when the texture has been cleared public: virtual void Cleared() = 0; /// Called when the texture has been modified /// Box around the changed area /// /// This callback is used for textures of any dimensionality (well, up to 3 /// naturally). The unused coordinates will be set to 0 and 1 for consistency, /// so a 2D texture, for example, will generate boxes with the /// coordinate set to 0 and /// coordinate set to 1. /// public: virtual void Changed(const Box &changedBox) = 0; }; #pragma endregion // class Observer /// Initializes a new texture with the specified size /// Space required to store the texture in bytes /// Memory layout the texture's pixels will use /// How the texture will be accessed public: NUCLEX_GRAPHICS_API Texture( std::size_t sizeInBytes, PixelFormat::Enum pixelFormat, Usage::Enum usage ); /// Initializes a texture by copying an existing texture /// Existing texture that will be copied public: NUCLEX_GRAPHICS_API Texture(const Texture &other); /// Destroys the texture public: NUCLEX_GRAPHICS_API virtual ~Texture(); /// Returns the capacity of the buffer in bytes /// The number of bytes that fit in the buffer public: NUCLEX_GRAPHICS_API std::size_t GetSizeInBytes() const { return this->SizeInBytes; } /// Erases the contents of the texture public: NUCLEX_GRAPHICS_API virtual void Clear() = 0; /// Counts the number of dimensions the texture has /// The texture's number of dimensions public: NUCLEX_GRAPHICS_API virtual std::size_t CountDimensions() const = 0; /// Retrieves the length of one of the texture's dimensions /// /// Index of the dimension whose length will be returned /// /// The length of the specified dimension public: NUCLEX_GRAPHICS_API virtual std::size_t GetLength( std::size_t dimensionIndex ) const = 0; /// Returns the pixel format used by the texture /// The pixel format the texture uses public: NUCLEX_GRAPHICS_API PixelFormat::Enum GetPixelFormat() const { return this->PixelFormat; } /// Returns the indicates usage of the texture /// How the texture will be accessed by the CPU and the GPU public: NUCLEX_GRAPHICS_API Usage::Enum GetUsage() const { return this->usage; } /// Suppresses the notifications and begins queueing them /// /// Use this method if you plan to apply many small changes to the buffer in /// order to avoid the overhead that would result in any observers having /// to process hundreds of micro-changes. The buffer will collect all changes /// and merge them. Once notifications are enabled again, a single notification /// even will be fired, containing the changed area. /// public: NUCLEX_GRAPHICS_API virtual void SuppressChangeNotifications(); /// Enables change notifications again /// /// If any changes happened while notifications were suppressed, this will /// trigger a change notification. /// public: NUCLEX_GRAPHICS_API virtual void PermitChangeNotifications(); /// Retrieves the observer attached by the specified owner /// Owner whose observer will be looked up /// The observer registered by the specified owner or a nullptr public: NUCLEX_GRAPHICS_API Observer *GetObserver(const void *owner) const; /// Attaches an observer to the texture /// The observer's owner, used as a unique key /// Observer that will be attached to the texture public: NUCLEX_GRAPHICS_API void AttachObserver(const void *owner, Observer *observer); /// Detaches the specified owner's observer from the texture /// Owner whose observer will be detached public: NUCLEX_GRAPHICS_API void DetachObserver(const void *owner); /// Copies the contents of another buffer into this buffer /// Other buffer whose contents will be copied /// A reference to this buffer protected: NUCLEX_GRAPHICS_API Texture &operator =(const Texture &other); /// Notifies all observers that the texture is about to be destroyed protected: NUCLEX_GRAPHICS_API void OnDestroying(); /// Notifies all observers that the texture has been cleared protected: NUCLEX_GRAPHICS_API void OnCleared(); /// Notifies all observers that the texture has been changed /// Region that has been changed protected: NUCLEX_GRAPHICS_API void OnChanged(const Box &changedRegion); /// Pixel format used by the texture protected: const PixelFormat::Enum PixelFormat; /// Size of the texture in bytes protected: const std::size_t SizeInBytes; /// The contents of the buffer /// /// The pixel pointer is constant (since a texture is allocated once and cannot be /// resized or replaced), but the data is not. /// protected: std::uint8_t *const Pixels; /// How the texture will be accessed by the CPU and the GPU private: Usage::Enum usage; /// Region that has changed whilst notifications were suppressed private: Box changedRegion; /// Observers to changes happening to the buffer private: Helpers::ConcurrentObserverSet observers; }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Graphics::Rasterization #endif // NUCLEX_GRAPHICS_RASTERIZATION_TEXTURE_H