![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
быстрый доступ к пикселам поверхности [Delphi, Windows]
Xerx © (2004-04-16 18:39:00)Привет! Кто-нить может подсказать, как МАКСИМАЛЬНО БЫСТРО получить указатель на пиксель поверхности IDirectDrawSurface7 по координатам, считать его, преобразовать и засунуть обратно...
И ещё, как можно повернуть картинку быстрее, чем у меня:
function TImageMap.Rotare(Angle: single; Xc, Yc : integer): HRESULT;
var
cosA,
sinA : extended;
x, y,
w, h,
iO,
iP,
jO,
jP : integer;
r : PCardinal;
sur : TDDSURFACEDESC2;
e : extended;
begin
Result := DD_FALSE;
with Rect do
begin
w := Right-Left+1;
h := Bottom-Top+1;
end;
if (Xc=-1) then
Xc := w div 2;
if (Yc=-1) then
Yc := h div 2;
asm
FLD Angle
FSINCOS
FSTP cosA
FSTP sinA
FWAIT
end;
ZeroMemory(@sur, SizeOf(sur));
sur.dwSize := SizeOf(sur);
FSurface.Lock(nil, sur, DDLOCK_WAIT, 0);
for y := h-1 downto 0 do
begin
jP := y - Yc;
for x := w-1 downto 0 do
begin
iP := x - Xc;
asm
fild iO
fld cosA
fmulp st(1),st
fild jO
fld sinA
fmulp st(1),st
fsubp st(1),st
fild Xc
faddp st(1),st
fistp iO
fild iO
fld cosA
fmulp st(1),st
fild jO
fld sinA
fmulp st(1),st
faddp st(1),st
fild Yc
faddp st(1),st
fistp jO
end;
// iO := Xc + trunc(iP * cosA - jP * sinA);
// jO := Yc + trunc(iP * sinA + jP * cosA);
if (iO>=0)and(iO<w)and(jO>=0)and(jO<h) then
begin
r := PCardinal(integer(sur.lpSurface)+y*sur.lPitch+4*x);
r^ := FEffectArray[iO, jO];//точка в массиве, хранящем исходную картинку
end;
end;//for x
end;//for y
Result := FSurface.Unlock(nil);
end;
Нужно вносить изменения ИМЕННО В ПОВЕРХНОСТЬ!!!
cyborg (2004-04-17 20:58:00) [21]Вместо этой глупости, лучше бы осознал свою ошибку.
Запусти свою программу на компьютере с маленьким объёмом оперативной памяти.
miek (2004-04-17 18:31:00) [22]>Когда виндоуз поместит твою поверхность, которая в оперативной памяти, в своп
Никогда не поместит, мой дорогой Ватсон! Попробуйте продемонстрировать (примерчик там написать) свое глубокомысленное заявление.
cyborg (2004-04-17 10:08:00) [23][3] miek © (16.04.04 22:47)
Когда виндоуз поместит твою поверхность, которая в оперативной памяти, в своп, то у тебя выскочит супер эффект от Микрософт, асес виолатион называется.
А если ты размещаешь поверхность в видеопамяти, то при захвате (Lock) поверхности, она с видеопамяти переносится в оперативную, где ты её изменяешь, затем при освобождении (Unlock) она переностися назад в видеопамять, что ты сам и указал "ТОЛЬКО: это должна быть не первичная поверхность." она ведь в видеопамяти находится.
miek (2004-04-16 22:47:00) [24]Ну да. Шоб мэнэ повылазыло! Попробуй сам. Или вот живой пример (без исходников, правда) http://www.miek.narod.ru/spacediver.zip
А на MSDN иногда и положить можно.
VMcL (2004-04-16 21:22:00) [25]>>miek © (16.04.04 20:37) [1]
Да ну?
After retrieving a surface memory pointer, you can access the surface memory until a corresponding IDirectDrawSurface7::Unlock method is called. When the surface is unlocked, the pointer to the surface memory is invalid.
miek (2004-04-16 20:37:00) [26]Не обязательно постоянно лочить-разлочивать. Залочил, получил указатель, разлочил. Дальше и используешь этот указатель. ТОЛЬКО: это должна быть не первичная поверхность.
А насчет поворота посмотри, например, как у меня в SpriteUtils-2. http://www.miek.narod.ru/spriteutils2.zip