Как стать автором
Обновить
136
0.2

Пользователь

Отправить сообщение
Просто быстродействие для движков — это жизнь. Ведь там как делается? Вам дали, скажем, 10 секунд на ход. Вы запускается бесконечный анализ с увеличением глубины до тех пор, пока время не закончится. И чем дальше вы успели зайти, тем лучше. Вот потому и вшивают жёстко в надежде на максимальную скорость. Для того же и битовые маски ходов придумали — они ещё быстрее.
Кстати, в моём движке нет такого итеративного углубления, он считает сразу на максимальную глубину и ограничений по времени не имеет.
А так проще было реализовать в GUI и к тому же сложно случайно походить не туда. Как я уже и говорил, интерфейс писался на скорую руку.
Да, тема огромная. Но вот лежал движок шахматный и, думаю, вдруг кому интересно будет. Может, свои шахматы напишут с ЭЛО 4000. :)
Правильно я понял, что вы просто пускаете множество лучей и рисуете те грани, с которыми они пересеклись? Такой способ может давать ошибки, если луч просто не попадёт на большом расстоянии, скажем, в проём между блоками. Дерево не будет отсекать невидимые блоки без списка видимых для узла, хотя и сократит число рассматриваемых блоков и упорядочит их. У вас самый простой вариант был бы метод порталов, а учитывая плоскую карту, он тут вообще довольно прост.
Кстати, как вы отсекаете невидимые грани? В оригинальном Wolf-3D была трассировка лучей при сканировании по экрану, но вряд ли она применима в вашем варианте с OpenGL и произвольной ориентацией головы.
Вообще, фонарик надо шейдерами делать. Но я их совсем не знаю. А в инете вроде как есть примеры.

Кстати, есть ещё один простой способ построения красивых теней. Но он медленный и заключается фактически в обратной трассировке луча. Можно дважды строить сцену — первый раз без освещения (с полной яркостью) и считать её в буфер. А второй раз построить в условных цветах (цвет равен номеру полигона) и опять считать в другой буфер вместе с глубиной пикселя. А дальше пробежаться по буферу и для каждой точки картинки посмотреть, какие источники её освещают и вычислить освещённость точки (0-1 по каналам R,G,B), после чего умножить её значение из буфера на эту освещённость. Собственно, картинки с геометрией из этой статьи таким способом и были сделаны.
Тут стоит правильно настроить GL_SHININESS, чтобы Specular почти не влиял, потому что блик на крупных полигонах способен сильно испортить картинку. И возможно стоит настроить коэффициенты ослабления света — я уже не помню, как они называются в OpenGL. От них тоже картинка зависит сильно.
Ага. :) Заработало. Но фонарик странный.
А какие у вас настройки параметров фонарика и материала потолка?
Я имею в виду вот это:

 glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,sMatherial.Ambient);
 glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,sMatherial.Diffuse);
 glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,sMatherial.Specular);
 glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,sMatherial.Emission);
 glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,sMatherial.Shininess);


И вот это:


 glLightfv(GL_LIGHT0,GL_POSITION,l0_position);
 glLightfv(GL_LIGHT0,GL_AMBIENT,l0_ambient);
 glLightfv(GL_LIGHT0,GL_DIFFUSE,l0_diffuse);
 glLightfv(GL_LIGHT0,GL_SPECULAR,l0_specular);
 glLightfv(GL_LIGHT0,GL_SHININESS,l0_shininess);


Очень похоже на то, что фонарик работает на GL_SPECULAR, а не за счёт GL_DIFFUSE.
Не знал, что Wolf-3D имел версии. :) У меня «Release date: 16th Jun 1992» и никакого номера версии я не нашёл. Он у меня под DOS который. Вот тут я в него играю на 4 минуте: ссылка
А, вот оно что! :) Скопировал от оригинального. Запустилось. Но графика перепуталась почему-то. А в самой игре получилось вот что:



