Самоучитель по 3dsmax 7

         

Каждую линию рисуем кусками по 8/16/32 пикселов (на самом деле, кусками любой длины; просто...


Каждую линию рисуем кусками по 8/16/32 пикселов (на самом деле, кусками любой длины; просто если длина - степень двойки, то при вычислении du/dx и dv/dx для текущего куска можно деление на длину куска заменить сдвигом вправо) и, если надо, рисуем оставшийся хвостик. Для расчета точных значений u, v в конце каждого куска пользуемся посчитанными (ага!) значениями d(u/Z)/dsx, d(v/Z)/dsx, d(1/Z)/dsx; раз значения u/Z, v/Z, 1/Z в начале куска известны, меняются они линейно и длина куска известна (либо 16 пикселов, либо длина остатка), то в конце куска они считаются все это до боли просто: // расчет u/Z, v/Z, 1/Z в конце куска uZ_b = uZ_a + length * duZ_dsx; vZ_b = vZ_a + length * dvZ_dsx; Z1_b = Z1_a + length * dZ1_dsx;

Все вместе выглядеть это будет примерно так: // ... current_sx = x_start; length = x_end - x_start; // расчет u/Z, v/Z, 1/Z, u, v в начале самого первого куска uZ_a = uZ_start; vZ_a = vZ_start; Z1_a = Z1_start; // это 1/Z u_a = uZ_a / Z1_a; v_a = vZ_a / Z1_a; // рисуем куски по 16 пикселов while (length >= 16) { // расчет u/Z, v/Z, 1/Z, u, v в конце куска uZ_b = uZ_a + 16 * duZ_dsx; vZ_b = vZ_a + 16 * dvZ_dsx; Z1_b = Z1_a + 16 * dZ1_dsx; u_b = uZ_b / Z1_b; v_b = vZ_b / Z1_b; u = u_a; // начинаем текстурирование с начала куска v = v_a; // можно сделать >> 4, используя fixedpoint du = (u_b - u_a) / 16; dv = (v_b - v_a) / 16; // рисуем 16 пикселов старым добрым "аффинным" методом len = 16; while (len--) { putpixel(current_sx, current_sy, texture[(int)v][(int)u]); u += du; v += dv; current_sx++; } length -= 16; // конец куска становится началом следующего куска uZ_a = uZ_b; vZ_a = vZ_b; Z1_a = Z1_b; u_a = u_b; v_a = v_b; } // дорисовываем "хвост" линии, если он непуст if (length != 0) { uZ_b = uZ_a + length * duZ_dsx; vZ_b = vZ_a + length * dvZ_dsx; Z1_b = Z1_a + length * dZ1_dsx; u_b = uZ_b / Z1_b; v_b = vZ_b / Z1_b; u = u_a; // начинаем текстурирование с начала куска v = v_a; du = (u_b - u_a) / length; dv = (v_b - v_a) / length; // рисуем остаток пикселов старым добрым "аффинным" методом while (length--) { putpixel(current_sx, current_sy, texture[v][u]); u += du; v += dv; current_sx++; } } // ...

Как и в 4.2, пройдемся подобным куском кода по всем строкам грани, не забыв вместо "// ..." вставить интерполяцию всяких там [u/v/1]Z_start, содранную с интерполяции u_start..



Содержание раздела