Конференция "Игры" » Быстрый канвас [Delphi, Windows, ХР]
 
  • Дуб © (05.03.09 10:37) [80]
    > MBo ©   (05.03.09 07:11) [77]

    Пас.
  • antonn © (05.03.09 12:53) [81]

    > Дуп   (05.03.09 05:11) [76]


    Но в случаях просчета именно "синусов/косинусов" со сканлайном могут быть тормоза больше обычного, если кривая строится по вычисляемым точкам и практически для каждой точки берется bt.scanline[y] со всей строкой пикселов, а сканлайн максимально эффективно используется как раз для "разового" прохода по X - т.е. можно пробегать по холсту и смотреть, является ли такая точка частью кривой, а не наоборот, в общем с другой стороны рисовать :)
  • Вася (08.03.09 21:43) [82]
    >>> т.е. можно пробегать по холсту и смотреть, является ли такая точка частью кривой, а не наоборот

    Я не проверяю никаких кривых, я считаю для каждого пиксела собственный синус... Там нету кривых...

    А вот есть ли способ рисовать быстрее чем на TBitmap? Может сделать массив какой, а потом его быстро в TBitmap конвертировать? Можно так?
  • Pavia © (08.03.09 23:06) [83]
    Дело не в том что использовать, а в том как использовать. А ты неговоришь что да как.  Поэтому тебе помочь неполучается.


    > Я не проверяю никаких кривых, я считаю для каждого пиксела
    > собственный синус..

    А зачем считать собственный синус если числа случайные?
    Следовательно не случайные. И можно отказаться от расчета синуса к более быстрой операции, на основе закономерности Но так как ты так и несказал какие операции ты используешь то ответить невозможно.


    > А вот есть ли способ рисовать быстрее чем на TBitmap? Может
    > сделать массив какой, а потом его быстро в TBitmap конвертировать?
    >  Можно так?

    А чем тебе TBitmap не угодил? Такой же массив при условии правильного использования. А ты до сих пор не доказал что его используешь правильно.


    > >>> т.е. можно пробегать по холсту и смотреть, является
    > ли такая точка частью кривой, а не наоборотЯ не проверяю
    > никаких кривых, я считаю для каждого пиксела собственный
    > синус... Там нету кривых...

    А синус что не кривая?
  • DomiNickDark (08.03.09 23:38) [84]
    > А синус что не кривая?
    Хех... Синус - это периодическая тригонометрическая функция... :)

    Вася, есть нормальный материал по созданию СкринСейвера в Делфи7..? А то решил из своей графики тоже скринсейвер делать, а все найденные исходники глючные какие-то... :(

    P.S. А как ты этот кадр выводишь? Пробовал так?:
    BitBlt(Form1.Canvas.Handle, 0, 0, Form1.Width, Form1.Height, Bit.Canvas.Handle, 0, 0, SRCCOPY);

  • Pavia © (09.03.09 01:37) [85]

    > Вася, есть нормальный материал по созданию СкринСейвера
    > в Делфи7..? А то решил из своей графики тоже скринсейвер
    > делать, а все найденные исходники глючные какие-то... :(

    У меня где-то был.
    Минимальный это просто переименовать exe в scr и растянуть форму на весь экран и стиль применить . И по движению мыши и нажатию клавишы выходить.

    Набросал простой пример. FPS ограничен таймером мне быстрее просто не нужно было.

    Неплохая плазма получилась, прям как в ламе.
    http://slil.ru/27034240
  • Вася (09.03.09 22:57) [86]
    Э... А объясните как это работает, пожалуйста...


    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)]{-SinTable1[c and (2048-1)]}+128*256) shr 8;
               p[i*3+2]:=(CosTable2[(j ) and (2048-1)]{-SinTable1[c and (2048-1)]}+128*256) shr 8;
               end;
         Inc(DWord(p),LL);
         end;
    end;



    Почему ScanLine делается только для нулевой (первой) строки, что есть "PByteArray" и что за странные индексы такие - "p[i*3+0]"...

    >>> А ты до сих пор не доказал что его используешь правильно

    Ну так покажите, как правильно... :))
  • Vetal (09.03.09 23:39) [87]

    > Почему ScanLine делается только для нулевой (первой) строки


    Определяется сдвиг LL на который и инкрементируется указатель - р (Inc(DWord(p),LL)).


    > что за странные индексы такие - "p[i*3+0]"


    Незабываем, что 24 бит изображение состоит из трёх компонент - R, G, B.
  • Pavia © (10.03.09 01:31) [88]

    > Э... А объясните как это работает, пожалуйста...

    Как напичанно так и работает. Чистая импровизация.
    В  CosTable1 предварительно вычесленные значения. shr 8 нужно для округления так как использую формат с фиксированной точкой. Нужно для оптимизации.


    > ScanLine делается только для нулевой (первой) строки

    Так захотелось особенно плюсов недает экономью на вызовах.

    PByteArray это основной тип, про него все написанно в справке. Можно и свой тип определить.


    > за странные индексы такие - "p[i*3+0]"
    А чего тут странного? У меня формат битмепа 24битный.
    Только напомню что цвета идут в порядке B G R. И строки в обратном порядке. Поэтому LL отрицательное. И из завыравнивания отличается от -Width*3.


    > Ну так покажите, как правильно... :))

    В интернете по этому делу полно статей.
  • DomiNickDark (11.03.09 21:07) [89]

    > Как напичанно так и работает. Чистая импровизация.


    Pavia, твоя импровизация?) Можешь ещё сымпровизировать?))

    А я тогда померяю, как быстрее будет...))

    P.S. СкринСейвер хороший, а вот как сделать, чтоб он в "предпросмотре" показывался?
  • Вася (12.03.09 22:24) [90]
    >>> В интернете по этому делу полно статей

    Ага... Например эта... Просто не хотите помочь?..

    Может хоть кто-то рассказать варианты от простого к сложному?.. :(
  • Pavia © (12.03.09 23:18) [91]

    > Ага... Например эта... Просто не хотите помочь?.

    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. Программирование компьютерной графики

    Так что это вы сами не хотите себе помочь.


    > Может хоть кто-то рассказать варианты от простого к сложному?
    > .. :(
    Это не школа. Нужно самому учиться. Вот если есть конкретные вопросы то на них можно ответиь.
  • Вася (13.03.09 22:15) [92]
    Я спрашивал про самый быстрый способ нарисования изображения попиксельно на Canvas...
    Без использования всяких OpenGL...

    Не знаете - так и скажите...

    :(
  • @!!ex © (13.03.09 23:29) [93]
    > P.S. СкринСейвер хороший, а вот как сделать, чтоб он в "предпросмотре"
    > показывался?

    Гугл знает.
    Если вкратце, то скринсейвер запускается со спец ключом и хэндлом окна на котором рисовать предпросмотр.


    > [92] Вася   (13.03.09 22:15)
    > Я спрашивал про самый быстрый способ нарисования изображения
    > попиксельно на Canvas...
    > Без использования всяких OpenGL...
    >
    > Не знаете - так и скажите...

    Бред. Как связан расчет косинуса со скоростью вывода пикселей на кэнвас?
    1) В любом месте и везде вам скажут использовать OGL или D3D для этих целей(могут еще DDraw посоветовать, но это смысла не имеет).
    2) Если так хочеться считать всякую хрень, то лучше пиксели хранить в отдельном массиве, считать там, а потом через сканлайн вываливать блоки. Буде быстрее. Правда не на много.
    3) Переделайте нафиг архитектуру и методику расчета. Ибо любой тормозящий скринсейвер идет в трэш.
  • Pavia © (13.03.09 23:36) [94]

    > Я спрашивал про самый быстрый способ нарисования изображения
    > попиксельно на Canvas...Без использования всяких OpenGL.
    > ..Не знаете - так и скажите...

    Математика она и в африке математика и в OpenGL таже самая математика.


    > Не знаете - так и скажите...:(

    Не хочешь учится так и скажи. B)
  • DomiNickDark (16.03.09 01:49) [95]

    > Гугл знает.
    > Если вкратце, то скринсейвер запускается со спец ключом
    > и хэндлом окна на котором рисовать предпросмотр.


    Про спец ключи я знаю...
    У меня есть множество готовых исходников на Делфи 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;

  • DomiNickDark (16.03.09 02:19) [96]
    Вариант №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"... :)
  • DomiNickDark (16.03.09 02:32) [97]
    Пробовал вариант от 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"... :(
  • @!!ex © (16.03.09 08:09) [98]
    > [95] DomiNickDark   (16.03.09 01:49)
    > Про спец ключи я знаю...

    Тогда мне не понятна проблема. :)
  • Sapersky (16.03.09 14:05) [99]
    но он оказался чуть медленнее, чем "Вариант №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 он никакого отношения не имеет), ну и масса других классов/библиотек...
 
Конференция "Игры" » Быстрый канвас [Delphi, Windows, ХР]
Есть новые Нет новых   [134427   +38][b:0.001][p:0.003]