Pull to refresh

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 точках, задающих плоскость). Боле того, в этом случае пр небольшой высоте источника над плоскостью плоскость вообще может стать тёмной. Здесь исходные многоугольники должны быть сравнимы с расстоянием до источника света.
Ну тут по сути те же сектора (полигоны ведь режутся на куски) и источники для каждого. Так что очень похоже.
Разница только в большей гибкости, Кстати динамические объекты всё равно этой тени не заметят, как я понимаю. На них будут действовать все источники в пределах досягаемости, что палевно.
Ну в этом смысле да, похоже.
Динамические объекты можно освещать так же, как сейчас освещается рука с палочкой в этом движке (освещается только от фрагмента, на котором стоит игрок). Тень не будет на них падать, но освещение объекта будет меняться, когда объект будет перемещаться.
Sign up to leave a comment.

Articles