diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index f433a8d7d..52abbe3fc 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -12,9 +12,9 @@ #include #include #include +#include #include #include -#include class NzTexture; @@ -23,7 +23,7 @@ using NzTextureRef = NzResourceRef; struct NzTextureImpl; -class NAZARA_API NzTexture : public NzResource, NzNonCopyable +class NAZARA_API NzTexture : public NzAbstractImage, public NzResource, NzNonCopyable { friend class NzRenderer; friend class NzRenderTexture; @@ -42,18 +42,19 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable void EnsureMipmapsUpdate() const; - nzUInt8 GetBytesPerPixel() const; unsigned int GetDepth(nzUInt8 level = 0) const; nzPixelFormat GetFormat() const; unsigned int GetHeight(nzUInt8 level = 0) const; + nzUInt8 GetLevelCount() const; + nzUInt8 GetMaxLevel() const; + unsigned int GetMemoryUsage() const; + unsigned int GetMemoryUsage(nzUInt8 level) const; NzVector3ui GetSize(nzUInt8 level = 0) const; nzImageType GetType() const; unsigned int GetWidth(nzUInt8 level = 0) const; bool HasMipmaps() const; - bool IsCompressed() const; - bool IsCubemap() const; bool IsValid() const; // Load diff --git a/include/Nazara/Utility/AbstractImage.hpp b/include/Nazara/Utility/AbstractImage.hpp new file mode 100644 index 000000000..345868890 --- /dev/null +++ b/include/Nazara/Utility/AbstractImage.hpp @@ -0,0 +1,42 @@ +// 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 + +#pragma once + +#ifndef NAZARA_ABSTRACTIMAGE_HPP +#define NAZARA_ABSTRACTIMAGE_HPP + +#include +#include +#include +#include +#include + +class NAZARA_API NzAbstractImage +{ + public: + NzAbstractImage() = default; + ~NzAbstractImage(); + + nzUInt8 GetBytesPerPixel() const; + virtual unsigned int GetDepth(nzUInt8 level = 0) const = 0; + virtual nzPixelFormat GetFormat() const = 0; + virtual unsigned int GetHeight(nzUInt8 level = 0) const = 0; + virtual nzUInt8 GetLevelCount() const = 0; + virtual nzUInt8 GetMaxLevel() const = 0; + virtual unsigned int GetMemoryUsage() const = 0; + virtual unsigned int GetMemoryUsage(nzUInt8 level) const = 0; + virtual NzVector3ui GetSize(nzUInt8 level = 0) const = 0; + virtual nzImageType GetType() const = 0; + virtual unsigned int GetWidth(nzUInt8 level = 0) const = 0; + + bool IsCompressed() const; + bool IsCubemap() const; + + virtual bool Update(const nzUInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0) = 0; + virtual bool Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0) = 0; + virtual bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0) = 0; +}; + +#endif // NAZARA_IMAGE_HPP diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index f59811d40..d94177bbe 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -13,12 +13,8 @@ #include #include #include -#include -#include -#include +#include #include -#include -#include #include ///TODO: Filtres @@ -40,7 +36,7 @@ using NzImageConstRef = NzResourceRef; using NzImageLoader = NzResourceLoader; using NzImageRef = NzResourceRef; -class NAZARA_API NzImage : public NzResource +class NAZARA_API NzImage : public NzAbstractImage, public NzResource { friend NzImageLoader; @@ -68,7 +64,6 @@ class NAZARA_API NzImage : public NzResource bool FlipHorizontally(); bool FlipVertically(); - nzUInt8 GetBytesPerPixel() const; const nzUInt8* GetConstPixels(unsigned int x = 0, unsigned int y = 0, unsigned int z = 0, nzUInt8 level = 0) const; unsigned int GetDepth(nzUInt8 level = 0) const; nzPixelFormat GetFormat() const; @@ -83,8 +78,6 @@ class NAZARA_API NzImage : public NzResource nzImageType GetType() const; unsigned int GetWidth(nzUInt8 level = 0) const; - bool IsCompressed() const; - bool IsCubemap() const; bool IsValid() const; // Load @@ -107,9 +100,9 @@ class NAZARA_API NzImage : public NzResource void SetLevelCount(nzUInt8 levelCount); bool SetPixelColor(const NzColor& color, unsigned int x, unsigned int y = 0, unsigned int z = 0); - void Update(const nzUInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); - void Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); - void Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); + bool Update(const nzUInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); + bool Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); + bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); NzImage& operator=(const NzImage& image); NzImage& operator=(NzImage&& image) noexcept; diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index 5c5ae4cdf..ee53e0ed0 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 148d06031..855a70e2f 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -311,19 +312,6 @@ void NzTexture::EnsureMipmapsUpdate() const } } -nzUInt8 NzTexture::GetBytesPerPixel() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return 0; - } - #endif - - return NzPixelFormat::GetBytesPerPixel(m_impl->format); -} - unsigned int NzTexture::GetDepth(nzUInt8 level) const { #if NAZARA_RENDERER_SAFE @@ -363,6 +351,89 @@ unsigned int NzTexture::GetHeight(nzUInt8 level) const return GetLevelSize(m_impl->height, level); } +nzUInt8 NzTexture::GetLevelCount() const +{ + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + #endif + + return m_impl->levelCount; +} + +nzUInt8 NzTexture::GetMaxLevel() const +{ + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + #endif + + return NzImage::GetMaxLevel(m_impl->type, m_impl->width, m_impl->height, m_impl->depth); +} + +unsigned int NzTexture::GetMemoryUsage() const +{ + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + #endif + + unsigned int width = m_impl->width; + unsigned int height = m_impl->height; + unsigned int depth = m_impl->depth; + + unsigned int size = 0; + for (unsigned int i = 0; i < m_impl->levelCount; ++i) + { + size += width * height * depth; + + if (width > 1) + width >>= 1; + + if (height > 1) + height >>= 1; + + if (depth > 1) + depth >>= 1; + } + + if (m_impl->type == nzImageType_Cubemap) + size *= 6; + + return size * NzPixelFormat::GetBytesPerPixel(m_impl->format); +} + +unsigned int NzTexture::GetMemoryUsage(nzUInt8 level) const +{ + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + + if (level >= m_impl->levelCount) + { + NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_impl->levelCount) + ')'); + return 0; + } + #endif + + return (GetLevelSize(m_impl->width, level)) * + (GetLevelSize(m_impl->height, level)) * + ((m_impl->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_impl->depth, level)) * + NzPixelFormat::GetBytesPerPixel(m_impl->format); +} + NzVector3ui NzTexture::GetSize(nzUInt8 level) const { #if NAZARA_RENDERER_SAFE @@ -415,32 +486,6 @@ bool NzTexture::HasMipmaps() const return m_impl->levelCount > 1; } -bool NzTexture::IsCompressed() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - #endif - - return NzPixelFormat::IsCompressed(m_impl->format); -} - -bool NzTexture::IsCubemap() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - #endif - - return m_impl->type == nzImageType_Cubemap; -} - bool NzTexture::IsValid() const { return m_impl != nullptr; diff --git a/src/Nazara/Utility/AbstractImage.cpp b/src/Nazara/Utility/AbstractImage.cpp new file mode 100644 index 000000000..9e5ea28a0 --- /dev/null +++ b/src/Nazara/Utility/AbstractImage.cpp @@ -0,0 +1,24 @@ +// 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 + +NzAbstractImage::~NzAbstractImage() = default; + +nzUInt8 NzAbstractImage::GetBytesPerPixel() const +{ + return NzPixelFormat::GetBytesPerPixel(GetFormat()); +} + +bool NzAbstractImage::IsCompressed() const +{ + return NzPixelFormat::IsCompressed(GetFormat()); +} + +bool NzAbstractImage::IsCubemap() const +{ + return GetType() == nzImageType_Cubemap; +} diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 70bdd5da9..0532294bb 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -590,11 +591,6 @@ bool NzImage::FlipVertically() return true; } -nzUInt8 NzImage::GetBytesPerPixel() const -{ - return NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); -} - const nzUInt8* NzImage::GetConstPixels(unsigned int x, unsigned int y, unsigned int z, nzUInt8 level) const { #if NAZARA_UTILITY_SAFE @@ -850,16 +846,6 @@ unsigned int NzImage::GetWidth(nzUInt8 level) const return GetLevelSize(m_sharedImage->width, level); } -bool NzImage::IsCompressed() const -{ - return NzPixelFormat::IsCompressed(m_sharedImage->format); -} - -bool NzImage::IsCubemap() const -{ - return m_sharedImage->type == nzImageType_Cubemap; -} - bool NzImage::IsValid() const { return m_sharedImage != &emptyImage; @@ -1199,25 +1185,25 @@ bool NzImage::SetPixelColor(const NzColor& color, unsigned int x, unsigned int y return true; } -void NzImage::Update(const nzUInt8* pixels, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) +bool NzImage::Update(const nzUInt8* pixels, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) { #if NAZARA_UTILITY_SAFE if (m_sharedImage == &emptyImage) { NazaraError("Image must be valid"); - return; + return false; } if (!pixels) { NazaraError("Invalid pixel source"); - return; + return false; } if (level >= m_sharedImage->levelCount) { NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')'); - return; + return false; } #endif @@ -1229,27 +1215,29 @@ void NzImage::Update(const nzUInt8* pixels, unsigned int srcWidth, unsigned int GetLevelSize(m_sharedImage->depth, level), 0, 0, srcWidth, srcHeight); + + return true; } -void NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) +bool NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) { #if NAZARA_UTILITY_SAFE if (m_sharedImage == &emptyImage) { NazaraError("Image must be valid"); - return; + return false; } if (!pixels) { NazaraError("Invalid pixel source"); - return; + return false; } if (level >= m_sharedImage->levelCount) { NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')'); - return; + return false; } #endif @@ -1260,7 +1248,7 @@ void NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int src if (!box.IsValid()) { NazaraError("Invalid box"); - return; + return false; } unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level); @@ -1268,7 +1256,7 @@ void NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int src (m_sharedImage->type == nzImageType_Cubemap && box.depth > 1)) // Nous n'autorisons pas de modifier plus d'une face du cubemap à la fois { NazaraError("Box dimensions are out of bounds"); - return; + return false; } #endif @@ -1281,9 +1269,11 @@ void NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int src box.width, box.height, box.depth, width, height, srcWidth, srcHeight); + + return true; } -void NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) +bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) { return Update(pixels, NzBoxui(rect.x, rect.y, z, rect.width, rect.height, 1), srcWidth, srcHeight, level); }