Текущий архив: 2007.03.25;
Скачать: CL | DM;
Вниз
Обрезание (нафиг) Найти похожие ветки
← →
KiberKot © (2006-04-21 22:27) [0]Вот мучаюсь с обрезанием картинок.
Объект, частично попадая за пределы экрана, должен это чатично
обрезать и вывестись без него. Для этого я ввел переменную, которая
наченает увеличиваться, после того, как координаты объекта стали
меньше нуля. Потом в процедуре я обрезаю от картинки кусок,
равный значению этой переменной и вывожу все остальное.
Так же и в другую сторону, т.е. если координаты стали больше предела
экраны.
Правильно ли я это, и вообще, можноли обойтись без обрезания
(а то уже припаило)
← →
Mortem © (2006-04-21 22:29) [1]Зачем обрезаешь? Попробуй без обрезания.
← →
KiberKot © (2006-04-21 23:30) [2]нельзя вроде без обрезания, ошибку выкидывает
← →
Cash © (2006-04-21 23:55) [3]KiberKot © (21.04.06 22:27):
Батенька, это дело хорошо только у равимов получается! :-D
> Правильно ли я это, и вообще, можноли обойтись без обрезания
По моему маленько нет. Ты не по частям обрезай! А просто не отрисовывай
те фигурки, которые всеми сфоими частями за пределами экрана. Обрежит
за тебя девайс, у него это должно быстрее получаться.
> ошибку выкидывает
Какую ошибку??? 8|
← →
KiberKot © (2006-04-22 00:05) [4]
> Cash ©
Девайсто обрезает, но что если фигура у меня на пол экрана (земля), он ее
все скрывает
← →
XProger © (2006-04-22 01:55) [5]Небесные чакры раскрылись, и что-то мне подсказывает, DirectDraw"ом тут пованивает...
← →
KiberKot © (2006-04-22 02:09) [6]
> Небесные чакры раскрылись, и что-то мне подсказывает, DirectDraw"ом
> тут пованивает...
попахивает
← →
KiberKot © (2006-04-22 02:11) [7]а в ОГЛ само обризает , или там бобще не обрезается ?
← →
Don Nikola © (2006-04-22 06:23) [8]Я так делал. Много и страшно, но работает. Может можно проще, не знаю.
function PrepareClipRects(Dest: TImage; DestX,DestY,DestWidth,DestHeight: integer; Src:TImage;SrcX,SrcY,SrcWidth,SrcHeight: integer; var DestRect,SrcRect: TRect): boolean;
begin
Result:=false;
if (Dest=nil)or(Src=nil) then Exit;
if DestX<0 then
begin
DestWidth:=DestWidth+DestX;
SrcX:=SrcX-DestX;
DestX:=0;
end;
if DestY<0 then
begin
DestHeight:=DestHeight+DestY;
SrcY:=SrcY-DestY;
DestY:=0;
end;
if SrcX<0 then
begin
SrcWidth:=SrcWidth+SrcX;
DestX:=DestX-SrcX;
SrcX:=0;
end;
if SrcY<0 then
begin
SrcHeight:=SrcHeight+SrcY;
DestY:=DestY-SrcY;
SrcY:=0;
end;
if (SrcX+SrcWidth)>integer(Src.Width) then SrcWidth:=integer(Src.Width)-SrcX;
if (SrcY+SrcHeight)>integer(Src.Height) then SrcHeight:=integer(Src.Height)-SrcY;
if (DestX+DestWidth)>integer(Dest.Width) then DestWidth:=integer(Dest.Width)-DestX;
if (DestY+DestHeight)>integer(Dest.Height) then DestHeight:=integer(Dest.Height)-DestY;
if SrcWidth>DestWidth then SrcWidth:=DestWidth;
if SrcHeight>DestHeight then SrcHeight:=DestHeight;
if (SrcWidth<=0)or(SrcHeight<=0) then Exit;
DestRect.Left:=DestX;
DestRect.Top:=DestY;
DestRect.Right:=DestX+SrcWidth;
DestRect.Bottom:=DestY+SrcHeight;
SrcRect.Left:=SrcX;
SrcRect.Top:=SrcY;
SrcRect.Right:=SrcX+SrcWidth;
SrcRect.Bottom:=SrcY+SrcHeight;
Result:=true;
end;
← →
Don Nikola © (2006-04-22 06:26) [9]Вывод делал так
procedure DrawImageEx(Dest: TImage; DestX,DestY,DestW,DestH: integer; DestFrame: dword; Src: TImage; SrcX,SrcY,SrcW,SrcH: integer; SrcFrame: dword);
var
SrcRect,DestRect: TRect;
begin
if (not InitOk)or(Dest=nil)or(Dest.Surface=nil)or(Dest.Frames=0)or(Src=nil)or(Src.Surfac e=nil)or(Src.Frames=0)or(PrepareClipRects(Dest,DestX,DestY,DestW,DestH,Src,SrcX, SrcY,SrcW,SrcH,DestRect,SrcRect)=false) then Exit;
if DestFrame>=Dest.Frames then
DestFrame:=DestFrame mod Dest.Frames;
if SrcFrame>=Src.Frames then
SrcFrame:=SrcFrame mod Src.Frames;
inc(DestRect.Top,Dest.Height*DestFrame);
inc(DestRect.Bottom,Dest.Height*DestFrame);
inc(SrcRect.Top,Src.Height*SrcFrame);
inc(SrcRect.Bottom,Src.Height*SrcFrame);
if IDirectDrawSurface7(Dest.Surface).IsLost=DDERR_SURFACELOST then ReloadImage(Dest);
if IDirectDrawSurface7(Src.Surface).IsLost=DDERR_SURFACELOST then ReloadImage(Src);
if GetColorKey(Src)=clOpaque then
IDirectDrawSurface7(Dest.Surface).Blt(@DestRect,IDirectDrawSurface7(Src.Surface) ,@SrcRect,DDBLT_WAIT,nil) else
IDirectDrawSurface7(Dest.Surface).Blt(@DestRect,IDirectDrawSurface7(Src.Surface) ,@SrcRect,DDBLT_WAIT or DDBLT_KEYSRC,nil);
end;
← →
Cash © (2006-04-22 08:11) [10]KiberKot © (22.04.06 02:09) [6]:
Уф... неуж то DD юзаешь! 8[
Лана, на будущее, лучше юзать D3D или OGL (в ортогоне), там есть такие
хорошие штуки, которые называются "областью видового отсечения". Т. е.
все, что не попало в область ViewPort обрезается за ненадобностью.
← →
KiberKot © (2006-04-22 13:39) [11]
> Don Nikola ©
Както у тебя запутано, у меня вроде попроще
// обрезание (пока только с лева)
procedure iRect (Sprite : TBaseSprite);
var
wrkI : Integer;
rcRectOne : TRect;
begin
for wrkI := 0 to MaxObjects - 1 do begin
with Objects[wrkI] do begin
SetRect(rcRectOne, lRect , 158, SpriteWidth , 158 + SpriteHeight );
frmDD.FDDSBack.BltFast(PosX + lrect , PosY, frmDD.FDDSImages,@rcRectOne, DDBLTFAST_WAIT);
end;
end;
end;
// lRect - увеличивается или уменьшается при скрытии за экран
if diks [DIK_RIGHT] and $80 <> 0 then begin
Warrior.Direction := dirRight;
Warrior.PosX := Warrior.PosX + Warrior.Speed;
if (Warrior.PosX >= 640 - Warrior.SpriteWidth)
then begin
Warrior.PosX := 640 - Warrior.SpriteWidth;
for wrkI := 0 to MaxObjects -1 do Objects[wrkI].PosX := Objects[wrkI].PosX - Warrior.Speed;
for wrkI := 0 to MaxObjects - 1 do
if (Objects[wrkI].PosX < 0) and
(Objects[wrkI].PosX + Objects[wrkI].SpriteWidth > 0) then
Objects[wrkI].lRect := Objects[wrkI].lRect + Warrior.Speed;
if lftRect > 630 then begin
for wrkI := 0 to MaxObjects - 1 do Objects[wrkI].PosX:=Objects[wrkI].PosX + Warrior.Speed;
end;
end;
← →
XProger © (2006-04-22 13:44) [12]KiberKot, у тебя проще, а у него работоспособнее... выбирай :)
← →
KiberKot © (2006-04-22 13:49) [13]я упорно пытаюсь понять че там написано, но не че не получается,
дай хотяб расшифровку переменных
← →
Don Nikola © (2006-04-22 19:50) [14]2KiberKot:
function PrepareClipRects(Dest: TImage; DestX,DestY,DestWidth,DestHeight: integer; Src:TImage;SrcX,SrcY,SrcWidth,SrcHeight: integer; var DestRect,SrcRect: TRect): boolean;
Dest - приемник
Src - источник
X,Y,Width,Height - позиция верхнего-левого угла и размеры
DestRect,SrcRect - конечные ограничивающие прямоугольники
begin
Result:=false;
if (Dest=nil)or(Src=nil) then Exit;
Проверяем валидность поверхностей
if DestX<0 then
begin
DestWidth:=DestWidth+DestX;
SrcX:=SrcX-DestX;
DestX:=0;
end;
Если выводим левее приемника, то обрезаем/обновляем позицию как приемника, так и источника.
if DestY<0 then
begin
DestHeight:=DestHeight+DestY;
SrcY:=SrcY-DestY;
DestY:=0;
end;
if SrcX<0 then
begin
SrcWidth:=SrcWidth+SrcX;
DestX:=DestX-SrcX;
SrcX:=0;
end;
if SrcY<0 then
begin
SrcHeight:=SrcHeight+SrcY;
DestY:=DestY-SrcY;
SrcY:=0;
end;
Тоже самое сверху и слева для источника и приемника
if (SrcX+SrcWidth)>integer(Src.Width) then SrcWidth:=integer(Src.Width)-SrcX;
Если слишком справа, то обрезаем.
if (SrcY+SrcHeight)>integer(Src.Height) then SrcHeight:=integer(Src.Height)-SrcY;
if (DestX+DestWidth)>integer(Dest.Width) then DestWidth:=integer(Dest.Width)-DestX;
if (DestY+DestHeight)>integer(Dest.Height) then DestHeight:=integer(Dest.Height)-DestY;
Тоже самое снизу и справа для источника и приемника
if SrcWidth>DestWidth then SrcWidth:=DestWidth;
if SrcHeight>DestHeight then SrcHeight:=DestHeight;
Выбираем минимальную ширину/высоту.
if (SrcWidth<=0)or(SrcHeight<=0) then Exit;
Если все заклипилось, то возвращаем false.
DestRect.Left:=DestX;
DestRect.Top:=DestY;
DestRect.Right:=DestX+SrcWidth;
DestRect.Bottom:=DestY+SrcHeight;
SrcRect.Left:=SrcX;
SrcRect.Top:=SrcY;
SrcRect.Right:=SrcX+SrcWidth;
SrcRect.Bottom:=SrcY+SrcHeight;
Устанавливаем конечные прямоугольники.
Result:=true;
end;
Так как я сейчас немного выпимши, то могу что-то невнятно указать, задай вопрос с указанием строчки и что не понятно, попробую объяснить, но, imho, там ничего сложного нет.
Попробуй нарисовать на бумаге два прямоугольника с частичным перекрытием и все станет ясно.
← →
Mortem © (2006-04-22 20:00) [15]оффтоп (наболело):
Когда вся страна выпивает, обязательно находится парочка алкошей, которые выпимают... Чё за нафиг? ):
← →
Don Nikola © (2006-04-22 20:26) [16]2Mortem:
Прошу прощения что так ужасно исковеркал Великий Русский Язык и тем самым нарушил Вашу гармонию со вселенной. Пошел искать разум и осознание.
Просто сказать "я нажрался на Херсонесе" мне воспитание не позволяет ;)
← →
Don Nikola © (2006-04-22 20:32) [17]оффтоп (наболело):
Когда вся страна пишет смайлы слева направа, обязательно находится парочка кульзизопов которые повернут его по-семитски... Ну и далее по тексту.
Вообще-то указывать на орфографию в инете - дурной тон.
← →
Mortem © (2006-04-22 21:08) [18]Почему парочка? Я один такой! Остальные - плагиаторы, который хуже расстрелать!
ЗЫ. Я не на орфографию указываю, а на идеологию. Плевал я на орфографию... (:
← →
KiberKot © (2006-04-22 22:11) [19]
> Don Nikola © (22.04.06 19:50) [14]
Я свое вроде сделал, но твой способ разберу попозже, так как у меня бошка
боли (пол дня пытался в своем обрезании знаки правильно расставить,
и всетаки методом научного тыка получилось).
Хотя метод уменя ужасно корявый, но переделывать его щас небуду, а то
пол проги прейдется менять. Твоим воспользуюсь следующий раз, хотя
надеюсь не прийдется, т.к. Cash говорит что в d3d методы хорошие есть.
З.Ы. а вообще обрезание это большой геморой
← →
antonn © (2006-04-22 22:38) [20]KiberKot © (22.04.06 22:11) [19]
З.Ы. а вообще обрезание это большой геморой
только с другой стороны %)
← →
Sapersky (2006-04-23 02:10) [21]Автоматизированное отсечение в DDraw есть:
FClipper : IDirectDrawClipper;
FDD7.CreateClipper(0,FClipper,nil));
FClipper.SetHWnd(0,Handle);
FPrimarySurface.SetClipper(FClipper));
// или к бэкбуферу его нужно присоединять - не помню уже
Вариант вручную:
// dRect - прямоугольник в бэкбуфере, sRect - на спрайте, vpRect - прямоугольник бэкбуфера
function Rect_Clip(Var dRect, sRect : TRect; Const vpRect : TRect): Boolean;
Var r : TRect;
begin
Result:=False;
IntersectRect(r,dRect,vpRect);
If IsRectEmpty(r) then Exit;
If not EqualRect(r,dRect) then With sRect do begin
Dec(Left, dRect.Left - r.Left);
Dec(Top, dRect.Top - r.Top);
Dec(Right, dRect.Right - r.Right);
Dec(Bottom, dRect.Bottom - r.Bottom);
dRect:=r;
end;
Result:=True;
end;
Если в результате будет true, подсунуть Blt"у то, что возвратилось в dRect и sRect.
← →
KiberKot © (2006-04-23 02:49) [22]
> Sapersky
Вопрос стоит не втом, как отсеч (это просто). Надо порезать все обекты,
которые выходят за границы экрана при передвижении, а потом выводить
остатки.
А режит и выводит у меня вот:
SetRect(rcRectOne, lRect , NachRect, SpriteWidth - rRect, NachRect + SpriteHeight );
frmDD.FDDSBack.BltFast(PosX + lrect , PosY, frmDD.FDDSImages, @rcRectOne, DDBLTFAST_WAIT);
← →
Sapersky (2006-04-23 14:19) [23]Именно как "порезать" я и имел в виду. В оригинале "clipping". Во всех книжках по DDraw переводится как "отсечение". Ну пусть будет "обрезание", если вам так больше нравится :)
Только искать в и-нете рекомендую всё же по "clipping"... :)
← →
KiberKot © (2006-04-23 14:42) [24]
> Sapersky [23]
Спасибо, учту
← →
Don Nikola © (2006-04-24 11:17) [25]2Mortem: Зайди, пожалуйста, на http://kevan.org/brain.cgi?DonNikola
2Sapersky: Imho, голый код выполниться быстрее, чем до IDDClipper через интерфейсы дойдет. А про IntersectRect я просто забыл, надо чаще хелп читать ;)
← →
Darthman © (2006-04-25 10:54) [26]Решение для DirectDraw есть в моей реализации Turrican TGame (игра и сурсы на моем сайте), ничего обрезать там не надо, просто задать область вывода грамотно. Глянь, может быть пригодится.
← →
Mortem © (2006-04-25 11:08) [27]
> Don Nikola © (24.04.06 11:17) [25]
Больше не кури! (:
← →
KiberKot © (2006-04-25 15:57) [28]
> Darthman ©
С твоим способом отрисобки, разберусь попозже. Щас времени нету, через два
дня здавать игру. Игра почти готова (скоро вылажу), а вот записку к ней так и не написал (опять на перездачу :(((( )
Кстати, как ты карты делал, и в каком формате храниш ? Я все в одном модуле писал
и карту тамже описал.
ЗЫ тормозит сук..........
Страницы: 1 вся ветка
Текущий архив: 2007.03.25;
Скачать: CL | DM;
Память: 0.55 MB
Время: 0.043 c