Comments 28
Актуальность столь запоздавших статей для современного программирования трёхмерной графики, конечно, нулевая

Ну, почему же нулевая? Для моего http://www.moddb.com/mods/wolfgl-3d — будет в самый раз, там как раз освещение работает через GL_LIGHTING :)

Кстати, у меня ваш Wolf почему-то вылетает с ошибкой «Программа выполнила недопустимую операцию» и совсем не запускается. У меня, правда, Windows XP (да, я ретроград :) ), но компьютер трёхгодичной давности.
И, кстати, попробуйте исходники прогнать статическим анализатором, например, CPPCheck 1.64 (1.7… чего-то там у меня глючила и врала) — у вас есть критические ошибки. Возможно, это позволит улучшить стабильность работы программы.

У меня предыдущая версия была тоже XP :)


У Вас в папке с игрой файлы GAMEMAPS.WL6 и остальные .WL6 (или .SOD) от оригинальной игры версии 1.4 присутствуют?
(помню, что у кого-то игра вылетала просто из-за отсутствия этих файлов)

А, вот оно что! :) Скопировал от оригинального. Запустилось. Но графика перепуталась почему-то. А в самой игре получилось вот что:



:D

А версия файлов у Вас какая? Поддерживается 1.4


PS фонарик можно выключать.

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

PS официально, потому что эта ссылка дана на сайте 3D-Realms (вряд ли бы 3D-Realms давала пиратскую ссылку)

Ага. :) Заработало. Но фонарик странный.
А какие у вас настройки параметров фонарика и материала потолка?
Я имею в виду вот это:

 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.

Фонарик имеет два конуса:


  • внешний конус и Diffuse и Specular по 0.5
  • внутренний конус и Diffuse и Specular по 0.9

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

Тут стоит правильно настроить GL_SHININESS, чтобы Specular почти не влиял, потому что блик на крупных полигонах способен сильно испортить картинку. И возможно стоит настроить коэффициенты ослабления света — я уже не помню, как они называются в OpenGL. От них тоже картинка зависит сильно.

Спасибо за дельный совет! Фонарик, действительно, очень странно освещает.

PS в принципе у меня есть редактор материалов, работающий с файлами настроек вида


Ambient 63 50 18 3F3212
Diffuse 192 155 58 C09B3A
Specular 160 142 94 A08E5E
Emission 0 0 0 000000
Shiness 51

но, пока он к Вольфу ещё не прикручен.

Вообще, фонарик надо шейдерами делать. Но я их совсем не знаю. А в инете вроде как есть примеры.

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

Шейдеры будут позже, а сейчас мне интересно поработать с со стандартным GL_LIGHTING

Кстати, как вы отсекаете невидимые грани? В оригинальном Wolf-3D была трассировка лучей при сканировании по экрану, но вряд ли она применима в вашем варианте с OpenGL и произвольной ориентацией головы.

То какую грань из четырёх рисовать у Кармака определяется координатами игрока. Например, если игрок находится левее стены, то рисуется именно левая грань "квадрата", и не рисуется правая. Трассировка же определяет какие именно "квадраты" рисовать.


Моя же версия сейчас находится в оптимизации. Для начала попробовал уменьшить число лучей — выпуская их только для углов и центра "квадрата", но, полезли глюки. Так же пытаюсь использовать Quad-Trees, и тоже в процессе работы.


PS после смены версии C++ проект перестал компилироваться. Сейчас уже компилируется, но, всё ещё не запускается. Как начнёт запускаться — продолжу оптимизацию и доделывание.

Правильно я понял, что вы просто пускаете множество лучей и рисуете те грани, с которыми они пересеклись? Такой способ может давать ошибки, если луч просто не попадёт на большом расстоянии, скажем, в проём между блоками. Дерево не будет отсекать невидимые блоки без списка видимых для узла, хотя и сократит число рассматриваемых блоков и упорядочит их. У вас самый простой вариант был бы метод порталов, а учитывая плоскую карту, он тут вообще довольно прост.

Нет, я сейчас делаю ровно наоборот посылаю луч от "квадрата" к наблюдателю, и смотрю не пересёкся ли он. И поскольку, как Вы заметили, луч может и не попасть в проём между блоками, то наблюдаются глюки.

Кстати, я тут про софтверный движок статью сделал: ссылка Там есть вариант с геометрическим порталом. Для работы под OpenGL достаточно из этого портала выкинуть нафиг софтверную отрисовку графики и обрезание граней при отрисовке. А вот обрезания порталов нужно оставить. Порталами у вас будут пустые грани клеток (где нет стен), а секторами — сами клетки. И вот в таком виде, думаю, все ваши проблемы с трассировкой лучей легко решатся.
Хм. В списке хабов не могу найти ничего похожего на «работа с 3D графикой». Может быть, я где-то не там ищу?
Сами ссылки открываются. Но там, где «Хабы» таких хабов как «CGI» или «работа с 3D графикой» у меня нет. Но у меня поток задан как «разработка».
По логике очень напоминает псевдо-тени в движках типа DOOM 1,2. Хотя там больше 1 активного источника на сектор было сделать нельзя.
В Doom можно было задать освещённость сектора и из таких секторов как раз и делали тени. Здесь же тени предвычисляются автоматически заранее, а смешивание цветов выполняет уже OpenGL. Кстати, отсюда присутствуют и те же ограничения на источники света — нельзя на большой плоскости (заданной по 4 координатам) поставить в центре на небольшой высоте над плоскостью источник света и получить пятно рядом с ним (так как свет будет посчитан в 4 точках, задающих плоскость). Боле того, в этом случае пр небольшой высоте источника над плоскостью плоскость вообще может стать тёмной. Здесь исходные многоугольники должны быть сравнимы с расстоянием до источника света.
Ну тут по сути те же сектора (полигоны ведь режутся на куски) и источники для каждого. Так что очень похоже.
Разница только в большей гибкости, Кстати динамические объекты всё равно этой тени не заметят, как я понимаю. На них будут действовать все источники в пределах досягаемости, что палевно.
Ну в этом смысле да, похоже.
Динамические объекты можно освещать так же, как сейчас освещается рука с палочкой в этом движке (освещается только от фрагмента, на котором стоит игрок). Тень не будет на них падать, но освещение объекта будет меняться, когда объект будет перемещаться.
Only those users with full accounts are able to leave comments. Log in, please.