예제 #1
0
파일: rendutil.cs 프로젝트: kwanboy/mcs
 /*-------------------------------------------------
 *   set_render_color - cleaner way to set a color
 *  -------------------------------------------------*/
 public static void set_render_color(render_color color, float a, float r, float g, float b)
 {
     color.a = a;
     color.r = r;
     color.g = g;
     color.b = b;
 }
예제 #2
0
        /*-------------------------------------------------
        *   resample_argb_bitmap_bilinear - perform texture
        *   sampling via a bilinear filter
        *  -------------------------------------------------*/
        static void resample_argb_bitmap_bilinear(PointerU32 dest, u32 drowpixels, u32 dwidth, u32 dheight, PointerU32 source, u32 srowpixels, u32 swidth, u32 sheight, render_color color, u32 dx, u32 dy)  //static void resample_argb_bitmap_bilinear(u32 *dest, u32 drowpixels, u32 dwidth, u32 dheight, const u32 *source, u32 srowpixels, u32 swidth, u32 sheight, const render_color &color, u32 dx, u32 dy)
        {
            u32 maxx = swidth << 12;
            u32 maxy = sheight << 12;
            u32 r;
            u32 g;
            u32 b;
            u32 a;
            u32 x;
            u32 y;

            /* precompute premultiplied R/G/B/A factors */
            r = (u32)(color.r * color.a * 256.0f);
            g = (u32)(color.g * color.a * 256.0f);
            b = (u32)(color.b * color.a * 256.0f);
            a = (u32)(color.a * 256.0f);

            /* loop over the target vertically */
            for (y = 0; y < dheight; y++)
            {
                u32 starty = y * dy;

                /* loop over the target horizontally */
                for (x = 0; x < dwidth; x++)
                {
                    u32   startx = x * dx;
                    rgb_t pix0;
                    rgb_t pix1;
                    rgb_t pix2;
                    rgb_t pix3;
                    u32   sumr;
                    u32   sumg;
                    u32   sumb;
                    u32   suma;
                    u32   nextx;
                    u32   nexty;
                    u32   curx;
                    u32   cury;
                    u32   factor;

                    /* adjust start to the center; note that this math will tend to produce */
                    /* negative results on the first pixel, which is why we clamp below */
                    curx = startx + dx / 2 - 0x800;
                    cury = starty + dy / 2 - 0x800;

                    /* compute the neighboring pixel */
                    nextx = curx + 0x1000;
                    nexty = cury + 0x1000;

                    /* fetch the four relevant pixels */
                    pix0 = pix1 = pix2 = pix3 = new rgb_t(0);
                    if ((int)cury >= 0 && cury < maxy && (int)curx >= 0 && curx < maxx)
                    {
                        pix0 = new rgb_t(source[(cury >> 12) * srowpixels + (curx >> 12)]);  //pix0 = source[(cury >> 12) * srowpixels + (curx >> 12)];
                    }
                    if ((int)cury >= 0 && cury < maxy && (int)nextx >= 0 && nextx < maxx)
                    {
                        pix1 = new rgb_t(source[(cury >> 12) * srowpixels + (nextx >> 12)]);  //pix1 = source[(cury >> 12) * srowpixels + (nextx >> 12)];
                    }
                    if ((int)nexty >= 0 && nexty < maxy && (int)curx >= 0 && curx < maxx)
                    {
                        pix2 = new rgb_t(source[(nexty >> 12) * srowpixels + (curx >> 12)]);  //pix2 = source[(nexty >> 12) * srowpixels + (curx >> 12)];
                    }
                    if ((int)nexty >= 0 && nexty < maxy && (int)nextx >= 0 && nextx < maxx)
                    {
                        pix3 = new rgb_t(source[(nexty >> 12) * srowpixels + (nextx >> 12)]);  //pix3 = source[(nexty >> 12) * srowpixels + (nextx >> 12)];
                    }
                    /* compute the x/y scaling factors */
                    curx &= 0xfff;
                    cury &= 0xfff;

                    /* contributions from pixel 0 (top,left) */
                    factor = (0x1000 - curx) * (0x1000 - cury);
                    sumr   = factor * pix0.r();
                    sumg   = factor * pix0.g();
                    sumb   = factor * pix0.b();
                    suma   = factor * pix0.a();

                    /* contributions from pixel 1 (top,right) */
                    factor = curx * (0x1000 - cury);
                    sumr  += factor * pix1.r();
                    sumg  += factor * pix1.g();
                    sumb  += factor * pix1.b();
                    suma  += factor * pix1.a();

                    /* contributions from pixel 2 (bottom,left) */
                    factor = (0x1000 - curx) * cury;
                    sumr  += factor * pix2.r();
                    sumg  += factor * pix2.g();
                    sumb  += factor * pix2.b();
                    suma  += factor * pix2.a();

                    /* contributions from pixel 3 (bottom,right) */
                    factor = curx * cury;
                    sumr  += factor * pix3.r();
                    sumg  += factor * pix3.g();
                    sumb  += factor * pix3.b();
                    suma  += factor * pix3.a();

                    /* apply scaling */
                    suma = (suma >> 24) * a / 256;
                    sumr = (sumr >> 24) * r / 256;
                    sumg = (sumg >> 24) * g / 256;
                    sumb = (sumb >> 24) * b / 256;

                    /* if we're translucent, add in the destination pixel contribution */
                    if (a < 256)
                    {
                        rgb_t dpix = new rgb_t(dest[y * drowpixels + x]);  //rgb_t dpix = dest[y * drowpixels + x];
                        suma += dpix.a() * (256 - a);
                        sumr += dpix.r() * (256 - a);
                        sumg += dpix.g() * (256 - a);
                        sumb += dpix.b() * (256 - a);
                    }

                    /* store the target pixel, dividing the RGBA values by the overall scale factor */
                    dest[y * drowpixels + x] = new rgb_t((u8)suma, (u8)sumr, (u8)sumg, (u8)sumb);  //dest[y * drowpixels + x] = rgb_t(suma, sumr, sumg, sumb);
                }
            }
        }
