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
This commit is contained in:
parent
7659fdf460
commit
96ea5fdaa7
|
|
@ -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 <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
|
||||
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 <Nazara/Core/Color.inl>
|
||||
|
||||
#endif // NAZARA_COLOR_HPP
|
||||
|
|
@ -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 <Nazara/Core/StringStream.hpp>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Utility/Debug.hpp>
|
||||
|
||||
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<int>(r) << ", " << static_cast<int>(g) << ", " << static_cast<int>(b);
|
||||
|
||||
if (a != 255)
|
||||
ss << ", " << static_cast<int>(a);
|
||||
|
||||
ss << ')';
|
||||
|
||||
return ss;
|
||||
}
|
||||
|
||||
inline NzColor NzColor::operator+(const NzColor& color) const
|
||||
{
|
||||
return NzColor(std::min(static_cast<nzUInt16>(r) + color.r, 255),
|
||||
std::min(static_cast<nzUInt16>(r) + color.r, 255),
|
||||
std::min(static_cast<nzUInt16>(r) + color.r, 255),
|
||||
std::min(static_cast<nzUInt16>(r) + color.r, 255));
|
||||
}
|
||||
|
||||
inline NzColor NzColor::operator*(const NzColor& color) const
|
||||
{
|
||||
return NzColor(static_cast<nzUInt16>(r) * color.r/255,
|
||||
static_cast<nzUInt16>(r) * color.r/255,
|
||||
static_cast<nzUInt16>(r) * color.r/255,
|
||||
static_cast<nzUInt16>(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<nzUInt8>(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 <Nazara/Utility/DebugOff.hpp>
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#define NAZARA_IMAGE_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Core/InputStream.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Utility/ResourceLoader.hpp>
|
||||
|
|
@ -77,6 +78,8 @@ class NAZARA_API NzImage : public NzResource, public NzResourceLoader<NzImage, N
|
|||
unsigned int GetDepth() const;
|
||||
nzPixelFormat GetFormat() const;
|
||||
unsigned int GetHeight() const;
|
||||
NzColor GetPixel(unsigned int x, unsigned int y = 0, unsigned int z = 0) const;
|
||||
NzColor GetPixelFace(nzCubemapFace face, unsigned int x, unsigned int y) const;
|
||||
nzUInt8* GetPixels();
|
||||
unsigned int GetSize() const;
|
||||
nzImageType GetType() const;
|
||||
|
|
@ -90,8 +93,12 @@ class NAZARA_API NzImage : public NzResource, public NzResourceLoader<NzImage, N
|
|||
bool LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params = NzImageParams());
|
||||
bool LoadFromStream(NzInputStream& stream, const NzImageParams& params = NzImageParams());
|
||||
|
||||
bool SetPixel(const NzColor& color, unsigned int x, unsigned int y = 0, unsigned int z = 0);
|
||||
bool SetPixelFace(const NzColor& color, nzCubemapFace face, unsigned int x, unsigned int y);
|
||||
|
||||
bool Update(const nzUInt8* pixels);
|
||||
bool Update(const nzUInt8* pixels, const NzRectui& rect);
|
||||
bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0);
|
||||
//bool Update(const nzUInt8* pixels, const NzCubeui& cube);
|
||||
bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels);
|
||||
bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRectui& rect);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
// 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 <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
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);
|
||||
|
|
@ -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<NzImage, NzImageParams>::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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue