Fixed many bugs

Added NzOpenGL::GetEntry
Activated preprocessor error if not compiling with a C++11 compliant
compiler
Cube can now be constructed with a Rect
Desactived utility option "threaded window" (bugged)
Epured Image interface (No more UpdateFace, use Update with z = the face
you are targetting)
Fixed compilation errors (Thanks to RafBill)
Fixed predefined colors not exported
Fixed uplading pixels not aligned by 4 bytes
Fixed Thumbs.db files not ignored by git
NzImage now supports Filling and Flipping (Horizontally and vertically)
NzImage::Get(Const)Pixels now support pixel location
NzVector(2/3) can now return floatting distance/length with all types
NzVector(2/3/4) can now be constructed by a vector of smaller dimension
Premake now set "-std=c++11" build option for GCC
Renamed NzImage::(Get/Set)Pixel to (Get/Set)PixelColor
Updated new([])/delete([]) in the leaks tracker to the new C++11
signatures
This commit is contained in:
Lynix
2012-06-15 11:03:43 +02:00
parent 0f84f8eda8
commit be0a5d2819
39 changed files with 739 additions and 462 deletions

View File

@@ -7,22 +7,22 @@
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size) throw(std::bad_alloc)
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size) throw(std::bad_alloc)
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) throw()
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) throw()
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}

View File

@@ -7,22 +7,22 @@
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size) throw(std::bad_alloc)
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size) throw(std::bad_alloc)
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) throw()
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) throw()
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}

View File

@@ -73,7 +73,7 @@ void* NzMemoryManager::Allocate(std::size_t size, bool multi, const char* file,
Block* ptr = reinterpret_cast<Block*>(std::malloc(size+sizeof(Block)));
if (!ptr)
return nullptr;
return nullptr; // Impossible d'envoyer une exception car cela allouerait de la mémoire avec new (boucle infinie)
ptr->array = multi;
ptr->file = file;

View File

@@ -65,7 +65,7 @@ void NzThreadImpl::Terminate()
TerminateThread(m_thread, 0);
}
unsigned int _stdcall NzThreadImpl::ThreadProc(void* userdata)
unsigned int __stdcall NzThreadImpl::ThreadProc(void* userdata)
{
NzThread* owner = reinterpret_cast<NzThread*>(userdata);
NzFunctor* func = owner->m_func;

View File

@@ -29,7 +29,7 @@ class NzThreadImpl
void Terminate();
private:
static unsigned int _stdcall ThreadProc(void* userdata);
static unsigned int __stdcall ThreadProc(void* userdata);
HANDLE m_thread;
unsigned int m_threadId;

View File

@@ -7,22 +7,22 @@
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size) throw(std::bad_alloc)
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size) throw(std::bad_alloc)
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) throw()
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) throw()
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}

View File

@@ -7,22 +7,22 @@
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size) throw(std::bad_alloc)
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size) throw(std::bad_alloc)
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) throw()
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) throw()
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}

View File

@@ -145,7 +145,7 @@ void* NzBuffer::GetBufferPtr()
if (!m_impl)
{
NazaraError("Buffer not created");
return false;
return nullptr;
}
#endif
@@ -158,7 +158,7 @@ const void* NzBuffer::GetBufferPtr() const
if (!m_impl)
{
NazaraError("Buffer not created");
return false;
return nullptr;
}
#endif

View File

@@ -7,22 +7,22 @@
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size) throw(std::bad_alloc)
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size) throw(std::bad_alloc)
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) throw()
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) throw()
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}

View File

