From 96ea5fdaa724f2590be7ed50ecd6a71df1a5788a Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 27 May 2012 11:57:34 +0200 Subject: [PATCH] Added NzImage::Get/SetPixel(Face) NzImage::Update(const nzUInt8* pixels, const NzRectui& rect) now takes a third argument to specify the layer of the 3D image (if a 3D image), default to 0 Optimized NzPixelFormat conversion from RGBA4 Added NzColor --- include/Nazara/Core/Color.hpp | 68 +++++ include/Nazara/Core/Color.inl | 410 +++++++++++++++++++++++++++++ include/Nazara/Utility/Image.hpp | 9 +- src/Nazara/Core/Color.cpp | 16 ++ src/Nazara/Utility/Image.cpp | 212 ++++++++++++++- src/Nazara/Utility/PixelFormat.cpp | 10 +- 6 files changed, 711 insertions(+), 14 deletions(-) create mode 100644 include/Nazara/Core/Color.hpp create mode 100644 include/Nazara/Core/Color.inl create mode 100644 src/Nazara/Core/Color.cpp diff --git a/include/Nazara/Core/Color.hpp b/include/Nazara/Core/Color.hpp new file mode 100644 index 000000000..be4143c7f --- /dev/null +++ b/include/Nazara/Core/Color.hpp @@ -0,0 +1,68 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_COLOR_HPP +#define NAZARA_COLOR_HPP + +#include +#include +#include + +class NzColor +{ + public: + NzColor(); + NzColor(nzUInt8 red, nzUInt8 green, nzUInt8 blue, nzUInt8 alpha = 255); + explicit NzColor(nzUInt8 lightness); + NzColor(nzUInt8 color[3], nzUInt8 alpha = 255); + NzColor(const NzColor& color) = default; + ~NzColor() = default; + + NzString ToString() const; + + NzColor operator+(const NzColor& angles) const; + NzColor operator*(const NzColor& angles) const; + + NzColor operator+=(const NzColor& angles); + NzColor operator*=(const NzColor& angles); + + bool operator==(const NzColor& angles) const; + bool operator!=(const NzColor& angles) const; + + static NzColor FromCMY(float cyan, float magenta, float yellow); + static NzColor FromCMYK(float cyan, float magenta, float yellow, float black); + static NzColor FromHSL(nzUInt8 hue, nzUInt8 saturation, nzUInt8 lightness); + static NzColor FromHSV(nzUInt8 hue, nzUInt8 saturation, float value); + static NzColor FromXYZ(const NzVector3f& vec); + static NzColor FromXYZ(float x, float y, float z); + static void ToCMY(const NzColor& color, float* cyan, float* magenta, float* yellow); + static void ToCMYK(const NzColor& color, float* cyan, float* magenta, float* yellow, float* black); + static void ToXYZ(const NzColor& color, NzVector3f* vec); + static void ToXYZ(const NzColor& color, float* x, float* y, float* z); + static void ToHSL(const NzColor& color, nzUInt8* hue, nzUInt8* saturation, nzUInt8* lightness); + static void ToHSV(const NzColor& color, nzUInt8* hue, nzUInt8* saturation, float* value); + + nzUInt8 r, g, b, a; + + static const NzColor Black; + static const NzColor Blue; + static const NzColor Cyan; + static const NzColor Green; + static const NzColor Magenta; + static const NzColor Orange; + static const NzColor Red; + static const NzColor Yellow; + static const NzColor White; + + private: + static float Hue2RGB(float v1, float v2, float vH); +}; + +std::ostream& operator<<(std::ostream& out, const NzColor& color); + +#include + +#endif // NAZARA_COLOR_HPP diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl new file mode 100644 index 000000000..ec5491dd8 --- /dev/null +++ b/include/Nazara/Core/Color.inl @@ -0,0 +1,410 @@ +// Copyright (C) 2012 Jérôme Leclercq +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include + +inline NzColor::NzColor() +{ +} + +inline NzColor::NzColor(nzUInt8 red, nzUInt8 green, nzUInt8 blue, nzUInt8 alpha) : +r(red), +g(green), +b(blue), +a(alpha) +{ +} + +inline NzColor::NzColor(nzUInt8 lightness) : +r(lightness), +g(lightness), +b(lightness), +a(255) +{ +} + +inline NzColor::NzColor(nzUInt8 vec[3], nzUInt8 alpha) : +r(vec[0]), +g(vec[1]), +b(vec[2]), +a(alpha) +{ +} + +inline NzString NzColor::ToString() const +{ + NzStringStream ss; + ss << "Color(" << static_cast(r) << ", " << static_cast(g) << ", " << static_cast(b); + + if (a != 255) + ss << ", " << static_cast(a); + + ss << ')'; + + return ss; +} + +inline NzColor NzColor::operator+(const NzColor& color) const +{ + return NzColor(std::min(static_cast(r) + color.r, 255), + std::min(static_cast(r) + color.r, 255), + std::min(static_cast(r) + color.r, 255), + std::min(static_cast(r) + color.r, 255)); +} + +inline NzColor NzColor::operator*(const NzColor& color) const +{ + return NzColor(static_cast(r) * color.r/255, + static_cast(r) * color.r/255, + static_cast(r) * color.r/255, + static_cast(r) * color.r/255); +} + +inline NzColor NzColor::operator+=(const NzColor& color) +{ + return operator=(operator+(color)); +} + +inline NzColor NzColor::operator*=(const NzColor& color) +{ + return operator=(operator+(color)); +} + +inline bool NzColor::operator==(const NzColor& color) const +{ + return r == color.r && g == color.g && b == color.b && a == color.a; +} + +inline bool NzColor::operator!=(const NzColor& color) const +{ + return !operator==(color); +} + +// Algorithmes venant de http://www.easyrgb.com/index.php?X=MATH + +inline NzColor NzColor::FromCMY(float cyan, float magenta, float yellow) +{ + return NzColor((1.f-cyan)*255.f, (1.f-magenta)*255.f, (1.f-yellow)*255.f); +} + +inline NzColor NzColor::FromCMYK(float cyan, float magenta, float yellow, float black) +{ + return FromCMY(cyan * (1.f - black) + black, + magenta * (1.f - black) + black, + yellow * (1.f - black) + black); +} + +inline NzColor NzColor::FromHSL(nzUInt8 hue, nzUInt8 saturation, nzUInt8 lightness) +{ + // Norme Windows + float l = lightness/240.f; + + if (saturation == 0) + { + // RGB results from 0 to 255 + return NzColor(lightness * 255.f, + lightness * 255.f, + lightness * 255.f); + } + else + { + float h = hue/240.f; + float s = saturation/240.f; + + float v2; + if (l < 0.5f) + v2 = l * (1.f + s); + else + v2 = (l + s) - (s*l); + + float v1 = 2.f * l - v2; + + return NzColor(255.f * Hue2RGB(v1, v2, h + (1.f/3.f)), + 255.f * Hue2RGB(v1, v2, h), + 255.f * Hue2RGB(v1, v2, h - (1.f/3.f))); + } +} + +inline NzColor NzColor::FromHSV(nzUInt8 hue, nzUInt8 saturation, float value) +{ + if (saturation == 0) + return NzColor(static_cast(value * 255.f)); + else + { + float h = hue/240.f * 6.f; + float s = saturation/240.f; + + if (NzNumberEquals(h, 6.f)) + h = 0; // hue must be < 1 + + int i = h; + float v1 = value * (1.f - s); + float v2 = value * (1.f - s * (h - i)); + float v3 = value * (1.f - s * (1.f - (h - i))); + + float r, g, b; + switch (i) + { + case 0: + r = value; + g = v3; + b = v1; + + case 1: + r = v2; + g = value; + b = v1; + + case 2: + r = v1; + g = value; + b = v3; + + case 3: + r = v1; + g = v2; + b = value; + + case 4: + r = v3; + g = v1; + b = value; + + default: + r = value; + g = v1; + b = v2; + } + + // RGB results from 0 to 255 + return NzColor(r*255.f, g*255.f, b*255.f); + } +} +inline NzColor NzColor::FromXYZ(const NzVector3f& vec) +{ + return FromXYZ(vec.x, vec.y, vec.z); +} + +inline NzColor NzColor::FromXYZ(float x, float y, float z) +{ + x /= 100; // X from 0 to 95.047 + y /= 100; // Y from 0 to 100.000 + z /= 100; // Z from 0 to 108.883 + + double r = x * 3.2406 + y * -1.5372 + z * -0.4986; + double g = x * -0.9689 + y * 1.8758 + z * 0.0415; + double b = x * 0.0557 + y * -0.2040 + z * 1.0570; + + if (r > 0.0031308) + r = 1.055 * (std::pow(r, 1.0/2.4)) - 0.055; + else + r *= 12.92; + + if (g > 0.0031308) + g = 1.055 * (std::pow(g, 1.0/2.4)) - 0.055; + else + g *= 12.92; + + if (b > 0.0031308) + b = 1.055 * (std::pow(b, 1.0/2.4)) - 0.055; + else + b *= 12.92; + + return NzColor(r * 255.0, g * 255.0, b * 255.0); +} + +inline void NzColor::ToCMY(const NzColor& color, float* cyan, float* magenta, float* yellow) +{ + *cyan = 1.f - color.r/255.f; + *magenta = 1.f - color.g/255.f; + *yellow = 1.f - color.b/255.f; +} + +inline void NzColor::ToCMYK(const NzColor& color, float* cyan, float* magenta, float* yellow, float* black) +{ + float c, m, y; + ToCMY(color, &c, &m, &y); + + float k = std::min(std::min(std::min(1.f, c), m), y); + + if (NzNumberEquals(k, 1.f)) + { + //Black + *cyan = 0.f; + *magenta = 0.f; + *yellow = 0.f; + } + else + { + *cyan = (c-k)/(1.f-k); + *magenta = (m-k)/(1.f-k); + *yellow = (y-k)/(1.f-k); + } + + *black = k; +} + +inline void NzColor::ToHSL(const NzColor& color, nzUInt8* hue, nzUInt8* saturation, nzUInt8* lightness) +{ + float r = color.r / 255.f; + float g = color.g / 255.f; + float b = color.b / 255.f; + + float min = std::min(std::min(r, g), b); // Min. value of RGB + float max = std::max(std::max(r, g), b); // Max. value of RGB + + float deltaMax = max - min; //Delta RGB value + + float l = (max + min)/2.f; + + if (NzNumberEquals(deltaMax, 0.f)) + { + //This is a gray, no chroma... + *hue = 0; //HSL results from 0 to 1 + *saturation = 0; + } + else + { + //Chromatic data... + if (l < 0.5f) + *saturation = deltaMax/(max+min)*240.f; + else + *saturation = deltaMax/(2.f-max-min)*240.f; + + *lightness = l*240.f; + + float deltaR = ((max - r)/6.f + deltaMax/2.f)/deltaMax; + float deltaG = ((max - g)/6.f + deltaMax/2.f)/deltaMax; + float deltaB = ((max - b)/6.f + deltaMax/2.f)/deltaMax; + + float h; + + if (NzNumberEquals(r, max)) + h = deltaB - deltaG; + else if (NzNumberEquals(g, max)) + h = (1.f/3.f) + deltaR - deltaB; + else if (NzNumberEquals(b, max)) + h = (2.f/3.f) + deltaG - deltaR; + + if (h < 0.f) + h += 1.f; + else if (h > 1.f) + h -= 1.f; + + *hue = h*240.f; + } +} + +inline void NzColor::ToHSV(const NzColor& color, nzUInt8* hue, nzUInt8* saturation, float* value) +{ + float r = color.r / 255.f; + float g = color.g / 255.f; + float b = color.b / 255.f; + + float min = std::min(std::min(r, g), b); //Min. value of RGB + float max = std::max(std::max(r, g), b); //Max. value of RGB + + float deltaMax = max - min; //Delta RGB value + + *value = max; + + if (NzNumberEquals(deltaMax, 0.f)) + { + //This is a gray, no chroma... + *hue = 0; //HSV results from 0 to 1 + *saturation = 0; + } + else + { + //Chromatic data... + *saturation = deltaMax/max*240.f; + + float deltaR = ((max - r)/6.f + deltaMax/2.f)/deltaMax; + float deltaG = ((max - g)/6.f + deltaMax/2.f)/deltaMax; + float deltaB = ((max - b)/6.f + deltaMax/2.f)/deltaMax; + + float h; + + if (NzNumberEquals(r, max)) + h = deltaB - deltaG; + else if (NzNumberEquals(g, max)) + h = (1.f/3.f) + deltaR - deltaB; + else if (NzNumberEquals(b, max)) + h = (2.f/3.f) + deltaG - deltaR; + + if (h < 0.f) + h += 1.f; + else if (h > 1.f) + h -= 1.f; + + *hue = h*240.f; + } +} + +inline void NzColor::ToXYZ(const NzColor& color, NzVector3f* vec) +{ + return ToXYZ(color, &vec->x, &vec->y, &vec->z); +} + +inline void NzColor::ToXYZ(const NzColor& color, float* x, float* y, float* z) +{ + double r = color.r/255.0; //R from 0 to 255 + double g = color.g/255.0; //G from 0 to 255 + double b = color.b/255.0; //B from 0 to 255 + + if (r > 0.04045) + r = std::pow((r + 0.055)/1.055, 2.4); + else + r /= 12.92; + + if (g > 0.04045) + g = std::pow((g + 0.055)/1.055, 2.4); + else + g /= 12.92; + + if (b > 0.04045) + b = std::pow((b + 0.055)/1.055, 2.4); + else + b /= 12.92; + + r *= 100.0; + g *= 100.0; + b *= 100.0; + + //Observer. = 2°, Illuminant = D65 + *x = r*0.4124 + g*0.3576 + b*0.1805; + *y = r*0.2126 + g*0.7152 + b*0.0722; + *z = r*0.0193 + g*0.1192 + b*0.9505; +} + +inline float NzColor::Hue2RGB(float v1, float v2, float vH) +{ + if (vH < 0.f) + vH += 1; + + if (vH > 1.f) + vH -= 1; + + if ((6.f * vH) < 1.f) + return v1 + (v2-v1)*6*vH; + + if ((2.f * vH) < 1.f) + return v2; + + if ((3.f * vH) < 2.f) + return v1 + (v2 - v1)*(2.f/3.f - vH)*6; + + return v1; +} + +inline std::ostream& operator<<(std::ostream& out, const NzColor& color) +{ + return out << color.ToString(); +} + +#include diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index 515a3607c..c77ad76d3 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -8,6 +8,7 @@ #define NAZARA_IMAGE_HPP #include +#include #include #include #include @@ -77,6 +78,8 @@ class NAZARA_API NzImage : public NzResource, public NzResourceLoader +#include + +const NzColor NzColor::Black(0, 0, 0); +const NzColor NzColor::Blue(0, 0, 255); +const NzColor NzColor::Cyan(0, 255, 255); +const NzColor NzColor::Green(0, 255, 0); +const NzColor NzColor::Magenta(255, 0, 255); +const NzColor NzColor::Orange(255, 165, 0); +const NzColor NzColor::Red(255, 0, 0); +const NzColor NzColor::Yellow(255, 255, 0); +const NzColor NzColor::White(255, 255, 255); diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 96d037cce..2ede746b5 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -237,6 +237,100 @@ unsigned int NzImage::GetHeight() const return m_sharedImage->height; } +NzColor NzImage::GetPixel(unsigned int x, unsigned int y, unsigned int z) const +{ + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Image must be valid"); + 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"); + return NzColor(); + } + + if (x >= m_sharedImage->width) + { + NazaraError("X value exceeds width (" + NzString::Number(x) + " >= (" + NzString::Number(m_sharedImage->width) + ')'); + return NzColor(); + } + + if (y >= m_sharedImage->height) + { + NazaraError("Y value exceeds width (" + NzString::Number(y) + " >= (" + NzString::Number(m_sharedImage->height) + ')'); + return NzColor(); + } + + if (z >= m_sharedImage->depth) + { + NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(m_sharedImage->depth) + ')'); + return NzColor(); + } + #endif + + NzColor color; + + const nzUInt8* pixel = &m_sharedImage->pixels[(m_sharedImage->height*(m_sharedImage->width*z+y) + x) * NzPixelFormat::GetBPP(m_sharedImage->format)]; + + if (!NzPixelFormat::Convert(m_sharedImage->format, nzPixelFormat_RGBA8, pixel, &color.r)) + NazaraError("Failed to convert image's format to RGBA8"); + + return color; +} + +NzColor NzImage::GetPixelFace(nzCubemapFace face, unsigned int x, unsigned int y) const +{ + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Image must be valid"); + return NzColor(); + } + + if (m_sharedImage->type != nzImageType_Cubemap) + { + 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(); + } + + if (x >= m_sharedImage->width) + { + NazaraError("X value exceeds width (" + NzString::Number(x) + " >= (" + NzString::Number(m_sharedImage->width) + ')'); + return NzColor(); + } + + if (y >= m_sharedImage->height) + { + NazaraError("Y value exceeds width (" + NzString::Number(y) + " >= (" + NzString::Number(m_sharedImage->height) + ')'); + return NzColor(); + } + #endif + + NzColor color; + + const nzUInt8* pixel = &m_sharedImage->pixels[(m_sharedImage->height*(m_sharedImage->width*(face-nzCubemapFace_PositiveX)+y) + x) * NzPixelFormat::GetBPP(m_sharedImage->format)]; + + 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() { EnsureOwnership(); @@ -246,7 +340,7 @@ nzUInt8* NzImage::GetPixels() unsigned int NzImage::GetSize() const { - return m_sharedImage->width * m_sharedImage->height * m_sharedImage->depth * NzPixelFormat::GetBPP(m_sharedImage->format); + return m_sharedImage->width * m_sharedImage->height * ((m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth) * NzPixelFormat::GetBPP(m_sharedImage->format); } nzImageType NzImage::GetType() const @@ -289,6 +383,102 @@ bool NzImage::LoadFromStream(NzInputStream& stream, const NzImageParams& params) return NzResourceLoader::LoadResourceFromStream(this, stream, params); } +bool NzImage::SetPixel(const NzColor& color, unsigned int x, unsigned int y, unsigned int z) +{ + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Image must be valid"); + 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"); + 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; + } + + if (z >= m_sharedImage->depth) + { + NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(m_sharedImage->depth) + ')'); + return false; + } + #endif + + nzUInt8* pixel = &m_sharedImage->pixels[(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(const NzColor& color, nzCubemapFace face, 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[(m_sharedImage->height*(m_sharedImage->width*(face-nzCubemapFace_PositiveX)+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::Update(const nzUInt8* pixels) { #if NAZARA_UTILITY_SAFE @@ -318,7 +508,7 @@ bool NzImage::Update(const nzUInt8* pixels) return true; } -bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect) +bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z) { #if NAZARA_UTILITY_SAFE if (!IsValid()) @@ -345,18 +535,24 @@ bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect) return false; } - if (rect.width > m_sharedImage->width || rect.height > m_sharedImage->height) + if (rect.x+rect.width > m_sharedImage->width || rect.y+rect.height > m_sharedImage->height) { NazaraError("Rectangle dimensions are out of bounds"); return false; } + + if (z >= m_sharedImage->depth) + { + NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(m_sharedImage->depth) + ')'); + return false; + } #endif EnsureOwnership(); nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format); - nzUInt8* dstPixels = m_sharedImage->pixels + (rect.x + rect.y * m_sharedImage->width) * bpp; + nzUInt8* dstPixels = &m_sharedImage->pixels[(m_sharedImage->height*(m_sharedImage->width*z + rect.y) + rect.x) * NzPixelFormat::GetBPP(m_sharedImage->format)]; unsigned int srcStride = rect.width * bpp; unsigned int dstStride = m_sharedImage->width * bpp; @@ -382,7 +578,7 @@ bool NzImage::UpdateFace(nzCubemapFace face, const nzUInt8* pixels) if (m_sharedImage->type != nzImageType_Cubemap) { - NazaraError("Update is only designed for cubemaps, use Update instead"); + NazaraError("Update is designed for cubemaps, use Update instead"); return false; } @@ -412,7 +608,7 @@ bool NzImage::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRect if (m_sharedImage->type != nzImageType_Cubemap) { - NazaraError("Update is only designed for cubemaps, use Update instead"); + NazaraError("Update is designed for cubemaps, use Update instead"); return false; } @@ -428,7 +624,7 @@ bool NzImage::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRect return false; } - if (rect.width > m_sharedImage->width || rect.height > m_sharedImage->height) + if (rect.x+rect.width > m_sharedImage->width || rect.y+rect.height > m_sharedImage->height) { NazaraError("Rectangle dimensions are out of bounds"); return false; @@ -439,7 +635,7 @@ bool NzImage::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRect nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format); - nzUInt8* dstPixels = m_sharedImage->pixels + (rect.x + rect.y * m_sharedImage->width + (face-nzCubemapFace_PositiveX)*m_sharedImage->width*m_sharedImage->height) * bpp; + nzUInt8* dstPixels = &m_sharedImage->pixels[(m_sharedImage->height*(m_sharedImage->width*(face-nzCubemapFace_PositiveX) + rect.y) + rect.x) * NzPixelFormat::GetBPP(m_sharedImage->format)]; unsigned int srcStride = rect.width * bpp; unsigned int dstStride = m_sharedImage->width * bpp; diff --git a/src/Nazara/Utility/PixelFormat.cpp b/src/Nazara/Utility/PixelFormat.cpp index 8dff3adcb..9723b970d 100644 --- a/src/Nazara/Utility/PixelFormat.cpp +++ b/src/Nazara/Utility/PixelFormat.cpp @@ -14,7 +14,7 @@ namespace { inline nzUInt8 c4to8(nzUInt8 c) { - return c * (255.f/15.f); + return c * (255/15); } inline nzUInt8 c5to8(nzUInt8 c) @@ -327,7 +327,7 @@ namespace *ptr++ = (l << 11) | (l << 6) | (l << 1) | - 1; + 1; start += 1; } @@ -480,9 +480,9 @@ namespace { while (start < end) { - *dst++ = (c4to8((start[1] & 0xF0) >> 4)); - *dst++ = (c4to8((start[0] & 0x0F) >> 0)); - *dst++ = (c4to8((start[0] & 0xF0) >> 4)); + *dst++ = c4to8((start[1] & 0xF0) >> 4); + *dst++ = c4to8((start[0] & 0x0F) >> 0); + *dst++ = c4to8((start[0] & 0xF0) >> 4); start += 2; }