Graphics/Image: dont store PixelFormat, instead define a new enum for number of channels.
The image class has a strict internal representation so we dont need "format". PixelFormat enum can be passed to functions that modify the pixel data (like setPixels()) so that a proper convertion can be done.
This commit is contained in:
parent
6f9b33be8f
commit
f7fcc2633c
4 changed files with 53 additions and 86 deletions
|
|
@ -99,10 +99,7 @@ Glyph FreeTypeEngine::loadGlyph(unsigned int codepoint, Image& img, unsigned int
|
|||
FT_Glyph_To_Bitmap(&glyph_info, FT_RENDER_MODE_NORMAL, 0, true);
|
||||
FT_Bitmap& bmp = reinterpret_cast<FT_BitmapGlyph>(glyph_info)->bitmap;
|
||||
|
||||
img.create(PixelFormat::PF_Alpha,
|
||||
bmp.width,
|
||||
bmp.rows,
|
||||
bmp.buffer);
|
||||
img.create(bmp.width, bmp.rows, bmp.buffer, PixelFormat::PF_Alpha);
|
||||
|
||||
glyph.offset.x = static_cast<unsigned char>(metrics.horiBearingX / (1 << 6));
|
||||
glyph.offset.y = static_cast<unsigned char>(metrics.horiBearingY / (1 << 6));
|
||||
|
|
|
|||
|
|
@ -10,17 +10,17 @@ static ImageLoader _loader;
|
|||
|
||||
Image::Image() :
|
||||
m_size (0, 0),
|
||||
m_format (PF_Unknown)
|
||||
m_channels (RGBA)
|
||||
{
|
||||
}
|
||||
|
||||
void Image::create(unsigned width, unsigned height, const Color& color)
|
||||
void Image::create(unsigned width, unsigned height, const Color& color, enum Channels comp)
|
||||
{
|
||||
m_size.x = width;
|
||||
m_size.y = height;
|
||||
m_format = PixelFormat::PF_RGBA;
|
||||
m_channels = comp;
|
||||
|
||||
m_pixels.resize(m_size.x * m_size.y * (getBpp() / 8));
|
||||
m_pixels.resize(m_size.x * m_size.y * getNumChannels());
|
||||
|
||||
for(size_t i = 0; i < m_pixels.size(); i += 4) {
|
||||
|
||||
|
|
@ -31,48 +31,12 @@ void Image::create(unsigned width, unsigned height, const Color& color)
|
|||
}
|
||||
}
|
||||
|
||||
void Image::create(unsigned width, unsigned height, const void* pixels)
|
||||
{
|
||||
create(PixelFormat::PF_RGBA, width, height, pixels);
|
||||
}
|
||||
|
||||
void Image::create(PixelFormat format, unsigned width, unsigned height, const Color& color)
|
||||
void Image::create(unsigned width, unsigned height, const void* pixels, PixelFormat format)
|
||||
{
|
||||
m_size.x = width;
|
||||
m_size.y = height;
|
||||
m_format = format;
|
||||
|
||||
m_pixels.resize(m_size.x * m_size.y * (getBpp() / 8));
|
||||
|
||||
if (getBpp() == 32) {
|
||||
for(size_t i = 0; i < m_pixels.size(); i += 4) {
|
||||
|
||||
m_pixels[i+0] = color.r;
|
||||
m_pixels[i+1] = color.g;
|
||||
m_pixels[i+2] = color.b;
|
||||
m_pixels[i+3] = color.a;
|
||||
}
|
||||
} else if (getBpp() == 24) {
|
||||
for(size_t i = 0; i < m_pixels.size(); i += 3) {
|
||||
|
||||
m_pixels[i+0] = color.r;
|
||||
m_pixels[i+1] = color.g;
|
||||
m_pixels[i+2] = color.b;
|
||||
}
|
||||
} else {
|
||||
for(size_t i = 0; i < m_pixels.size(); i += 1) {
|
||||
m_pixels[i] = color.a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Image::create(PixelFormat format, unsigned width, unsigned height, const void* pixels)
|
||||
{
|
||||
m_size.x = width;
|
||||
m_size.y = height;
|
||||
m_format = format;
|
||||
|
||||
setPixels(pixels);
|
||||
setPixels(pixels, format);
|
||||
}
|
||||
|
||||
const Vector2u& Image::getSize() const
|
||||
|
|
@ -90,31 +54,36 @@ unsigned int Image::getHeight() const
|
|||
return m_size.y;
|
||||
}
|
||||
|
||||
unsigned int Image::getBpp() const
|
||||
unsigned int Image::getNumChannels() const
|
||||
{
|
||||
switch(m_format) {
|
||||
case PixelFormat::PF_RGBA : return 32;
|
||||
case PixelFormat::PF_RGB : return 24;
|
||||
case PixelFormat::PF_Alpha : return 8;
|
||||
case PixelFormat::PF_Unknown :
|
||||
switch(m_channels) {
|
||||
case Channels::RGBA : return 4;
|
||||
case Channels::RGB : return 3;
|
||||
case Channels::Alpha :
|
||||
default : break;
|
||||
}
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int Image::getStride() const
|
||||
{
|
||||
return m_size.x * (getBpp() / 8);
|
||||
return m_size.x * getNumChannels();
|
||||
}
|
||||
|
||||
PixelFormat Image::getFormat() const
|
||||
{
|
||||
return m_format;
|
||||
switch(m_channels) {
|
||||
case Channels::RGBA : return PixelFormat::PF_RGBA;
|
||||
case Channels::RGB : return PixelFormat::PF_RGB;
|
||||
case Channels::Alpha :
|
||||
default : break;
|
||||
}
|
||||
return PixelFormat::PF_Alpha;
|
||||
}
|
||||
|
||||
bool Image::hasAlpha() const
|
||||
{
|
||||
return m_format == PixelFormat::PF_RGBA || m_format == PixelFormat::PF_Alpha;
|
||||
return m_channels != Channels::RGB;
|
||||
}
|
||||
|
||||
bool Image::loadFromFile(const std::string& filename)
|
||||
|
|
@ -138,17 +107,17 @@ void Image::saveToFile(const std::string& filename) const
|
|||
|
||||
void Image::setPixel(unsigned x, unsigned y, const Color& c)
|
||||
{
|
||||
unsigned char *base = m_pixels.data() + ((getBpp() / 8) * ((y * m_size.x) + x));
|
||||
unsigned char *base = m_pixels.data() + (getNumChannels() * ((y * m_size.x) + x));
|
||||
|
||||
if (m_format == PixelFormat::PF_RGB || m_format == PixelFormat::PF_RGBA) {
|
||||
if (m_channels == RGB || m_channels == RGBA) {
|
||||
base[0] = c.r;
|
||||
base[1] = c.g;
|
||||
base[2] = c.b;
|
||||
if (m_format == PixelFormat::PF_RGBA) {
|
||||
if (m_channels == RGBA) {
|
||||
base[3] = c.a;
|
||||
}
|
||||
}
|
||||
else if (m_format == PixelFormat::PF_Alpha) {
|
||||
else if (m_channels == Alpha) {
|
||||
base[0] = c.a;
|
||||
}
|
||||
}
|
||||
|
|
@ -156,21 +125,21 @@ void Image::setPixel(unsigned x, unsigned y, const Color& c)
|
|||
Color Image::getPixel(unsigned x, unsigned y) const
|
||||
{
|
||||
Color c;
|
||||
const unsigned char *base = m_pixels.data() + ((getBpp() / 8) * ((y * m_size.x) + x));
|
||||
const unsigned char *base = m_pixels.data() + (getNumChannels() * ((y * m_size.x) + x));
|
||||
|
||||
// RGB / RGBA formats.
|
||||
if (m_format == PixelFormat::PF_RGB || m_format == PixelFormat::PF_RGBA) {
|
||||
if (m_channels == RGB || m_channels == RGBA) {
|
||||
c.r = base[0];
|
||||
c.g = base[1];
|
||||
c.b = base[2];
|
||||
if (m_format == PixelFormat::PF_RGBA) {
|
||||
if (m_channels == RGBA) {
|
||||
c.a = base[3];
|
||||
} else {
|
||||
c.a = 255;
|
||||
}
|
||||
}
|
||||
// Alpha, single channel format.
|
||||
else if (m_format == PixelFormat::PF_Alpha) {
|
||||
else if (m_channels == Alpha) {
|
||||
c = Color(0, 0, 0, base[0]);
|
||||
}
|
||||
return c;
|
||||
|
|
@ -194,11 +163,17 @@ void Image::flipY()
|
|||
}
|
||||
}
|
||||
|
||||
void Image::setPixels(const void *pixels)
|
||||
void Image::setPixels(const void *pixels, PixelFormat format)
|
||||
{
|
||||
unsigned int size = m_size.y * getStride();
|
||||
if (format == PixelFormat::PF_RGB) {
|
||||
m_channels = RGB;
|
||||
} else if (format == PixelFormat::PF_RGBA) {
|
||||
m_channels = RGBA;
|
||||
} else if (format == PixelFormat::PF_Alpha) {
|
||||
m_channels = Alpha;
|
||||
}
|
||||
|
||||
m_pixels.resize(size);
|
||||
m_pixels.resize(m_size.y * getStride());
|
||||
memcpy(&m_pixels[0], pixels, m_pixels.size());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,11 +89,7 @@ void Texture::create(const Image& image)
|
|||
|
||||
enable();
|
||||
|
||||
if (image.getBpp() == 32) {
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
} else {
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
}
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, image.getNumChannels());
|
||||
|
||||
srcFormat = pixelFormatToGL(image.getFormat());
|
||||
glFormat = pixelFormatToInternal(image.getFormat());
|
||||
|
|
@ -149,11 +145,7 @@ void Texture::update(vec2u pos, const Image& image)
|
|||
|
||||
enable();
|
||||
|
||||
if (image.getFormat() == PixelFormat::PF_RGBA) {
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
} else {
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
}
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, image.getNumChannels());
|
||||
|
||||
format = pixelFormatToGL(image.getFormat());
|
||||
|
||||
|
|
@ -185,7 +177,7 @@ Image Texture::copyToImage() const
|
|||
GL_UNSIGNED_BYTE,
|
||||
&pixels[0]);
|
||||
|
||||
img.create(m_format, m_size.x, m_size.y, &pixels[0]);
|
||||
img.create(m_size.x, m_size.y, &pixels[0], m_format);
|
||||
|
||||
disable();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue