示例#1
0
	//! copies this surface into another, scaling it to fit it.
	void CImage::copyToScalingBoxFilter(IImage* target, SINT32 bias, bool blend)
	{
		const dimension2d<UINT32> destSize = target->getDimension();

		const Real sourceXStep = (Real)Size.Width / (Real)destSize.Width;
		const Real sourceYStep = (Real)Size.Height / (Real)destSize.Height;

		target->lock();

		SINT32 fx = ceil32(sourceXStep);
		SINT32 fy = ceil32(sourceYStep);
		Real sx;
		Real sy;

		sy = 0.f;
		for (UINT32 y = 0; y != destSize.Height; ++y)
		{
			sx = 0.f;
			for (UINT32 x = 0; x != destSize.Width; ++x)
			{
				target->setPixel(x, y,
					getPixelBox(floor32(sx), floor32(sy), fx, fy, bias), blend);
				sx += sourceXStep;
			}
			sy += sourceYStep;
		}

		target->unlock();
	}
示例#2
0
//! to be called every frame
void CFPSCounter::registerFrame(u32 now, u32 primitivesDrawn)
{
	++FramesCounted;
	PrimitiveTotal += primitivesDrawn;
	PrimitivesCounted += primitivesDrawn;
	Primitive = primitivesDrawn;

	const u32 milliseconds = now - StartTime;

	if (milliseconds >= 1500 )
	{
		const f32 invMilli = reciprocal ( (f32) milliseconds );
		
		FPS = ceil32 ( ( 1000 * FramesCounted ) * invMilli );
		PrimitiveAverage = ceil32 ( ( 1000 * PrimitivesCounted ) * invMilli );

		FramesCounted = 0;
		PrimitivesCounted = 0;
		StartTime = now;
	}
}
/*!
*/
inline void CTRTextureDetailMap2::scanline_bilinear ( sScanLineData * data ) const
{
	tVideoSample *dst;

#ifdef IPOL_Z
	TZBufferType2 *z;
#endif

	s32 xStart;
	s32 xEnd;
	s32 dx;

	f32 invDeltaX;

#ifdef SUBTEXEL
	f32 subPixel;
#endif

#ifdef IPOL_Z
	f32 slopeZ;
#endif
#ifdef IPOL_W
	f32 slopeW;
#endif
#ifdef IPOL_C
	sVec4 slopeC;
#endif
#ifdef IPOL_T0
	sVec2 slopeT0;
#endif
#ifdef IPOL_T1
	sVec2 slopeT1;
#endif

	// apply top-left fill-convention, left
	xStart = ceil32( data->x[0] );
	xEnd = ceil32( data->x[1] ) - 1;

	dx = xEnd - xStart;

	if ( dx < 0 )
		return;

	// slopes
	invDeltaX = data->x[1] - data->x[0];
	invDeltaX = inverse32 ( invDeltaX );

#ifdef IPOL_Z
	slopeZ = (data->z[1] - data->z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
	slopeW = (data->w[1] - data->w[0]) * invDeltaX;
#endif
#ifdef IPOL_C
	slopeC = (data->c[1] - data->c[0]) * invDeltaX;
#endif
#ifdef IPOL_T0
	slopeT0 = (data->t0[1] - data->t0[0]) * invDeltaX;
#endif
#ifdef IPOL_T1
	slopeT1 = (data->t1[1] - data->t1[0]) * invDeltaX;
#endif

#ifdef SUBTEXEL
	subPixel = ( (f32) xStart ) - data->x[0];
#ifdef IPOL_Z
	data->z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
	data->w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C
	data->c[0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
	data->t0[0] += slopeT0 * subPixel;
#endif
#ifdef IPOL_T1
	data->t1[0] += slopeT1 * subPixel;
#endif
#endif

	dst = lockedSurface + ( data->y * SurfaceWidth ) + xStart;

#ifdef IPOL_Z
	z = lockedZBuffer + ( data->y * SurfaceWidth ) + xStart;
#endif


#ifdef IPOL_W
	f32 inversew;
#endif

	tFixPoint tx0, tx1;
	tFixPoint ty0, ty1;

	tFixPoint r0, g0, b0;
	tFixPoint r1, g1, b1;
	tFixPoint r2, g2, b2;


	for ( s32 i = 0; i <= dx; ++i )
	{
#ifdef CMP_Z
		if ( data->z[0] < z[i] )
#endif
		{
#ifdef IPOL_W
			inversew = inverse32 ( data->w[0] );

			tx0 = f32_to_fixPoint ( data->t0[0].x * inversew);
			ty0 = f32_to_fixPoint ( data->t0[0].y * inversew);
			tx1 = f32_to_fixPoint ( data->t1[0].x * inversew);
			ty1 = f32_to_fixPoint ( data->t1[0].y * inversew);

#else
			tx0 = f32_to_fixPoint ( data->t0[0].x );
			ty0 = f32_to_fixPoint ( data->t0[0].y );
			tx1 = f32_to_fixPoint ( data->t1[0].x );
			ty1 = f32_to_fixPoint ( data->t1[0].y );
#endif
			getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
			getSample_texture ( r1, g1, b1, &IT[1], tx1,ty1 );

#define FIX_POINT_HALF_COLOR ( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) )

			// bias half color
			r1 += -FIX_POINT_HALF_COLOR;
			g1 += -FIX_POINT_HALF_COLOR;
			b1 += -FIX_POINT_HALF_COLOR;

			r2 = clampfix_mincolor ( clampfix_maxcolor ( r0 + r1 ) );
			g2 = clampfix_mincolor ( clampfix_maxcolor ( g0 + g1 ) );
			b2 = clampfix_mincolor ( clampfix_maxcolor ( b0 + b1 ) );

			dst[i] = fix_to_color ( r2, g2, b2 );

#ifdef WRITE_Z
			z[i] = data->z[0];
#endif
		}

#ifdef IPOL_Z
		data->z[0] += slopeZ;
#endif
#ifdef IPOL_W
		data->w[0] += slopeW;
#endif
#ifdef IPOL_C
		data->c[0] += slopeC;
#endif
#ifdef IPOL_T0
		data->t0[0] += slopeT0;
#endif
#ifdef IPOL_T1
		data->t1[0] += slopeT1;
#endif
	}

}
void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
	sScanConvertData scan;
	sScanLineData line;


	// sort on height, y
	if ( a->Pos.y > b->Pos.y ) swapVertices(&a, &b);
	if ( a->Pos.y > c->Pos.y ) swapVertices(&a, &c);
	if ( b->Pos.y > c->Pos.y ) swapVertices(&b, &c);


	// calculate delta y of the edges
	scan.invDeltaY[0] = c->Pos.y - a->Pos.y;
	scan.invDeltaY[1] = b->Pos.y - a->Pos.y;
	scan.invDeltaY[2] = c->Pos.y - b->Pos.y;

	scan.invDeltaY[0] = inverse32 ( scan.invDeltaY[0] );
	scan.invDeltaY[1] = inverse32 ( scan.invDeltaY[1] );
	scan.invDeltaY[2] = inverse32 ( scan.invDeltaY[2] );

	if ( (f32) 0.0 == scan.invDeltaY[0] )
		return;

	// find if the major edge is left or right aligned
	f32 temp[4];

	temp[0] = a->Pos.x - c->Pos.x;
	temp[1] = a->Pos.y - c->Pos.y;
	temp[2] = b->Pos.x - a->Pos.x;
	temp[3] = b->Pos.y - a->Pos.y;

	scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1;
	scan.right = 1 - scan.left;

	// calculate slopes for the major edge
	scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
	scan.x[0] = a->Pos.x;

#ifdef IPOL_Z
	scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
	scan.z[0] = a->Pos.z;
#endif

#ifdef IPOL_W
	scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
	scan.w[0] = a->Pos.w;
#endif

#ifdef IPOL_C
	scan.slopeC[0] = (c->Color - a->Color) * scan.invDeltaY[0];
	scan.c[0] = a->Color;
#endif

#ifdef IPOL_T0
	scan.slopeT0[0] = (c->Tex0 - a->Tex0) * scan.invDeltaY[0];
	scan.t0[0] = a->Tex0;
#endif

#ifdef IPOL_T1
	scan.slopeT1[0] = (c->Tex1 - a->Tex1) * scan.invDeltaY[0];
	scan.t1[0] = a->Tex1;
#endif

	// top left fill convention y run
	s32 yStart;
	s32 yEnd;
	s32 y;

#ifdef SUBTEXEL
	f32 subPixel;
#endif

	lockedSurface = (tVideoSample*)RenderTarget->lock();

#ifdef IPOL_Z
	lockedZBuffer = ZBuffer->lock();
#endif

#ifdef IPOL_T0
	IT[0].data = (tVideoSample*)IT[0].Texture->lock();
#endif

#ifdef IPOL_T1
	IT[1].data = (tVideoSample*)IT[1].Texture->lock();
#endif

	// rasterize upper sub-triangle
	if ( (f32) 0.0 != scan.invDeltaY[1]  )
	{
		// calculate slopes for top edge
		scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
		scan.x[1] = a->Pos.x;

#ifdef IPOL_Z
		scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
		scan.z[1] = a->Pos.z;
#endif

#ifdef IPOL_W
		scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
		scan.w[1] = a->Pos.w;
#endif

#ifdef IPOL_C
		scan.slopeC[1] = (b->Color - a->Color) * scan.invDeltaY[1];
		scan.c[1] = a->Color;
#endif

#ifdef IPOL_T0
		scan.slopeT0[1] = (b->Tex0 - a->Tex0) * scan.invDeltaY[1];
		scan.t0[1] = a->Tex0;
#endif

#ifdef IPOL_T1
		scan.slopeT1[1] = (b->Tex1 - a->Tex1) * scan.invDeltaY[1];
		scan.t1[1] = a->Tex1;
#endif

		// apply top-left fill convention, top part
		yStart = ceil32( a->Pos.y );
		yEnd = ceil32( b->Pos.y ) - 1;

#ifdef SUBTEXEL
		subPixel = ( (f32) yStart ) - a->Pos.y;

		// correct to pixel center
		scan.x[0] += scan.slopeX[0] * subPixel;
		scan.x[1] += scan.slopeX[1] * subPixel;		

#ifdef IPOL_Z
		scan.z[0] += scan.slopeZ[0] * subPixel;
		scan.z[1] += scan.slopeZ[1] * subPixel;		
#endif

#ifdef IPOL_W
		scan.w[0] += scan.slopeW[0] * subPixel;
		scan.w[1] += scan.slopeW[1] * subPixel;		
#endif

#ifdef IPOL_C
		scan.c[0] += scan.slopeC[0] * subPixel;
		scan.c[1] += scan.slopeC[1] * subPixel;		
#endif

#ifdef IPOL_T0
		scan.t0[0] += scan.slopeT0[0] * subPixel;
		scan.t0[1] += scan.slopeT0[1] * subPixel;		
#endif

#ifdef IPOL_T1
		scan.t1[0] += scan.slopeT1[0] * subPixel;
		scan.t1[1] += scan.slopeT1[1] * subPixel;		
#endif

#endif

		// rasterize the edge scanlines
		for( y = yStart; y <= yEnd; ++y)
		{
			line.y = y;

			line.x[scan.left] = scan.x[0];
			line.x[scan.right] = scan.x[1];

#ifdef IPOL_Z
			line.z[scan.left] = scan.z[0];
			line.z[scan.right] = scan.z[1];
#endif

#ifdef IPOL_W
			line.w[scan.left] = scan.w[0];
			line.w[scan.right] = scan.w[1];
#endif

#ifdef IPOL_C
			line.c[scan.left] = scan.c[0];
			line.c[scan.right] = scan.c[1];
#endif

#ifdef IPOL_T0
			line.t0[scan.left] = scan.t0[0];
			line.t0[scan.right] = scan.t0[1];
#endif

#ifdef IPOL_T1
			line.t1[scan.left] = scan.t1[0];
			line.t1[scan.right] = scan.t1[1];
#endif

			// render a scanline
			scanline_bilinear ( &line );

			scan.x[0] += scan.slopeX[0];
			scan.x[1] += scan.slopeX[1];

#ifdef IPOL_Z
			scan.z[0] += scan.slopeZ[0];
			scan.z[1] += scan.slopeZ[1];
#endif

#ifdef IPOL_W
			scan.w[0] += scan.slopeW[0];
			scan.w[1] += scan.slopeW[1];
#endif

#ifdef IPOL_C
			scan.c[0] += scan.slopeC[0];
			scan.c[1] += scan.slopeC[1];
#endif

#ifdef IPOL_T0
			scan.t0[0] += scan.slopeT0[0];
			scan.t0[1] += scan.slopeT0[1];
#endif

#ifdef IPOL_T1
			scan.t1[0] += scan.slopeT1[0];
			scan.t1[1] += scan.slopeT1[1];
#endif

		}
	}

	// rasterize lower sub-triangle
	if ( (f32) 0.0 != scan.invDeltaY[2] )
	{
		// advance to middle point
		if( (f32) 0.0 != scan.invDeltaY[1] )
		{
			temp[0] = b->Pos.y - a->Pos.y;	// dy

			scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
			scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
			scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C
			scan.c[0] = a->Color + scan.slopeC[0] * temp[0];
#endif
#ifdef IPOL_T0
			scan.t0[0] = a->Tex0 + scan.slopeT0[0] * temp[0];
#endif
#ifdef IPOL_T1
			scan.t1[0] = a->Tex1 + scan.slopeT1[0] * temp[0];
#endif

		}

		// calculate slopes for bottom edge
		scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
		scan.x[1] = b->Pos.x;

#ifdef IPOL_Z
		scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
		scan.z[1] = b->Pos.z;
#endif

#ifdef IPOL_W
		scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
		scan.w[1] = b->Pos.w;
#endif

#ifdef IPOL_C
		scan.slopeC[1] = (c->Color - b->Color) * scan.invDeltaY[2];
		scan.c[1] = b->Color;
#endif

#ifdef IPOL_T0
		scan.slopeT0[1] = (c->Tex0 - b->Tex0) * scan.invDeltaY[2];
		scan.t0[1] = b->Tex0;
#endif

#ifdef IPOL_T1
		scan.slopeT1[1] = (c->Tex1 - b->Tex1) * scan.invDeltaY[2];
		scan.t1[1] = b->Tex1;
#endif

		// apply top-left fill convention, top part
		yStart = ceil32( b->Pos.y );
		yEnd = ceil32( c->Pos.y ) - 1;

#ifdef SUBTEXEL

		subPixel = ( (f32) yStart ) - b->Pos.y;

		// correct to pixel center
		scan.x[0] += scan.slopeX[0] * subPixel;
		scan.x[1] += scan.slopeX[1] * subPixel;		

#ifdef IPOL_Z
		scan.z[0] += scan.slopeZ[0] * subPixel;
		scan.z[1] += scan.slopeZ[1] * subPixel;		
#endif

#ifdef IPOL_W
		scan.w[0] += scan.slopeW[0] * subPixel;
		scan.w[1] += scan.slopeW[1] * subPixel;		
#endif

#ifdef IPOL_C
		scan.c[0] += scan.slopeC[0] * subPixel;
		scan.c[1] += scan.slopeC[1] * subPixel;		
#endif

#ifdef IPOL_T0
		scan.t0[0] += scan.slopeT0[0] * subPixel;
		scan.t0[1] += scan.slopeT0[1] * subPixel;		
#endif

#ifdef IPOL_T1
		scan.t1[0] += scan.slopeT1[0] * subPixel;
		scan.t1[1] += scan.slopeT1[1] * subPixel;		
#endif

#endif

		// rasterize the edge scanlines
		for( y = yStart; y <= yEnd; ++y)
		{
			line.y = y;
			line.x[scan.left] = scan.x[0];
			line.x[scan.right] = scan.x[1];

#ifdef IPOL_Z
			line.z[scan.left] = scan.z[0];
			line.z[scan.right] = scan.z[1];
#endif

#ifdef IPOL_W
			line.w[scan.left] = scan.w[0];
			line.w[scan.right] = scan.w[1];
#endif

#ifdef IPOL_C
			line.c[scan.left] = scan.c[0];
			line.c[scan.right] = scan.c[1];
#endif

#ifdef IPOL_T0
			line.t0[scan.left] = scan.t0[0];
			line.t0[scan.right] = scan.t0[1];
#endif

#ifdef IPOL_T1
			line.t1[scan.left] = scan.t1[0];
			line.t1[scan.right] = scan.t1[1];
#endif

			// render a scanline
			scanline_bilinear ( &line );

			scan.x[0] += scan.slopeX[0];
			scan.x[1] += scan.slopeX[1];

#ifdef IPOL_Z
			scan.z[0] += scan.slopeZ[0];
			scan.z[1] += scan.slopeZ[1];
#endif

#ifdef IPOL_W
			scan.w[0] += scan.slopeW[0];
			scan.w[1] += scan.slopeW[1];
#endif

#ifdef IPOL_C
			scan.c[0] += scan.slopeC[0];
			scan.c[1] += scan.slopeC[1];
#endif

#ifdef IPOL_T0
			scan.t0[0] += scan.slopeT0[0];
			scan.t0[1] += scan.slopeT0[1];
#endif

#ifdef IPOL_T1
			scan.t1[0] += scan.slopeT1[0];
			scan.t1[1] += scan.slopeT1[1];
#endif

		}
	}

	RenderTarget->unlock();

#ifdef IPOL_Z
	ZBuffer->unlock();
#endif

#ifdef IPOL_T0
	IT[0].Texture->unlock();
#endif

#ifdef IPOL_T1
	IT[1].Texture->unlock();
#endif

}
/*!
*/
inline void CTRTextureGouraud2::scanline_bilinear ( sScanLineData * data ) const
{
	tVideoSample *dst;

#ifdef IPOL_Z
	TZBufferType2 *z;
#endif

	s32 xStart;
	s32 xEnd;
	s32 dx;

	f32 invDeltaX;

#ifdef SUBTEXEL
	f32 subPixel;
#endif

#ifdef IPOL_Z
	f32 slopeZ;
#endif
#ifdef IPOL_W
	f32 slopeW;
#endif
#ifdef IPOL_C
	sVec4 slopeC;
#endif
#ifdef IPOL_T0
	sVec2 slopeT0;
#endif
#ifdef IPOL_T1
	sVec2 slopeT1;
#endif

	// apply top-left fill-convention, left
	xStart = ceil32( data->x[0] );
	xEnd = ceil32( data->x[1] ) - 1;

	dx = xEnd - xStart;

	if ( dx < 0 )
		return;

	// slopes
	invDeltaX = data->x[1] - data->x[0];
	invDeltaX = inverse32 ( invDeltaX );

#ifdef IPOL_Z
	slopeZ = (data->z[1] - data->z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
	slopeW = (data->w[1] - data->w[0]) * invDeltaX;
#endif
#ifdef IPOL_C
	slopeC = (data->c[1] - data->c[0]) * invDeltaX;
#endif
#ifdef IPOL_T0
	slopeT0 = (data->t0[1] - data->t0[0]) * invDeltaX;
#endif
#ifdef IPOL_T1
	slopeT1 = (data->t1[1] - data->t1[0]) * invDeltaX;
#endif

#ifdef SUBTEXEL
	subPixel = ( (f32) xStart ) - data->x[0];
#ifdef IPOL_Z
	data->z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
	data->w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C
	data->c[0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
	data->t0[0] += slopeT0 * subPixel;
#endif
#ifdef IPOL_T1
	data->t1[0] += slopeT1 * subPixel;
#endif
#endif

	dst = lockedSurface + ( data->y * SurfaceWidth ) + xStart;

#ifdef IPOL_Z
	z = lockedZBuffer + ( data->y * SurfaceWidth ) + xStart;
#endif


#ifdef IPOL_W
	f32 inversew;
#endif

	tFixPoint tx0;
	tFixPoint ty0;

	tFixPoint r0, g0, b0;
#ifdef IPOL_C
	tFixPoint r1, g1, b1;
	tFixPoint r2, g2, b2;
#endif

	for ( s32 i = 0; i <= dx; ++i )
	{
#ifdef CMP_Z
		if ( data->z[0] < z[i] )
#endif
		{
#ifdef IPOL_W
			inversew = inverse32 ( data->w[0] );

			tx0 = f32_to_fixPoint ( data->t0[0].x * inversew);
			ty0 = f32_to_fixPoint ( data->t0[0].y * inversew);
#ifdef IPOL_C
			getSample_plain ( r1, g1, b1, data->c[0] * inversew );
#endif
#else
			tx0 = f32_to_fixPoint ( data->t0[0].x );
			ty0 = f32_to_fixPoint ( data->t0[0].y );
#ifdef IPOL_C
			getSample_plain ( r1, g1, b1, data->c[0] );
#endif
#endif

#ifdef IPOL_C
			getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );

			r2 = imulFix ( r0, r1 );
			g2 = imulFix ( g0, g1 );
			b2 = imulFix ( b0, b1 );

			dst[i] = fix_to_color ( r2, g2, b2 );
#else
			getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
			dst[i] = fix_to_color ( r0, g0, b0 );
#endif

#ifdef WRITE_Z
			z[i] = data->z[0];
#endif
		}

#ifdef IPOL_Z
		data->z[0] += slopeZ;
#endif
#ifdef IPOL_W
		data->w[0] += slopeW;
#endif
#ifdef IPOL_C
		data->c[0] += slopeC;
#endif
#ifdef IPOL_T0
		data->t0[0] += slopeT0;
#endif
#ifdef IPOL_T1
		data->t1[0] += slopeT1;
#endif
	}

}