Delphi - рисование ( Image>Paintbox>dxpaintbox>dxdraw )

Mulder

Member
Joined
Jul 17, 2004
Messages
50
Reaction score
0
Age
64
Требуеться помощь. В рисование графики в своей програме. Перепробовал след. компоненты: Image > Paintbox > DXPaintbox > DXDraw. Один другого работает быстрей, но все равно, моргает. Все вроде пишут использовать DXDraw. Но он у меня МОРГАЕТ:eek: . Почему? Что я не так делаю.
Компонент DXDraw стоит на Panel, она на форме. Рисую в памяти на Bitmap потом нужный кусок отрисовываю на DXDraw.
 

Mulder

Member
Joined
Jul 17, 2004
Messages
50
Reaction score
0
Age
64
Нет, на данный момент только 2D-графика.
 

Mulder

Member
Joined
Jul 17, 2004
Messages
50
Reaction score
0
Age
64
Так подскажет кто-нибудь. Может ссылку какую подкините.
 

xaxulin

Member
Joined
Jan 24, 2004
Messages
17
Reaction score
18
Age
47
Location
russia
Уточни в чем проблема....Если только 2D, тогда зачем тебе DXDraw нужен? Создай в памяти Bitmap и рисуй в нем потом отрисовывай его в своем Image. Мерцания не будет.
 

tobefree

Member
Joined
Apr 24, 2007
Messages
11
Reaction score
4
Age
36
Location
Москва
Doublebuffered как то так свойство называется.... поставь его в тру.
 

ploki

Member
Joined
May 16, 2005
Messages
237
Reaction score
180
Location
Москва
А что понимается под морганием - мерцание или просто низкая частота кадров?

Если скорость не важна, достаточно просто отрисовывать bitmap через BitBlt.

Если частоты кадров не хватает, надо смотреть, как весь процесс отрисовки организован. Лучше всего по таймеру (только не обычному, а, например, mmtime) организовать вывод в контекст DirectDraw. Но всё зависит от того, что рисуется...
 

disas

Member
Joined
Nov 16, 2004
Messages
32
Reaction score
0
Age
39
Что бы не моогало давно уже придуман способ - рисовать надо не на самом изображении а на его копии в буфере (в досе это переключение страниц видео памяти например). После окончания отрисовки картинку меняем и т.д.
 

Mulder

Member
Joined
Jul 17, 2004
Messages
50
Reaction score
0
Age
64
Ничего не пониманию. На image долго выводить. По морганием понимается, что картинка целиком или полосами мигает, заметно исчезновение картинки, хотя я ее никуда не деваю.
Doublebuffered пробовал, как не странно не помагает.
А рисую я сначало в памяти.
 

Mulder

Member
Joined
Jul 17, 2004
Messages
50
Reaction score
0
Age
64
На данный момент мне надо только 2D-графика, бес анимации. Я хачу отрисовывать данные что бы делать это как я хочу, раньше я выводил данные на stringgrid.

Значит есть 3 массива, один ( mastexx_text ) содержит в себе текстовую информацию, другое ( mastexx_param ) параметры, третий ( mastexx_area ) - координаты. С использованием всех этих данных я отрисовываю таблицу в памяти и вывожу на экран. Фигня конечно, но я хочу отрисовать все самостоятельно.

Code:
  if mastexx_param[global_x{+1},global_y{+1},6]='AB' then begin
   bmp_drawtexx.Canvas.TextOut( strtoint(mastexx_area[x2{+1},y2{+1},0])
           + (strtoint(mastexx_area[x2{+1},y2{+1},2]) div 2 - bmp_drawtexx.Canvas.TextWidth(mastexx_text[x2,y2]) div 2),
   strtoint(mastexx_area[x2{+1},y2{+1},1]), mastexx_text[x2,y2] );
  end;

mastexx_param и mastexx_area это массивы.
bmp_drawtexx это bitmap в памяти на котором все рисуеться

Code:
                      dxdraw1.Surface.Canvas.CopyRect(Rect
(global_x3,global_y3,panel2.Width,panel2.Height)
          ,bmp_drawtexx.Canvas
          ,Rect(0,0,panel2.Width-global_x3,panel2.Height-global_y3));

и выводим
Code:
dxdraw1.Surface.Canvas.Release;

