// Internal function - Called to load up a texture map - file is known to exist
Texture *textureFromBitmap(bitmap *loadbm, Texture *tex)
{	bitmap *swizzleBm, *scaleBm, *resizeCanvasSrc;
	bool mustSwizzle = false;
	bool mustScale = false;

	// Step 1: Check for a need to swizzle (if the video card doesn't support this texture mode)
	uintf dataType = loadbm->flags & (bitmap_DataTypeMask | bitmap_DataInfoMask);
	// ### This code is not yet complete, must leave this block with 'swizzleBM' pointing to swizzled bitmap data

	// If Video card only handles 'Power-of-2' texture dimensions
	bool resizeCanvas=false;
	// if (GLESWarnings) //!(videoFeatures & videodriver_nonP2Tex))
	{	uintf newCanvasWidth = loadbm->width;
		uintf newCanvasHeight = loadbm->height;

		if (!isPow2(loadbm->width))
		{	resizeCanvas=true;
			newCanvasWidth=nextPow2(loadbm->width);
		}
		if (!isPow2(loadbm->height))
		{	resizeCanvas=true;
			newCanvasHeight=nextPow2(loadbm->height);
		}
		if (resizeCanvas)
		{	resizeCanvasSrc = loadbm;
			loadbm = newbitmap("resizeCanvasP2Tex",newCanvasWidth,newCanvasHeight,bitmap_ARGB32);
			uintf x,y;
			uint32 *src32 = (uint32 *)resizeCanvasSrc->pixel;
			uint32 *dst32 = (uint32 *)loadbm->pixel;
			for (y=0; y<resizeCanvasSrc->height; y++)
			{	uint32 *src = &src32[y*(resizeCanvasSrc->width)];
				uint32 *dst = &dst32[y*newCanvasWidth];
				for (x=0; x<resizeCanvasSrc->width; x++)
					*dst++ = *src++;
				for (;x<newCanvasWidth; x++)
					*dst++ = 0;
			}
			for (;y<newCanvasHeight; y++)
			{	uint32 *dst = &dst32[y*newCanvasWidth];
				for (x=0; x<newCanvasWidth; x++)
					*dst++=0;
			}
		}

/*		// Work out X scale
		uintf size = 1;
		while (size<=maxtexwidth)
		{	if (newx<=size) break;
			size <<=1;
		}
		if (size>maxtexwidth) size = maxtexwidth;
		newx = size;

		// Work out Y scale
		size = 1;
		while (size<=maxtexheight)
		{	if (newy<=size) break;
			size <<=1;
		}
		if (size>maxtexheight) size = maxtexheight;
		newy = size;
*/
	}

	// Step 2: Check if we need to resize - this may change swizzle mode
	uintf newx = loadbm->width;
	uintf newy = loadbm->height;
	if (newx>maxtexwidth)
		newx = maxtexwidth;
	if (newy>maxtexheight)
		newy = maxtexheight;

	if (newx!=loadbm->width || newy!=loadbm->height)
	{	dataType = bitmap_DataTypeRGB | bitmap_RGB_32bit;
		mustSwizzle = true;
		mustScale = true;
	}

	if (mustSwizzle)
	{	dataType |= loadbm->flags & bitmap_AlphaMask;
		swizzleBm = SwizzleBitmap(loadbm, dataType);
	}	else
		swizzleBm = loadbm;

	if (mustScale)
	{	// Bitmap needs to be resized before hardware will accept it
		scaleBm = scalebitmap(swizzleBm,newx,newy);
	}	else
		scaleBm = swizzleBm;

	// If we don't have a texture provided, create a new one
	if (!tex)
		tex = newTexture(NULL, 0, 0);
	downloadbitmaptex(tex, scaleBm, 0);
	estimatedtexmemused += tex->texmemused;
	if (mustScale)
		deleteBitmap(scaleBm);
	if (mustSwizzle)
		deleteBitmap(swizzleBm);
	if (resizeCanvas)
	{	deleteBitmap(loadbm);
		loadbm = resizeCanvasSrc;
		tex->flags |= texture_canvasSize;
		tex->UVscale.x = (float)loadbm->width / (float)tex->width;
		tex->UVscale.y = (float)loadbm->height/ (float)tex->height;
	}
	return tex;
}
Ejemplo n.º 2
0
int GPbitblt (
    Gwidget_t *widget, Gpoint_t gp, Grect_t gr, Gbitmap_t *bitmap,
    char *mode, Ggattr_t *ap
) {
    PIXrect_t pr, r;
    PIXpoint_t pp;
    PIXsize_t s;
    Gsize_t scale;
    Gxy_t p;
    HBITMAP pix;
    HDC gc;
    double tvx, tvy, twx, twy;

    if (gr.o.x > gr.c.x)
        p.x = gr.o.x, gr.o.x = gr.c.x, gr.c.x = p.x;
    if (gr.o.y > gr.c.y)
        p.y = gr.o.y, gr.o.y = gr.c.y, gr.c.y = p.y;
    if (strcmp (mode, "b2c") == 0) {
        tvx = WPU->vsize.x, tvy = WPU->vsize.y;
        twx = WPU->wrect.c.x - WPU->wrect.o.x;
        twy = WPU->wrect.c.y - WPU->wrect.o.y;
        scale.x = tvx / twx, scale.y = tvy / twy;
        if (scale.x == 1 && scale.y == 1) {
            pix = bitmap->u.bmap.orig;
            bitmap->scale = scale;
        } else {
            if (scale.x != bitmap->scale.x || scale.y != bitmap->scale.y)
                scalebitmap (widget, bitmap, scale, TRUE, 1);
            pix = bitmap->u.bmap.scaled;
        }
        pr = rdrawtopix (widget, gr);
        pp = pdrawtobpix (bitmap, gp);
        s.x = pr.c.x - pr.o.x + 1, s.y = pr.c.y - pr.o.y + 1;
        r.o.x = pp.x, r.o.y = pp.y - s.y + 1;
        r.c.x = r.o.x + s.x - 1, r.c.y = r.o.y + s.y - 1;
        if (r.o.x < 0)
            pr.o.x -= r.o.x, r.o.x = 0;
        if (r.o.y < 0)
            pr.o.y -= r.o.y, r.o.y = 0;
        if (r.c.x >= bitmap->size.x * scale.x) {
            pr.c.x -= (r.c.x + 1 - bitmap->size.x * scale.x);
            r.c.x = bitmap->size.x * scale.x - 1;
        }
        if (r.c.y >= bitmap->size.y * scale.y) {
            pr.c.y -= (r.c.y + 1 - bitmap->size.y * scale.y);
            r.c.y = bitmap->size.y * scale.y - 1;
        }
        if (pr.o.x < 0)
            r.o.x -= pr.o.x, pr.o.x = 0;
        if (pr.o.y < 0)
            r.o.y -= pr.o.y, pr.o.y = 0;
        setgattr (widget, ap);
        gc = CreateCompatibleDC (GC);
        SelectObject (gc, pix);
        BitBlt (
            GC, pr.o.x, pr.o.y, r.c.x - r.o.x + 1, r.c.y - r.o.y + 1,
            gc, r.o.x, r.o.y, (WPU->gattr.mode == G_SRC) ? SRCCOPY : SRCINVERT
        );
        DeleteDC (gc);
    } else if (strcmp (mode, "c2b") == 0) {
        tvx = WPU->vsize.x, tvy = WPU->vsize.y;
        twx = WPU->wrect.c.x - WPU->wrect.o.x;
        twy = WPU->wrect.c.y - WPU->wrect.o.y;
        scale.x = tvx / twx, scale.y = tvy / twy;
        if (scale.x == 1 && scale.y == 1) {
            pix = bitmap->u.bmap.orig;
            bitmap->scale = scale;
        } else {
            if (scale.x != bitmap->scale.x || scale.y != bitmap->scale.y)
                scalebitmap (widget, bitmap, scale, FALSE, 1);
            pix = bitmap->u.bmap.scaled;
        }
        pr = rdrawtobpix (bitmap, gr);
        pp = pdrawtopix (widget, gp);
        s.x = pr.c.x - pr.o.x + 1, s.y = pr.c.y - pr.o.y + 1;
        r.o.x = pp.x, r.o.y = pp.y - s.y + 1;
        r.c.x = r.o.x + s.x - 1, r.c.y = r.o.y + s.y - 1;
        if (pr.o.x < 0)
            r.o.x -= pr.o.x, pr.o.x = 0;
        if (pr.o.y < 0)
            r.o.y -= pr.o.y, pr.o.y = 0;
        if (pr.c.x >= bitmap->size.x * scale.x) {
            r.c.x -= (pr.c.x + 1 - bitmap->size.x * scale.x);
            pr.c.x = bitmap->size.x * scale.x - 1;
        }
        if (pr.c.y >= bitmap->size.y * scale.y) {
            r.c.y -= (pr.c.y + 1 - bitmap->size.y * scale.y);
            pr.c.y = bitmap->size.y * scale.y - 1;
        }
        if (r.o.x < 0)
            pr.o.x -= r.o.x, r.o.x = 0;
        if (r.o.y < 0)
            pr.o.y -= r.o.y, r.o.y = 0;
        setgattr (widget, ap);
        gc = CreateCompatibleDC (GC);
        SelectObject (gc, pix);
        BitBlt (
            gc, pr.o.x, pr.o.y, r.c.x - r.o.x + 1, r.c.y - r.o.y + 1,
            GC, r.o.x, r.o.y, (WPU->gattr.mode == G_SRC) ? SRCCOPY : SRCINVERT
        );
        if (pix != bitmap->u.bmap.orig)
            scalebitmap (widget, bitmap, scale, TRUE, -1);
        DeleteDC (gc);
    }
    return 0;
}