172 lines
4.4 KiB
C++
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;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
}}
|