#51
19 ноября 2008 в 13:13
GT-Agressor<br />У меня в асе очень жесткий стоит анти-спам, никто вне моего списка контактов пробиться ко мне не может, пока я сам его не добавлю.<br /><br />
возможности графики ку3 меня оч интересуют<br />На самом деле, при правильном апгрейде, графику любого движка можно расширить достаточно сильно. ХЛ2 - пример расширения графики QWorld'-а, правда, не идеальный. Почему - выглядит как картон. Unreal 3 - недостаточно удачный пример расширения графики Unreal. Потому, что выглядит, как глина+пластилин+картон. Надо еще очень много работать, чтобы написать такие шейдеры, которые не делали бы объекты в играх такими. А потому, DooM 3 - действительно удачный пример расширения графики игрового движка.
#52
19 ноября 2008 в 18:03
GT-Agressor: несколько портов ку3 из тех, что я знаю:<br />1) XReal - один из первых серьезный портов Ку3, 100% ориентирован на попикселку, но к сожалению давно откололся от ку3, позиционируя себя как отдельный движок. Автор мутит на нем свою игру (еще не завершена), поэтому релизов XReal почти нет в сети, но исходники и работающие альфа-билды достать можно. <br />2) Evolution Quake 3 - подгонка XReal под Q3. <br />3) IO Quake 3 - хороший порт в основном ориентированный на багфиксинг и мультиплатформенность, вводит некоторое количество новых фич.
#53
19 ноября 2008 в 18:52
Я и забыл про Evolution как производное от Хрюала ;)
#54
19 ноября 2008 в 18:57
Спасибо, попробую договориться с создателем эволюшна :)
#55
20 ноября 2008 в 23:53
<br />В пейнте я залил фон серым цветом, чтобы перса видно было, а то как ни старался, сильно уйти от черного цвета не удалось. Зато, вышло весьма неплохо. На этого кэтсолдиера затрачено 29928 полигонов. Весьма неплохо, с учетом того, что моделвьювер рисует его с производительностью 40 фпс.
#56
21 ноября 2008 в 05:28
29928 полигонов<br />имхо, примерно 28 тысяч там лишние - модель выглядит простовато. Может, нормальные текстуры решат эту проблему.
#57
21 ноября 2008 в 05:54
#58
21 ноября 2008 в 07:33
А мне моделька понравилась, чем то неуловимым напомнила гнума
#59
21 ноября 2008 в 07:59
имхо, примерно 28 тысяч там лишние - модель выглядит простовато. Может, нормальные текстуры решат эту проблему.<br />Постараемся. Компилятор не пожелал жевать текстуру 2048х2048, пришлось так - многократно уменьшить.
#60
21 ноября 2008 в 22:55
Рефакторинг и обновление кода движка продолжаются. Разбивка на отдельные библиотеки, имевшая место ранее, удалась на славу. На движке планируется более-менее пристойное технодемо, по мере собственных возможностей (хотя возможности игрового движка, имхо, безграничны, при правильном с ним обращении). Чтобы продемонстрировать, как изменяется движок, выложу код вектора из оригинальной Q3, и код вектора из своей версии. Замечу, что рефакторинг производится исключительно мной, дополнение движка (шейдеры и принципиально новая функциональность) производится еще двумя людьми. С большим трудом дается создание оригинальных новшеств вроде источников освещения, имеющих длину. Зачем нужна такая ерунда? Да просто для более точной имитации флуоресцентных ламп. Сейчас трудно придумать что-то реально новое, остается совершенствовать старое. ;)<br /><br />Оригинал:<br />[i]<br /><br />vec3_t vec3_origin = {0,0,0};<br /><br />void Vec10Copy( vec_t *in, vec_t *out ) {<br /> out[0] = in[0];<br /> out[1] = in[1];<br /> out[2] = in[2];<br /> out[3] = in[3];<br /> out[4] = in[4];<br /> out[5] = in[5];<br /> out[6] = in[6];<br /> out[7] = in[7];<br /> out[8] = in[8];<br /> out[9] = in[9];<br />}<br /><br />void VectorRotate3x3( vec3_t v, float r[3][3], vec3_t d )<br />{<br /> d[0] = v[0] * r[0][0] + v[1] * r[1][0] + v[2] * r[2][0];<br /> d[1] = v[0] * r[0][1] + v[1] * r[1][1] + v[2] * r[2][1];<br /> d[2] = v[0] * r[0][2] + v[1] * r[1][2] + v[2] * r[2][2];<br />}<br /><br />double VectorLength( const vec3_t v ) {<br /> int i;<br /> double length;<br /> <br /> length = 0;<br /> for (i=0 ; i< 3 ; i++)<br /> length += v[i]*v[i];<br /> length = sqrt (length); // FIXME<br /><br /> return length;<br />}<br /><br />qboolean VectorCompare( const vec3_t v1, const vec3_t v2 ) {<br /> int i;<br /> <br /> for (i=0 ; i<3 ; i++)<br /> if (fabs(v1[i]-v2[i]) > EQUAL_EPSILON)<br /> return qfalse;<br /> <br /> return qtrue;<br />}<br /><br />vec_t Q_rint (vec_t in)<br />{<br /> return floor (in + 0.5);<br />}<br /><br />void VectorMA( const vec3_t va, double scale, const vec3_t vb, vec3_t vc ) {<br /> vc[0] = va[0] + scale*vb[0];<br /> vc[1] = va[1] + scale*vb[1];<br /> vc[2] = va[2] + scale*vb[2];<br />}<br /><br />void CrossProduct( const vec3_t v1, const vec3_t v2, vec3_t cross ) {<br /> cross[0] = v1[1]*v2[2] - v1[2]*v2[1];<br /> cross[1] = v1[2]*v2[0] - v1[0]*v2[2];<br /> cross[2] = v1[0]*v2[1] - v1[1]*v2[0];<br />}<br /><br />vec_t _DotProduct (vec3_t v1, vec3_t v2)<br />{<br /> return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];<br />}<br /><br />void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out)<br />{<br /> out[0] = va[0]-vb[0];<br /> out[1] = va[1]-vb[1];<br /> out[2] = va[2]-vb[2];<br />}<br /><br />void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out)<br />{<br /> out[0] = va[0]+vb[0];<br /> out[1] = va[1]+vb[1];<br /> out[2] = va[2]+vb[2];<br />}<br /><br />void _VectorCopy (vec3_t in, vec3_t out)<br />{<br /> out[0] = in[0];<br /> out[1] = in[1];<br /> out[2] = in[2];<br />}<br /><br />void _VectorScale (vec3_t v, vec_t scale, vec3_t out)<br />{<br /> out[0] = v[0] * scale;<br /> out[1] = v[1] * scale;<br /> out[2] = v[2] * scale;<br />}<br /><br />vec_t VectorNormalize( const vec3_t in, vec3_t out ) {<br /> vec_t length, ilength;<br /><br /> length = sqrt (in[0]*in[0] + in[1]*in[1] + in[2]*in[2]);<br /> if (length == 0)<br /> {<br /> VectorClear (out);<br /> return 0;<br /> }<br /><br /> ilength = 1.0/length;<br /> out[0] = in[0]*ilength;<br /> out[1] = in[1]*ilength;<br /> out[2] = in[2]*ilength;<br /><br /> return length;<br />}<br /><br />vec_t ColorNormalize( const vec3_t in, vec3_t out ) {<br /> float max, scale;<br /><br /> max = in[0];<br /> if (in[1] > max)<br /> max = in[1];<br /> if (in[2] > max)<br /> max = in[2];<br /><br /> if (max == 0) {<br /> out[0] = out[1] = out[2] = 1.0;<br /> return 0;<br /> }<br /><br /> scale = 1.0 / max;<br /><br /> VectorScale (in, scale, out);<br /><br /> return max;<br />}<br /><br /><br /><br />void VectorInverse (vec3_t v)<br />{<br /> v[0] = -v[0];<br /> v[1] = -v[1];<br /> v[2] = -v[2];<br />}<br /><br />void ClearBounds (vec3_t mins, vec3_t maxs)<br />{<br /> mins[0] = mins[1] = mins[2] = 99999;<br /> maxs[0] = maxs[1] = maxs[2] = -99999;<br />}<br /><br />void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs ) {<br /> int i;<br /> vec_t val;<br /><br /> for (i=0 ; i<3 ; i++)<br /> {<br /> val = v[i];<br /> if (val < mins[i])<br /> mins[i] = val;<br /> if (val > maxs[i])<br /> maxs = val;<br /> }<br />}<br /><br /><br /><br />Моя версия<br /><br /><br />class Dvec3d<br />{<br />public:<br /> float x, y, z;<br /><br /> pForce Dvec3d(){}<br /> pForce Dvec3d(float VecF): x(VecF), y(VecF), z(VecF){}<br /> pForce Dvec3d( float VecX, float VecY, float VecZ ): x(VecX), y(VecY), z(VecZ){}<br /><br /> //Операторы, функции<br /><br />//Задание вектора (повторение конструктора)<br /> pForce Dvec3d Set(float x, float y, float z){};<br />//Получение вектора<br /> pForce Dvec3d Get(float x, float y, float z) const<br /> { <br /> return (x, y, z);<br /> }<br />//Прямое произведение векторов<br /> pForce float vDotProduct(const Dvec3d &v1) const<br /> {<br /> return(x*v1.x, y*v1.y, z*v1.z);<br /> }<br />//Скалярное произведение векторов<br /> pForce float vCrossProduct(const Dvec3d &v1)<br /> {<br /> return (y * v1.z - z * v1.y,<br /> z * v1.x - x * v1.z,<br /> x * v1.y - y * v1.x);<br /> }<br />//Сравнение векторов<br /> pForce bool Compare(const Dvec3d &v1, float tol)<br /> {<br /> if (fabs(v1.x - x) > tol) return pFalse;<br /> if (fabs(v1.y - y) > tol) return pFalse;<br /> if (fabs(v1.z - z) > tol) return pFalse;<br /> return pTrue;<br /> }<br /><br />//Нормализуем вектор<br /> pForce float vNormalize()<br /> {<br /> float OneOverDist, Dist, PreDist;<br /> PreDist = (x*x, y*y, z*z);<br /> Dist = invSqrt(PreDist);<br /> if (Dist == 0.0) return 0.0f;<br /> OneOverDist = 1.0f/Dist;<br /> x *= OneOverDist; y *= OneOverDist; z *= OneOverDist;<br /> return Dist;<br /> }<br /><br />//Скалируем вектор<br /> pForce Dvec3d vScale(float Scale) const<br /> {<br /> return(x*Scale, y*Scale, z*Scale);<br /> }<br />//Длина вектора<br /> pForce float vLenght(Dvec3d &v1) const<br /> {<br /> return sqrt(x*x + y*y + z*z);<br /> }<br />//Длина в квадрате<br /> pForce float vLenghtSquared() const<br /> {<br /> return (x*x + y*y + z*z);<br /> }<br /><br /> //Размер вектора (аналог Lenght)<br /> pForce float Size() const<br /> {<br /> return sqrt( x*x + y*y + z*z );<br /> }<br /><br /> //Размер вектора в квадрате<br /> pForce float SizeSquared() const<br /> {<br /> return x*x + y*y + z*z;<br /> }<br />//Вычитание векторов<br /> pForce Dvec3d Subtract(const Dvec3d &v1) const<br /> {<br /> return Dvec3d(x - v1.x, y - v1.y, z - v1.z);<br /> }<br />//Сложение векторов<br /> pForce Dvec3d Add(const Dvec3d &v1) const<br /> {<br /> return Dvec3d(x + v1.x, y + v1.y, z + v1.z);<br /> }<br />//Копирование вектора<br /> pForce Dvec3d Copy(Dvec3d &VDst)<br /> {<br /> return Dvec3d(x = VDst.x, y = VDst.y, z = VDst.z);<br /> }<br />//Очистка вектора<br /> pForce Dvec3d Clear()<br /> {<br /> return Dvec3d(x = 0.0f, y = 0.0f, z = 0.0f);<br /> }<br />//Инверсия вектора<br /> pForce Dvec3d Inverse(float x, float y, float z) const<br /> {<br /> return(-x, -y, -z);<br /> }<br />//Аналог Add<br /> pForce Dvec3d MA(Dvec3d &v1, float Scale) const<br /> {<br /> return (x + v1.x * Scale,<br /> y + v1.y * Scale,<br /> z + v1.z * Scale);<br /> }<br />//Добавление скалированного вектора<br /> pForce Dvec3d AddScaled(Dvec3d &v1, float Scale) const<br /> {<br /> return (x + v1.x * Scale,<br /> y + v1.y * Scale,<br /> z + v1.z * Scale);<br /> }<br /><br /> pForce Dvec3d DistanceBetween(Dvec3d &v1, Dvec3d &B)<br /> {<br /> //Узнаем дотпродукт вектора<br /> B = (x - v1.x, y - v1.y, z - v1.z);<br /><br /> //Затем, узнаем длину полученного вектора<br /> return sqrt(B.x*B.x + B.y*B.y + B.z*B.z);;<br /> }<br /><br /> //Если чего-то не хватает, добавьте ваш код ниже<br />};<br /><br /><br /><br />В общем, мой вариант ничем не универсальнее, однако, полностью использует объектно-ориентированную систему, и весь код вектора размещается исключительно в хедере (хотя и с подключением в почти пустой главный cpp-файл матлибы). Да, думаю, у кого-то есть вопрос - зачем нужна куча форсинлайновых процедур, которые можно заменить на операторы? Отвечу. У меня небольшие проблемы с операторами - я их различаю с трудом, а потому, написав pForce Dvec3d operator^ никогда потом не вспомню того, что он у меня означает кросспродукт вектора. И пусть С++ поддерживает комментарии в тексте программ, иногда может просто быть проще по-быстрому перевести с английского имя процедуры, чем лезть куда-то вглубь читать комментарии.<br /><br />Об обновлениях структуры BSP. Скажу сразу, что обновления проходят и пройдут еще весьма непростые. Сейчас идет работа над зонированием (разбиение пространства карты на зоны, и автоматическая расстановка в нужных местах порталов - то, чего мне так не хватало в DooM 3 =) ), увеличением размеров уровней. Чуть позднее займусь аддитивным построением дерева (сложение двух и более брашей производится быстрее вычитания - тут мы не обрезаем ничего, ничего не вырезаем в брашах в процессе компиляции, тут мы просто добавляем. Двери, окна - по старинке, вычитательно).<br /><br />Текущая версия редактора карт не поддерживает привычного изменения брашей по типу drag-and-drop, а постоянный ввод значений надоедает. Впрочем, его переработка - тоже дело относительно обыкновенное и привычное уже.