Текущий архив: 2003.02.06;
Скачать: CL | DM;
ВнизВстроенный ASM Найти похожие ветки
← →
Холод (2002-11-21 12:31) [0]Господа!Как с помощью встроенного асма в делфях нарисовать на битмаре какую-нибудь фигуру (ромб,квадрат и т.д)???
← →
Anatoly Podgoretsky (2002-11-21 12:35) [1]Зачем тебе это, нормально делается без всякого АСМ
← →
Холод (2002-11-24 00:19) [2]Просто на асме быстрее работает
← →
sniknik (2002-11-24 01:10) [3]в виндах? это вряд ли у тебя получится (быстрее в смысле)
← →
Anatoly Podgoretsky (2002-11-24 10:33) [4]Быстрее если очень хорошо знаешь ассемблер, и медленне если наоборот. А ты явно не очень.
← →
apay (2002-11-24 23:47) [5]не известно что быстрее... компилятор вроде имеет встроенный оптимизатор кода, а на асме башкой оптимизировать надо, а здесь без знания архитектуры проца далеко не уедешь. а работа с графикой в виндах - ну выиграешь в лучшем случае пару миллисекунд, и что? остальное винда тормозить будет!
← →
Ihor Osov'yak (2002-11-25 10:01) [6]
> Как с помощью встроенного асма в делфях нарисовать на битмаре
> какую-нибудь фигуру (ромб,квадрат и т.д)???
Так же, как в паскале(делфи) - путем вызова соотв. функций.
← →
BJValentine (2002-11-25 18:50) [7]Да это же бред! Винда пользуется драйвером для видео карты. Лучше чем драйвер врятли можно отрисовать что нибудь путём АСМА. Тем более, что в картах современных есть процессор, который довольно таки не хило растормаживает систему и быыыстро рисует и выполняет манипуляцию видео данными.
← →
apay (2002-11-26 00:44) [8]2 BJValentine
никто и не говорит про работу с картой напрямую :)
(тут еще и драйверок для работы с портами/прерываниями писать)
как я понял, говорится про вызов апишных ф-ии на асме. если не так, то сам вопрос не имеет смысла :)
← →
Юрий Зотов (2002-11-26 09:02) [9]> Просто на асме быстрее работает
На Асме, или нет, но все равно задача сведется к вызову какой-то функции GDI (BitBlt, StretchBlt и пр). Вот она-то (само собственно рисование) и съест 99% времени. Так что Асм здесь практически ничего не даст. Если надо получить быстрое рисование, то, вероятно, придется использовать не GDI, а что-то типа DirectX.
← →
int64 (2002-11-26 10:46) [10]Вот пример попиксельного рисования на Асме. Других причин использования Асма в рисовании, как именно попиксельного, не вижу. (Разве что, что-то типа GetPixel или Fill)
TFrame = class
private
Bitmap : HBitmap;
lpvbits : Pointer;
Bitmapinfo : PBitmapinfo;
FWidth : integer;
FHeight : integer;
FSize : integer;
FLineLen : integer;
public
constructor Create(ACanvas:TCanvas;Width,Height:integer);
destructor Destroy;override;
function Draw(ACanvas:TCanvas;X,Y:integer):integer;
procedure Plot(X,Y,Color:integer);
end;
........
constructor TFrame.Create(ACanvas:TCanvas;Width,Height:integer);
var LineAdj:integer;
begin
FWidth := Width;
FHeight := Height;
FLineLen := 3*Width;
LineAdj := FLineLen and 3;
LineAdj := 4 - LineAdj;
LineAdj := LineAdj and 3;
FLineLen := FLineLen + LineAdj;
FSize := FLineLen * FHeight;
New(Bitmapinfo);
with Bitmapinfo^.bmiHeader do
begin
bisize := 40;
biWidth := Width;
biHeight := Height;
biPlanes := 1;
biBitCount := 24;
biCompression := BI_RGB;
biSizeImage := FSize;
biXPelsPerMeter := 0;
biYPelsPerMeter := 0;
biClrUsed := 0;
biClrImportant := 0;
end;
Bitmap := CreateDIBSection(ACanvas.Handle,Bitmapinfo^,
DIB_RGB_COLORS,lpvbits,0,0);
end;
destructor TFrame.Destroy;
begin
DeleteObject(Bitmap);
Dispose(Bitmapinfo);
end;
function TFrame.Draw(ACanvas:TCanvas;X,Y:integer):integer;
begin
StretchDIBits(ACanvas.Handle,X,Y,FWidth,FHeight,0,0,FWidth,FHeight,
lpvbits,Bitmapinfo^,DIB_RGB_COLORS,SRCCOPY);
Result := GetLastError;
end;
procedure TFrame.Plot(X,Y,Color:integer);assembler;
asm
push ebx
mov ebx,[eax].Bitmap
cmp ebx,0
je @plotdone
pop ebx
push ebx
cmp edx,0
jl @plotdone
cmp edx,[eax].FWidth
jge @plotdone
cmp ecx,0
jl @plotdone
cmp ecx,[eax].FHeight
jge @plotdone
push eax
push edx
mov eax,[eax].FLineLen
mul ecx
mov edx,eax
pop ecx
pop eax
add edx,ecx
shl ecx,1
add edx,ecx
add edx,[eax].lpvbits
mov ecx,[edx]
and ecx,0ff000000h
mov ebx,Color
and ebx,0ffffffh
xor ecx,ebx
mov [edx],ecx
@plotdone:
pop ebx
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Frame:TFrame;
X, Y, i: integer;
begin
Frame := TFrame.Create(Self.Canvas,400,300);
for i:= 1 to 10000 do
begin
for x := 0 to 399 do
for y := 0 to 299 do
Frame.Plot(x,y,x*y+i*x);
Frame.Draw(Self.Canvas,10,10);
end;
Frame.Free;
end;
Есть ощущение, что ScanLine всё-таки быстрее. Вот только никак руки не доходят проверить.
← →
Tano (2002-11-26 21:19) [11]To Холод: Еще причина не связываться с этим - встроенная во многие чипы поддержка аппаратной 2D графики (в общем-то не знаю ни одного AGP-адаптера без этого).
Короче, с тех пор, как появились GPU и OEM драйвера для них самое лучшее решение для оптимизации - придумать наиболее оптимальные комбинации вызовов функций рисования.
Я тоже рисовал на ASMе, но это было актуально в эпоху поточечного построения изображения (VESA режимы, линейные буфферы кадра в памяти, быстрое переключение страниц или копирование и т.п.).
Если только ради интереса пробовать, либо строить что-то вроде фрактальных рисунков, тогда см. int64 © (26.11.02 10:46)
← →
Kiber (2002-11-27 03:16) [12]Scanline действительно быстрее, только я не знаю как его с
asm подружить.
← →
int64 (2002-11-28 09:29) [13]
> Scanline действительно быстрее
Одинаково. Вот функция Plot, если её на человеческий язык перевести:
procedure TFrame.Plot(X,Y, Color: integer);
type
TRGB = array[0..2] of Byte;
pRGB = ^TRGB;
var
p: pRGB;
temp: TRGB absolute Color;
begin
p:= lpvbits;
inc(p, Y*FWidth+X);
p^:= temp;
end;
А если вынести за циклp:= lpvbits
(что и есть Scanline), и если писать простоinc(p)
(X,Y всеравно все значения пробегают), будет ещё быстрее.
← →
BODOM (2002-11-29 14:08) [14]Не бери Х""" в голову прочитай журнал "Программист"
об оптимизации кода.
← →
Холод (2002-12-01 14:41) [15]To Int64
>>Есть ощущение, что ScanLine всё-таки быстрее. Вот только никак руки не доходят проверить.
А как рисовать сканлайном в цикле??? Т.е. сканлайн дает нам указатель на строку битмапа, а как потом перемещаться по этой строке и получать следующую?
← →
AngeL B. (2002-12-02 18:46) [16]
> А как рисовать сканлайном в цикле??? Т.е. сканлайн дает
> нам указатель на строку битмапа, а как потом перемещаться
> по этой строке и получать следующую?
Получить через ScanLine указатели на каждую строку. Записать их в массив, а дальше рисовать с использованием относительной адресации.
Однако все же лучше поискать соответствующую функцию. Или писать на паскале. У него щас оптимизатор ну очень хороший.
Страницы: 1 вся ветка
Текущий архив: 2003.02.06;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.011 c