@@ -102,6 +102,11 @@ namespace
}
}
NzOpenGLFunc NzOpenGL::GetEntry(const NzString& entryPoint)
{
return LoadEntry(entryPoint.GetConstBuffer(), false);
}
unsigned int NzOpenGL::GetVersion()
{
return openGLversion;
@@ -262,6 +267,7 @@ bool NzOpenGL::Initialize()
glGetUniformLocation = reinterpret_cast<PFNGLGETUNIFORMLOCATIONPROC>(LoadEntry("glGetUniformLocation"));
glLinkProgram = reinterpret_cast<PFNGLLINKPROGRAMPROC>(LoadEntry("glLinkProgram"));
glMapBuffer = reinterpret_cast<PFNGLMAPBUFFERPROC>(LoadEntry("glMapBuffer"));
glPixelStorei = reinterpret_cast<PFNGLPIXELSTOREIPROC>(LoadEntry("glPixelStorei"));
glPolygonMode = reinterpret_cast<PFNGLPOLYGONMODEPROC>(LoadEntry("glPolygonMode"));
glReadPixels = reinterpret_cast<PFNGLREADPIXELSPROC>(LoadEntry("glReadPixels"));
glScissor = reinterpret_cast<PFNGLSCISSORPROC>(LoadEntry("glScissor"));
@@ -600,6 +606,7 @@ PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = nullptr;
PFNGLLINKPROGRAMPROC glLinkProgram = nullptr;
PFNGLMAPBUFFERPROC glMapBuffer = nullptr;
PFNGLMAPBUFFERRANGEPROC glMapBufferRange = nullptr;
PFNGLPIXELSTOREIPROC glPixelStorei = nullptr;
PFNGLPOLYGONMODEPROC glPolygonMode = nullptr;
PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d = nullptr;
PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f = nullptr;

View File

@@ -80,8 +80,7 @@ bool NzRenderWindow::CopyToImage(NzImage* image)
nzUInt8* pixels = image->GetPixels();
glReadPixels(0, 0, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
for (unsigned int j = 0; j < size.y/2; ++j)
std::swap_ranges(&pixels[j*size.x*4], &pixels[(j+1)*size.x*4-1], &pixels[(size.y-j-1)*size.x*4]);
image->FlipVertically();
return true;
}

View File

@@ -13,21 +13,13 @@
struct NzTextureImpl
{
// GCC 4.7 !!!!!!
NzTextureImpl() :
isTarget(false),
mipmapping(false),
mipmapsUpdated(true)
{
}
GLuint id;
nzImageType type;
nzPixelFormat format;
nzUInt8 levelCount;
bool isTarget;
bool mipmapping;
bool mipmapsUpdated;
bool isTarget = false;
bool mipmapping = false;
bool mipmapsUpdated = true;
unsigned int depth;
unsigned int height;
unsigned int width;
@@ -279,6 +271,18 @@ namespace
}
}
inline void SetUnpackAlignement(nzUInt8 bpp)
{
if (bpp % 8 == 0)
glPixelStorei(GL_UNPACK_ALIGNMENT, 8);
else if (bpp % 4 == 0)
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
else if (bpp % 2 == 0)
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
else
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}
void UnlockTexture(NzTextureImpl* impl)
{
#ifdef NAZARA_DEBUG
@@ -539,27 +543,11 @@ bool NzTexture::Download(NzImage* image) const
unsigned int width = m_impl->width;
unsigned int height = m_impl->height;
unsigned int depth = m_impl->depth;
nzUInt8 bpp = NzPixelFormat::GetBPP(m_impl->format);
nzUInt8* mirrored = new nzUInt8[width*height*depth*bpp];
// Téléchargement...
for (nzUInt8 level = 0; level < m_impl->levelCount; ++level)
{
glGetTexImage(openglTarget[m_impl->type], level, format.dataFormat, format.dataType, mirrored);
// Inversion de la texture pour le repère d'OpenGL
///FIXME: Gérer l'inversion dans NzImage, et gérer également les images compressées
unsigned int faceSize = width*height*bpp;
nzUInt8* ptr = mirrored;
for (unsigned int d = 0; d < depth; ++d)
{
for (unsigned int j = 0; j < height/2; ++j)
std::swap_ranges(&ptr[j*width*bpp], &ptr[(j+1)*width*bpp-1], &ptr[(height-j-1)*width*bpp]);
ptr += faceSize;
}
glGetTexImage(openglTarget[m_impl->type], level, format.dataFormat, format.dataType, image->GetPixels(level));
if (width > 1)
width >>= 1;
@@ -573,7 +561,9 @@ bool NzTexture::Download(NzImage* image) const
UnlockTexture(m_impl);
delete[] mirrored;
// Inversion de la texture pour le repère d'OpenGL
if (!image->FlipVertically())
NazaraWarning("Failed to flip image");
return true;
}
@@ -1138,7 +1128,20 @@ bool NzTexture::Update(const NzImage& image, const NzRectui& rect, unsigned int
}
#endif
return Update(image.GetConstPixels(level), rect, z, level);
const nzUInt8* pixels = image.GetConstPixels(level, rect.x, rect.y, z);
if (!pixels)
{
NazaraError("Failed to access image's pixels");
return false;
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, image.GetWidth(level));
bool success = Update(pixels, rect, z, level);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
return success;
}
bool NzTexture::Update(const NzImage& image, const NzCubeui& cube, nzUInt8 level)
@@ -1157,7 +1160,22 @@ bool NzTexture::Update(const NzImage& image, const NzCubeui& cube, nzUInt8 level
}
#endif
return Update(image.GetConstPixels(level), cube, level);
const nzUInt8* pixels = image.GetConstPixels(level, cube.x, cube.y, cube.z);
if (!pixels)
{
NazaraError("Failed to access image's pixels");
return false;
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, image.GetWidth(level));
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, image.GetHeight(level));
bool success = Update(pixels, cube, level);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
return success;
}
bool NzTexture::Update(const nzUInt8* pixels, nzUInt8 level)
@@ -1208,8 +1226,12 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int
NazaraError("Invalid rectangle");
return false;
}
#endif
if (rect.x+rect.width > std::max(m_impl->width >> level, 1U) || rect.y+rect.height > std::max(m_impl->height >> level, 1U))
unsigned int height = std::max(m_impl->height >> level, 1U);
#if NAZARA_RENDERER_SAFE
if (rect.x+rect.width > std::max(m_impl->width >> level, 1U) || rect.y+rect.height > height)
{
NazaraError("Rectangle dimensions are out of bounds");
return false;
@@ -1238,39 +1260,35 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int
nzUInt8 bpp = NzPixelFormat::GetBPP(m_impl->format);
// Inversion de la texture pour le repère d'OpenGL
///FIXME: Gérer l'inversion dans NzImage, et gérer également les images compressées
unsigned int size = rect.width*rect.height*bpp;
nzUInt8* mirrored = new nzUInt8[size];
std::memcpy(mirrored, pixels, size);
NzImage mirrored;
mirrored.Create(m_impl->type, m_impl->format, rect.width, rect.height);
mirrored.Update(pixels);
nzUInt8* ptr = &mirrored[size*z];
for (unsigned int j = 0; j < rect.height/2; ++j)
std::swap_ranges(&ptr[j*rect.width*bpp], &ptr[(j+1)*rect.width*bpp-1], &ptr[(rect.height-j-1)*rect.width*bpp]);
if (!mirrored.FlipVertically())
NazaraWarning("Failed to flip image");
SetUnpackAlignement(bpp);
LockTexture(m_impl);
switch (m_impl->type)
{
case nzImageType_1D:
glTexSubImage1D(GL_TEXTURE_1D, level, rect.x, rect.width, format.dataFormat, format.dataType, mirrored);
glTexSubImage1D(GL_TEXTURE_1D, level, rect.x, rect.width, format.dataFormat, format.dataType, mirrored.GetConstPixels());
break;
case nzImageType_2D:
glTexSubImage2D(GL_TEXTURE_2D, level, rect.x, rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored);
glTexSubImage2D(GL_TEXTURE_2D, level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored.GetConstPixels());
break;
case nzImageType_3D:
glTexSubImage3D(GL_TEXTURE_3D, level, rect.x, rect.y, z, rect.width, rect.height, 1, format.dataFormat, format.dataType, mirrored);
glTexSubImage3D(GL_TEXTURE_3D, level, rect.x, height-rect.height-rect.y, z, rect.width, rect.height, 1, format.dataFormat, format.dataType, mirrored.GetConstPixels());
break;
default:
NazaraInternalError("Image type not handled (0x" + NzString::Number(m_impl->type, 16) + ')');
}
UnlockTexture(m_impl);
delete[] mirrored;
return true;
}
@@ -1306,9 +1324,13 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve
NazaraError("Invalid rectangle");
return false;
}
#endif
unsigned int height = std::max(m_impl->height >> level, 1U);
#if NAZARA_RENDERER_SAFE
if (cube.x+cube.width > std::max(m_impl->width >> level, 1U) ||
cube.y+cube.height > std::max(m_impl->height >> level, 1U) ||
cube.y+cube.height > height ||
cube.z+cube.depth > std::max(m_impl->depth >> level, 1U))
{
NazaraError("Cube dimensions are out of bounds");
@@ -1332,45 +1354,35 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve
nzUInt8 bpp = NzPixelFormat::GetBPP(m_impl->format);
// Inversion de la texture pour le repère d'OpenGL
///FIXME: Gérer l'inversion dans NzImage, et gérer également les images compressées
unsigned int faceSize = cube.width*cube.height*bpp;
unsigned int size = faceSize*cube.depth;
nzUInt8* mirrored = new nzUInt8[size];
std::memcpy(mirrored, pixels, size);
NzImage mirrored;
mirrored.Create(m_impl->type, m_impl->format, cube.width, cube.height, cube.depth);
mirrored.Update(pixels);
nzUInt8* ptr = mirrored;
for (unsigned int d = 0; d < cube.depth; ++d)
{
for (unsigned int j = 0; j < cube.height/2; ++j)
std::swap_ranges(&ptr[j*cube.width*bpp], &ptr[(j+1)*cube.width*bpp-1], &ptr[(cube.height-j-1)*cube.width*bpp]);
if (!mirrored.FlipVertically())
NazaraWarning("Failed to flip image");
ptr += faceSize;
}
SetUnpackAlignement(bpp);
LockTexture(m_impl);
switch (m_impl->type)
{
case nzImageType_1D:
glTexSubImage1D(GL_TEXTURE_1D, level, cube.x, cube.width, format.dataFormat, format.dataType, mirrored);
glTexSubImage1D(GL_TEXTURE_1D, level, cube.x, cube.width, format.dataFormat, format.dataType, mirrored.GetConstPixels());
break;
case nzImageType_2D:
glTexSubImage2D(GL_TEXTURE_2D, level, cube.x, cube.y, cube.width, cube.height, format.dataFormat, format.dataType, mirrored);
glTexSubImage2D(GL_TEXTURE_2D, level, cube.x, height-cube.height-cube.y, cube.width, cube.height, format.dataFormat, format.dataType, mirrored.GetConstPixels());
break;
case nzImageType_3D:
glTexSubImage3D(GL_TEXTURE_3D, level, cube.x, cube.y, cube.z, cube.width, cube.height, cube.depth, format.dataFormat, format.dataType, mirrored);
glTexSubImage3D(GL_TEXTURE_3D, level, cube.x, height-cube.height-cube.y, cube.z, cube.width, cube.height, cube.depth, format.dataFormat, format.dataType, mirrored.GetConstPixels());
break;
default:
NazaraInternalError("Image type not handled (0x" + NzString::Number(m_impl->type, 16) + ')');
}
UnlockTexture(m_impl);
delete[] mirrored;
return true;
}
@@ -1409,7 +1421,13 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const NzImage& image, const NzRec
}
#endif
return UpdateFace(face, image.GetConstPixels(level), rect, level);
glPixelStorei(GL_UNPACK_ROW_LENGTH, image.GetWidth(level));
bool success = UpdateFace(face, image.GetConstPixels(level), rect, level);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
return success;
}
bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, nzUInt8 level)
@@ -1457,8 +1475,12 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe
NazaraError("Invalid rectangle");
return false;
}
#endif
if (rect.x+rect.width > std::max(m_impl->width >> level, 1U) || rect.y+rect.height > std::max(m_impl->height >> level, 1U))
unsigned int height = std::max(m_impl->height >> level, 1U);
#if NAZARA_RENDERER_SAFE
if (rect.x+rect.width > std::max(m_impl->width >> level, 1U) || rect.y+rect.height > height)
{
NazaraError("Rectangle dimensions are out of bounds");
return false;
@@ -1481,21 +1503,19 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe
nzUInt8 bpp = NzPixelFormat::GetBPP(m_impl->format);
// Inversion de la texture pour le repère d'OpenGL
///FIXME: Gérer l'inversion dans NzImage, et gérer également les images compressées
unsigned int size = rect.width*rect.height*bpp;
nzUInt8* mirrored = new nzUInt8[size];
std::memcpy(mirrored, pixels, size);
for (unsigned int j = 0; j < rect.height/2; ++j)
std::swap_ranges(&mirrored[j*rect.width*bpp], &mirrored[(j+1)*rect.width*bpp-1], &mirrored[(rect.height-j-1)*rect.width*bpp]);
NzImage mirrored;
mirrored.Create(m_impl->type, m_impl->format, rect.width, rect.height);
mirrored.Update(pixels);
if (!mirrored.FlipVertically())
NazaraWarning("Failed to flip image");
SetUnpackAlignement(bpp);
LockTexture(m_impl);
glTexSubImage2D(cubemapFace[face], level, rect.x, rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored);
glTexSubImage2D(cubemapFace[face], level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored.GetConstPixels());
UnlockTexture(m_impl);
delete[] mirrored;
return true;
}

