Форум: "Прочее";
Текущий архив: 2008.02.17;
Скачать: [xml.tar.bz2];
ВнизСмешение цветов, быстрее можно ли? Найти похожие ветки
← →
Dib@zol © (2008-01-14 16:01) [40]Нет... увы :( Чем больше отличия Rate от половины, тем больше прут искажения :(
> всё-таки: а зачем? может, смотреть в сторону аппаратного
> ускорения, если уж так скорость важна? а то вот на 286 твой
> код тоже нерабочий…
Дыкъ! Спрошенож было: а можно ли быстрее? Я ответил: "В лоб" - можно, но ненамного. "В обход" - нельзя, ибо глюкаво. Хотя...
ЗЫ На 286-м вряд ли кто-то в здравом уме будет ставить и запускать хотя бы Win 3.11, а тем более уж 9х и далее.
ЗЗЫ Пойду Висту на х286 поставлю :D
← →
DVM © (2008-01-14 17:35) [41]
> всё-таки: а зачем? может, смотреть в сторону аппаратного
> ускорения, если уж так скорость важна?
Если кто-то возьмется написать с использованием MMX/SSE я не против :)
Немного о том, зачем мене все это понадобилось. Занялся изучением антиалиазинга (который бы не помешал мне в некотором подобии векторного редактора надо которым работаю). Поэтому возникла идея создать модуль с основными функциями рисования графических примитивов, но с антиалиазингом. Вот, собственно.
← →
homm © (2008-01-14 17:39) [42]> [41] DVM © (14.01.08 17:35)
> Поэтому возникла идея создать модуль с основными функциями
> рисования графических примитивов, но с антиалиазингом.
Как доберешся до элипса с произвольной толщиной заливки границы, дай мне знать :)
← →
J_f_S (2008-01-14 17:48) [43]Баян конечно, но курите алгоритмы, примененные в антигрейне. Антигрейн на сегодня - лучшая, самая качественная и быстрая графическая библиотека. Это факт.
http://antigrain.com/
Стиль чисто плюсовый, все на шаблонах, но алгоритмы ситаются очень хорошо.
← →
J_f_S (2008-01-14 17:49) [44]ситаются = читаются. :(
← →
homm © (2008-01-14 17:59) [45]> [43] J_f_S (14.01.08 17:48)
Это что-то! Спасибо за ссылку.
← →
@!!ex © (2008-01-14 18:06) [46]> Если кто-то возьмется написать с использованием MMX/SSE
> я не против :)
Объясни алгоритм смешивания на пальцах.. А то мне сейчас думать влом над кодом в [0].
SSE владею, если пойму, напишу с использованием SSE.
← →
homm © (2008-01-14 18:11) [47]> [46] @!!ex © (14.01.08 18:06)
> Объясни алгоритм смешивания на пальцах.. А то мне сейчас
> думать влом над кодом в [0].
Он проще чем то можно представить :)
← →
antonn © (2008-01-14 22:01) [48]
> @!!ex © (14.01.08 18:06) [46]
примерно так:function BlendColors(const Color1, Color2: TColor; Amount: Extended): TColor;
Var
R,R2,G,G2,B,B2: Integer;
win1, win2: Integer;
begin
win1 := ColorToRGB(color1);
win2 := ColorToRGB(color2);
R := GetRValue(win1);
G := GetGValue(win1);
B := GetBValue(win1);
R2 := GetRValue(win2);
G2 := GetGValue(win2);
B2 := GetBValue(win2);
b2:=round((1-amount)*b+amount*b2);
g2:=round((1-amount)*g+amount*g2);
r2:=round((1-amount)*r+amount*r2);
if R2 < 0 then R2 := 0;
if G2 < 0 then G2 := 0;
if B2 < 0 then B2 := 0;
if R2 > 255 then R2 := r;
if G2 > 255 then G2 := r;
if B2 > 255 then B2 := r;
Result := TColor(RGB(R2, G2, B2));
end;
← →
@!!ex © (2008-01-14 22:19) [49]> [48] antonn © (14.01.08 22:01)
мда... здесь SSE Не поможет... нужен SSE3 помойму, вроде в нем есть умножение вектора на число.
Хотя ничто не мешает сделать вектор заполненный amount...
Но в любом случае первый SSE не умет работать с целыми, либо MMX(который я не знаю), либо SSE2>, который я не помню...
Завтра посмотрю на свежую голову, заодно ассемблер потренирую. ;)
← →
antonn © (2008-01-14 22:24) [50]у меня через ммх не получается :)
есть "обычное" смешение, без указания степени:function AverageColor(const c1, c2: Tcolor): TColor;
asm
mov ecx, $7F7F7F
shr eax, 1
shr edx, 1
and eax, ecx
and edx, ecx
add eax, edx
end;
← →
DVM © (2008-01-14 22:32) [51]
> Dib@zol © (14.01.08 15:37) [38]
Rate должна быть типа Single. С byte я и сам ьыстрее написать могу ибо Round - главный тормоз становится не нужен. Но обычно при вычислениях на вход будет подаваться именно Single. От этого никуда не денешься ибо это результат деления. Кстати, Real48 или Double тоже чуть медленнее.
> @!!ex © (14.01.08 18:06) [46]
да, конечно код из [25] воспринимается с трудом :) Но сам алгоритм прост.
> J_f_S (14.01.08 17:48) [43]
Да, мимо этой библиотеки я не мог пройти при поиске инфы об антиалиазинге. Библиотека хорошая, но навороченная и придется много кода перелопатить, чтобы выявить сами алгоритмы.
> antonn © (14.01.08 22:01) [48]
Да, это примерно тот код, который я оптимизировал. Кстати, его скорость примерно 640 против 240 из [25]
> homm © (14.01.08 17:39) [42]
Обязательно. :) От хороших советов не откажусь.
← →
antonn © (2008-01-14 22:35) [52]
>
> Да, это примерно тот код, который я оптимизировал. Кстати,
> его скорость примерно 640 против 240 из [25]
у меня мой грубо говоря 50, а твой 17. Там перед ними еще куча нулей :)
кстати, на моем к2д round работает в 4-5 раз быстрее трунка. Был удивлен очень...
← →
ketmar © (2008-01-15 05:46) [53]>[52] antonn ©(14.01.08 22:35)
>round работает в 4-5 раз быстрее трунка
известная фича. round() быстрее, и ощутимо.
← →
homm © (2008-01-15 10:49) [54]> [51] DVM © (14.01.08 22:32)
> Но обычно при вычислениях на вход будет подаваться именно
> Single. От этого никуда не денешься ибо это результат деления.
Денешся. Еще как. Я сомневаюсь, что там есть функции, которые нельзя перевести к целочисленной арифметике. Я делал градиентную заливку под произвольным угром. После того, как перешел на целочисленуб арифметику, ускорение было в 2 раза, точность не пострадала, кажется у меня 24 бита отводилось на промежуток от 0 до 1.
← →
DVM © (2008-01-15 11:10) [55]
> homm © (15.01.08 10:49) [54]
Целочисленная арифметика в случае с инталиазингом неприменима по его сути. Дело в том, что яркость краевого пиксела - это по сути площадь трапеции (она <=1) которая образуется идеальной линией (у которой концы заданы вещественными координатами) и координатной сеткой (сеткой из пикселей растра). Соответственно округлять эту площадь все равно придется - либо до вызова функции смешения цветов, либо в ней самой.
← →
DVM © (2008-01-15 11:11) [56]Под яркостью я подразумеваю степень смешения с фоном
← →
homm © (2008-01-15 11:28) [57]> [55] DVM © (15.01.08 11:10)
> у которой концы заданы вещественными координатами
Я говорю о полном переходе на целочисленую арифметику. Это не так сложно. Те же координаты пересчитаывем с целые числа (integer, верхнее слово — целая часть, нижнее — количество долей целой единицы.). Для линии синус и косинус нужно посчитать один раз, после вычисления они точно так же преобразуются. До умножения 2-х таких сисел они сдвигаются на 8 бит вправо, после умножения еще раз вправо (кажжется так). При сложении, складываются как есть. Коорджинаты все целые.
Вот в помошь:
http://delphimaster.net/view/8-1189622890/
← →
DVM © (2008-01-15 11:31) [58]
> Те же координаты пересчитаывем с целые числа (integer, верхнее
> слово — целая часть, нижнее — количество долей целой единицы.
> ).
А ты вон о чем. Т.е предлагаешь изобрести свой новый тип данных с целой и дробной частью, заданными целыми числами?
← →
homm © (2008-01-15 11:34) [59]> [58] DVM © (15.01.08 11:31)
Ну ты же хочешь утвердительный ответ на сабж :)
← →
DVM © (2008-01-15 11:39) [60]
> Ну ты же хочешь утвердительный ответ на сабж :)
Мороки много больно.
У меня вот щас в векторном редакторе все координаты вершин - целые числа. Вначале это было некритично, но теперь я понял, какую ошибку я совершил, не став использовать вещественные. В том же твоем примере про градиент - угол только целочисленный, но для серьезного применения этого недостаточно. Будет большая погрешность при больших размерах фигур.
Вот пример. Есть ломаная в виде горизонтальной пилы шириной 100 точек. Пользователь выставляет горизонтальный размер в 1 точку для этой фигуры.
Она превращается визуально в вертикальный отрезок. Далее он возвращает ее ширину к прежней. Если координаты вершин будут целочисленные, то обратно ее не вернуть к прежнему виду ибо х координата всех вершин станет одинаковой.
← →
homm © (2008-01-15 11:46) [61]> [60] DVM © (15.01.08 11:39)
> В том же твоем примере про градиент - угол только целочисленный
Это вообще не принципиально, угол нужен для синуса и косинуса, которые в любом случае вещественные, поэто му целый угол — искуственное ограничени, меняешь описание функции, получаешь вещественный угол.
> Вот пример.
Я разве говорю о формате в котором хранятся данные? Да пусть хоть в текстовом, главное при расчете цвета исходные данные легко переводятся в любое представление.
← →
DVM © (2008-01-15 11:51) [62]
> homm © (15.01.08 11:46) [61]
А вообще с градиентом у тебя хорошо получилось. Быстро. :)
Вот кстати так как то можно расширить возможности функции по заливке градиентом, чтобы заливать регион любой формы:
procedure GradientFillRgn(Canvas: TCanvas; ARect: TRect; ARgn: HRGN; StartColor, EndColor: TColor; AAngle: Integer);
var
rgn: HRGN;
i: integer;
FWasClippingRgn: Boolean;
begin
rgn := CreateRectRgn(0, 0, 0, 0);
i := GetClipRgn(Canvas.Handle, rgn); // Old clipping region
FWasClippingRgn := (i = 1);
SelectClipRgn(Canvas.Handle, ARgn);
DrawAngleGradient(Canvas, ARect, StartColor, EndColor, AAngle);
if FWasClippingRgn then
SelectClipRgn(Canvas.Handle, rgn)
else
SelectClipRgn(Canvas.Handle, 0);
DeleteObject(rgn);
end;
← →
homm © (2008-01-15 11:53) [63]> [62] DVM © (15.01.08 11:51)
> Вот кстати так как то можно расширить возможности функции
> по заливке градиентом, чтобы заливать регион любой формы:
А разве рект из региона не проще и логичнее узнавать?
← →
DVM © (2008-01-15 11:54) [64]
> А разве рект из региона не проще и логичнее узнавать?
ну мало ли , вдруг надо залить надо часть региона.
← →
Sapersky (2008-01-15 13:54) [65]Я говорю о полном переходе на целочисленую арифметику. Это не так сложно.
Подтверждаю. В FastLIB масса примеров, хотя бы то же масштабирование картинки.
Если так уж пугает "новый тип", можно считать, что просто переходим на другие единицы измерения, вместо 1 пикселя - 1/65536-я пикселя.
Вот мой пример получения значения пикселя с "дробной" координатой X (с линейной интерполяцией между двумя соседними), имеется FP и целочисленный вариант, так что можно сравнить:
Var x, w2, i2, i3, t, t2, z, iz : Integer;
i, k : Single;
w2 := w div 2;
t := Round(theta * 65536); // theta = 0..1
t2 := w2 * (65536 - t);
If Smooth then
For x:=0 to w-1 do begin
// get average from neighbour pixels
If UseRealFP then begin // note: floating point calculations here
i := (x - w2) * theta + w2; // are slower 6-7 times
k := Frac(i); i2 := Trunc(i);
i3 := Round(SLine[i2] * (1-k) + SLine[i2+1] * (k));
end else begin
i2 := (x * t + t2); // really i * 65536
z := i2 and $FFFF; // float part (k)
iz := $FFFF - z; // 1 - k
i2 := i2 shr 16; // integer part
i3 := (SLine[i2] * iz + SLine[i2 + 1] * z) shr 16;
end;
<...>
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2008.02.17;
Скачать: [xml.tar.bz2];
Память: 0.61 MB
Время: 0.043 c