Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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
1-1170060525
Express
2007-01-29 11:48
2007.03.25
Как динамически создать TStatusBar?


15-1172596623
SamProf
2007-02-27 20:17
2007.03.25
Как сделать WYSIWYG редактор?


15-1173032855
Nij/-\
2007-03-04 21:27
2007.03.25
Ipod nano


15-1172460204
Slider007
2007-02-26 06:23
2007.03.25
С днем рождения ! 23 февраля


2-1172746478
Mashenka_84
2007-03-01 13:54
2007.03.25
создание файла