View File

@@ -7,22 +7,22 @@
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size) throw(std::bad_alloc)
void* operator new(std::size_t size)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size) throw(std::bad_alloc)
void* operator new[](std::size_t size)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) throw()
void operator delete(void* pointer) noexcept
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) throw()
void operator delete[](void* pointer) noexcept
{
NzMemoryManager::Free(pointer, true);
}

View File

@@ -9,6 +9,19 @@
#include <cmath>
#include <Nazara/Utility/Debug.hpp>
namespace
{
inline unsigned int GetLevelSize(unsigned int size, nzUInt8 level)
{
return std::max(size >> level, 1U);
}
inline nzUInt8* GetPixelPtr(nzUInt8* base, nzUInt8 bpp, unsigned int x, unsigned int y, unsigned int z, unsigned int width, unsigned int height)
{
return &base[(width*(height*z+y) + x) * bpp];
}
}
NzImage::NzImage() :
m_sharedImage(&emptyImage)
{
@@ -98,13 +111,13 @@ bool NzImage::Convert(nzPixelFormat format)
}
if (width > 1)
width /= 2;
width >>= 1;
if (height > 1)
height /= 2;
height >>= 1;
if (depth > 1 && m_sharedImage->type != nzImageType_Cubemap)
depth /= 2;
depth >>= 1;
}
SharedImage* newImage = new SharedImage(1, m_sharedImage->type, format, m_sharedImage->levelCount, levels, m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth);
@@ -115,7 +128,7 @@ bool NzImage::Convert(nzPixelFormat format)
return true;
}
bool NzImage::Copy(const NzImage& source, const NzRectui& srcRect, const NzVector2ui& dstPos)
bool NzImage::Copy(const NzImage& source, const NzCubeui& srcCube, const NzVector3ui& dstPos)
{
#if NAZARA_UTILITY_SAFE
if (!source.IsValid())
@@ -131,29 +144,49 @@ bool NzImage::Copy(const NzImage& source, const NzRectui& srcRect, const NzVecto
}
#endif
return Update(&source.GetConstPixels()[(srcRect.x + srcRect.y * source.GetHeight()) * source.GetBPP()],
NzRectui(dstPos.x, dstPos.y, srcRect.width, srcRect.height));
}
bool NzImage::CopyToFace(nzCubemapFace face, const NzImage& source, const NzRectui& srcRect, const NzVector2ui& dstPos)
{
#if NAZARA_UTILITY_SAFE
if (!source.IsValid())
const nzUInt8* pixels = source.GetConstPixels(0, srcCube.x, srcCube.y, srcCube.z);
if (!pixels)
{
NazaraError("Source image must be valid");
NazaraError("Failed to access pixels");
return false;
}
if (source.GetFormat() != m_sharedImage->format)
{
NazaraError("Source image format does not match destination image format");
return false;
}
#endif
/*
Correctif temporaire : Update veut de la mémoire contigüe
Il est donc nécessaire de prendre la partie de la texture que nous voulons mettre à jour
return UpdateFace(face,
&source.GetConstPixels()[(srcRect.x + srcRect.y * source.GetHeight()) * source.GetBPP()],
NzRectui(dstPos.x, dstPos.y, srcRect.width, srcRect.height));
FIXME: Trouver une interface pour gérer ce genre de problème (Façon OpenGL?)
(Appliquer l'interface à NzTexture également)
*/
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
unsigned int dstLineStride = srcCube.width*bpp;
unsigned int dstFaceStride = dstLineStride*srcCube.height;
unsigned int srcLineStride = m_sharedImage->width*bpp;
unsigned int srcFaceStride = srcLineStride*m_sharedImage->height;
nzUInt8* cube = new nzUInt8[dstFaceStride*srcCube.depth];
nzUInt8* ptr = cube;
for (unsigned int z = 0; z < srcCube.depth; ++z)
{
nzUInt8* facePixels = ptr;
for (unsigned int y = 0; y < srcCube.height; ++y)
{
std::memcpy(facePixels, pixels, dstLineStride);
facePixels += dstLineStride;
pixels += srcLineStride;
}
ptr += dstFaceStride;
pixels += srcFaceStride;
}
bool success = Update(cube, NzCubeui(dstPos.x, dstPos.y, dstPos.z, srcCube.width, srcCube.height, srcCube.depth));
delete[] cube;
return success;
}
bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount)
@@ -233,13 +266,13 @@ bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width,
levels[i] = new nzUInt8[w * h * d * NzPixelFormat::GetBPP(format)];
if (w > 1)
w /= 2;
w >>= 1;
if (h > 1)
h /= 2;
h >>= 1;
if (d > 1 && type != nzImageType_Cubemap)
d /= 2;
d >>= 1;
}
catch (const std::exception& e)
{
@@ -263,14 +296,323 @@ void NzImage::Destroy()
ReleaseImage();
}
bool NzImage::Fill(const NzColor& color)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
{
NazaraError("Image must be valid");
return false;
}
if (NzPixelFormat::IsCompressed(m_sharedImage->format))
{
NazaraError("Cannot access pixels from compressed image");
return false;
}
#endif
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8* pixels = new nzUInt8[bpp];
if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixels))
{
NazaraError("Failed to convert RGBA8 to " + NzPixelFormat::ToString(m_sharedImage->format));
delete[] pixels;
return false;
}
unsigned int width = m_sharedImage->width;
unsigned int height = m_sharedImage->height;
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth;
for (unsigned int level = 0; level < m_sharedImage->levelCount; ++level)
{
nzUInt8* ptr = &m_sharedImage->pixels[level][0];
nzUInt8* end = &m_sharedImage->pixels[level][width*height*depth*bpp];
while (ptr < end)
{
std::memcpy(ptr, pixels, bpp);
ptr += bpp;
}
if (width > 1U)
width >>= 1;
if (height > 1U)
height >>= 1;
if (depth > 1U && m_sharedImage->type != nzImageType_Cubemap)
depth >>= 1;
}
delete[] pixels;
return true;
}
bool NzImage::Fill(const NzColor& color, const NzRectui& rect, unsigned int z)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
{
NazaraError("Image must be valid");
return false;
}
if (!rect.IsValid())
{
NazaraError("Invalid rectangle");
return false;
}
if (rect.x+rect.width > m_sharedImage->width || rect.y+rect.height > m_sharedImage->height)
{
NazaraError("Rectangle dimensions are out of bounds");
return false;
}
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth;
if (z >= depth)
{
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')');
return false;
}
#endif
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8* pixels = new nzUInt8[bpp];
if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixels))
{
NazaraError("Failed to convert RGBA8 to " + NzPixelFormat::ToString(m_sharedImage->format));
delete[] pixels;
return false;
}
nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->pixels[0], bpp, rect.x, rect.y, z, m_sharedImage->width, m_sharedImage->height);
unsigned int srcStride = rect.width * bpp;
unsigned int dstStride = m_sharedImage->width * bpp;
for (unsigned int y = 0; y < rect.height; ++y)
{
nzUInt8* start = dstPixels;
nzUInt8* end = dstPixels + srcStride;
while (start < end)
{
std::memcpy(start, pixels, bpp);
start += bpp;
}
dstPixels += dstStride;
}
return true;
}
bool NzImage::Fill(const NzColor& color, const NzCubeui& cube)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
{
NazaraError("Image must be valid");
return false;
}
if (!cube.IsValid())
{
NazaraError("Invalid rectangle");
return false;
}
if (cube.x+cube.width > m_sharedImage->width || cube.y+cube.height > m_sharedImage->height || cube.z+cube.depth > m_sharedImage->depth)
{
NazaraError("Cube dimensions are out of bounds");
return false;
}
#endif
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8* pixels = new nzUInt8[bpp];
if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixels))
{
NazaraError("Failed to convert RGBA8 to " + NzPixelFormat::ToString(m_sharedImage->format));
delete[] pixels;
return false;
}
nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->pixels[0], bpp, cube.x, cube.y, cube.z, m_sharedImage->width, m_sharedImage->height);
unsigned int srcStride = cube.width * bpp;
unsigned int dstStride = m_sharedImage->width * bpp;
unsigned int faceSize = dstStride * m_sharedImage->height;
for (unsigned int z = 0; z < cube.depth; ++z)
{
nzUInt8* facePixels = dstPixels;
for (unsigned int y = 0; y < cube.height; ++y)
{
nzUInt8* start = facePixels;
nzUInt8* end = facePixels + srcStride;
while (start < end)
{
std::memcpy(start, pixels, bpp);
start += bpp;
}
facePixels += dstStride;
}
dstPixels += faceSize;
}
delete[] pixels;
return true;
}
bool NzImage::FlipHorizontally()
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
{
NazaraError("Image must be valid");
return false;
}
if (NzPixelFormat::IsCompressed(m_sharedImage->format))
{
NazaraError("Cannot flip compressed image");
return false;
}
#endif
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
unsigned int width = m_sharedImage->width;
unsigned int height = m_sharedImage->height;
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth;
for (unsigned int level = 0; level < m_sharedImage->levelCount; ++level)
{
for (unsigned int z = 0; z < depth; ++z)
{
nzUInt8* ptr = &m_sharedImage->pixels[level][width*height*z];
unsigned int lineStride = width*bpp;
for (unsigned int y = 0; y < height; ++y)
{
for (unsigned int x = 0; x < width/2; ++x)
std::swap_ranges(&ptr[x*bpp], &ptr[(x+1)*bpp], &ptr[(width-x)*bpp]);
ptr += lineStride;
}
}
if (width > 1U)
width >>= 1;
if (height > 1U)
height >>= 1;
if (depth > 1U && m_sharedImage->type != nzImageType_Cubemap)
depth >>= 1;
}
return true;
}
bool NzImage::FlipVertically()
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
{
NazaraError("Image must be valid");
return false;
}
if (NzPixelFormat::IsCompressed(m_sharedImage->format))
{
NazaraError("Cannot flip compressed image");
return false;
}
#endif
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
unsigned int width = m_sharedImage->width;
unsigned int height = m_sharedImage->height;
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth;
for (unsigned int level = 0; level < m_sharedImage->levelCount; ++level)
{
for (unsigned int z = 0; z < depth; ++z)
{
nzUInt8* ptr = &m_sharedImage->pixels[level][width*height*z];
unsigned int lineStride = width*bpp;
for (unsigned int y = 0; y < height/2; ++y)
std::swap_ranges(&ptr[y*lineStride], &ptr[(y+1)*lineStride-1], &ptr[(height-y-1)*lineStride]);
}
if (width > 1U)
width >>= 1;
if (height > 1U)
height >>= 1;
if (depth > 1U && m_sharedImage->type != nzImageType_Cubemap)
depth >>= 1;
}
return true;
}
nzUInt8 NzImage::GetBPP() const
{
return NzPixelFormat::GetBPP(m_sharedImage->format);
}
const nzUInt8* NzImage::GetConstPixels(nzUInt8 level) const
const nzUInt8* NzImage::GetConstPixels(nzUInt8 level, unsigned int x, unsigned int y, unsigned int z) const
{
return m_sharedImage->pixels[level];
#if NAZARA_UTILITY_SAFE
if (!IsValid())
{
NazaraError("Image must be valid");
return nullptr;
}
if (level >= m_sharedImage->levelCount)
{
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
return nullptr;
}
if (x >= m_sharedImage->width)
{
NazaraError("X value exceeds width (" + NzString::Number(x) + " >= (" + NzString::Number(m_sharedImage->width) + ')');
return nullptr;
}
if (y >= m_sharedImage->height)
{
NazaraError("Y value exceeds width (" + NzString::Number(y) + " >= (" + NzString::Number(m_sharedImage->height) + ')');
return nullptr;
}
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth;
if (z >= depth)
{
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')');
return nullptr;
}
#endif
return GetPixelPtr(m_sharedImage->pixels[level], NzPixelFormat::GetBPP(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height);
}
unsigned int NzImage::GetDepth(nzUInt8 level) const
@@ -283,7 +625,7 @@ unsigned int NzImage::GetDepth(nzUInt8 level) const
}
#endif
return std::max(m_sharedImage->depth >> level, 1U);
return GetLevelSize(m_sharedImage->depth, level);
}
nzPixelFormat NzImage::GetFormat() const
@@ -301,7 +643,7 @@ unsigned int NzImage::GetHeight(nzUInt8 level) const
}
#endif
return std::max(m_sharedImage->height >> level, 1U);
return GetLevelSize(m_sharedImage->height, level);
}
nzUInt8 NzImage::GetLevelCount() const
@@ -314,7 +656,7 @@ nzUInt8 NzImage::GetMaxLevel() const
return GetMaxLevel(m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth);
}
NzColor NzImage::GetPixel(unsigned int x, unsigned int y, unsigned int z) const
NzColor NzImage::GetPixelColor(unsigned int x, unsigned int y, unsigned int z) const
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
@@ -323,12 +665,6 @@ NzColor NzImage::GetPixel(unsigned int x, unsigned int y, unsigned int z) const
return NzColor();
}
if (m_sharedImage->type == nzImageType_Cubemap)
{
NazaraError("GetPixel is not designed for cubemaps, use GetPixelFace instead");
return NzColor();
}
if (NzPixelFormat::IsCompressed(m_sharedImage->format))
{
NazaraError("Cannot access pixels from compressed image");
@@ -347,14 +683,15 @@ NzColor NzImage::GetPixel(unsigned int x, unsigned int y, unsigned int z) const
return NzColor();
}
if (z >= m_sharedImage->depth)
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth;
if (z >= depth)
{
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(m_sharedImage->depth) + ')');
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')');
return NzColor();
}
#endif
const nzUInt8* pixel = &m_sharedImage->pixels[0][(m_sharedImage->height*(m_sharedImage->width*z+y) + x) * NzPixelFormat::GetBPP(m_sharedImage->format)];
const nzUInt8* pixel = GetPixelPtr(m_sharedImage->pixels[0], NzPixelFormat::GetBPP(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height);
NzColor color;
if (!NzPixelFormat::Convert(m_sharedImage->format, nzPixelFormat_RGBA8, pixel, &color.r))
@@ -363,54 +700,44 @@ NzColor NzImage::GetPixel(unsigned int x, unsigned int y, unsigned int z) const
return color;
}
NzColor NzImage::GetPixelFace(nzCubemapFace face, unsigned int x, unsigned int y) const
nzUInt8* NzImage::GetPixels(nzUInt8 level, unsigned int x, unsigned int y, unsigned int z)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
{
NazaraError("Image must be valid");
return NzColor();
return nullptr;
}
if (m_sharedImage->type != nzImageType_Cubemap)
if (level >= m_sharedImage->levelCount)
{
NazaraError("GetPixelFace is designed for cubemaps, use GetPixel instead");
return NzColor();
}
if (NzPixelFormat::IsCompressed(m_sharedImage->format))
{
NazaraError("Cannot access pixels from compressed image");
return NzColor();
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
return nullptr;
}
if (x >= m_sharedImage->width)
{
NazaraError("X value exceeds width (" + NzString::Number(x) + " >= (" + NzString::Number(m_sharedImage->width) + ')');
return NzColor();
return nullptr;
}
if (y >= m_sharedImage->height)
{
NazaraError("Y value exceeds width (" + NzString::Number(y) + " >= (" + NzString::Number(m_sharedImage->height) + ')');
return NzColor();
return nullptr;
}
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth;
if (z >= depth)
{
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')');
return nullptr;
}
#endif
const nzUInt8* pixel = &m_sharedImage->pixels[0][(m_sharedImage->height*(m_sharedImage->width*(face-nzCubemapFace_PositiveX)+y) + x) * NzPixelFormat::GetBPP(m_sharedImage->format)];
NzColor color;
if (!NzPixelFormat::Convert(m_sharedImage->format, nzPixelFormat_RGBA8, pixel, &color.r))
NazaraError("Failed to convert image's format to RGBA8");
return color;
}
nzUInt8* NzImage::GetPixels(nzUInt8 level)
{
EnsureOwnership();
return m_sharedImage->pixels[level];
return GetPixelPtr(m_sharedImage->pixels[level], NzPixelFormat::GetBPP(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height);
}
unsigned int NzImage::GetSize() const
@@ -425,13 +752,13 @@ unsigned int NzImage::GetSize() const
size += width * height * depth;
if (width > 1)
width /= 2;
width >>= 1;
if (height > 1)
height /= 2;
height >>= 1;
if (depth > 1)
depth /= 2;
depth >>= 1;
}
if (m_sharedImage->type == nzImageType_Cubemap)
@@ -450,9 +777,9 @@ unsigned int NzImage::GetSize(nzUInt8 level) const
}
#endif
return (std::max(m_sharedImage->width >> level, 1U)) *
(std::max(m_sharedImage->height >> level, 1U)) *
((m_sharedImage->type == nzImageType_Cubemap) ? 6 : std::max(m_sharedImage->depth >> level, 1U)) *
return (GetLevelSize(m_sharedImage->width, level)) *
(GetLevelSize(m_sharedImage->height, level)) *
((m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level)) *
NzPixelFormat::GetBPP(m_sharedImage->format);
}
@@ -471,7 +798,7 @@ unsigned int NzImage::GetWidth(nzUInt8 level) const
}
#endif
return std::max(m_sharedImage->width >> level, 1U);
return GetLevelSize(m_sharedImage->width, level);
}
bool NzImage::IsCompressed() const
@@ -549,7 +876,7 @@ bool NzImage::SetLevelCount(nzUInt8 levelCount)
return true;
}
bool NzImage::SetPixel(const NzColor& color, unsigned int x, unsigned int y, unsigned int z)
bool NzImage::SetPixelColor(const NzColor& color, unsigned int x, unsigned int y, unsigned int z)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
@@ -558,12 +885,6 @@ bool NzImage::SetPixel(const NzColor& color, unsigned int x, unsigned int y, uns
return false;
}
if (m_sharedImage->type == nzImageType_Cubemap)
{
NazaraError("SetPixel is not designed for cubemaps, use SetPixelFace instead");
return false;
}
if (NzPixelFormat::IsCompressed(m_sharedImage->format))
{
NazaraError("Cannot access pixels from compressed image");
@@ -582,59 +903,15 @@ bool NzImage::SetPixel(const NzColor& color, unsigned int x, unsigned int y, uns
return false;
}
if (z >= m_sharedImage->depth)
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth;
if (z >= depth)
{
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(m_sharedImage->depth) + ')');
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')');
return false;
}
#endif
nzUInt8* pixel = &m_sharedImage->pixels[0][(m_sharedImage->height*(m_sharedImage->width*z+y) + x) * NzPixelFormat::GetBPP(m_sharedImage->format)];
if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixel))
{
NazaraError("Failed to convert RGBA8 to image's format");
return false;
}
return true;
}
bool NzImage::SetPixelFace(nzCubemapFace face, const NzColor& color, unsigned int x, unsigned int y)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
{
NazaraError("Image must be valid");
return false;
}
if (m_sharedImage->type != nzImageType_Cubemap)
{
NazaraError("SetPixelFace is designed for cubemaps, use SetPixel instead");
return false;
}
if (NzPixelFormat::IsCompressed(m_sharedImage->format))
{
NazaraError("Cannot access pixels from compressed image");
return false;
}
if (x >= m_sharedImage->width)
{
NazaraError("X value exceeds width (" + NzString::Number(x) + " >= (" + NzString::Number(m_sharedImage->width) + ')');
return false;
}
if (y >= m_sharedImage->height)
{
NazaraError("Y value exceeds width (" + NzString::Number(y) + " >= (" + NzString::Number(m_sharedImage->height) + ')');
return false;
}
#endif
nzUInt8* pixel = &m_sharedImage->pixels[0][(m_sharedImage->height*(m_sharedImage->width*(face-nzCubemapFace_PositiveX)+y) + x) * NzPixelFormat::GetBPP(m_sharedImage->format)];
nzUInt8* pixel = GetPixelPtr(m_sharedImage->pixels[0], NzPixelFormat::GetBPP(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height);
if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixel))
{
@@ -654,12 +931,6 @@ bool NzImage::Update(const nzUInt8* pixels, nzUInt8 level)
return false;
}
if (m_sharedImage->type == nzImageType_Cubemap)
{
NazaraError("Update is not designed for cubemaps, use UpdateFace instead");
return false;
}
if (!pixels)
{
NazaraError("Invalid pixel source");
@@ -689,12 +960,6 @@ bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z
return false;
}
if (m_sharedImage->type == nzImageType_Cubemap)
{
NazaraError("Update is not designed for cubemaps, use UpdateFace instead");
return false;
}
if (!pixels)
{
NazaraError("Invalid pixel source");
@@ -706,25 +971,25 @@ bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
return false;
}
#endif
unsigned int width = std::max(m_sharedImage->width >> level, 1U);
unsigned int height = std::max(m_sharedImage->height >> level, 1U);
#if NAZARA_UTILITY_SAFE
if (!rect.IsValid())
{
NazaraError("Invalid rectangle");
return false;
}
#endif
unsigned int width = GetLevelSize(m_sharedImage->width, level);
unsigned int height = GetLevelSize(m_sharedImage->height, level);
#if NAZARA_UTILITY_SAFE
if (rect.x+rect.width > width || rect.y+rect.height > height)
{
NazaraError("Rectangle dimensions are out of bounds");
return false;
}
unsigned int depth = std::max(m_sharedImage->depth >> level, 1U);
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level);
if (z >= depth)
{
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')');
@@ -735,14 +1000,14 @@ bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8* dstPixels = &m_sharedImage->pixels[level][(height*(width*z + rect.y) + rect.x) * bpp];
nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->pixels[level], bpp, rect.x, rect.y, z, width, height);
unsigned int srcStride = rect.width * bpp;
unsigned int blockSize = width * bpp;
for (unsigned int i = 0; i < rect.height; ++i)
unsigned int dstStride = m_sharedImage->width * bpp;
for (unsigned int y = 0; y < rect.height; ++y)
{
std::memcpy(dstPixels, pixels, blockSize);
std::memcpy(dstPixels, pixels, srcStride);
pixels += srcStride;
dstPixels += blockSize;
dstPixels += dstStride;
}
return true;
@@ -758,12 +1023,6 @@ bool NzImage::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level)
return false;
}
if (m_sharedImage->type == nzImageType_Cubemap)
{
NazaraError("Update is not designed for cubemaps, use UpdateFace instead");
return false;
}
if (!pixels)
{
NazaraError("Invalid pixel source");
@@ -777,9 +1036,9 @@ bool NzImage::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level)
}
#endif
unsigned int width = std::max(m_sharedImage->width >> level, 1U);
unsigned int height = std::max(m_sharedImage->height >> level, 1U);
unsigned int depth = std::max(m_sharedImage->height >> level, 1U);
unsigned int width = GetLevelSize(m_sharedImage->width, level);
unsigned int height = GetLevelSize(m_sharedImage->height, level);
unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->height, level);
#if NAZARA_UTILITY_SAFE
if (!cube.IsValid())
@@ -798,18 +1057,18 @@ bool NzImage::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level)
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8* dstPixels = &m_sharedImage->pixels[level][(height*(width*cube.z + cube.y) + cube.x) * bpp];
nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->pixels[level], bpp, cube.x, cube.y, cube.z, width, height);
unsigned int srcStride = cube.width * bpp;
unsigned int blockSize = width * bpp;
unsigned int faceSize = width * height * bpp;
unsigned int dstStride = width * bpp;
unsigned int faceSize = dstStride * height;
for (unsigned int z = 0; z < cube.depth; ++z)
{
nzUInt8* facePixels = dstPixels;
for (unsigned int i = 0; i < cube.height; ++i)
for (unsigned int y = 0; y < cube.height; ++y)
{
std::memcpy(dstPixels, pixels, blockSize);
std::memcpy(facePixels, pixels, srcStride);
pixels += srcStride;
facePixels += blockSize;
facePixels += dstStride;
}
dstPixels += faceSize;
@@ -818,98 +1077,6 @@ bool NzImage::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level)
return true;
}
bool NzImage::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, nzUInt8 level)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
{
NazaraError("Image must be valid");
return false;
}
if (m_sharedImage->type != nzImageType_Cubemap)
{
NazaraError("UpdateFace is designed for cubemaps, use Update instead");
return false;
}
if (!pixels)
{
NazaraError("Invalid pixel source");
return false;
}
if (level >= m_sharedImage->levelCount)
{
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
return false;
}
#endif
EnsureOwnership();
unsigned int size = GetSize(level);
std::memcpy(&m_sharedImage->pixels[level][size*(face-nzCubemapFace_PositiveX)], pixels, size);
return true;
}
bool NzImage::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRectui& rect, nzUInt8 level)
{
#if NAZARA_UTILITY_SAFE
if (!IsValid())
{
NazaraError("Image must be valid");
return false;
}
if (m_sharedImage->type != nzImageType_Cubemap)
{
NazaraError("UpdateFace is designed for cubemaps, use Update instead");
return false;
}
if (!pixels)
{
NazaraError("Invalid pixel source");
return false;
}
if (!rect.IsValid())
{
NazaraError("Invalid rectangle");
return false;
}
if (rect.x+rect.width > std::max(m_sharedImage->width >> level, 1U) || rect.y+rect.height > std::max(m_sharedImage->height >> level, 1U))
{
NazaraError("Rectangle dimensions are out of bounds");
return false;
}
if (level >= m_sharedImage->levelCount)
{
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
return false;
}
#endif
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8* dstPixels = &m_sharedImage->pixels[level][(m_sharedImage->height*(m_sharedImage->width*(face-nzCubemapFace_PositiveX) + rect.y) + rect.x) * bpp];
unsigned int srcStride = rect.width * bpp;
unsigned int blockSize = m_sharedImage->width * bpp;
for (unsigned int i = 0; i < rect.height; ++i)
{
std::memcpy(dstPixels, pixels, blockSize);
pixels += srcStride;
dstPixels += blockSize;
}
return true;
}
NzImage& NzImage::operator=(const NzImage& image)
{
ReleaseImage();
@@ -988,7 +1155,7 @@ void NzImage::EnsureOwnership()
{
unsigned int size = GetSize(i);
pixels[i] = new nzUInt8[size];
std::memcpy(pixels[i], &m_sharedImage->pixels[i], size);
std::memcpy(pixels[i], m_sharedImage->pixels[i], size);
}
m_sharedImage = new SharedImage(1, m_sharedImage->type, m_sharedImage->format, m_sharedImage->levelCount, pixels, m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth);

View File

@@ -11,7 +11,7 @@
#include <Nazara/Utility/Image.hpp>
#define STBI_HEADER_FILE_ONLY
#include <Nazara/Utility/Loaders/STB/stb_image.c>
#include <Nazara/Utility/Loaders/STB/stb_image.cpp>
#include <Nazara/Utility/Debug.hpp>

View File

@@ -4,6 +4,8 @@
// Un grand merci à Laurent Gomila pour la SFML qui m'aura bien aidé à réaliser cette implémentation
#define OEMRESOURCE
#include <Nazara/Utility/Win32/WindowImpl.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Mutex.hpp>
@@ -14,6 +16,11 @@
#include <windowsx.h>
#include <Nazara/Utility/Debug.hpp>
#ifdef _WIN64
#define GWL_USERDATA GWLP_USERDATA
#define GCL_HCURSOR GCLP_HCURSOR
#endif
// N'est pas définit avec MinGW apparemment
#ifndef MAPVK_VK_TO_VSC
#define MAPVK_VK_TO_VSC 0
@@ -116,7 +123,7 @@ bool NzWindowImpl::Create(NzVideoMode mode, const NzString& title, nzUInt32 styl
win32StyleEx = 0;
RECT rect = {0, 0, width, height};
RECT rect = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)};
AdjustWindowRect(&rect, win32Style, false);
width = rect.right-rect.left;
height = rect.bottom-rect.top;
@@ -330,7 +337,7 @@ void NzWindowImpl::SetPosition(int x, int y)
void NzWindowImpl::SetSize(unsigned int width, unsigned int height)
{
// SetWindowPos demande la taille totale de la fenêtre
RECT rect = {0, 0, width, height};
RECT rect = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)};
AdjustWindowRect(&rect, GetWindowLongPtr(m_handle, GWL_STYLE), false);
SetWindowPos(m_handle, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER);

View File

@@ -308,6 +308,7 @@ void NzWindow::SetEventListener(bool listener)
m_impl->SetEventListener(listener);
if (!listener)
{
// On vide la pile des évènements
NzLockGuard lock(m_eventMutex);
while (!m_events.empty())
m_events.pop();