Здравствуйте!
Решил сделать сабж в оконном режиме DirectDraw7, для чего завел внеэкранную поверхность (2000х600 пикселей), часть которой при обновлении каждого кадра копирую на первичную поверхность при помощи Blt. Сдвиг делается на 1-4 пикселя, количество кадров 24-48 в секунду.
Проблемы:
1)при большом сдвиге (4 пикселя на кадр) фон двигается рывками (это можно решить увеличивая количество кадров в секунду при сдвиге 1-2 пикселя на кадр),
2)размываются правая и левая граница объектов на фоне (разноцветные круги на синем фоне)
Как этого избежать?
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте! А>Решил сделать сабж в оконном режиме DirectDraw7, для чего завел внеэкранную поверхность (2000х600 пикселей), часть которой при обновлении каждого кадра копирую на первичную поверхность при помощи Blt. Сдвиг делается на 1-4 пикселя, количество кадров 24-48 в секунду. А>Проблемы: А>1)при большом сдвиге (4 пикселя на кадр) фон двигается рывками (это можно решить увеличивая количество кадров в секунду при сдвиге 1-2 пикселя на кадр), А>2)размываются правая и левая граница объектов на фоне (разноцветные круги на синем фоне) А>Как этого избежать?
Clipper включён?
А вообще лучше использовать объекты мозаичного отображения
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте! А>Решил сделать сабж в оконном режиме DirectDraw7, для чего завел внеэкранную поверхность (2000х600 пикселей), часть которой при обновлении каждого кадра копирую на первичную поверхность при помощи Blt. Сдвиг делается на 1-4 пикселя, количество кадров 24-48 в секунду. А>Проблемы: А>1)при большом сдвиге (4 пикселя на кадр) фон двигается рывками (это можно решить увеличивая количество кадров в секунду при сдвиге 1-2 пикселя на кадр), А>2)размываются правая и левая граница объектов на фоне (разноцветные круги на синем фоне) А>Как этого избежать?
Проблема наверное в том, что пикселы — дискретны, а время — нет. Думаю без корректной интерполяции цвета пикселов тут сложно будет.
Я бы сделал это через D3D. Там это всё есть.
Здравствуйте, Александр Сергеевич, Вы писали:
АС>Clipper включён?
Да.
АС>А вообще лучше использовать объекты мозаичного отображения
То есть много маленьких кусочков? А почему это лучше (особенно если они почти все разные)?
Здравствуйте, De Bug, Вы писали:
E>>Я бы сделал это через D3D. Там это всё есть. DB>Объясните поподробнее (хотя бы линк на пример), пожалуйста.
Нужно прочитать в DXSDK и понять как делать следующие вещи:
— Инициализация (создание) D3D устройства в оконном режиме.
— Использование ортогональной проекции.
— Рисование треугольников.
— Создание (загрузка) текстуры.
— Текстурные координаты.
— Рисование текстурированных треугольников.
После этого скролящийся бак можно сделать так:
Перпендикулярно направлению камеры рисуешь прямоугольник из 2-х треугольников, причём прямоугольник должен иметь такой размер, чтоб закрывал весь бакбуффер. На этот прямоугольник натягиваешь часть текстуры бакграунда. Инкрементируешь по времени текстурные координаты. Получается сглаженная скролящаяся картинка.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re: scrolling background
От:
Аноним
Дата:
23.01.06 07:59
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте! А>Решил сделать сабж в оконном режиме DirectDraw7, для чего завел внеэкранную поверхность (2000х600 пикселей), часть которой при обновлении каждого кадра копирую на первичную поверхность при помощи Blt. Сдвиг делается на 1-4 пикселя, количество кадров 24-48 в секунду. А>Проблемы: А>1)при большом сдвиге (4 пикселя на кадр) фон двигается рывками (это можно решить увеличивая количество кадров в секунду при сдвиге 1-2 пикселя на кадр), А>2)размываются правая и левая граница объектов на фоне (разноцветные круги на синем фоне) А>Как этого избежать?
1. Зачем делать такую поверхность? Согласен с постом о мозаичной карте — это будет грамотнее. Для примера — у меня карта 8192х8192 — 32x32 клетки, каждая клетка по 32 пикселя. Двигается всё без проблем, это при том что поверх рисуется ещё около 50-60 изображений параллельно отображается ещё. 30 кадров стабильно.
2. Ты очищал поверхность после создания и перед копированием в него изображения?
3. Пример кода не помешал бы.
А>1. Зачем делать такую поверхность? Согласен с постом о мозаичной карте — это будет грамотнее. Для примера — у меня карта 8192х8192 — 32x32 клетки, каждая клетка по 32 пикселя. Двигается всё без проблем, это при том что поверх рисуется ещё около 50-60 изображений параллельно отображается ещё. 30 кадров стабильно.
Клетка может быть показана частично? Или ты ее выводишь только целиком? А>2. Ты очищал поверхность после создания и перед копированием в него изображения?
Нет. Как (и зачем) это делается? А>3. Пример кода не помешал бы.
Вечером.
Здравствуйте, ecco, Вы писали:
E>Проблема наверное в том, что пикселы — дискретны, а время — нет. Думаю без корректной интерполяции цвета пикселов тут сложно будет. E>Я бы сделал это через D3D. Там это всё есть.
Гм... А почему многие игры на DirectDraw работают без проблем с прокруткой? И для чего интерполяция цвета???
Здравствуйте, De Bug, Вы писали:
DB>Здравствуйте, Александр Сергеевич, Вы писали:
АС>>Clipper включён? DB>Да.
АС>>А вообще лучше использовать объекты мозаичного отображения DB>То есть много маленьких кусочков? А почему это лучше (особенно если они почти все разные)?
Разные в каком смысле?
А лучше это потому, что и карты строить проще и вывод быстрее.
Кроме того, когда ты используешь большую поверхность... ты уверен что она создаётся в видеопамяти, а не в системной?
А если она будет в системной памяти, то блиттинг будет много медленнее.
И ещё... Ты используешь двойную буферизацию, очищаешь поверхность перед блиттингом? Как у тебя идёт усреднение числа кадров? Ну и код желательно бы...
Здравствуйте, De Bug, Вы писали:
DB>Здравствуйте, Аноним, Вы писали:
А>>1. Зачем делать такую поверхность? Согласен с постом о мозаичной карте — это будет грамотнее. Для примера — у меня карта 8192х8192 — 32x32 клетки, каждая клетка по 32 пикселя. Двигается всё без проблем, это при том что поверх рисуется ещё около 50-60 изображений параллельно отображается ещё. 30 кадров стабильно. DB>Клетка может быть показана частично? Или ты ее выводишь только целиком?
Нет, у меня создаётся внеэкранная поверхность размером 768х768, к ней вешается клиппер и сюда я рисую саму карту с любым смещением. После этого я делаю блит этого изображения на экран. А>>2. Ты очищал поверхность после создания и перед копированием в него изображения? DB>Нет. Как (и зачем) это делается?
Ну при создании поверхности выделяется болк памяти, но сама память не чиститься, в итоге по указателю на буффер может остаться изображение рабочего стола, либо ещё каких нибуть других графических рисунков, и если в твоём спрайте есть прозрачные пиксели, т.е. при блитинге переносится только чатсть изображения, то получится наложение на неочищенную поверхность. Как пример, у меня алгоритм такой:
1. загружаю битмаповый массив из 128х128 (например)
2. создаю 4х4 массив поверхностей.
3. очищаю поверхность при копировании из битмапки в поверхность
4. копирую изображение.
5. устанавливаю colorKey.
Всё, поверхность готова. Единственное — такой алгоритм неплох при загрузке, но не в реал тайм, потому что очистка поверхности это количество строк изображения*memset(&image,0,sizeof(line)) что явно не добавит скорости. Поэтому в реал тайме у меня ещё есть проверка — если нет прозрачных пикселей в исходном изображении, то поверхность-приёмник не очищается перед блитингом.
Ну а использовать вместо одной карты мозаичное изображение гораздо гибче. Я могу скомбинировать различные поверхности простым наложением, и мне не приходится рисовать все возможные варианты стыковки изображений. Это во-первых, а во-вторых я согласен Александром Сергеевичем в том, что уверенности что это изображение не создастся в системной памяти нет. Тогда действительно могут быть тормоза.
И кстати, я тут подумал, в рывках в принципе не должно быть разницы, смещаешь ты на 1-2 пикселя либо на 10-20 пикселей. Функции блиттинга то всё-равно с какого указателя ей начать копировать одну область памяти в другую. Так что тут возможно либо я что-то неправильно понял, либо есть проблема в твоей архитектуре. А>>3. Пример кода не помешал бы. DB>Вечером.
Тогда завтра посмотрим, у меня дома к сожалению инета нет.
Здравствуйте, Аноним, Вы писали: А>И кстати, я тут подумал, в рывках в принципе не должно быть разницы, смещаешь ты на 1-2 пикселя либо на 10-20 пикселей. Функции блиттинга то всё-равно с какого указателя ей начать копировать одну область памяти в другую. Так что тут возможно либо я что-то неправильно понял, либо есть проблема в твоей архитектуре.
Вот-вот, мне тоже так кажется. Потому я и написал про синхронизацию кадров. Может быть дело в ней.
Здравствуйте, Александр Сергеевич, Вы писали:
АС>Разные в каком смысле?
Разное изображение в каждом кусочке (на самом деле это не так, но хотелось упростить себе жизнь)
АС>Кроме того, когда ты используешь большую поверхность... ты уверен что она создаётся в видеопамяти, а не в системной?
Видеопамяти 16 мегабайт, а первичная поверхность занимает 3 мегабайта, да битмап на 4 мегабайта. Поместится?
Как определить где реально создалась поверхность?
АС>А если она будет в системной памяти, то блиттинг будет много медленнее.
Программа выполняет только одну операцю — прокрутку битмапа, мне кажется, что рано упираться в быстродействие
АС>И ещё... Ты используешь двойную буферизацию, очищаешь поверхность перед блиттингом? Как у тебя идёт усреднение числа кадров? Ну и код желательно бы...
Здравствуйте, Аноним, Вы писали:
АА>Ну при создании поверхности выделяется болк памяти, но сама память не чиститься, в итоге по указателю на буффер может остаться изображение рабочего стола, либо ещё каких нибуть других графических рисунков, и если в твоём спрайте есть прозрачные пиксели, т.е. при блитинге переносится только чатсть изображения, то получится наложение на неочищенную поверхность.
Фоновый рисунок не содержит прозрачных пикселов.
Здравствуйте, Александр Сергеевич, Вы писали:
АС>Здравствуйте, Аноним, Вы писали: А>>И кстати, я тут подумал, в рывках в принципе не должно быть разницы, смещаешь ты на 1-2 пикселя либо на 10-20 пикселей. Функции блиттинга то всё-равно с какого указателя ей начать копировать одну область памяти в другую. Так что тут возможно либо я что-то неправильно понял, либо есть проблема в твоей архитектуре. АС>Вот-вот, мне тоже так кажется. Потому я и написал про синхронизацию кадров. Может быть дело в ней.
Я не нашел слово "синхронизация" в ваших предыдущих постах
Под анонимом был я, извините что сразу не подписался.
DB>Здравствуйте, Аноним, Вы писали:
АС>Разное изображение в каждом кусочке (на самом деле это не так, но хотелось упростить себе жизнь)
Это не проблема. Реализуется достаточно просто
АС>Видеопамяти 16 мегабайт, а первичная поверхность занимает 3 мегабайта, да битмап на 4 мегабайта. Поместится? АС>Как определить где реально создалась поверхность?
Я точно не уверен, но даже если карточка имеет 16 мегабайт, кроме Вашего приложения ресурсы могут взять другие приложения, поэтому стоит всё таки об этом задуматься сразу.Тем более, что эта поверхность будет юзаться активнее всего, правильно? В таком случае надо постараться сделать всё, чтобы эта поверхность находилась в видеопамяти.
АС>Программа выполняет только одну операцю — прокрутку битмапа, мне кажется, что рано упираться в быстродействие
Если она будет тормозить только от одной этой операции, то это будет уже плохо. Тем более, что это не оптимизация, а проектирование. Ведь на самом деле не видеосистема отвечает за то что вы хотите создать такой большой битмап, а Вы. И если Вы изначально будете делать с такой большой битмапкой, то в будущем, если Вы придёте к решению переделать отображение карты в мозаичном виде, придётся переделывать очень много.
Ну и вопрос Александра Сергеевича по поводу двойной буферизации?
Здравствуйте, Александр Сергеевич, Вы писали:
АС>Гм... А почему многие игры на DirectDraw работают без проблем с прокруткой?
Честно говоря не знаю, не изучал способов реализации данного эффекта на DDraw.
Думаю сложности возникают при относительно низких разрешении и скорости прокрутки.
АС> И для чего интерполяция цвета???
Чтобы вычислить цвет пиксела экрана из пикселов скролящейся текстуры. Ведь, если считать в вещественных числах, то редко когда пиксел текстуры совпадает с пикселом экрана.
Имхо в любом случае с интерполяцией красивее.
Я не знаток DDraw, так что не бейте сильно если туплю, лучше объясните в чём и почему не прав.
Здравствуйте, ecco, Вы писали: E>Я не знаток DDraw, так что не бейте сильно если туплю, лучше объясните в чём и почему не прав.
Дело в том, что это не текстура. А картинка на экране в плоскости один в один. Поэтому искажений там быть не может. Это как BitBlt в GDI.
Здравствуйте, De Bug, Вы писали:
DB>Здравствуйте, Александр Сергеевич, Вы писали:
АС>>Разные в каком смысле? DB>Разное изображение в каждом кусочке (на самом деле это не так, но хотелось упростить себе жизнь)
Т.е. большая карта нарисованная на большом изображении? Ну смотря для какой области это использовать... Может этот подходи и подойдёт...
АС>>Кроме того, когда ты используешь большую поверхность... ты уверен что она создаётся в видеопамяти, а не в системной? DB>Видеопамяти 16 мегабайт, а первичная поверхность занимает 3 мегабайта, да битмап на 4 мегабайта. Поместится?
По логике да, а еще из этого я заключаю, что ты не используешь вторичный буфер (потому как не посчитал его, а может просто забыл), а надо бы
DB>Как определить где реально создалась поверхность?
Точно не помню, но по-моему надо смотреть IDirectDrawSurface::GetCaps или как-то так...
АС>>И ещё... Ты используешь двойную буферизацию, очищаешь поверхность перед блиттингом? Как у тебя идёт усреднение числа кадров? Ну и код желательно бы...
Ну вот это всё же хотелось бы узнать...