예제 #3
0
        /*-------------------------------------------------
        *   resample_argb_bitmap_average - resample a texture
        *   by performing a true weighted average over
        *   all contributing pixels
        *  -------------------------------------------------*/
        static void resample_argb_bitmap_average(PointerU32 dest, u32 drowpixels, u32 dwidth, u32 dheight, PointerU32 source, u32 srowpixels, u32 swidth, u32 sheight, render_color color, u32 dx, u32 dy)  //static void resample_argb_bitmap_average(u32 *dest, u32 drowpixels, u32 dwidth, u32 dheight, const u32 *source, u32 srowpixels, u32 swidth, u32 sheight, const render_color &color, u32 dx, u32 dy)
        {
            u64 sumscale = (u64)dx * (u64)dy;
            u32 r;
            u32 g;
            u32 b;
            u32 a;
            u32 x;
            u32 y;

            /* precompute premultiplied R/G/B/A factors */
            r = (u32)(color.r * color.a * 256.0f);
            g = (u32)(color.g * color.a * 256.0f);
            b = (u32)(color.b * color.a * 256.0f);
            a = (u32)(color.a * 256.0f);

            /* loop over the target vertically */
            for (y = 0; y < dheight; y++)
            {
                u32 starty = y * dy;

                /* loop over the target horizontally */
                for (x = 0; x < dwidth; x++)
                {
                    u64 sumr   = 0;
                    u64 sumg   = 0;
                    u64 sumb   = 0;
                    u64 suma   = 0;
                    u32 startx = x * dx;
                    u32 xchunk;
                    u32 ychunk;
                    u32 curx;
                    u32 cury;

                    u32 yremaining = dy;

                    /* accumulate all source pixels that contribute to this pixel */
                    for (cury = starty; yremaining != 0; cury += ychunk)
                    {
                        u32 xremaining = dx;

                        /* determine the Y contribution, clamping to the amount remaining */
                        ychunk = 0x1000 - (cury & 0xfff);
                        if (ychunk > yremaining)
                        {
                            ychunk = yremaining;
                        }
                        yremaining -= ychunk;

                        /* loop over all source pixels in the X direction */
                        for (curx = startx; xremaining != 0; curx += xchunk)
                        {
                            u32 factor;

                            /* determine the X contribution, clamping to the amount remaining */
                            xchunk = 0x1000 - (curx & 0xfff);
                            if (xchunk > xremaining)
                            {
                                xchunk = xremaining;
                            }
                            xremaining -= xchunk;

                            /* total contribution = x * y */
                            factor = xchunk * ychunk;

                            /* fetch the source pixel */
                            rgb_t pix = new rgb_t(source[(cury >> 12) * srowpixels + (curx >> 12)]);  //rgb_t pix = source[(cury >> 12) * srowpixels + (curx >> 12)];

                            /* accumulate the RGBA values */
                            sumr += factor * pix.r();
                            sumg += factor * pix.g();
                            sumb += factor * pix.b();
                            suma += factor * pix.a();
                        }
                    }

                    /* apply scaling */
                    suma = (suma / sumscale) * a / 256;
                    sumr = (sumr / sumscale) * r / 256;
                    sumg = (sumg / sumscale) * g / 256;
                    sumb = (sumb / sumscale) * b / 256;

                    /* if we're translucent, add in the destination pixel contribution */
                    if (a < 256)
                    {
                        rgb_t dpix = new rgb_t(dest[y * drowpixels + x]);  //rgb_t dpix = dest[y * drowpixels + x];
                        suma += dpix.a() * (256 - a);
                        sumr += dpix.r() * (256 - a);
                        sumg += dpix.g() * (256 - a);
                        sumb += dpix.b() * (256 - a);
                    }

                    /* store the target pixel, dividing the RGBA values by the overall scale factor */
                    dest[y * drowpixels + x] = new rgb_t((u8)suma, (u8)sumr, (u8)sumg, (u8)sumb);  //dest[y * drowpixels + x] = rgb_t(suma, sumr, sumg, sumb);
                }
            }
        }
