Files
moslab-code/src/l4/pkg/mag-gfx/include/mem_texture
2025-09-12 15:55:45 +02:00

172 lines
4.4 KiB
C++

// vi:ft=cpp
/*
* (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
*
* This file is part of TUD:OS and distributed under the terms of the
* GNU General Public License 2.
* Please see the COPYING-GPL-2 file for details.
*/
#pragma once
#include <l4/mag-gfx/texture>
#include <cstring>
namespace Mag_gfx {
namespace Mem {
template< typename PT >
class Texture : public Mag_gfx::Texture
{
public:
typedef PT Pixel_traits;
typedef typename PT::Pixel Pixel;
typedef typename PT::Color Color;
public:
Texture(Pixel *pixels, Area const &size, bool xalpha = false)
: Mag_gfx::Texture(PT::type(), pixels, size, xalpha)
{}
bool alloc_buffer(Area const &size)
{
if (_pixels)
return false;
_size = size;
_pixels = malloc(_size.pixels() * (sizeof(Pixel) + (extra_alpha() ? 1 :0)));
return _pixels;
}
Pixel const *pixels() const
{ return (Pixel const *)Mag_gfx::Texture::pixels(); }
Pixel *pixels()
{ return (Pixel *)Mag_gfx::Texture::pixels(); }
unsigned char const *alpha_buffer() const
{
return extra_alpha()
? reinterpret_cast<unsigned char const *>(pixels() + size().pixels())
: 0;
}
unsigned char *alpha_buffer()
{
return extra_alpha()
? reinterpret_cast<unsigned char *>(pixels() + size().pixels())
: 0;
}
void blit(Mag_gfx::Texture const *o, int start_line = 0)
{
Pixel *dst = pixels();
if (start_line >= size().h())
return;
dst += size().w() * start_line;
int const w = std::min(size().w(), o->size().w());
int const h = std::min(size().h() - start_line, o->size().h());
if (o->type() == type())
{
int const ow = o->size().w();
Pixel const *src = reinterpret_cast<Pixel const *>(o->pixels());
for (int i = 0; i < h; ++i, dst += size().w(), src += ow)
memcpy(dst, src, size().w() * sizeof(Pixel));
if (extra_alpha())
memset(alpha_buffer() + size().w() * start_line, ~0, size().w() * h);
}
else
{
#if 0
printf("texture convert: %dx%d %d(%d):%d(%d):%d(%d):%d(%d) -> %dx%d %d(%d):%d(%d):%d(%d):%d(%d)\n",
(int)o->size().w(), (int)o->size().h(),
(int)o->type()->r.si, (int)o->type()->r.sh,
(int)o->type()->g.si, (int)o->type()->g.sh,
(int)o->type()->b.si, (int)o->type()->b.sh,
(int)o->type()->a.si, (int)o->type()->a.sh,
(int)size().w(), (int)size().h(),
(int)type()->r.si, (int)type()->r.sh,
(int)type()->g.si, (int)type()->g.sh,
(int)type()->b.si, (int)type()->b.sh,
(int)type()->a.si, (int)type()->a.sh);
#endif
int const ow = o->size().w() * o->type()->bytes_per_pixel();
int const op = o->type()->bytes_per_pixel();
char const *src = reinterpret_cast<char const *>(o->pixels());
unsigned char *ab = alpha_buffer();
bool const xa = ab;
ab += size().w() * start_line;
for (int i = 0; i < h; i++, dst += size().w(), src += ow)
{
for (int y = 0; y < w; y++)
{
Mag_gfx::Pixel_info::Color c = o->type()->get(src + y*op);
dst[y] = Color(c);
if (xa)
ab[y] = c.a >> 8;
}
if (xa)
ab += size().w();
}
}
}
void blit_line(void const *_src, Pixel_info const *st, int line, unsigned *offset_buffer)
{
Pixel *dst = pixels();
if (line >= size().h())
return;
dst += size().w() * line;
char const *src = (char const *)_src;
if (st == type())
{
for (int i = 0; i < size().w(); ++i, ++dst)
*dst = *(Pixel const *)(src + offset_buffer[i]);
if (extra_alpha())
memset(alpha_buffer() + size().w() * line, ~0, size().w());
}
else
{
#if 0
printf("texture convert: %dx%d %d(%d):%d(%d):%d(%d):%d(%d) -> %dx%d %d(%d):%d(%d):%d(%d):%d(%d)\n",
(int)o->size().w(), (int)o->size().h(),
(int)o->type()->r.si, (int)o->type()->r.sh,
(int)o->type()->g.si, (int)o->type()->g.sh,
(int)o->type()->b.si, (int)o->type()->b.sh,
(int)o->type()->a.si, (int)o->type()->a.sh,
(int)size().w(), (int)size().h(),
(int)type()->r.si, (int)type()->r.sh,
(int)type()->g.si, (int)type()->g.sh,
(int)type()->b.si, (int)type()->b.sh,
(int)type()->a.si, (int)type()->a.sh);
#endif
unsigned char *ab = alpha_buffer();
bool const xa = ab;
ab += size().w() * line;
for (int y = 0; y < size().w(); y++)
{
Mag_gfx::Pixel_info::Color c = st->get(src + offset_buffer[y]);
dst[y] = Color(c);
if (xa)
ab[y] = c.a >> 8;
}
}
}
};
}}