// 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; }
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; }