Общество изобретателей велосипедов
GameDev.ru / Сообщества / Вело-изобретатели / Форум / Написание софтверного рендерера. (2 стр)

Написание софтверного рендерера. (2 стр)

Страницы: 1 2 3 4 Следующая »
MOПостоялецwww3 мая 200616:59#15
Mikle
Ну на счет пушки... где то слышал что для генерации нормаль карт в DoomIII вообще аппаратный рендер использовался:) На самом деле у меня всё крайне примитивно, http://paste.netimperia.com/results/zlm9ypyyr1.html реализацию естественно не дам. Однако рендер. Софтварный. И работает:)
MikleМодераторwww18 мая 200618:56#16
Обновил движек SR2D и SDK к нему:
http://tuapse-mikle.narod.ru/Sr2d.rar
MikleМодераторwww23 мая 200610:15#17
Очередное обновление по тому же адресу:
http://tuapse-mikle.narod.ru/Sr2d.rar
Теперь маску можно инвертировать.
MikleМодераторwww27 мая 200611:32#18
Сделал несколько туториалов, в том числе генерация анимированного огня и наложение света:
http://tuapse-mikle.narod.ru/SR2D.rar
Shadow_HunterНовичокwww2 июня 200613:01#19
Эхх, вот были времена. Когда мне было 10 лет и у меня был компутер ака P1 66 mhz , я уже захотел писать игры. Причем сразу в 3d. Для этого у меня было очень мощное средство разработки - Visual Basic. Я придумал как рисовать треугольник ( три линии), потом как этот треугольник отрехмерить (три треугольника). Даже как затекстурировать) (передний заролняется черными точками, задний черными -1). И не знал я тогда, что такое классы, функции и структуры, весь код писался сплошняком, а обновлялась картинка нажатием кнопки "обновить". Сейчас бы исходнячок этого дела найти.... эх...
MikleМодераторwww2 июня 200619:31#20
Shadow_Hunter
Ностальгия - вещь приятная, но деструктивная. Я иногда достаю Quick Basic и начинаю делать такое... и приходит мысль, жаль, что я до этого не додумался ТОГДА, когда это было актуально....
AlprogМодераторwww10 июня 200612:25#21
Я, наверное, самый ярый пользователь твоего движка.
Поэтому буду говорить от лица общественности.

Общественность (то есть я) просит реализовать следущие фичи:

1. Вёрстка текстур. Например, вода течёт сверху вниз и текстура со всех сторон стыкуется с соседними такими же.
Как-нибудь надо ограничивать область. И сначала рисовать текстуру чуть выше, а потом внизу... или как там ещё этого можно добится. Ну, вобщем, чтобы так как на рисунке.

2. Растяжение текстур. Этой функции очень не хватает. Например, на простых библиотеках в камуфлётчике это было задействовано:

Иллюстрирую:

Изображение удалено

