| Разработка и ромхакинг > Ромхакинг и программирование |
| SGDK |
| << < (21/40) > >> |
| Sharpnull:
--- Цитата: ALKOSHA от 23 Январь 2019, 10:01:17 ---так ведь 64 тайла - это 512 пикселей. Зачем рисовать лишнее за пределами экранной области? --- Конец цитаты --- Это если делать один вызов VDP_setTileMapData(), размер слоя 64x32, там же память должна идти линейно. Можно вызывать 28 раз по 40 тайлов и смотреть на скорость. В Red Zone заранее рассчитанные тайлы. Попиксельно меняется только мини-карта. Вода + часть объектов на слое A, земля на слое B, у обоих при повороте приходится переставлять все тайлы и по-моему это делается не каждый кадр, вода точно каждый второй кадр обновляется при макс. скорости поворота. При перемещении вверх/вниз было бы необязательно переставлять тайлы, но вертолёт шатает, поэтому как минимум вода обновляется. Арки, которые кажутся трёхмерными, и большинство других объектов - просто спрайты. Вывод фактически в 256x224. |
| ALKOSHA:
--- Цитата: Sharpnull от 23 Январь 2019, 11:48:15 ---Вывод фактически в 256x224. --- Конец цитаты --- А, ну да. Забыл, что справа ещё интерфейс. --- Цитата: Sharpnull от 23 Январь 2019, 11:48:15 ---Арки, которые кажутся трёхмерными, и большинство других объектов - просто спрайты. --- Конец цитаты --- Ну эт я в курсе. Однако параллакс стен внутри зданий - полигоны, как мне кажется. Ещё внутри зданий 3 слоя этажей бывает местами, тоже довольно интересная фишка. |
| Sharpnull:
ALKOSHA, я забыл, что MD поддерживает 3D полигоны. Возможно там и используются. |
| ALKOSHA:
--- Цитата: Sharpnull от 23 Январь 2019, 12:50:39 ---что MD поддерживает 3D полигоны --- Конец цитаты --- "поддерживает" эт сильно сказано. Ведь для переброски хотя бы одного пиксела в позицию XY, процу нужно выполнить кучу лишних операций. бенчмарк в SGDK - предел оптимизации в этом плане, позволяет залить экран с филл-рейтом 15-20 кадров в секунду. И это при шакальном разрешении 256*160. --- Цитата: Sharpnull от 23 Январь 2019, 09:43:52 ---15 FPS Даже если вызывать random() один раз на кадр. --- Конец цитаты --- я тут подумал, при такой дискретности даже 15-ти кадров должно хватить. Там, где для per-pixel вывода нужно 60 кадров, в потайловом выводе достаточно 60/8. Тем паче при трассировке стен зачастую одна треть экрана пустует (если не смотреть на стенку в упор). Так что, вполне неплохой результат, имхо. Но оптимизация хотя бы до 30-ти кадров не будет лишней, конечно же. Добавлено позже: --- Цитата: Sharpnull от 22 Январь 2019, 15:06:31 --- например этот простой движок --- Конец цитаты --- По объёму строк он вроде бы и прост. Но некоторые ф-ции высокоуровневые JS непонятно как перенести в сишку. К примеру ray = map.cast(player, player.direction + angle, this.range); или ? inspect(stepX, 1, 0, origin.distance, stepX.y) : inspect(stepY, 0, 1, origin.distance, stepY.x); и с JS я практически не знаком. Тут тоже кажется простым на первый взгляд. Но тоже есть свои подводные камни. Как например класс векторов надо в массив структур переделать vector<pair<float, float>> p; Или как быть с этим? sort(p.begin(), p.end(), [](const pair<float, float> &left, const pair<float, float> &right) {return left.first < right.first; }); Уже готовая ф-ция сортировки. более доходчивые примеры пытаюсь найти. |
| Sharpnull:
ALKOSHA, там внизу статьи порты, например на Java. --- Цитата: ALKOSHA от 23 Январь 2019, 13:19:57 ---К примеру ray = map.cast(player, player.direction + angle, this.range); или ? inspect(stepX, 1, 0, origin.distance, stepX.y) : inspect(stepY, 0, 1, origin.distance, stepY.x); --- Конец цитаты --- map.cast - это метод у map, а inspect функция. Тернарный операция ?: работает как в C/C++. Да, в JS нужно привыкнуть к ООП через прототипы и функции и к замыканиям. --- Цитата: ALKOSHA от 23 Январь 2019, 13:19:57 ---sort(p.begin(), p.end(), [](const pair<float, float> &left, const pair<float, float> &right) {return left.first < right.first; }); --- Конец цитаты --- Обычная функция сортировки: начало, конец и функция сравнения. В SGDK есть сортировка qsort(), но возможно придётся свою реализовать. |
| ALKOSHA:
--- Цитата: Sharpnull от 23 Январь 2019, 15:40:01 ---ALKOSHA, там внизу статьи порты, например на Java. --- Конец цитаты --- О, это жы LibGDX. На нём я нынче пишу Кровавого мяча под андроид/ПК. (сега-версия слишком утомила непредсказуемыми багами, поэтому решил, не пропадать же добру - перенесу на мобилки хотя бы) https://vk.com/wall-145919754_381 https://vk.com/wall-145919754_229 https://vk.com/wall-145919754_278 Но делать рейкаст для современных платформ иррационально по сравнению с аппаратной растеризацией поликов, конечно же. |
| Sharpnull:
ALKOSHA, посмотрел код с консолью, в принципе проблем не должно быть. Вместо sqrt для расчёта длины можно использовать упрощённое вычисление, в SGDK уже есть: u32 getApproximatedDistance (s32 dx, s32 dy). vector там не нужен, всегда 4 элемента :lol:, а pair заменить на структуру. --- Код: ---pair<float, float> p[4]; // Test each corner of hit tile, storing the distance from // the player, and the calculated dot product of the two rays int i = 0; for (int tx = 0; tx < 2; tx++) for (int ty = 0; ty < 2; ty++) { // Angle of corner to eye float vy = (float)nTestY + ty - fPlayerY; float vx = (float)nTestX + tx - fPlayerX; float d = sqrt(vx*vx + vy * vy); float dot = (fEyeX * vx / d) + (fEyeY * vy / d); p[i] = make_pair(d, dot); //.push_back(make_pair(d, dot)); i++; } // Sort Pairs from closest to farthest sort(&p[0], &p[4], [](const pair<float, float> &left, const pair<float, float> &right) {return left.first < right.first; }); // First two/three are closest (we will never see all four) float fBound = 0.01f; if (acos(p[0].second) < fBound) bBoundary = true; if (acos(p[1].second) < fBound) bBoundary = true; if (acos(p[2].second) < fBound) bBoundary = true; --- Конец кода --- -------- Ошибся с sort(&p[0], &p[4], здесь второй аргумент это элемент после последнего. |
| Sharpnull:
Попробовал реализовать этот код из видео, оказалось что там вместо нормального вычисления шага для проверки стены, делается шаг постоянный 0.1, что медленно, а если его увеличить до 1.0, будет 30 FPS на 256x224, но тогда будут неточные высоты. В общем, лучше код из моего примера реализовывать. |
| ALKOSHA:
--- Цитата: Sharpnull от 23 Январь 2019, 09:43:52 ---Если вместо DMA_QUEUE использовать DMA или CPU, видны разрывы экрана. Я думал, что всё-таки будет 60 FPS для такого простого кода. Может знающие ASM и архитектуру сделают лучше. --- Конец цитаты --- А если перед циклом рендеринга отрубить прерывания? Может побыстрее будет? Я проверить смогу только вечером. |
| Sharpnull:
ALKOSHA, я не понял о каком коде речь, в том примере, если изменить на CPU разрывы не уйдут и будет даже меньше FPS - 56.2: --- Код: ---VDP_showFPS(TRUE); SYS_disableInts(); u16 rand = random() % 16; for (int i = 0; i < 32 * 28; i++) { u16 tileIndex = (rand + i) % 16; tileAttrs[i] = TILE_ATTR_FULL(PAL1, FALSE, FALSE, FALSE, tileIndex); } VDP_setTileMapData(VDP_PLAN_B, tileAttrs, 0, 32 * 28, CPU); SYS_enableInts(); VDP_waitVSync(); --- Конец кода --- Я так и не узнал, что будет, если не отключать прерывания во время доступа к VDP. Может только на реальном железе заметно. |
| ALKOSHA:
Если чё, там ф-ция рандома неоптимизированная. http://gendev.spritesmind.net/forum/viewtopic.php?f=19&t=2968 Добавлено позже: Вот только как бы это линейное заполнение преобразовать в X Y ? *dst++ = TILE_ATTR_FULL(PAL1, FALSE, FALSE, FALSE, rand() & 0xF); |
| ALKOSHA:
u16 x,y; x=10; y=10; dst = x*y; эмм.. .пытаюсь сообразить.. ээ.. там же 24 неиспользующихся тайла за экраном. поэтому... :shifty: щас... dst = x*y*24 ? Не... чёт многовато, мне кажется. Думай, галава, думай. :wall: если Y равен 1 то dst = x+y+24; да? или... dst= x+y+24*y; |
| SeregaZ:
в моем случае экран это 64х28 тайлов. для чтения их нумеров тайлов используется массив в массиве и соответственно два цикла. не знаю есть ли в твоей среде разработки сложные массивы... --- Код: ---Structure constr Y.l[28] EndStructure Global Dim CoordX.constr(64) ; в итоге это выглядит примерно так CoordX(5)\Y[5] = 123 ; типа в координатах 5:5 рисовать номер 123 ; чтение If ReadFile(#File, PathFile$) For y = 1 To 28 ; y выше так как построчно х1, х2, х3... y+1, x1, x2... For x = 1 To 64 CoordX(5)\Y[5] = ReadUnicodeCharacter(#File) Next Next CloseFile(#File) EndIf ; но это случай, когда весь экран на 64 по х забитый. ; там просто начиная с 41 нули ; в твоем случае должно быть что-то типа: dst = y * 64 + x --- Конец кода --- |
| ALKOSHA:
Моё видение тайлового рейкастинга на СМД. |
| Sharpnull:
ALKOSHA, вот код того парня с ютюба. Он там к тому же перепутал синусы и косинусы, но всё работало правильно, так как и карта, и углы были в другую сторону. Теперь карта записанная в коде отображается на обычную координатную плоскость: ноль слева внизу, x - вправо, y - вверх. Исправления от "рыбьего глаза" добавил. Всё ещё нужно определять stepX, stepY, так как из-за шага в 0.1 и дальности 16 происходит 160 проверок на одну колонку и FPS может падать до 8. Если шаг увеличить - fStepSize, то расстояния будут с большой погрешностью. В книге Game Engine Black Book: Wolfenstein 3D есть про рейкастинг, но не очень подробно, автор реализовал вульфа под винду (код рейкастинга), но там код сложнее чем у A first-person engine in 265 lines (нужный код в Map.prototype.cast = function(point, angle, range)). Напомню, что в SGDK у sin/cos входные значения от 0 до 1023 (0 - 2PI). У Fusion скорость эмуляции выше, чем в других эмуляторах, так что нужно ориентироваться на другие. |
| Skay:
--- Цитата: Sharpnull от 30 Январь 2019, 12:11:09 ---В книге Game Engine Black Book: Wolfenstein 3D есть про рейкастинг, но не очень подробно --- Конец цитаты --- про рейкастинг вроде бы неплохо рассказывается у Е.В. Шишкин, А.В. Боресков - Компьютерная графика - 2001 (по матчасти лучше и более полного руководства, с таким уровнем вхождения не встречал), там и теория и тоже на примере волфстейна, дума |
| Werton:
--- Цитата: Sharpnull от 30 Январь 2019, 12:11:09 ---вот код того парня с ютюба --- Конец цитаты --- Работает прыкольна :) но фпс маловато, наверное не обойтись без уменьшения области рендера, да и без текстур все как то грустно. |
| worm:
--- Цитата: Werton от 30 Январь 2019, 14:24:06 ---Работает прыкольна :) но фпс маловато, наверное не обойтись без уменьшения области рендера, да и без текстур все как то грустно. --- Конец цитаты --- Ну тут уж ничего не поделаешь - не тянет сежка псевдо 3д на адекватном уровне. Лучше играть в качественные 2д игры, чем в пиксельное слайд-шоу. |
| SPOT:
Помню KRIKzz делал рейкастинг и вроде бы даже были какие-то исходники. |
| ALKOSHA:
--- Цитата: Werton от 30 Январь 2019, 14:24:06 --- да и без текстур все как то грустно. --- Конец цитаты --- Тайлами можно разнообразить.(см. мой скетч). Нужно лишь заготовить определённый набор паттернов в виде дизеринга. Ещё интересно сделали дум на спермуме. Там тоже тайл-рейкаст, только вместо вертикальных полос - заранее заготовленные текстуры по два кадра чётная/нечётная позиция. Добавлено позже: --- Цитата: worm от 30 Январь 2019, 15:23:32 ---Ну тут уж ничего не поделаешь - не тянет сежка псевдо 3д на адекватном уровне. Лучше играть в качественные 2д игры, чем в пиксельное слайд-шоу. --- Конец цитаты --- А как жы недоделанный порт вульфва ? Вполне адекватный уровень. Так там вообще по горизонтали более ста лучей. Ещё и per-pixel вывод, что само по себе тормознее, чем аппаратные тайлы. Добавлено позже: Для тайлов нужно заготовить табличные значения. 40 лучей - не так уж и много. Добавлено позже: --- Цитата: Skay от 30 Январь 2019, 12:38:05 ---там и теория и тоже на примере волфстейна, дума --- Конец цитаты --- В думе не рейкаст, а полигончики. Так, для справки. Там оптимизация за счёт BSP-отсечения плоскостей (как и в кваке, только в отличие от кваки, BSP-дерево работает в одной плоскости, поэтому нет этажей) |
| Навигация |
| Главная страница сообщений |
| Следующая страница |
| Предыдущая страница |