Improved/Fixed Texture class

Allowed move constructor/operator
Fixed Texture::Download/Texture::Update
Made InvalidateMipmaps public


Former-commit-id: b8b6a54bc5d6250f640fed6582dc694df6405f73
This commit is contained in:
Lynix 2015-01-07 21:03:29 +01:00
parent 9293022e71
commit 904319ee90
2 changed files with 35 additions and 31 deletions

View File

@ -26,11 +26,12 @@ struct NzTextureImpl;
class NAZARA_API NzTexture : public NzAbstractImage, public NzResource, NzNonCopyable class NAZARA_API NzTexture : public NzAbstractImage, public NzResource, NzNonCopyable
{ {
friend class NzRenderer; friend class NzRenderer;
friend class NzRenderTexture;
public: public:
NzTexture() = default; NzTexture() = default;
NzTexture(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1);
explicit NzTexture(const NzImage& image); explicit NzTexture(const NzImage& image);
NzTexture(NzTexture&& texture);
~NzTexture(); ~NzTexture();
bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1);
@ -55,6 +56,7 @@ class NAZARA_API NzTexture : public NzAbstractImage, public NzResource, NzNonCop
bool HasMipmaps() const; bool HasMipmaps() const;
void InvalidateMipmaps();
bool IsValid() const; bool IsValid() const;
// Load // Load
@ -92,6 +94,8 @@ class NAZARA_API NzTexture : public NzAbstractImage, public NzResource, NzNonCop
// Fonctions OpenGL // Fonctions OpenGL
unsigned int GetOpenGLID() const; unsigned int GetOpenGLID() const;
NzTexture& operator=(NzTexture&& texture);
static unsigned int GetValidSize(unsigned int size); static unsigned int GetValidSize(unsigned int size);
static bool IsFormatSupported(nzPixelFormat format); static bool IsFormatSupported(nzPixelFormat format);
static bool IsMipmappingSupported(); static bool IsMipmappingSupported();
@ -99,7 +103,6 @@ class NAZARA_API NzTexture : public NzAbstractImage, public NzResource, NzNonCop
private: private:
bool CreateTexture(bool proxy); bool CreateTexture(bool proxy);
void InvalidateMipmaps();
NzTextureImpl* m_impl = nullptr; NzTextureImpl* m_impl = nullptr;
}; };

View File

@ -5,6 +5,7 @@
#include <Nazara/Renderer/Texture.hpp> #include <Nazara/Renderer/Texture.hpp>
#include <Nazara/Core/CallOnExit.hpp> #include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Renderer/Context.hpp> #include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/Renderer.hpp> #include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Renderer/OpenGL.hpp> #include <Nazara/Renderer/OpenGL.hpp>
@ -47,17 +48,22 @@ namespace
} }
} }
NzTexture::NzTexture(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount)
{
NzErrorFlags flags(nzErrorFlag_ThrowException);
Create(type, format, width, height, depth, levelCount);
}
NzTexture::NzTexture(const NzImage& image) NzTexture::NzTexture(const NzImage& image)
{ {
NzErrorFlags flags(nzErrorFlag_ThrowException);
LoadFromImage(image); LoadFromImage(image);
#ifdef NAZARA_DEBUG
if (!m_impl)
{
NazaraError("Failed to create texture");
throw std::runtime_error("Constructor failed");
} }
#endif
NzTexture::NzTexture(NzTexture&& texture) :
m_impl(texture.m_impl)
{
texture.m_impl = nullptr;
} }
NzTexture::~NzTexture() NzTexture::~NzTexture()
@ -248,30 +254,11 @@ bool NzTexture::Download(NzImage* image) const
return false; return false;
} }
unsigned int width = m_impl->width;
unsigned int height = m_impl->height;
unsigned int depth = m_impl->depth;
// Téléchargement... // Téléchargement...
NzOpenGL::BindTexture(m_impl->type, m_impl->id); NzOpenGL::BindTexture(m_impl->type, m_impl->id);
for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) for (nzUInt8 level = 0; level < m_impl->levelCount; ++level)
{
glGetTexImage(NzOpenGL::TextureTarget[m_impl->type], level, format.dataFormat, format.dataType, image->GetPixels(level)); glGetTexImage(NzOpenGL::TextureTarget[m_impl->type], level, format.dataFormat, format.dataType, image->GetPixels(level));
if (width > 1)
width >>= 1;
if (height > 1)
height >>= 1;
if (depth > 1)
depth >>= 1;
}
// Inversion de la texture pour le repère d'OpenGL
if (!image->FlipVertically())
NazaraWarning("Failed to flip image");
return true; return true;
} }
@ -292,7 +279,11 @@ bool NzTexture::EnableMipmapping(bool enable)
} }
if (m_impl->levelCount == 1) // Transformation d'une texture sans mipmaps vers une texture avec mipmaps if (m_impl->levelCount == 1) // Transformation d'une texture sans mipmaps vers une texture avec mipmaps
{
///FIXME: Est-ce que cette opération est seulement possible ?
m_impl->levelCount = NzImage::GetMaxLevel(m_impl->width, m_impl->height, m_impl->depth); m_impl->levelCount = NzImage::GetMaxLevel(m_impl->width, m_impl->height, m_impl->depth);
SetMipmapRange(0, m_impl->levelCount-1);
}
if (!m_impl->mipmapping && enable) if (!m_impl->mipmapping && enable)
m_impl->mipmapsUpdated = false; m_impl->mipmapsUpdated = false;
@ -1006,16 +997,16 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int s
case nzImageType_1D_Array: case nzImageType_1D_Array:
case nzImageType_2D: case nzImageType_2D:
glTexSubImage2D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, height-box.height-box.y, box.width, box.height, format.dataFormat, format.dataType, pixels); glTexSubImage2D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, box.y, box.width, box.height, format.dataFormat, format.dataType, pixels);
break; break;
case nzImageType_2D_Array: case nzImageType_2D_Array:
case nzImageType_3D: case nzImageType_3D:
glTexSubImage3D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, height-box.height-box.y, box.z, box.width, box.height, box.depth, format.dataFormat, format.dataType, pixels); glTexSubImage3D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, box.y, box.z, box.width, box.height, box.depth, format.dataFormat, format.dataType, pixels);
break; break;
case nzImageType_Cubemap: case nzImageType_Cubemap:
glTexSubImage2D(NzOpenGL::CubemapFace[box.z], level, box.x, height-box.height-box.y, box.width, box.height, format.dataFormat, format.dataType, pixels); glTexSubImage2D(NzOpenGL::CubemapFace[box.z], level, box.x, box.y, box.width, box.height, format.dataFormat, format.dataType, pixels);
break; break;
} }
@ -1040,6 +1031,16 @@ unsigned int NzTexture::GetOpenGLID() const
return m_impl->id; return m_impl->id;
} }
NzTexture& NzTexture::operator=(NzTexture&& texture)
{
Destroy();
m_impl = texture.m_impl;
texture.m_impl = nullptr;
return *this;
}
unsigned int NzTexture::GetValidSize(unsigned int size) unsigned int NzTexture::GetValidSize(unsigned int size)
{ {
if (NzRenderer::HasCapability(nzRendererCap_TextureNPOT)) if (NzRenderer::HasCapability(nzRendererCap_TextureNPOT))