예제 #4
0
        /* ----- render utilities ----- */

        /*-------------------------------------------------
        *   render_resample_argb_bitmap_hq - perform a high
        *   quality resampling of a texture
        *  -------------------------------------------------*/
        public static void render_resample_argb_bitmap_hq(bitmap_argb32 dest, bitmap_argb32 source, render_color color, bool force = false)
        {
            if (dest.width() == 0 || dest.height() == 0)
            {
                return;
            }

            /* adjust the source base */
            PointerU32 sbase = source.pix(0);  //const u32 *sbase = &source.pix(0);

            /* determine the steppings */
            u32 swidth  = (u32)source.width();
            u32 sheight = (u32)source.height();
            u32 dwidth  = (u32)dest.width();
            u32 dheight = (u32)dest.height();
            u32 dx      = (swidth << 12) / dwidth;
            u32 dy      = (sheight << 12) / dheight;

            /* if the source is higher res than the target, use full averaging */
            if (dx > 0x1000 || dy > 0x1000 || force)
            {
                resample_argb_bitmap_average(dest.pix(0), (u32)dest.rowpixels(), dwidth, dheight, sbase, (u32)source.rowpixels(), swidth, sheight, color, dx, dy);
            }
            else
            {
                resample_argb_bitmap_bilinear(dest.pix(0), (u32)dest.rowpixels(), dwidth, dheight, sbase, (u32)source.rowpixels(), swidth, sheight, color, dx, dy);
            }
        }
예제 #5
0
        public float b;                  // blue component (0.0 = none, 1.0 = max)


        public render_color(render_color other)
        {
            this.a = other.a; this.r = other.r; this.g = other.g; this.b = other.b;
        }
예제 #6
0
파일: rendutil.cs 프로젝트: kwanboy/mcs
        /* ----- render utilities ----- */

        /*-------------------------------------------------
        *   render_resample_argb_bitmap_hq - perform a high
        *   quality resampling of a texture
        *  -------------------------------------------------*/
        public static void render_resample_argb_bitmap_hq(bitmap_argb32 dest, bitmap_argb32 source, render_color color, bool force = false)
        {
            if (dest.width() == 0 || dest.height() == 0)
            {
                return;
            }

            /* adjust the source base */
            //const UINT32 *sbase = &source.pix32(0);
            RawBuffer sbaseBuf;
            u32       sbaseOffset = source.pix32(out sbaseBuf, 0);

            /* determine the steppings */
            u32 swidth  = (u32)source.width();
            u32 sheight = (u32)source.height();
            u32 dwidth  = (u32)dest.width();
            u32 dheight = (u32)dest.height();
            u32 dx      = (swidth << 12) / dwidth;
            u32 dy      = (sheight << 12) / dheight;

            //throw new emu_unimplemented();
            /* if the source is higher res than the target, use full averaging */
            if (dx > 0x1000 || dy > 0x1000 || force)
            {
                RawBuffer destBuf;
                u32       destOffset = dest.pix32(out destBuf, 0);
                resample_argb_bitmap_average(new RawBufferPointer(destBuf, (int)destOffset), (UInt32)dest.rowpixels(), dwidth, dheight, new RawBufferPointer(sbaseBuf, (int)sbaseOffset), (UInt32)source.rowpixels(), swidth, sheight, color, dx, dy);
            }
            else
            {
                RawBuffer destBuf;
                u32       destOffset = dest.pix32(out destBuf, 0);
                resample_argb_bitmap_bilinear(new RawBufferPointer(destBuf, (int)destOffset), (UInt32)dest.rowpixels(), dwidth, dheight, new RawBufferPointer(sbaseBuf, (int)sbaseOffset), (UInt32)source.rowpixels(), swidth, sheight, color, dx, dy);
            }
        }