[EMAIL PROTECTED] (Christoph Egger) writes:
> On Mon, 16 Apr 2001, Andreas Beck wrote:
>
> > > int stretch(ggiBlt_t bob, int dx, int dy, int width, int height)
> > > {
> > > double bob_xinc, bob_yinc;
> >
> > Please don't use floating point ! It isn't needed and it's slow.
>
> Why? Modern CPU's have a FPU. i386-CPU's executes floats/doubles as
> fast as integers and ALPHA-CPU's even faster...
the floating point results have to be converted to integer in order to
do the lookup from memory. that takes time. on everything below
pentium plain fixed point is a lot faster.
if you want to do clipping as well, here is a general stretchblit
routine that i wanted to use in my ggi extension experiment (still no
time, so pasting might prove most useful):
there's a lot of mess around this routine which could be stripped off
if you don't want to handle partial images. (one could opt for a
mechanism in which one should first define a `subimage' and then
stretchblit that.)
note also that this version is for 8bit modes only. i take it your
routine is only for demonstration purposes, and routines like these
should be filled in for every bitdepth of framebuffer devices without
hardware acceleration:
#define FLOAT_EPSILON 0.0000001 /* a small value */
void c_image_zoom_blit ( IMAGE_HANDLE dest_handle,
sint32 dest_x, sint32 dest_y,
sint32 dest_width, sint32 dest_height,
IMAGE_HANDLE src_handle,
float src_x, float src_y,
float src_width, float src_height )
{
Image* src = _c_image_ptr ( src_handle );
Image* dest = _c_image_ptr ( dest_handle );
int dest_stride;
uint8* src_buffer;
uint8* dest_buffer;
uint8* src_ptr;
int dx0 = dest_x;
int dy0 = dest_y;
int dx1 = dest_x + dest_width;
int dy1 = dest_y + dest_height;
float sx0 = src_x;
float sy0 = src_y;
float sx1 = src_x + src_width;
float sy1 = src_y + src_height;
int width, height;
int x, y;
int u, v; /* 16.16 fixed point */
int u0;
int dudx, dvdy;
/* clipping */
/* catch division by zero */
if (src_width < FLOAT_EPSILON)
return;
if (src_height < FLOAT_EPSILON)
return;
if ( sx0 < 0 )
{
dx0 += -sx0 * dest_width / src_width;
sx0 = 0;
}
if ( sy0 < 0 )
{
dy0 += -sy0 * dest_height / src_height;
sy0 = 0;
}
if ( sx1 > src->width )
sx1 = src->width;
if ( sy1 > src->height )
sy1 = src->height;
/* catch division by zero */
if (dest_height <= 0)
return;
if (dest_width <= 0)
return;
if ( dx0 < 0 )
{
sx0 += ( -dx0 * src_width ) / dest_width;
dx0 = 0;
}
if ( dy0 < 0 )
{
sy0 += -dy0 * src_height / dest_height;
dy0 = 0;
}
if ( dx1 > dest->width )
dx1 = dest->width;
if ( dy1 > dest->height )
dy1 = dest->height;
width = min ( dx1-dx0, (sx1-sx0)*dest_width/src_width );
height = min ( dy1-dy0, (sy1-sy0)*dest_height/src_height );
if (( width <= 0 ) || ( height <= 0))
return;
/* some setup of the buffers and step values*/
dest_buffer = dest->buffer + dx0 + dy0 * dest->stride;
src_buffer = src->buffer;
dest_stride = dest->stride - width;
dudx = src_width*65536.0 / dest_width;
dvdy = src_height*65536.0 / dest_height;
u0 = sx0*65536.0;
v = sy0*65536.0;
/* and now for the actual drawing */
for ( y = 0; y < height; y++ )
{
src_ptr = &src_buffer[ (v>>16) * src->stride ];
u = u0;
for ( x = 0; x < width; x++ )
{
*dest_buffer++ = src_ptr[ u>>16 ];
u += dudx;
}
dest_buffer += dest_stride;
v += dvdy;
}
}
#undef FLOAT_EPSILON
--
Tijs van Bakel, <[EMAIL PROTECTED]>