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

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

Отправить сообщение
Ну в этом смысле да, похоже.
Динамические объекты можно освещать так же, как сейчас освещается рука с палочкой в этом движке (освещается только от фрагмента, на котором стоит игрок). Тень не будет на них падать, но освещение объекта будет меняться, когда объект будет перемещаться.
В 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);

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

Блин, в файле shadows.h мусор от предыдущей версии. :) И оно компилируется!

Должно быть так:

#ifndef SHADOW_H
#define SHADOW_H

#define S_EPS 0.01
#define S_EPS1 0.0000001
#define S_EPS2 0.0001

#include "polygon.h"

long GetPointPositionPlane(SPoint sPoint_A,SPoint sPoint_Plane,SVector sVector_Normal);
bool GetLineIntersectionPlane(SPoint sPoint_A,SPoint sPoint_B,SPoint sPoint_Plane,SVector sVector_Normal,long mode,SPoint &sPointReturn);
long GetPointPositionInPlaneXZ(SPoint sPoint_A,SPoint sPoint_B,SPoint sPoint);
bool IsPointInPolygonXZ(SPoint sPoint,CPolygon cPolygon);
bool GetPieceIntersectionInPlaneXZ(SPoint A,SPoint B,SPoint C,SPoint D,SPoint &sPointReturn);
bool GetLineIntersectionPieceInPlaneXZ(SPoint A,SPoint B,SPoint C,SPoint D,SPoint &sPointReturn);
bool IsPointInPolygon(SPoint sPoint,CPolygon cPolygon);
bool GenerateShadow(CPolygon cPolygon_ShadowSource,CPolygon cPolygon_ShadowDestination,SPoint sPoint_Lighting,vector<CPolygon> &vector_CPolygon_Fragment);

#endif


Кстати, этот shadows.h-shadows.cpp как раз и делает разбиение выпуклого полигона на набор выпуклых фрагментов, зная полигон, отбрасывающий тень и источник света.

Даже не предполагал, что в одном проходе можно указывать разные источники света


Честно говоря, я не понял, что вы имели в виду. :)
Там вот что делается:
1) Рисуется карта. Исходные многоугольники являются выпуклыми (пол+потолок+стены).
2) Берётся полигон и определяются главные для него источники света (по яркости). Таких источников максимум 8 штук (гарантируется OpenGL не менее 8).
3) Для этого полигона перебираем ВСЕ остальные полигоны и для каждого источника света из выбранных главных строим тень на исходный полигон от остальных. Получаем для каждого исходного полигона набор полигонов теней, для каждого из которых известно, какие источники света отключены, а какие включены.
4) Дальше уже движок просто включает или отключает источники света при отрисовке полигонов. И всё.

Вот отдельный модуль генерации теней: ссылка
Ну вот теперь нестыковок нет. :)
Википедия не обещает истины — она обещает наличие источника. Следовательно, где-то есть источник, в котором написано про 1940 год.

И в любом случае, для докторской нужна сначала кандидатская. :)
Кстати, странно. В 1940-м он защитился (по данным википедии). А у вас написано что «Получив докторскую степень и завершив работу над «олимпийским» ревербератором, он занимает должность главного инженера института Герца в Ганновере, а несколько позже (1938-м) » — как так выходит-то? Других диссертаций Зеннхайзер не защищал. Что-то странное выходит с датировками.
А вы спросите себя, когда он защитил кандидатскую по философии, раз на докторскую пошёл. :) И зачем ему эта философия вообще нужна была дважды (кандидат и доктор). :)
Он 100% защитил обычную кандидатскую, непричастную к философии.
Вот и Википедия пишет: «и в 1940 получил степень кандидата наук (англ. Ph.D.)».
sh в немецком читается как «сх». А вот sch — как «ш». Правильно читается Карлсхорст, без буквы ё. (я, кстати, немецкий учил, но… не выучил за все года в школе и 2 курса института — забывается быстро без практики. :) )
Тогда это и есть кандидатская и совсем не по философии. :) И PhD у нас — это кандидатская, а не докторская (которая у нас куда как серьёзнее кандидатской).
А так:
Я философию постиг,
Я стал юристом, стал врачом…
Увы! с усердьем и трудом
И в богословье я проник, —
И не умней я стал в конце концов,
Чем прежде был…
Глупец я из глупцов!
Магистр и доктор я — и вот
Тому пошёл десятый год;
А что конкретно могло не работать в DirectDraw, тем более в полноэкранном режиме? Я такого не встречал даже на S3, которая для PCI.

Там ведь всё рисование-то:
LPDIRECTDRAWSURFACE7 lpddssecondary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,NULL);
UINT* Video_Buffer=(UINT *)ddsd.lpSurface;
 lPitch32=ddsd.lPitch>>2;
 //рисуем
 UINT *vptr=Video_Buffer;
 UINT *sptr=ScreenBuffer;
 for(y=0;y<480;y++,vptr+=lPitch32)
 {
  UINT *vptrx=vptr;  
  for(int x=0;x<640;x++,vptrx++,sptr++) *(vptrx)=*(sptr);
 }
 lpddssecondary->Unlock(NULL);
 lpddsprimary->Flip(NULL,DDFLIP_WAIT);


Обычный проход по памяти с заполнением пикселя (как в MS-DOS). Большего в Q2 и не требовалось. А тут даже блиттер не нужен.

А вот на I740 OpenGL глючил в Q2 — это я хорошо помню. :)
Так GDI в любом случае медленнее работает, чем прямая запись через DirectDraw (с блиттером или без). Просто, в оконном режиме в DirectDraw нужно знать, какой формат представления цвета выбран в настоящий момент и рисовать именно в этом формате (а форматов этих довольно много, вплоть до палитровых). В случае же использования GDI все преобразования (с потерей производительности) выполнит сама Windows. Я так думаю, просто оконный режим был сделан «для галочки».
>>Фриц Зенхайзер защищает докторскую диссертацию по философии

А здесь, случайно, не получилось ошибки при переводе PhD? Уж больно странно такие защиты выглядят.

Информация

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