//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	FeatureGrid::BLENDFUNCTION (
		FeatureInstance *featureInstance, 
		unsigned char *pix_buf, 
		int start_span, 
		int end_span,
		int downScale
	)
{
	Feature *feature = featureInstance->feature;

	Verify(feature->featureMask0!=NULL);
	
	unsigned char *mask0data0 = featureInstance->currentMask0Ptr;

#ifdef SHOW_MATERIAL
	DWORD mat_color = downScale & 0xffffff;
	downScale >>= 24;
#endif

	int mask0_x_off = featureInstance->mask0_x_off >> downScale;
	int mask0_z_off = featureInstance->mask0_z_off >> downScale;

	int shifter = feature->GetZMask0Scale() + feature->GetXMask0Scale() - 2*downScale;

	int x_stretch = 1<<(feature->GetXMask0Scale()-downScale);
	int z_stretch = 1<<(feature->GetZMask0Scale()-downScale);

#ifdef MASK0_HORIZONTAL_FLIP
	int advancer = x_stretch-1;
#else
	int advancer = ~(x_stretch-1);
#endif

	int advr, mixHr, mixr, mix0r, mix1r, mix00r, mix01r, mix10r, mix11r;
	int advg, mixHg, mixg, mix0g, mix1g, mix00g, mix01g, mix10g, mix11g;
	int advb, mixHb, mixb, mix0b, mix1b, mix00b, mix01b, mix10b, mix11b;
	int pitch = feature->featureMask0->depth * (feature->featureMask0->width + 2); // 2 - padding

	int src;
	
	src = *(int *)mask0data0;
	mix00r = (src & 0x1f) << 3;
	mix00g = (src & 0x3e0) >> 2;
	mix00b = (src & 0x7c00) >> 7;

	src = *(int *)(mask0data0 + feature->featureMask0->depth);
	mix01r = (src & 0x1f) << 3;
	mix01g = (src & 0x3e0) >> 2;
	mix01b = (src & 0x7c00) >> 7;

	src = *(int *)(mask0data0 + pitch);
	mix10r = (src & 0x1f) << 3; 
	mix10g = (src & 0x3e0) >> 2;
	mix10b = (src & 0x7c00) >> 7;

	src = *(int *)(mask0data0 + pitch + feature->featureMask0->depth);
	mix11r = (src & 0x1f) << 3;
	mix11g = (src & 0x3e0) >> 2;
	mix11b = (src & 0x7c00) >> 7;

	mix0r = (mix00r*(z_stretch - mask0_z_off) + mix10r*mask0_z_off);
	mix0g = (mix00g*(z_stretch - mask0_z_off) + mix10g*mask0_z_off);
	mix0b = (mix00b*(z_stretch - mask0_z_off) + mix10b*mask0_z_off);

	mix1r = (mix01r*(z_stretch - mask0_z_off) + mix11r*mask0_z_off);
	mix1g = (mix01g*(z_stretch - mask0_z_off) + mix11g*mask0_z_off);
	mix1b = (mix01b*(z_stretch - mask0_z_off) + mix11b*mask0_z_off);

	mixHr = (mix0r*(x_stretch - mask0_x_off) + mix1r*mask0_x_off);
	mixHg = (mix0g*(x_stretch - mask0_x_off) + mix1g*mask0_x_off);
	mixHb = (mix0b*(x_stretch - mask0_x_off) + mix1b*mask0_x_off);

	advr = mix1r - mix0r;
	advg = mix1g - mix0g;
	advb = mix1b - mix0b;

	int *pix_buf_int = (int *)pix_buf;
	for(int i=0;;)
	{
		mixr = mixHr>>shifter;

		mixg = mixHg>>shifter;

		mixb = mixHb>>shifter;

#ifdef MASK0_HORIZONTAL_FLIP
		mixHr -= advr;
		mixHg -= advg;
		mixHb -= advb;
#else
		mixHr += advr;
		mixHg += advg;
		mixHb += advb;
#endif

#ifdef SHOW_MATERIAL
		pix_buf_int[i] = mat_color;
#else
		DWORD buf;

		buf = mixr;

		buf |= mixg << 8;

		buf |= mixb << 16;

		pix_buf_int[i] = buf;
#endif

		if(++i>=end_span-start_span)
		{
			break;
		}

#ifdef MASK0_HORIZONTAL_FLIP
		if(--mask0_x_off < 0)
		{
			mask0_x_off = advancer;
			mask0data0 -= feature->featureMask0->depth;

			mix01r = mix00r;
			mix01g = mix00g;
			mix01b = mix00b;

			src = *(int *)mask0data0;
			mix00r = (src & 0x1f) << 3;
			mix00g = (src & 0x3e0) >> 2;
			mix00b = (src & 0x7c00) >> 7;

			mix11r = mix10r;
			mix11g = mix10g;
			mix11b = mix10b;

			src = *(int *)(mask0data0 + pitch);
			mix10r = (src & 0x1f) << 3; 
			mix10g = (src & 0x3e0) >> 2;
			mix10b = (src & 0x7c00) >> 7;

			mix1r = mix0r;
			mix1g = mix0g;
			mix1b = mix0b;

			mix0r = (mix00r*(z_stretch - mask0_z_off) + mix10r*mask0_z_off);
			mix0g = (mix00g*(z_stretch - mask0_z_off) + mix10g*mask0_z_off);
			mix0b = (mix00b*(z_stretch - mask0_z_off) + mix10b*mask0_z_off);
#else
		if(++mask0_x_off & advancer)
		{
			mask0_x_off = 0;
			mask0data0 += feature->featureMask0->depth;

			mix00r = mix01r;
			mix00g = mix01g;
			mix00b = mix01b;

			src = *(int *)(mask0data0 + feature->featureMask0->depth);
			mix01r = (src & 0x1f) << 3;
			mix01g = (src & 0x3e0) >> 2;
			mix01b = (src & 0x7c00) >> 7;

			mix10r = mix11r;
			mix10g = mix11g;
			mix10b = mix11b;

			src = *(int *)(mask0data0 + pitch + feature->featureMask0->depth);
			mix11r = (src & 0x1f) << 3;
			mix11g = (src & 0x3e0) >> 2;
			mix11b = (src & 0x7c00) >> 7;

			mix0r = mix1r;
			mix0g = mix1g;
			mix0b = mix1b;

			mix1r = (mix01r*(z_stretch - mask0_z_off) + mix11r*mask0_z_off);
			mix1g = (mix01g*(z_stretch - mask0_z_off) + mix11g*mask0_z_off);
			mix1b = (mix01b*(z_stretch - mask0_z_off) + mix11b*mask0_z_off);
#endif

			mixHr = (mix0r*(x_stretch - mask0_x_off) + mix1r*mask0_x_off);
			advr = mix1r - mix0r;

			mixHg = (mix0g*(x_stretch - mask0_x_off) + mix1g*mask0_x_off);
			advg = mix1g - mix0g;

			mixHb = (mix0b*(x_stretch - mask0_x_off) + mix1b*mask0_x_off);
			advb = mix1b - mix0b;
		}
	}
}
