Ну в этом смысле да, похоже.
Динамические объекты можно освещать так же, как сейчас освещается рука с палочкой в этом движке (освещается только от фрагмента, на котором стоит игрок). Тень не будет на них падать, но освещение объекта будет меняться, когда объект будет перемещаться.
В Doom можно было задать освещённость сектора и из таких секторов как раз и делали тени. Здесь же тени предвычисляются автоматически заранее, а смешивание цветов выполняет уже OpenGL. Кстати, отсюда присутствуют и те же ограничения на источники света — нельзя на большой плоскости (заданной по 4 координатам) поставить в центре на небольшой высоте над плоскостью источник света и получить пятно рядом с ним (так как свет будет посчитан в 4 точках, задающих плоскость). Боле того, в этом случае пр небольшой высоте источника над плоскостью плоскость вообще может стать тёмной. Здесь исходные многоугольники должны быть сравнимы с расстоянием до источника света.
А смысл в том, что карты освещения не позволяют очень просто менять, например, цвет источника света и не позволяют строить геометрически чёткие тени, да и памяти требуют дофига. И напомню, что всё это делалось в 2004 году, когда у меня был GeForce MX 440. :) И никаких пиксельных шейдеров. И в том же Doom-3 на тот момент вообще нигде не использовалось динамическое корректное цветное освещение (со всеми полутонами при переналожении теней).
Кстати, почти дописал статью. :) Либо здесь, либо на geektimes отправлю. :)
Там при перемещении источника света может кардинально поменяться набор фрагментов. Поэтому, лучше не трогать координаты источника света. А в реальном времени это вычислять очень дорого.
Надо попробовать собраться и хоть что-то оформить, как статью. :) Вот сейчас смотрю код и нифига не понимаю, вот зачем нужно добавлять к полигону точек тени точки пересечения теневого объёма с плоскостью полигона, на который падает тень. и которые находятся внутри полигона, на который падает тень. Комментирую фрагмент — видны ошибки работы с некоторых случаях. :) Склероз — штука страшная. :)
Не могу. :) Посмотрите год в файле. 2008! Это был последний раз, когда я ещё собрался и написал пару формул. Дальше я даже не прикасался к статье. И все формулы давно забыты, как и курс линейной алгебры. :( В общем, нифига не могу написать уже. :)
А вот модуль разбиения и движок остался. :) transit gloria mundi :)
Вот эта функция по исходному полигону cPolygon_ShadowDestination, полигону, отбрасывающему тень cPolygon_ShadowSource, положению источника света sPoint_Lighting формирует набор фрагментов исходного полигона в vector_CPolygon_Fragment. А дальше каждый фрагмент является новым исходным полигоном для уже следующего источника света (источниками теней лучше фрагменты не брать — бессмысленно).
Там всё очень просто. Главное, что этот набор фрагментов нужно построить на этапе подготовки карты в редакторе. А в самом движке только использовать, не выполняя никаких пересчётов теней, а только меняя характеристики источников света (но не координаты).
Кстати, этот shadows.h-shadows.cpp как раз и делает разбиение выпуклого полигона на набор выпуклых фрагментов, зная полигон, отбрасывающий тень и источник света.
Даже не предполагал, что в одном проходе можно указывать разные источники света
Честно говоря, я не понял, что вы имели в виду. :)
Там вот что делается:
1) Рисуется карта. Исходные многоугольники являются выпуклыми (пол+потолок+стены).
2) Берётся полигон и определяются главные для него источники света (по яркости). Таких источников максимум 8 штук (гарантируется OpenGL не менее 8).
3) Для этого полигона перебираем ВСЕ остальные полигоны и для каждого источника света из выбранных главных строим тень на исходный полигон от остальных. Получаем для каждого исходного полигона набор полигонов теней, для каждого из которых известно, какие источники света отключены, а какие включены.
4) Дальше уже движок просто включает или отключает источники света при отрисовке полигонов. И всё.
Кстати, странно. В 1940-м он защитился (по данным википедии). А у вас написано что «Получив докторскую степень и завершив работу над «олимпийским» ревербератором, он занимает должность главного инженера института Герца в Ганновере, а несколько позже (1938-м) » — как так выходит-то? Других диссертаций Зеннхайзер не защищал. Что-то странное выходит с датировками.
А вы спросите себя, когда он защитил кандидатскую по философии, раз на докторскую пошёл. :) И зачем ему эта философия вообще нужна была дважды (кандидат и доктор). :)
Он 100% защитил обычную кандидатскую, непричастную к философии.
Вот и Википедия пишет: «и в 1940 получил степень кандидата наук (англ. Ph.D.)».
sh в немецком читается как «сх». А вот sch — как «ш». Правильно читается Карлсхорст, без буквы ё. (я, кстати, немецкий учил, но… не выучил за все года в школе и 2 курса института — забывается быстро без практики. :) )
Тогда это и есть кандидатская и совсем не по философии. :) И PhD у нас — это кандидатская, а не докторская (которая у нас куда как серьёзнее кандидатской).
А так:
Я философию постиг,
Я стал юристом, стал врачом…
Увы! с усердьем и трудом
И в богословье я проник, —
И не умней я стал в конце концов,
Чем прежде был…
Глупец я из глупцов!
Магистр и доктор я — и вот
Тому пошёл десятый год;
Так GDI в любом случае медленнее работает, чем прямая запись через DirectDraw (с блиттером или без). Просто, в оконном режиме в DirectDraw нужно знать, какой формат представления цвета выбран в настоящий момент и рисовать именно в этом формате (а форматов этих довольно много, вплоть до палитровых). В случае же использования GDI все преобразования (с потерей производительности) выполнит сама Windows. Я так думаю, просто оконный режим был сделан «для галочки».
Динамические объекты можно освещать так же, как сейчас освещается рука с палочкой в этом движке (освещается только от фрагмента, на котором стоит игрок). Тень не будет на них падать, но освещение объекта будет меняться, когда объект будет перемещаться.
Кстати, почти дописал статью. :) Либо здесь, либо на geektimes отправлю. :)
Надо попробовать собраться и хоть что-то оформить, как статью. :) Вот сейчас смотрю код и нифига не понимаю, вот зачем нужно добавлять к полигону точек тени точки пересечения теневого объёма с плоскостью полигона, на который падает тень. и которые находятся внутри полигона, на который падает тень. Комментирую фрагмент — видны ошибки работы с некоторых случаях. :) Склероз — штука страшная. :)
А вот модуль разбиения и движок остался. :) transit gloria mundi :)
bool GenerateShadow(CPolygon cPolygon_ShadowSource,CPolygon cPolygon_ShadowDestination,SPoint sPoint_Lighting,vector &vector_CPolygon_Fragment);
Там всё очень просто. Главное, что этот набор фрагментов нужно построить на этапе подготовки карты в редакторе. А в самом движке только использовать, не выполняя никаких пересчётов теней, а только меняя характеристики источников света (но не координаты).
Должно быть так:
Кстати, этот shadows.h-shadows.cpp как раз и делает разбиение выпуклого полигона на набор выпуклых фрагментов, зная полигон, отбрасывающий тень и источник света.
Честно говоря, я не понял, что вы имели в виду. :)
1) Рисуется карта. Исходные многоугольники являются выпуклыми (пол+потолок+стены).
2) Берётся полигон и определяются главные для него источники света (по яркости). Таких источников максимум 8 штук (гарантируется OpenGL не менее 8).
3) Для этого полигона перебираем ВСЕ остальные полигоны и для каждого источника света из выбранных главных строим тень на исходный полигон от остальных. Получаем для каждого исходного полигона набор полигонов теней, для каждого из которых известно, какие источники света отключены, а какие включены.
4) Дальше уже движок просто включает или отключает источники света при отрисовке полигонов. И всё.
Вот отдельный модуль генерации теней: ссылка
И в любом случае, для докторской нужна сначала кандидатская. :)
Он 100% защитил обычную кандидатскую, непричастную к философии.
Вот и Википедия пишет: «и в 1940 получил степень кандидата наук (англ. Ph.D.)».
А так:
Там ведь всё рисование-то:
Обычный проход по памяти с заполнением пикселя (как в MS-DOS). Большего в Q2 и не требовалось. А тут даже блиттер не нужен.
А вот на I740 OpenGL глючил в Q2 — это я хорошо помню. :)
А здесь, случайно, не получилось ошибки при переводе PhD? Уж больно странно такие защиты выглядят.