-
> MBo © (05.03.09 07:11) [77]
Пас.
-
> Дуп (05.03.09 05:11) [76]
:Р Но в случаях просчета именно "синусов/косинусов" со сканлайном могут быть тормоза больше обычного, если кривая строится по вычисляемым точкам и практически для каждой точки берется bt.scanline[y] со всей строкой пикселов, а сканлайн максимально эффективно используется как раз для "разового" прохода по X - т.е. можно пробегать по холсту и смотреть, является ли такая точка частью кривой, а не наоборот, в общем с другой стороны рисовать :)
-
>>> т.е. можно пробегать по холсту и смотреть, является ли такая точка частью кривой, а не наоборот
Я не проверяю никаких кривых, я считаю для каждого пиксела собственный синус... Там нету кривых...
А вот есть ли способ рисовать быстрее чем на TBitmap? Может сделать массив какой, а потом его быстро в TBitmap конвертировать? Можно так?
-
Дело не в том что использовать, а в том как использовать. А ты неговоришь что да как. Поэтому тебе помочь неполучается.
> Я не проверяю никаких кривых, я считаю для каждого пиксела > собственный синус..
А зачем считать собственный синус если числа случайные? Следовательно не случайные. И можно отказаться от расчета синуса к более быстрой операции, на основе закономерности Но так как ты так и несказал какие операции ты используешь то ответить невозможно.
> А вот есть ли способ рисовать быстрее чем на TBitmap? Может > сделать массив какой, а потом его быстро в TBitmap конвертировать? > Можно так?
А чем тебе TBitmap не угодил? Такой же массив при условии правильного использования. А ты до сих пор не доказал что его используешь правильно.
> >>> т.е. можно пробегать по холсту и смотреть, является > ли такая точка частью кривой, а не наоборотЯ не проверяю > никаких кривых, я считаю для каждого пиксела собственный > синус... Там нету кривых...
А синус что не кривая?
-
> А синус что не кривая?Хех... Синус - это периодическая тригонометрическая функция... :) Вася, есть нормальный материал по созданию СкринСейвера в Делфи7..? А то решил из своей графики тоже скринсейвер делать, а все найденные исходники глючные какие-то... :( P.S. А как ты этот кадр выводишь? Пробовал так?: BitBlt(Form1.Canvas.Handle, 0, 0, Form1.Width, Form1.Height, Bit.Canvas.Handle, 0, 0, SRCCOPY);
-
> Вася, есть нормальный материал по созданию СкринСейвера > в Делфи7..? А то решил из своей графики тоже скринсейвер > делать, а все найденные исходники глючные какие-то... :(
У меня где-то был. Минимальный это просто переименовать exe в scr и растянуть форму на весь экран и стиль применить . И по движению мыши и нажатию клавишы выходить. Набросал простой пример. FPS ограничен таймером мне быстрее просто не нужно было. Неплохая плазма получилась, прям как в ламе. http://slil.ru/27034240
-
Э... А объясните как это работает, пожалуйста...
Procedure Plasm;
var LL, i, j: Integer; p: PByteArray;
begin
LL:=DWord(bp.ScanLine[1])-DWord(bp.ScanLine[0]);
p:=bp.ScanLine[0];
for j:=0 to bp.Height-1 do
begin
for i:=0 To bp.Width-1 do
begin
p[i*3+0]:=(CosTable1[(i +c) and (2048-1)]+CosTable1[(i+3242) and (2048-1)]+CosTable2[(j) and (2048-1)]-SinTable1[c and (2048-1)]+128*256) shr 8;
p[i*3+1]:=(CosTable1[(i +c) and (2048-1)]+128*256) shr 8;
p[i*3+2]:=(CosTable2[(j ) and (2048-1)]+128*256) shr 8;
end;
Inc(DWord(p),LL);
end;
end;
Почему ScanLine делается только для нулевой (первой) строки, что есть "PByteArray" и что за странные индексы такие - "p[i*3+0]"... >>> А ты до сих пор не доказал что его используешь правильно Ну так покажите, как правильно... :))
-
> Почему ScanLine делается только для нулевой (первой) строки
Определяется сдвиг LL на который и инкрементируется указатель - р (Inc(DWord(p),LL)).
> что за странные индексы такие - "p[i*3+0]"
Незабываем, что 24 бит изображение состоит из трёх компонент - R, G, B.
-
> Э... А объясните как это работает, пожалуйста...
Как напичанно так и работает. Чистая импровизация. В CosTable1 предварительно вычесленные значения. shr 8 нужно для округления так как использую формат с фиксированной точкой. Нужно для оптимизации.
> ScanLine делается только для нулевой (первой) строки
Так захотелось особенно плюсов недает экономью на вызовах.
PByteArray это основной тип, про него все написанно в справке. Можно и свой тип определить.
> за странные индексы такие - "p[i*3+0]" А чего тут странного? У меня формат битмепа 24битный. Только напомню что цвета идут в порядке B G R. И строки в обратном порядке. Поэтому LL отрицательное. И из завыравнивания отличается от -Width*3.
> Ну так покажите, как правильно... :))
В интернете по этому делу полно статей.
-
> Как напичанно так и работает. Чистая импровизация.
Pavia, твоя импровизация?) Можешь ещё сымпровизировать?))
А я тогда померяю, как быстрее будет...))
P.S. СкринСейвер хороший, а вот как сделать, чтоб он в "предпросмотре" показывался?
-
>>> В интернете по этому делу полно статей
Ага... Например эта... Просто не хотите помочь?..
Может хоть кто-то рассказать варианты от простого к сложному?.. :(
-
> Ага... Например эта... Просто не хотите помочь?.
h_ttp://democoder.ru/ h_ttp://www.hugi.scene.org/ h_ttp://www.enlight.ru/faq3d/main.htm h_ttp://www.enlight.ru/demo/faq/index.phtml h_ttp://algolist.manual.ru/graphics/index.php И тд.
Ф.Хилл OpenGL. Программирование компьютерной графики
Так что это вы сами не хотите себе помочь.
> Может хоть кто-то рассказать варианты от простого к сложному? > .. :( Это не школа. Нужно самому учиться. Вот если есть конкретные вопросы то на них можно ответиь.
-
Я спрашивал про самый быстрый способ нарисования изображения попиксельно на Canvas... Без использования всяких OpenGL...
Не знаете - так и скажите...
:(
-
> P.S. СкринСейвер хороший, а вот как сделать, чтоб он в "предпросмотре" > показывался?
Гугл знает. Если вкратце, то скринсейвер запускается со спец ключом и хэндлом окна на котором рисовать предпросмотр.
> [92] Вася (13.03.09 22:15) > Я спрашивал про самый быстрый способ нарисования изображения > попиксельно на Canvas... > Без использования всяких OpenGL... > > Не знаете - так и скажите...
Бред. Как связан расчет косинуса со скоростью вывода пикселей на кэнвас? 1) В любом месте и везде вам скажут использовать OGL или D3D для этих целей(могут еще DDraw посоветовать, но это смысла не имеет). 2) Если так хочеться считать всякую хрень, то лучше пиксели хранить в отдельном массиве, считать там, а потом через сканлайн вываливать блоки. Буде быстрее. Правда не на много. 3) Переделайте нафиг архитектуру и методику расчета. Ибо любой тормозящий скринсейвер идет в трэш.
-
> Я спрашивал про самый быстрый способ нарисования изображения > попиксельно на Canvas...Без использования всяких OpenGL. > ..Не знаете - так и скажите...
Математика она и в африке математика и в OpenGL таже самая математика.
> Не знаете - так и скажите...:(
Не хочешь учится так и скажи. B)
-
> Гугл знает. > Если вкратце, то скринсейвер запускается со спец ключом > и хэндлом окна на котором рисовать предпросмотр.
Про спец ключи я знаю... У меня есть множество готовых исходников на Делфи 7, но ни в одном предпросмотр не работает как надо... Либо при открытии вкладки "Заставка" он запускается, либо вообще никакой видимой реакции... Есть только один СкринСейвер, в котором предпросмотр срабатывает, но при открытии вкладки "Заставка" всё окошко "Свойства: Экран" наглухо зависает минуты на две... И при выборе этого СкринСейвера в списке тоже самое... :( > Может хоть кто-то рассказать варианты от простого к сложному? > .. :(
Могу... :) "от простого", значить, "к сложному"..... Вариант №1 - самое простое и банальное:
Procedure Draw;
Var x, y: Integer; Bitmap: TBitmap;
Begin
Bitmap:=TBitmap.Create;
Bitmap.PixelFormat:=pf24bit;
Bitmap.Width:=640;
Bitmap.Height:=480;
For y:=0 To Bitmap.Height-1 Do
For x:=0 To Bitmap.Width-1 Do
Bitmap.Canvas.Pixels[x, y]:=RGB(x+x, x+y, y+y);
Form1.Canvas.Draw(0, 0, Bitmap);
End;
-
Вариант №2 - с использованием "ScanLine":
Procedure Draw2;
Type
TRGB=Record Blue,Green,Red: Byte End;
ARGB = Array[0..0] Of TRGB;
PARGB=^ARGB;
Var x, y: Integer; Bitmap: TBitmap; Line: PARGB;
Begin
Bitmap:=TBitmap.Create;
Bitmap.PixelFormat:=pf24bit;
Bitmap.Width:=640;
Bitmap.Height:=480;
For y:=0 To Bitmap.Height-1 Do
Begin
Line:=Bitmap.ScanLine[y];
For x:=0 To Bitmap.Width-1 Do
Begin
Line[x].Red:=x+x;
Line[x].Green:=x+y;
Line[x].Blue:=y+y;
End;
End;
Form1.Canvas.Draw(0, 0, Bitmap);
End;
Работает примерно в 45 раз быстрее, чем "Вариант №1"... :)
-
Пробовал вариант от Pavia
Procedure Draw2_5;
Var x, y, dx: Integer; Bitmap: TBitmap; Pixels: PByteArray;
Begin
Bitmap:=TBitmap.Create;
Bitmap.PixelFormat:=pf24bit;
Bitmap.Width:=640;
Bitmap.Height:=480;
dx:=DWord(Bitmap.ScanLine[1])-DWord(Bitmap.ScanLine[0]);
Pixels:=Bitmap.ScanLine[0];
For y:=0 To Bitmap.Height-1 Do
Begin
For x:=0 To Bitmap.Width-1 Do
Begin
Pixels[x*3+0]:=y+y;
Pixels[x*3+1]:=x+y;
Pixels[x*3+2]:=x+x;
End;
Inc(DWord(Pixels), dx);
End;
Form1.Canvas.Draw(0, 0, Bitmap);
End;
но он оказался чуть медленнее, чем "Вариант №2"... :(
-
> [95] DomiNickDark (16.03.09 01:49) > Про спец ключи я знаю...
Тогда мне не понятна проблема. :)
-
но он оказался чуть медленнее, чем "Вариант №2"... :(
А у меня вариант Pavia быстрее, причём весьма прилично, почти в 2 раза. Основная причина - TBitmap.Scanline, точнее, функция GetScanline, в которой выполняется масса телодвижений весьма сомнительной полезности. В некоторых случаях они, может, и нужны, но скорости точно не добавляют.
Я тут приводил ссылку на FastLIB... так вот, там эти моменты, в отличие от TBitmap, хорошо продуманы: 1) Scanline - это заранее заполненный массив указателей, никаких функций не вызывается. Или, в качестве альтернативы, есть свойства BWidth (= dx из примера Pavia) и Gap (BWidth - Width * BytesPerPixel). 2) Быстрое свойство Pixels с привязкой к конкретному формату (Pixels8,Pixels24), без вызова функций. Полезно при выборе данных из произвольного места картинки (при последовательном обходе быстрее сканлайн). 3) Удобная работа с палитрой (см. тот же пример plasma). В TBitmap она вообще никакая. 4) Много готовых спецэффектов (FastFX.pas). Полезно не только в смысле использовать, но и чтобы поучиться, как писать свои. 5) Сам класс TFastDIB - гораздо более "тонкая" обёртка над DIB. Хотя в общем код не отличается понятностью, но при необходимости разобраться в "кишках" всё же проще, чем перелопачивать тонны кода TBitmap. Можно создавать TFastDIB и без DIB, просто на блоке памяти. Или "навешивать" на уже выделенный блок... 6) Ещё одно следствие "тонкости" - минимум автоматизации и в целом более предсказуемое поведение. Для новичка, может, автоматизация и полезна, но у человека сколь-нибудь опытного попытки класса-картинки заниматься "самодеятельностью" вызывают только раздражение (например, при изменении размера/bpp картинки "шибко умный" TBitmap пытается преобразовать картинку под новый формат, что нужно далеко не всегда; при этом занимает время/жрёт память).
Есть некий "промежуточный" между TBitmap и TFastDIB вариант - TDIB из DelphiX (к DirectX он никакого отношения не имеет), ну и масса других классов/библиотек...
|