Интерполяция цветов - Програмный рендеринг

Загрузить архив с примерами ЗДЕСЬ.

Результат работы программы для данной главы показан на рисунке ниже:

Интерполяция цветов - Програмный рендеринг

Как интерполировать цвета вершин треугольника показано в примере /src/02.002-color_cube/Tri_Color_Interpolation.

Интерполяция цветов - Програмный рендеринг

В прошлом примере у каждого треугольника куба был свой цвет. В этом примере у каждой вершины куба есть цвет, цвет вершины, и мы будем интерполировать цвета. Загрузить проект примера можно (использовалась функция DrawDibDraw) /src/02.002-color_cube/Color_Cube.

Какие отличия от предыдущего проекта. В буфере вершин как и в предыдущих проектах 8 вершин куба. И так же имеется массив цветов из 8ми элементов, цвет для каждой вершины (см.функцию Init_Cube):

	
	//color array for all 8 vertices
	m_color_array[0] = color_rgb(255, 255, 255);
	m_color_array[1] = color_rgb(0, 0, 0);
	m_color_array[2] = color_rgb(255, 0, 0);
	m_color_array[3] = color_rgb(0, 255, 0);
	m_color_array[4] = color_rgb(0, 0, 255);
	m_color_array[5] = color_rgb(255, 255, 0);
	m_color_array[6] = color_rgb(0, 255, 255);
	m_color_array[7] = color_rgb(255, 0, 255);

В конце функции Draw_Cube есть вызов функции:


	Draw_Color_Triangle(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y,
			rgb1, rgb2, rgb3);

В функцию Draw_Color_Triangle мы передаем три вершины треугольника в экранных координатах, и три цвета rgb1, rgb2, rgb3- эти три цвета соответствуют трем вершинам треугольника, цвета заранее приготовлены в массиве m_color_array. Далее в функции Draw_Color_Triangle мы сортируем вершины (как в предыдущем примере), но также в случае необходимости меняем местами цвета вершины:


void CMeshManager::Draw_Color_Triangle(float x1,float y1,
					   float x2,float y2,
					   float x3,float y3,
					   color_rgb color1,
					   color_rgb color2,
					   color_rgb color3)
{
	float t;
	int ct;
	int side;

	if (y2 < y1)
	{
		SWAP(x2,x1,t);
		SWAP(y2,y1,t);
		
		SWAP(color2.r, color1.r, ct);
		SWAP(color2.g, color1.g, ct);
		SWAP(color2.b, color1.b, ct);
	}

	if (y3 < y1)
	{
		SWAP(x3,x1,t);
		SWAP(y3,y1,t);

		SWAP(color3.r, color1.r, ct);
		SWAP(color3.g, color1.g, ct);
		SWAP(color3.b, color1.b, ct);
	}

	if (y3 < y2)
	{
		SWAP(x3,x2,t);
		SWAP(y3,y2,t);

		SWAP(color3.r, color2.r, ct);
		SWAP(color3.g, color2.g, ct);
		SWAP(color3.b, color2.b, ct);
	}
	

Далее как обычно определяем какая сторона треугольника длинее по Y:


	//определяем какая сторона треугольника длинее
	if (y2 > y1 && y3 > y2)
	{
		float dxdy1 = (x2 - x1) / (y2 - y1);
		float dxdy2 = (x3 - x1) / (y3 - y1);
		side = dxdy2 > dxdy1;
	}

	if (y1 == y2)
		side = x1 > x2;
	if (y2 == y3)
		side = x3 > x2;
	

И далее рисуем треугольник (в примере ниже показано только для треугольника с левой стороной длинее). Вычисляем начальную точку для x, red компоненты цвета, green и blue. И вычисляем приращение по Y для x, red компоненты, green и blue. Далее рисуем треугольник Draw_Color_Poly.


if (!side) //длинее левая сторона
	{
		m_xl = x1;
		m_redl = (float) color1.r;
		m_greenl = (float) color1.g;
		m_bluel = (float) color1.b;

		m_dxl = (x3 - x1) / (y3 - y1);
		m_dredl = (color3.r - color1.r) / (y3 - y1);
		m_dgreenl = (color3.g - color1.g) / (y3 - y1);
		m_dbluel = (color3.b - color1.b) / (y3 - y1);
	
		if ( y1 < y2)
		{
			m_xr = x1;
			m_redr = (float) color1.r;
			m_greenr = (float) color1.g;
			m_bluer = (float) color1.b;

			m_dxr = (x2 - x1) / (y2 - y1);
			m_dredr = (color2.r - color1.r) / (y2 - y1);
			m_dgreenr = (color2.g - color1.g) / (y2 - y1);
			m_dbluer = (color2.b - color1.b) / (y2 - y1);

			Draw_Color_Poly((int)y1, (int)y2);	
		}
		if(y2 < y3)
		{
			m_xr = x2;
			m_redr = (float) color2.r;
			m_greenr = (float) color2.g;
			m_bluer = (float) color2.b;

			m_dxr = (x3 - x2) / (y3 - y2);
			m_dredr = (color3.r - color2.r) / (y3 - y2);
			m_dgreenr = (color3.g - color2.g) / (y3 - y2);
			m_dbluer = (color3.b - color2.b) / (y3 - y2);

			Draw_Color_Poly((int)y2, (int)y3);
		}
	}	

В функции Draw_Color_Poly мы идем в цикле от y1 до y2, и от xl до xr, внутри цикла от y1 до y2 мы вычисляем начальную точку ri, gi, bi и приращение dr, dg, db для интерполяции значений по x, и интерполируем значения внутри цикла от xl до xr.