:D
Кстати, у меня ваш Wolf почему-то вылетает с ошибкой «Программа выполнила недопустимую операцию» и совсем не запускается. У меня, правда, Windows XP (да, я ретроград :) ), но компьютер трёхгодичной давности.
И, кстати, попробуйте исходники прогнать статическим анализатором, например, CPPCheck 1.64 (1.7… чего-то там у меня глючила и врала) — у вас есть критические ошибки. Возможно, это позволит улучшить стабильность работы программы.
Ну в этом смысле да, похоже.
Динамические объекты можно освещать так же, как сейчас освещается рука с палочкой в этом движке (освещается только от фрагмента, на котором стоит игрок). Тень не будет на них падать, но освещение объекта будет меняться, когда объект будет перемещаться.
В Doom можно было задать освещённость сектора и из таких секторов как раз и делали тени. Здесь же тени предвычисляются автоматически заранее, а смешивание цветов выполняет уже OpenGL. Кстати, отсюда присутствуют и те же ограничения на источники света — нельзя на большой плоскости (заданной по 4 координатам) поставить в центре на небольшой высоте над плоскостью источник света и получить пятно рядом с ним (так как свет будет посчитан в 4 точках, задающих плоскость). Боле того, в этом случае пр небольшой высоте источника над плоскостью плоскость вообще может стать тёмной. Здесь исходные многоугольники должны быть сравнимы с расстоянием до источника света.
Сами ссылки открываются. Но там, где «Хабы» таких хабов как «CGI» или «работа с 3D графикой» у меня нет. Но у меня поток задан как «разработка».
Хм. В списке хабов не могу найти ничего похожего на «работа с 3D графикой». Может быть, я где-то не там ищу?
А смысл в том, что карты освещения не позволяют очень просто менять, например, цвет источника света и не позволяют строить геометрически чёткие тени, да и памяти требуют дофига. И напомню, что всё это делалось в 2004 году, когда у меня был GeForce MX 440. :) И никаких пиксельных шейдеров. И в том же Doom-3 на тот момент вообще нигде не использовалось динамическое корректное цветное освещение (со всеми полутонами при переналожении теней).

Кстати, почти дописал статью. :) Либо здесь, либо на geektimes отправлю. :)
Там при перемещении источника света может кардинально поменяться набор фрагментов. Поэтому, лучше не трогать координаты источника света. А в реальном времени это вычислять очень дорого.
Надо попробовать собраться и хоть что-то оформить, как статью. :) Вот сейчас смотрю код и нифига не понимаю, вот зачем нужно добавлять к полигону точек тени точки пересечения теневого объёма с плоскостью полигона, на который падает тень. и которые находятся внутри полигона, на который падает тень. Комментирую фрагмент — видны ошибки работы с некоторых случаях. :) Склероз — штука страшная. :)
Не могу. :) Посмотрите год в файле. 2008! Это был последний раз, когда я ещё собрался и написал пару формул. Дальше я даже не прикасался к статье. И все формулы давно забыты, как и курс линейной алгебры. :( В общем, нифига не могу написать уже. :)
А вот модуль разбиения и движок остался. :) transit gloria mundi :)
Вот эта функция по исходному полигону cPolygon_ShadowDestination, полигону, отбрасывающему тень cPolygon_ShadowSource, положению источника света sPoint_Lighting формирует набор фрагментов исходного полигона в vector_CPolygon_Fragment. А дальше каждый фрагмент является новым исходным полигоном для уже следующего источника света (источниками теней лучше фрагменты не брать — бессмысленно).

bool GenerateShadow(CPolygon cPolygon_ShadowSource,CPolygon cPolygon_ShadowDestination,SPoint sPoint_Lighting,vector &vector_CPolygon_Fragment);

Там всё очень просто. Главное, что этот набор фрагментов нужно построить на этапе подготовки карты в редакторе. А в самом движке только использовать, не выполняя никаких пересчётов теней, а только меняя характеристики источников света (но не координаты).
Вот нагляднее, как разбивается исходный полигон каждым другим для каждого источника света. И каждый фрагмент знает, какими источниками он освещён.

Информация

В рейтинге
2 813-й
Откуда
Санкт-Петербург и область, Россия
Зарегистрирован
Активность