Форум: "Игры";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
ВнизБлиттинг Найти похожие ветки
← →
k-man © (2003-12-08 22:20) [0]В моем проекте(игра) есть некоторая(но не основная) часть - графика.
С нею лично я сталкиваюсь серьезно в первый раз посему хотелось бы получить ответы на простые наверное вопросы. Используется DirectX
инфа черпается из всем известной книги Краснова.
Мое приложение оконное, в книге есть глава посвященная моему случаю, там демонстрируется пример блиттинга растра на основную поверхность
которая находится на самой форме. Мне нужно чтобы блиттинг осуществлялся не на саму форму а на панель, если это возможно. Пробовал при установке уровня кооперации указывать не Хэндл формы а хэндл панели - неудача.
Подскажите что нужно делать.
← →
k-man © (2003-12-08 22:20) [0]В моем проекте(игра) есть некоторая(но не основная) часть - графика.
С нею лично я сталкиваюсь серьезно в первый раз посему хотелось бы получить ответы на простые наверное вопросы. Используется DirectX
инфа черпается из всем известной книги Краснова.
Мое приложение оконное, в книге есть глава посвященная моему случаю, там демонстрируется пример блиттинга растра на основную поверхность
которая находится на самой форме. Мне нужно чтобы блиттинг осуществлялся не на саму форму а на панель, если это возможно. Пробовал при установке уровня кооперации указывать не Хэндл формы а хэндл панели - неудача.
Подскажите что нужно делать.
← →
Sapersky © (2003-12-09 10:05) [1]Посмотреть параметры Blt или BltFast, которыми выводится растр, и указать правильный destination rect или просто dx,dy - в зависимости от текущего положения/размера панели.
Чтобы оконное приложение работало полностью корректно (не рисовало поверх других окон при частичном перекрытии ими, например), нужно создавать клиппер (IDirectDrawClipper) и выводить на экран Blt"ом. У Краснова наверняка есть примеры.
← →
Sapersky © (2003-12-09 10:05) [1]Посмотреть параметры Blt или BltFast, которыми выводится растр, и указать правильный destination rect или просто dx,dy - в зависимости от текущего положения/размера панели.
Чтобы оконное приложение работало полностью корректно (не рисовало поверх других окон при частичном перекрытии ими, например), нужно создавать клиппер (IDirectDrawClipper) и выводить на экран Blt"ом. У Краснова наверняка есть примеры.
← →
k-man © (2003-12-09 12:18) [2]
> Посмотреть параметры Blt или BltFast, которыми выводится
> растр, и указать правильный destination rect или просто
> dx,dy - в зависимости от текущего положения/размера панели.
А что должно хранится в этой структуре. Координаты панели на форме или на экране?
> У Краснова наверняка есть примеры.
Есть, но не работает. То есть с формой работает а с панелью нет.
← →
k-man © (2003-12-09 12:18) [2]
> Посмотреть параметры Blt или BltFast, которыми выводится
> растр, и указать правильный destination rect или просто
> dx,dy - в зависимости от текущего положения/размера панели.
А что должно хранится в этой структуре. Координаты панели на форме или на экране?
> У Краснова наверняка есть примеры.
Есть, но не работает. То есть с формой работает а с панелью нет.
← →
Sapersky © (2003-12-09 13:18) [3]На экране (т.е. всё в экранных координатах). DirectDraw не подозревает о существовании форм, да и окна учитывает только в том случае, если включить клиппер.
У Blt нужный параметр - первый TRect (точнее, PRect), прямоугольник, в который вписывается исходный растр (может масштабировать, если есть ускоритель, то с фильтрацией, иначе вызывает StretchDraw).
У BltFast - просто координаты точки - место, куда попадёт верхний-левый угол изображения.
← →
Sapersky © (2003-12-09 13:18) [3]На экране (т.е. всё в экранных координатах). DirectDraw не подозревает о существовании форм, да и окна учитывает только в том случае, если включить клиппер.
У Blt нужный параметр - первый TRect (точнее, PRect), прямоугольник, в который вписывается исходный растр (может масштабировать, если есть ускоритель, то с фильтрацией, иначе вызывает StretchDraw).
У BltFast - просто координаты точки - место, куда попадёт верхний-левый угол изображения.
← →
k-man © (2003-12-09 16:18) [4]
> На экране (т.е. всё в экранных координатах). DirectDraw
> не подозревает о существовании форм, да и окна учитывает
> только в том случае, если включить клиппер.
А как получить экранные координаты панели?
← →
k-man © (2003-12-09 16:18) [4]
> На экране (т.е. всё в экранных координатах). DirectDraw
> не подозревает о существовании форм, да и окна учитывает
> только в том случае, если включить клиппер.
А как получить экранные координаты панели?
← →
NikeOLD (2003-12-09 16:30) [5]Короче, если ты читал не только главу о 2D, то наверняка пропустил сведения в которых сказано, что DirectDraw не умеет делать блиттинг как Direct3D в окнах (т.е. в любых объектах, имеющих дескриптор окна). Это значит, что ты не сможешь в DirectDraw делать блиттинг в панель. При использовании клипперов задача вроде бы реализуема, но это не так, результат один - вывод на первичную поверхность. Это будет закрывать остальные окна, поэтому-то у Краснова и сделана минимизация окна при деактивации приложения. Можно вместо минимизации отключать рендеринг и выдавать просто черный экран.
Если хочешь делать блиттинг в окно, используй Direct3D. Это тоже есть у Краснова. По другому не получиться. Во всяком случае простым путем в одну-две команды ты не уложишься, я от этого вовсе отказался. Вообще у Краснова четко сказано, что нерекомендуется использовать стандартные VCL и DirectDraw одновременно.
> А как получить экранные координаты панели?
На память не помню. ClientToScreen - метод объекта, или API так же называется.
← →
NikeOLD (2003-12-09 16:30) [5]Короче, если ты читал не только главу о 2D, то наверняка пропустил сведения в которых сказано, что DirectDraw не умеет делать блиттинг как Direct3D в окнах (т.е. в любых объектах, имеющих дескриптор окна). Это значит, что ты не сможешь в DirectDraw делать блиттинг в панель. При использовании клипперов задача вроде бы реализуема, но это не так, результат один - вывод на первичную поверхность. Это будет закрывать остальные окна, поэтому-то у Краснова и сделана минимизация окна при деактивации приложения. Можно вместо минимизации отключать рендеринг и выдавать просто черный экран.
Если хочешь делать блиттинг в окно, используй Direct3D. Это тоже есть у Краснова. По другому не получиться. Во всяком случае простым путем в одну-две команды ты не уложишься, я от этого вовсе отказался. Вообще у Краснова четко сказано, что нерекомендуется использовать стандартные VCL и DirectDraw одновременно.
> А как получить экранные координаты панели?
На память не помню. ClientToScreen - метод объекта, или API так же называется.
← →
Sapersky © (2003-12-09 16:30) [6]Panel.ClientToScreen
← →
Sapersky © (2003-12-09 16:30) [6]Panel.ClientToScreen
← →
k-man © (2003-12-09 18:58) [7]Честно говря я довольно отрывисто читаю книгу, но ведь судя по названию
Direct3D используется для построения 3Д объектов, а мне то всего лишь блиттинг сделать..
> Вообще у Краснова четко сказано, что нерекомендуется использовать
> стандартные VCL и DirectDraw одновременно.
Но ведь объект формы - есть объект VCL, и с ней все работает
А может мне просто отчертить панель визуально не используя компонент?
То есть сделать блиттинг только на часть формы.
← →
k-man © (2003-12-09 18:58) [7]Честно говря я довольно отрывисто читаю книгу, но ведь судя по названию
Direct3D используется для построения 3Д объектов, а мне то всего лишь блиттинг сделать..
> Вообще у Краснова четко сказано, что нерекомендуется использовать
> стандартные VCL и DirectDraw одновременно.
Но ведь объект формы - есть объект VCL, и с ней все работает
А может мне просто отчертить панель визуально не используя компонент?
То есть сделать блиттинг только на часть формы.
← →
NikeOLD (2003-12-09 23:04) [8]
> Но ведь объект формы - есть объект VCL, и с ней все работает
Видишь ли, там в самых первых пример есть пример с кружком. Не помню на память номер. При изменении размеров формы менее размеров кружка, кружок не обрезается, а выводиться прямо на рабочий стол. Вот тебе и весь фокус.
Правда у того же Краснова есть примеры на построение Clipper"а. Я не пробовал применять клиппер для примера с этим кружком, но думаю эффекта не будет.
Краснов ставит клиппер на первичную поверхность. А ты замечал, что при выходе спрайта за пределы поверхности бакбуффера, он вовсе перестает отображаться. В этом месте Краснов делает искусственное обрезание спрайта, размеры видимой области спрайта высчитывает. Мне кажется (я делаю именно так и не имею проблем), имеет смысл ставить клиппер и на первичную поверхность (на всякий случай) и на бакбуффер (чтобы проблем с отрисовкой части спрайта было меньше). Однако метод, который используется для постановки клиппера на первичную поверхность совершенно неподходит для бакбуффера. Если хочешь подробности - пиши на мыло, я здесь редкий гость.
> А может мне просто отчертить панель визуально не используя
> компонент?
> То есть сделать блиттинг только на часть формы.
Без клипперов не обойдешься. К тому же клиппер на первичную поверхность у тебя не получиться сделать так, как это далает Краснов с целым окном. Придется мудрить. К тому же, подозреваю проблему в следующем, когда ты будешь таскать свое окно по экрану клиппер тоже надо будет переставлять на новое место (не уверен - поробуй). А в случае с уменьшением размеров формы клиппер будешь уменьшать? Подробнее Краснов гл.3, стр. 113-115 "Оконные приложения"
Если честно, то я от этих проблем ушел - размер формы не меняется, блиттинг на всю форму.
Пиши лучше на мыло вместе разбираться будем. Мне и самому когда-то начинать приходилось, не могу сказать что проффи в 2D, все времени не хватает.
Если обрисуешь вкратце задачу, может что еще подскажу.
← →
NikeOLD (2003-12-09 23:04) [8]
> Но ведь объект формы - есть объект VCL, и с ней все работает
Видишь ли, там в самых первых пример есть пример с кружком. Не помню на память номер. При изменении размеров формы менее размеров кружка, кружок не обрезается, а выводиться прямо на рабочий стол. Вот тебе и весь фокус.
Правда у того же Краснова есть примеры на построение Clipper"а. Я не пробовал применять клиппер для примера с этим кружком, но думаю эффекта не будет.
Краснов ставит клиппер на первичную поверхность. А ты замечал, что при выходе спрайта за пределы поверхности бакбуффера, он вовсе перестает отображаться. В этом месте Краснов делает искусственное обрезание спрайта, размеры видимой области спрайта высчитывает. Мне кажется (я делаю именно так и не имею проблем), имеет смысл ставить клиппер и на первичную поверхность (на всякий случай) и на бакбуффер (чтобы проблем с отрисовкой части спрайта было меньше). Однако метод, который используется для постановки клиппера на первичную поверхность совершенно неподходит для бакбуффера. Если хочешь подробности - пиши на мыло, я здесь редкий гость.
> А может мне просто отчертить панель визуально не используя
> компонент?
> То есть сделать блиттинг только на часть формы.
Без клипперов не обойдешься. К тому же клиппер на первичную поверхность у тебя не получиться сделать так, как это далает Краснов с целым окном. Придется мудрить. К тому же, подозреваю проблему в следующем, когда ты будешь таскать свое окно по экрану клиппер тоже надо будет переставлять на новое место (не уверен - поробуй). А в случае с уменьшением размеров формы клиппер будешь уменьшать? Подробнее Краснов гл.3, стр. 113-115 "Оконные приложения"
Если честно, то я от этих проблем ушел - размер формы не меняется, блиттинг на всю форму.
Пиши лучше на мыло вместе разбираться будем. Мне и самому когда-то начинать приходилось, не могу сказать что проффи в 2D, все времени не хватает.
Если обрисуешь вкратце задачу, может что еще подскажу.
← →
Sapersky © (2003-12-10 12:27) [9]2NikeOLD
А ты замечал, что при выходе спрайта за пределы поверхности бакбуффера, он вовсе перестает отображаться
Про бэкбуфер в данном случае вообще речи не шло. Вопрос был насчёт "блиттинга растра на основную поверхность". Другое дело, насколько это правильно, но - мало ли - может, человек хочет, чтобы программа запускалась на S3 c 1 Mb памяти :)
Поэтому достаточно поставить клиппер на первичную поверхность и присоединить его же к handle панели, что-то вроде этого:
If not DDCheck("CreateClipper:", FDD7.CreateClipper(0, FClipper, nil)) then Exit;
If not DDCheck("SetHwnd:", FClipper.SetHWnd(0, FWHandle)) then Exit;
If not DDCheck("SetClipper:", FPrimarySurface.SetClipper(FClipper)) then Exit;
Да и вообще для начала можно проигнорировать проблему рисования поверх других окон (не рисовать в неактивном состоянии - кто будет во время игры таскать над её окном другие окна? Или рисовать, но только надпись "paused" через GDI). В этом случае достаточно просто выставить нужные параметры в Blt/BltFast.
А ты загрузил несчастного :)
← →
Sapersky © (2003-12-10 12:27) [9]2NikeOLD
А ты замечал, что при выходе спрайта за пределы поверхности бакбуффера, он вовсе перестает отображаться
Про бэкбуфер в данном случае вообще речи не шло. Вопрос был насчёт "блиттинга растра на основную поверхность". Другое дело, насколько это правильно, но - мало ли - может, человек хочет, чтобы программа запускалась на S3 c 1 Mb памяти :)
Поэтому достаточно поставить клиппер на первичную поверхность и присоединить его же к handle панели, что-то вроде этого:
If not DDCheck("CreateClipper:", FDD7.CreateClipper(0, FClipper, nil)) then Exit;
If not DDCheck("SetHwnd:", FClipper.SetHWnd(0, FWHandle)) then Exit;
If not DDCheck("SetClipper:", FPrimarySurface.SetClipper(FClipper)) then Exit;
Да и вообще для начала можно проигнорировать проблему рисования поверх других окон (не рисовать в неактивном состоянии - кто будет во время игры таскать над её окном другие окна? Или рисовать, но только надпись "paused" через GDI). В этом случае достаточно просто выставить нужные параметры в Blt/BltFast.
А ты загрузил несчастного :)
← →
Sapersky © (2003-12-10 12:37) [10]В этом случае достаточно просто выставить нужные параметры в Blt/BltFast.
Комментарий к самому себе :) - не совсем достаточно, если окно частично вылезет за пределы экрана, блиттинг работать не будет. Тут - на выбор - либо показываем надпись "вытащи окно из-за экрана, идиот", либо клиппер, либо отсечение вручную. В последнем варианте, кстати, ничего сложного нет, вот, например:
function MakeClip(Var dRect, sRect : TRect; Const vpRect : TRect): Boolean;
// dRect - прямоугольник приёмника
// sRect - прямоугольник источника
// vpRect - прямоугольник области отсечения
// результат - False, если совсем ничего не видно (рисовать не надо)
// при попадании на границу нужным образом модифицируются sRect и dRect
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;
← →
Sapersky © (2003-12-10 12:37) [10]В этом случае достаточно просто выставить нужные параметры в Blt/BltFast.
Комментарий к самому себе :) - не совсем достаточно, если окно частично вылезет за пределы экрана, блиттинг работать не будет. Тут - на выбор - либо показываем надпись "вытащи окно из-за экрана, идиот", либо клиппер, либо отсечение вручную. В последнем варианте, кстати, ничего сложного нет, вот, например:
function MakeClip(Var dRect, sRect : TRect; Const vpRect : TRect): Boolean;
// dRect - прямоугольник приёмника
// sRect - прямоугольник источника
// vpRect - прямоугольник области отсечения
// результат - False, если совсем ничего не видно (рисовать не надо)
// при попадании на границу нужным образом модифицируются sRect и dRect
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;
← →
k-man © (2003-12-10 16:07) [11]Ух, спасибо что загрузили таким кол-вом пищи для моего графически неискушенного ума :)
Уточняю: примем что форма по экрану не ездит и размеры не меняются. Потому как если надо будет потом буду мудрить. После некоторых среднепродолжительных исследовательных работ удалось сделать блиттинг не на всю форму, а только на ее часть. Для этого я при установке уровня кооперации с указал хэндл панели, а не формы. А в координатах - координаты панели. Но появилась новая проблема:
Дело в том что если указать координаты панели на экране то рисунок полностью скрывается за ней(за панелью). ИМХО ключ тут в том что у клиппера есть процедура установки окна в котором он работает, SetHWND, и по логике там надо указать хэндл панели, но так дядюшка ДайректИкс мне тогда вообще ничего не отображает. В принципе на это можно было бы начхать, ведь я нашел способ частичного блиттинга, но я настырный и хотелось бы чтобы импенно на панель. :))
← →
k-man © (2003-12-10 16:07) [11]Ух, спасибо что загрузили таким кол-вом пищи для моего графически неискушенного ума :)
Уточняю: примем что форма по экрану не ездит и размеры не меняются. Потому как если надо будет потом буду мудрить. После некоторых среднепродолжительных исследовательных работ удалось сделать блиттинг не на всю форму, а только на ее часть. Для этого я при установке уровня кооперации с указал хэндл панели, а не формы. А в координатах - координаты панели. Но появилась новая проблема:
Дело в том что если указать координаты панели на экране то рисунок полностью скрывается за ней(за панелью). ИМХО ключ тут в том что у клиппера есть процедура установки окна в котором он работает, SetHWND, и по логике там надо указать хэндл панели, но так дядюшка ДайректИкс мне тогда вообще ничего не отображает. В принципе на это можно было бы начхать, ведь я нашел способ частичного блиттинга, но я настырный и хотелось бы чтобы импенно на панель. :))
Страницы: 1 вся ветка
Форум: "Игры";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.034 c