HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Half-Life SDK (https://hlfx.ru/forum/forumdisplay.php?forumid=8)
-- Стенсильные тени BUzer'a (https://hlfx.ru/forum/showthread.php?threadid=1672)
Отправлено Ku2zoff 07-01-2009 в 15:35:
Стенсильные тени BUzer'a
Итак, все форумчане наверняка знают о коде простых стенсильных теней, написанном BUzer'ом. Одним из недостатков этих теней(помимо того, что они не накладываются на модели; всегда смотрят в одну сторону; наконец, изредка рисуются сквозь стены[но очень редко]) является то, что для создания тени каждый(!) раз проводится операция пересчёта поверхностей и рёбер субмоделей. Это, конечно, не так уж заметно, но если сравнить скорость обработки обычной модели Барни и супрер детализированной(785 и 3200 полигонов соответственно), то мы имеем очень заметные подвисания в игре, когда модель попадает в поле зрения в первый раз. Затем, при смене уровней этого не наблюдается, поскольку пересчитанные фейсы и эджи хранятся в памяти. Но стоит выйти из игры(quit) и снова запустить её, как всё начинается заново. Это меня очень раздражает. На днях тов. fire64 дал ссылку на исходники мода Raven City, в котором использован код этих самых теней. Тени там улучшены: направление тени зависит источника света, теней для модели может быть несколько, тени накладываются на модели. Просматривая код я наткнулся на две функции: сохраняющую в файл и загружающую из него информацию о фейсах и эджах модели. Операция загрузки из файла занимает намного меньше времени, чем новый рассчёт. Посидев над этими функциями полчаса, я адаптировал их под код BUzer'a(они заточены под Raven City, а там гораздо больше параметров, правда я не знаю для чего).
Итак, приступим. Добавляем тени BUzer'a в ХЛ, пост здесь:
http://www.half-life.ru/forum/showt...&threadid=13398
Затем открываем StudioModelRenderer.h и после строки
C++ Source Code:
void GetShadowVector( myvec3_t &vecOut ); |
в классе CStudioModelRenderer
добавляем две новые строчки:C++ Source Code:
// Shadow data writing functions. |
virtual void StudioWriteData( void ); |
virtual bool StudioReadData( void ); |
После этого открываем StudioModelRenderer.cpp в нём находим функциюC++ Source Code:
void CStudioModelRenderer::SetupModelExtraData(void) |
и вставляем в неё после условияC++ Source Code:
if (m_pCurretExtraData->submodels.size() > 0) |
новое условиеC++ Source Code:
затем вставляем в самый низ этой функцииC++ Source Code:
После этого спускаемся в самый низ файла и вставляем, собственно, функции чтения и записи экстра данных для модели:C++ Source Code:
9 | //Load data from the .dat file. |
12 | bool CStudioModelRenderer::StudioReadData( void ) |
17 | std::string filename(m_pRenderModel->name); |
18 | sprintf(szFile, "%s/%s.dat", gEngfuncs.pfnGetGameDirectory(), filename.substr(0, filename.rfind('.')).c_str() ); |
20 | std::ifstream fin(szFile, ios_base::in | ios_base::binary); |
25 | fin.read((char*)&iSubmodelCount, sizeof(int)); |
26 | m_pCurretExtraData->submodels.resize(iSubmodelCount); |
28 | for ( i = 0; i < iSubmodelCount; i++ ) |
33 | Face m_fTriangles[MAXSTUDIOTRIANGLES]; |
34 | Edge m_fEdges[MAXSTUDIOTRIANGLES]; |
36 | SubModelData &m_pSubModel = m_pCurretExtraData->submodels[i]; |
38 | fin.read((char *)&iTriangleCount, sizeof(int)); |
39 | fin.read((char *)&m_fTriangles, sizeof(Face)*iTriangleCount ); |
41 | fin.read((char *)&iEdgeCount, sizeof(int)); |
42 | fin.read((char *)&m_fEdges, sizeof(Edge)*iEdgeCount ); |
44 | m_pSubModel.faces.reserve( iTriangleCount ); |
45 | for ( int k = 0; k < iTriangleCount; k++ ) |
46 | m_pSubModel.faces.push_back( Face( m_fTriangles[k].vertex0, m_fTriangles[k].vertex1, m_fTriangles[k].vertex2) ); |
48 | m_pSubModel.edges.reserve( iEdgeCount ); |
49 | for ( int j = 0; j < iEdgeCount; j++ ) |
50 | m_pSubModel.edges.push_back( Edge(m_fEdges[j]) ); |
53 | gEngfuncs.Con_Printf("Loaded extra data for %s\n", m_pRenderModel->name); |
57 | gEngfuncs.Con_Printf("Error loading extra data for %s!\n", m_pRenderModel->name); |
64 | //Writes Shadow volume data into a file. |
67 | void CStudioModelRenderer::StudioWriteData( void ) |
72 | std::string filename(m_pRenderModel->name); |
73 | sprintf(szFile, "%s/%s.dat", gEngfuncs.pfnGetGameDirectory(), filename.substr(0, filename.rfind('.')).c_str() ); |
74 | std::ofstream fout(szFile, ios_base::out | ios_base::binary | ios_base::trunc); |
78 | int iSubmodelCount = m_pCurretExtraData->submodels.size(); |
79 | fout.write((const char *)&iSubmodelCount, sizeof(int)); |
81 | for ( i = 0; i < m_pCurretExtraData->submodels.size(); i++ ) |
83 | SubModelData &m_pSubModel = m_pCurretExtraData->submodels[i]; |
84 | int iTriangleCount = m_pSubModel.faces.size(); |
86 | fout.write((const char *)&iTriangleCount, sizeof(int)); |
87 | fout.write((const char *)&m_pSubModel.faces[0], sizeof(Face)*iTriangleCount); |
89 | int iEdgeCount = m_pSubModel.edges.size(); |
91 | fout.write((const char *)&iEdgeCount, sizeof(int)); |
92 | fout.write((const char *)&m_pSubModel.edges[0], sizeof(Edge)*iEdgeCount); |
95 | gEngfuncs.Con_Printf("Writing extra data for %s\n", m_pRenderModel->name); |
Файлы с данными о рёбрах и поверхностях будут иметь форму имя_модели.dat и лежать в папке имя_мода/models
Вот собственно и всё, осталось только сделать проверку на обновление файлов при обновлении модели, также как это происходит с файлами *.nod и *.nrp в папке maps/graphs Это, я думаю будет не сложно, так что я не буду писать этот код, а то пост и так уже огромный :D (я печатать замучился).
Отправлено XaeroX 07-01-2009 в 15:43:
Ну что сказать... Молодцы ребята, постепенно своим умом восстанавливают код, который я написал пару лет назад 
Нет чтоб предложить мне продать свои сорцы, ну чисто символически, за пару ящиков пива? Ээээх... 
__________________
Отправлено Ku2zoff 07-01-2009 в 15:54:
XaeroX речь идёт о коде теней из хлфх? А про пару я щиков пива это шутка? А то вдруг сейчас фанаты кинуться бегать по магазинам 
Добавлено 07-01-2009 в 21:54:
У меня возник вопрос: файлы .дат от теней сохраняются в перемешку с моделями, это неудобно. Всё из-за того что имя модели в StudioModelRenderer с папкой models/, т.е. models/barney.mdl, models/hgrunt.mdl и т.п.
С помощью int strlen можно найти длину строки и "отрезать" опр. количество символов с конца. А есть ли функция "наоборот", т.е. "отрезать" символы с начала строки? Просто нужно избавиться от этого ненавистного models/
Отправлено XaeroX 07-01-2009 в 16:09:
Цитата:
Ku2zoff писал:
речь идёт о коде теней из хлфх?
Ну помнишь старый хлфх со стенсильными тенями а ля дум3? Я еще на хлру выкладывал скрины. Сейчас-то в хлфх другие тени, а те - валяются без дела.
За пару ящиков пива отдам, че уж
Правда там тени совмещены с попиксельным освещением и бампом, и они не только от моделей, но и от вообще всего, так что просто так их не вставишь. За десять ящиков - могу отдать полностью 
Цитата:
Ku2zoff писал:
С помощью int strlen можно найти длину строки и "отрезать" опр. количество символов с конца. А есть ли функция "наоборот", т.е. "отрезать" символы с начала строки?
Проще простого. Просто прибавь strlen("models/") к указателю.__________________
Отправлено Ku2zoff 07-01-2009 в 18:33:
Итак, ещё один вопрос. Для сравнения нод и бсп файлов хл использует движковую функцию pfnCompareFile. Но она есть только в enginefuncs_s. В cl_enginefuncs_s её нет. Почему вальв не подумали, что когда-нибудь мододелы захотят сравнить файлы по дате на клиенте? Так вот сам вопрос: какой функцией виндовс можно воспользоваться для сравнения? Искал по слову compare, но ничего подходящего не нашёл.
Отправлено XaeroX 07-01-2009 в 18:36:
Цитата:
Ku2zoff писал:
Так вот сам вопрос: какой функцией виндовс можно воспользоваться для сравнения?
GetFileTime__________________
Отправлено Дядя Миша 07-01-2009 в 19:41:
code:
int FS_FileTime (const char *filename)
{
struct stat buf;
if( stat( filename, &buf) == -1 )
return -1;
return buf.st_mtime;
}
int pfnCompareFileTime( const char *filename1, const char *filename2, int *iCompare )
{
int time1 = FS_FileTime( filename1 );
int time2 = FS_FileTime( filename2 );
if( iCompare )
{
if( time1 > time2 )
*iCompare = 1;
else if( time1 < time2 )
*iCompare = -1;
else *iCompare = 0;
}
return (time1 != time2);
}
От народ, такую элементарщину объяснять приходится. Только в пак не пихай эти файлы.
Добавлено 07-01-2009 в 22:41:
ЗЫ. способ сравнения времени файлов неудобен в принципе.
Гораздо умнее писать время файла непосредственно в заголовок файла при создании и сравнивать уже оттуда.__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено XaeroX 07-01-2009 в 21:30:
Цитата:
Дядя Миша писал:
Гораздо умнее писать время файла непосредственно в заголовок файла при создании и сравнивать уже оттуда.
Угу, как же, умнее.
То ли ты файл открыл, то ли время в FATе посмотрел - есть разница?__________________
Отправлено Ku2zoff 08-01-2009 в 06:38:
Проверка будет проведена, будет создан новый .dat файл, а .mdl не изменится. При следующей загрузке обнаружится, что .mdl старше и снова будет создан новый .dat. И так до бесконечности. Думаю, что вариант с записью информации в .dat файл наилучший. Я пробовал писать в файл и статус и время, но потом из него считывается "ничего", даже не null. Может надо как-то конвертировать time_t, например в int ?
Отправлено XaeroX 08-01-2009 в 09:32:
Я делал так: в MDX-файл сохранял CRC16-значение данных MDL (т.е. CRC_ProcessBuffer(mod->cache.data)) и при загрузке снова его считал и сверял. Если не совпадали - значит MDL был изменен и MDX надо построить заново.
__________________
Отправлено Дядя Миша 08-01-2009 в 10:54:
>>То ли ты файл открыл, то ли время в FATе посмотрел - есть разница?
ну конечно же есть! именно поэтому и советую. Вообще много способов есть.
Добавлено 08-01-2009 в 13:54:
Можно вписать доп инфу в саму модельку кстати. В заголовке есть какие-то неиспользуемые переменные - можно их заюзать как смещение до этой инфы.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено GuNsHiP 27-04-2009 в 19:13:
Сделал тени, но при компиляции нужны эти файлы
C++ Source Code:
У кого есть скиньте
Расчитываю на вашу помощь!
Отправлено Ku2zoff 28-04-2009 в 03:16:
Лучше в гугле поищи, быстрее будет. И кстати, я уже давно сделал норм. проверку возраста .mdl доберусь до своих исходников и выложу.
Отправлено FiEctro 28-04-2009 в 09:07:
GuNsHiP
http://hlfx.ru/forum/showthread.php?s=&threadid=826
Еще в сдк паранои есть.
Ku2zoff
Я своё время искал в гугле, ни один из них не подошел (хотя названия теже, а вот содержание разное). Пришлось просить у людей.
__________________
У котёнка мокрый нос и гладенькая шерсть, у него забавный хвост и быстрых лапок шесть. Две задних, две средних и две передних лапы, такая многоножка получилася у папы.
Он ученый — папа мой — зверушек изучает, гуляет по помойкам, ловит крыс и чаек. Две крысы белокрылые и чайки две унылые покрытые пупырчатою кожей лягушат без пёрышек тоскуют и ускакать спешат.
А ещё есть муравей большой размером с гуся он пугает всех зверей, и я его боюся, когда он ковыляет на лапках на своих.
И в двери ударяет, и начинает стих: Я — муравей, воды налей! Не меньше ведра, напиться мне пора!
Отправлено Дядя Миша 28-04-2009 в 10:27:
первый есть в студии, второй надо искать как можно более толстый (килобайт на 300-400).
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
На основе vBulletin версии 2.3.0
Авторское право © Jelsoft Enterprises Limited 2000 - 2002.
Дизайн и программирование: Crystice Softworks © 2005 - 2024