MikleМодераторwww10 июня 200614:52#22
Alprog
"Фича №1" уже и сейчас вполне доступна, посмотри в примерах как сделана анимация огня, примерно так же можно сделать и воду. Постараюсь за день сделать демку с водой.
А вот "Фича №2" в отсутствует, даже в планах :((( Движек позиционируется под 2D и псевдо-изометрию, где это практически не требуется.
AlprogМодераторwww10 июня 200615:37#23
Mikle
>"Фича №1" уже и сейчас вполне доступна, посмотри в примерах как сделана
>анимация огня, примерно так же можно сделать и воду.
Пример скачал. Завтра буду разбираться.

>А вот "Фича №2" в отсутствует, даже в планах :((( Движек позиционируется под 2D
>и псевдо-изометрию, где это практически не требуется.
Да мне тоже почти не надо. Но хотелось бы. Если очень надо, то можно, я думаю, использовать прозрачный gif, который даже не на этом движке, а отдельной картинкой.

Кстати, наверняка тоже можно, но я ещё не разобрался как сделать прозрачность изменяемой.
Например, дерево непрозрачное стоит. Заходим за него и оно плавненько так растворяется, чтобы видно и его и человечка.

MikleМодераторwww11 июня 200615:00#24
Alprog
Вот водичка:
http://tuapse-mikle.narod.ru/SR2DWater.rar
Я доработал движок - добавил бамп, и на нем сделал воду.
Только сейчас понял, что не доделано. Если перенести изображение отражений из общей части в класс воды, можно будет воду накладывать по маске, да и скорость возрастет. Здесь на компе бейсика нет, поэтому принесу доделанную демку завтра. А может сам разберешься?
Чтобы сделать видимым персонажа за объектами, типа деревьев или стен, можно накладывать его изображение два раза. Сначала, как обычно, отображение с помощью OpAlphaTest (или OpAlphaBlend), а потом, после отображения всех объектов, в том числе и закрывающих персонажа, снова накладываем изображение персонажа с помощью OpAdd2D, по маске, используя сам спрайт персонажа в качестве маски и битовую маску &h80000000.
AlprogМодераторwww11 июня 200616:28#25
Mikle
>Я доработал движок - добавил бамп, и на нем сделал воду.
>А может сам разберешься?
Не думаю, чё-то я запутался совсем. 8(

>Чтобы сделать видимым персонажа за объектами, типа деревьев или стен, можно
>накладывать его изображение два раза. Сначала, как обычно, отображение с
>помощью OpAlphaTest (или OpAlphaBlend), а потом, после отображения всех
>объектов, в том числе и закрывающих персонажа, снова накладываем изображение
>персонажа с помощью OpAdd2D, по маске, используя сам спрайт персонажа в
>качестве маски и битовую маску &h80000000.
Кажись понял.... Хотя я думал что решение проще.
Как насчёт того, чтобы если человек зашёл за дерево, то дерево загружать маской, где
в качестве спрайта дерево, а в качестве маски tga-файл с полупрозрачностью? Сработает?
Хотя, кажись, так не всегда будет виден человек 8(

А ещё я вот обнаружил, что не понимаю различия в "Операторы (Эффекты наложения)."
Я всегда всё использую по умолчанию. А хорошо это или плохо не знаю...
Объяни, если можешь, что означает каждый метод и зачем он нужен.

Что такое источник, что приёмник - это мне понятно, а вот какая разница между эфектами не понимаю.

MikleМодераторwww12 июня 200611:18#26
Обновил демку воды по тому же адресу:
http://tuapse-mikle.narod.ru/SR2DWater.rar
Можешь просто взять класс clsWater и использовать.

Если сделать прозрачным дерево, то сквозь него будет видно не только героя, а все.

Эффекты, примерно:

OpPaint - каждый байт приемника просто заменяется байтом из источника

OpAlphaBlend - в зависимости от значения A в цвете источника результат такой:
Rdest=(Rdest * (255 - Asrc) + Rsrc * Asrc) / 255
Gdest=(Gdest * (255 - Asrc) + Gsrc * Asrc) / 255
Bdest=(Bdest * (255 - Asrc) + Bsrc * Asrc) / 255
То есть, если A=0, то приемник не меняется, если A=255, то он полностью меняется на источник, как будто действует OpPaint. Если A лежит в диапазоне от 0 до 255, то пропорционально A растет вклад источника в результирующий цвет и уменьшается вклад приемника.

OpAlphaTest - если A < 128, то остается цвет приемника, если A >= 128, то он меняется на цвет источника. При загрузке спрайта с прозрачным цветом, сам цвет не меняется, просто создается альфаканал с A = 0 в тех местах, где цвет должен быть прозрачным, а оператор по умолчанию становится OpAlphaTest, но если этот спрайт печатать, используя OpPaint, то никакого прозрачного цвета не будет.

OpAdd - приемник и источник суммируются покомпонентно, то есть:
Rdest= Rdest + Rsrc
Gdest=Gdest  + Gsrc
Bdest=Bdest  + Bsrc
Adest=Adest  + Asrc
Если значение превышает 255, то результат ограничивается этим значением. Похоже на освещение, где источник черный - приемник не изменяется, в остальных местах он как бы высветляется.

OpAdd2D - не сумма, а полусумма, это эффект полупрозрачности, дает то же самое, что OpAlphaBlend при A=128, но работает быстрее и не требует создания альфаканала.

OpMod - покомпонентное умножение (с делением на 255), то есть где источник белый - приемник не меняется, в остальных местах затемняется, можно использовать для рисования тени (рисуем спрайт тени на белом фоне).

OpMod2X - то же, что OpMod, но с умножением на 2, то есть можно и затемнять, и высветлять, там, где источник серый (RGB(128,128,128)) - ничего не меняется.
С масками ты и сам, вижу, разобрался. Как работает бамп - объяснить сложнее, когда доделаю все режимы бампа (пока только один готов) - опишу.

AlprogМодераторwww12 июня 200617:32#27
Долго изучая код класса и главной формы, ко мне таки почти пришло понимание. Свои соображение выложу сюда:

Итак, насколько я понял, вся водичка это всего лишь один спрайт, который можно использовать как обычно, только имя у него длинее, то бишь: имя_класса.имя_спрайта
Всё отличие в том, что он постоянно меняется в реальном времени со скоростью задающейся предварительно: Water.Speed = 0.3
Если мы загрузим спрайт один раз, то он навсегда останется статичным, как и обычный.
Поэтому его нужно всё время обновлять, выполняя строчку Water.Update Timer. Если её отключить, то вода застывает.

Но так как я хочу допустим изменить водичку сделать её зелёной или с большими хребтами, то я начал копаться дальше:
Первый (нижний) спрайт рисуется полностью без всяких альф.
Сверху на него накладывается затемнение или осветление согласно второму спрайту.
С течением времени эти спрайты верстаются в диаметрально противоположных направлениях, оставаясь на месте.

В принципе, до сюда весь код понятен. Можно даже изготовить несколько подобных спрайтов собственными ручками и задать им скорость и направление вёрстки (вниз-верх, подиагоналям и так далее…)

Осталась только строчка SpWater.DrawBump SpBump, SpRefl, 0, 0
Назначение её непонятно. Ясно лишь то, что результат её зависит от спрайта SpRefl.

Каким-то мистическим образом этот спрайт влияет на картину в целом и я никак не соображу как именно. Менял яркость, цвета этого спрайта – результат самый неожиданный 8(

MikleМодераторwww13 июня 20069:57#28
Alprog
Ты все верно понял. Water.Update Timer применяется один раз в кадр, потом полученный спрайт применяется сколько угодно без обновления до конца кадра.
SpWater.DrawBump SpBump, SpRefl, 0, 0 - это тот самы бамп, который "объяснить сложнее".
Вкратце - текстура из SpBump используется не как изображение, а как набор адресов, по которым из текстуры SpRefl берется цвет, в SpBump используются каналы R и G. То есть, если SpRefl имеет размер 256*256, то из нее выводится цвет с позиции X=R и Y=G, если SpRefl имеет другой размер - координаты соответственно масштабируются. Спрайт SpBump задает форму волн, а SpRefl - цвет воды, его можно менять как угодно и давать любой размер в пределах 256*256.
AlprogМодераторwww18 июня 200612:49#29
Возможно ли как-нибудь грузить спрайты обратно на объекты со свойством picture?
Только НЕ рендерить изображение через .hDC, а именно тупо грузить?

Это связано с тем, что процесс рендера на несколько объектов достаточно ресурсоёмок и сильно жрёт "быстродействие",
поэтому в целях оптимизации кода хотелось бы, чтобы возврат на объекты существовал.

Конечно, всегда можно загрузить спрайты один раз на объекты из другой формы и потом загружать по принципу:
picture1.picture = form666.picture1.picture
Но если есть способ более рациональный, то почему бы его не задействовать?

Страницы: 1 2 3 4 Следующая »

/ Форум / Общество изобретателей велосипедов / SR2D - софтовый 2D движок

2001—2018 © GameDev.ru — Разработка игр