Может просто надо какую-то другую команду использовать. На image медленно. А с dxdraw я работаю в первый раз.
 
Last edited by a moderator:

ploki

Member
Joined
May 16, 2005
Messages
237
Reaction score
180
Location
Москва
Самый простой способ.

Пусть bmp_drawtexx - Ваш TBitMap, w и h - его ширина и высота.
Пусть у Вас создана процедура DrawTable(ACanvas: TCanvas), которая рисует на произвольном холсте ACanvas Ваше актуальное изображение.
На форму достаточно кинуть TPaintBox (пусть его имя - PB).

Тогда обработчик события OnPaint объекта PB выглядит так:
Code:
procedure TForm1.PBPaint(Sender: TObject);
begin
  if assigned(bmp_drawtexx) then begin
    DrawTable(bmp_drawtexx.canvas);
    bitblt(PB.Canvas.Handle, 0, 0, w, h, bmp_drawtexx.Canvas.Handle, 0, 0, SRCCOPY);
  end;
end;

Понятно, что w и h лучше делать равными размерам PB (например, в событии OnResize, правда, у PB такого события нет, поэтому PB кладётся на что-нибудь, у чего такое событие есть (например, TPanel) и выравнивается по контейнеру).
 

Mulder

Member
Joined
Jul 17, 2004
Messages
50
Reaction score
0
Age
64
А через процедуру что быстрей, чем например если под кнопку? Попробовал bitbtl с dxdraw эффект тот же - моргает. Моргает - то есть на фоне dxdraw появляються черные горизонтальные полосы по 100-150 px. Что за...? А как например браузер выводит на экран страницу, там же куча графики.
 
Last edited by a moderator:

ploki

Member
Joined
May 16, 2005
Messages
237
Reaction score
180
Location
Москва
Ещё никто никогда не сталкивался с мерцанием при выводе из буфера через BitBlt. Похоже, проблема в чём-то ещё.
Попробуйте не использовать "dxdraw".
DirectX конечно, обеспечит более быструю отрисовку, но им надо уметь пользоваться.
 

Mulder

Member
Joined
Jul 17, 2004
Messages
50
Reaction score
0
Age
64
Попробуем, через пару дней напишу
 

Mulder

Member
Joined
Jul 17, 2004
Messages
50
Reaction score
0
Age
64
Так на paintbox пусть и несильное но общее моргание картинки.
 

Mulder

Member
Joined
Jul 17, 2004
Messages
50
Reaction score
0
Age
64
Так ВРОДЕ пошло. Сначало в памяти потом методом Bitbtl ( спасибо, нормально работает ) на paintbox вывожу нужный кусок. Моргание убралось после перестановки койкакого кода местами, головой думать надо. Ну посмотрим что будет дальше. А как вообще память расходуеться при таком методе, не слишком?
 

xaxulin

Member
Joined
Jan 24, 2004
Messages
17
Reaction score
18
Age
47
Location
russia
Убери из отрисовки:
- strtoint(), лучше держи в памяти готовый массив INT-ЗНАЧЕНИЙ;
- сравнение с текстовой строкой 'AB'
- TextWidth - тоже не самая быстрая функция.
Удачи!
 

Mulder

Member
Joined
Jul 17, 2004
Messages
50
Reaction score
0
Age
64
Как убрать? Чем их заменить
 

Mulder

Member
Joined
Jul 17, 2004
Messages
50
Reaction score
0
Age
64
Оператор IF вроде сам по себе медленный, только чем его заменишь.
 
Last edited by a moderator:

ploki

Member
Joined
May 16, 2005
Messages
237
Reaction score
180
Location
Москва
Если mastexx_area - трёхмерный массив, то работать надо только с последним измерением: TmpArr := mastexx_area[x2, y2];

Хранить координаты в виде строк действительно нехорошо.

bmp_drawtexx.Canvas можно оптимизировать с использованием with.

Примерно так получится:
Code:
with bmp_drawtexx.Canvas do begin
  if mastexx_param[global_x, global_y,6]='AB' then begin
    TmpArr := mastexx_area[x2, y2];
    TextOut(TmpArr[0] + (TmpArr[2] div 2 - TextWidth(mastexx_text[x2,y2]) div 2),
   TmpArr[1], mastexx_text[x2,y2] );
  end;
end;

Наверняка можно ещё что-нибудь оптимизировать.
 
Top