// vi:ft=cpp /* * (c) 2010 Alexander Warg * 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 #include 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(pixels() + size().pixels()) : 0; } unsigned char *alpha_buffer() { return extra_alpha() ? reinterpret_cast(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(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(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; } } } }; }}