Para||elix — платформа демосцены
19 subscribers
14 photos
7 links
Parallelix — demoscene platform for multithreaded native intros
Чат: @parallelix_chat
Автор: @jin_x
Download Telegram
Работа пока стоит, а идеи в голову лезут 😄

1️⃣ Многослойность!

Фреймбуфер у меня большой (256 МБ) — это позволит хранить несколько кадров, несколько слоёв либо использовать масштабирование (зум).

С помощью специальной API-функции можно будет накладывать на область итогового слоя (по смещению 0; либо по любому другому смещению) блок из другой области памяти. При этом можно указать цвет прозрачности (опционально), а также размер области источника и приёмника. Вот только х/з что там с GDI-функциями на эту тему. Хорошо было бы вообще иметь возможность использовать 8 лишних бит в 32-битном режиме цветности как альфа-канал. Ну и, разумеется, указывать способы наложения (включая AND, OR, XOR и пр).

Таким образом, представьте, можно, например, нарисовать небольшой фон, растянуть его на весь экран с размытием, сверху нарисовать что-то ещё, а потом поверх этого генерировать анимацию (или 2, 3 анимации). При этом не нужно каждый раз перерисовывать нижние слои! Даже при необходимости сдвинуть или изменить их размер.

Пока писал, вспомнил свою интру DEEP TRIP (как пример, где можно было бы такое использовать), в которой вместо чёрного цвета фрактала Жюлиа рисуется пламя.
Ещё один пример — игра Тетрис. Не нужно рисовать большие квадраты, достаточно 1 пикселя.
На итоговый слой копируется фон, далее игровое поле (с масштабированием, без размытия). Ну и потом можно вывести счёт и т.п.

2️⃣ Спрайты!

Это почти то же самое (в целом можно даже совместить это всё в одной функции), только здесь появляются дополнительные плюшки. Например, глубина цвета спрайта может быть меньше глубины цвета видеорежима. Можно, скажем, использовать 1 бит на пиксель и дополнительно указать 1 или 2 цвета (в зависимости от необходимости прозрачности).

3️⃣ Шрифты!

О шрифтах я думаю уже давно. Их должно быть несколько: моноширинный, без засечек, с засечками и какой-нибудь интересный. Возможно, какой-то из них будет иметь вариант курсива, либо курсовом будет просто смещение верхней и нижней частей. И каждый из них должен иметь 2-4 размера (скорее всего, 4 размера моно и по 2-3 остальных).

Масштабировать их можно будет, но в естественном размере они, конечно, будут выглядеть лучше. Не знаю только насчёт полутонов (видеорежимы же могут быть и с палитрой, так что скорее нет, чем да). Разумеется, с указанием цвета текста и фона (либо прозрачный фон/текст). С возможностью поворота на угол, кратный 90 градусам.

Большой вопрос стоит относительно набора символов. Их должно быть 256, но туда нужно уместить и русские буквы, и буквы разных европейских народов (без иероглифов, арабских, грузинских, еврейских букв и т.п... греческие можно, если хватит места, но вряд ли его хватит). Пожалуй, стоит ввести диакритические знаки, которые будут накладываться поверх предыдущего символа. Но хорошо ли это будет выглядеть на немоноширинных шрифтах (хотя, Unicode же как-то приспособили)?

Ну вот как-то так...
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Салют!
Друзья, я снова сел за проект (наконец-то), уже кое-что перелопатил, подробнее чуть позже.

А пока важно вот что.
Я делаю область констант (чтобы не засорять код интро часто используемыми числами). Есть возможность разместить 64+15 = 79 чисел. По факту их будет гораздо больше, но уже за пределами области «удобной» адресации. Хотя можно разместить и 256 чисел (с «относительно» удобной адресацией) 😁

Сейчас планирую разместить там:
🟡 Последовательности 0...15 типа float и int32 (нужны в т.ч. для групповой обработки пикселей через SSE/AVX/AVX-512, чтобы добавлять их к номерам пикселей) [32 шт].
🟡 Обратные величины чисел 1...10 [10 шт].
🟡 Числа -4, -2, -1, 1.25, 1.5, 2.5, 7.5, 12.5, 16, 25, 32, 50, 64, 128, 256, 100, 125, 250, 500, 1000 (кроме нуля) и их обратные величины (кроме -1) [это 39 шт].
🟡 Маску знака (0x80000000), π, 2π, π/2, π/3, π/4, π/180, 180/π, sqrt(2), sqrt(3), 1/sqrt(2), 1/sqrt(3), sqrt(3)/2, 2/sqrt(3) (значения sin, cos, tg, cosec, sec, ctg стандартных углов), e, φ (золотое сечение) [14 шт].
🟡 Значения log2(e), log2(10), ln(2), ln(10), lg(2), lg(e) [6 шт].

Итого пока получается 101 шт. Можно ещё добавить степени 3, 5, степени 2 минус 1, больше степеней 2, 10, больше отрицательных чисел и их обратные величины. И т.д. Короче, добить «чем-нибудь» до 256 и (гораздо) более я смогу.

Главный вопрос...
Какие константы ещё могут быть полезны для генерации изображений, анимации, трёхмерных объектов, векторных и матричных вычислений?
🟡 Можно добавить постоянные Эйлера (γ), Каталана (G), Фейгенбаума (α, β) и пр. Но нужны ли они?
🟡 Таблицы sin, cos, tg, cosec, sec, ctg и arc* я сделаю, но по «более дальним» адресам.
🟡 Коэффициенты для вычисления функций через ряды Маклорена (Тейлора) будут, тоже «туда дальше».

Кто шарит во всех этих математических делах, гляньте, плиз, вот это список.
Если что-то вы сочтёте полезным, напишите в чат названия констант.
Может, есть что-то, что я не знаю / не пришло в голову? Отдельные числа, таблицы, ряды...
В общем, надеюсь на вашу активность на эту тему 🤝
Please open Telegram to view this post
VIEW IN TELEGRAM
Я портировал Space Fungus на Parallelix с использованием AVX (вычисляется 8 точек за раз).
Мой комп выдаёт 450 fps в FullHD (1920x1080) / TrueColor на 20-потоковым процессоре 😁
P.S. Расчётом занимается только CPU, GPU не задействован!

Шейдер-прототип выглядит так:
#define ITERATIONS 20

vec3 kaliset(vec3 p, vec3 u){
vec3 c=p;
for(int i=0;i<ITERATIONS;i++){
float len=length(p);
p=abs(p)/(len*len)-u; // abs(p)/dot(p,p)-u
c+=p;
}
return c/float(ITERATIONS);
}

void mainImage(out vec4 c, in vec2 xy)
{
vec2 uv=vec2(xy.x/iResolution.x-0.5,(xy.y-iResolution.y*0.5)/iResolution.x);
float m=iTime/60.0;
vec3 p=vec3(uv*iTime,0.1);
vec3 u=vec3(1.0,1.0,0.1)*m;
c.xyz=kaliset(p,u);
}
Please open Telegram to view this post
VIEW IN TELEGRAM
Друзья, две новости.

Новость 1️⃣ (об этом я частично писал в чате).
Платформа Para||elix будет выпускаться в трёх редакциях: «A», «B» и «C».

🔤SCETIC EDITION — версия с сокращёнными возможностями. Уменьшенное кол-во API-функций (нет поддержки спрайтов, генераторов палитры, функций рисования и пр.), малый набор палитр, один-два шрифта, отсутствуют области констант, встроенные текстуры.
Для тех, кто ценит простоту и любит делать всё своими руками.

🔤ASIC EDITION — стандартная версия. Будут добавлены слои и спрайты, несколько стандартных палитр + простые генераторы палитры, больше шрифтов. Доступ к ограниченному кол-ву констант (что особенно удобно при работе с SIMD). Стандартные текстуры (рандом, шум Перлина). Сжатия кода. Конфигуратор.
Для тех, кто любит удобства, но без перегибов.

🔤OMPLETE EDITION — всё по максимуму. Функции рисования (GDI, OpenGL), байт-коды FPU/SIMD, bytebeat/floatbeat с компиляцией, генератор нот. Генераторы сложных палитр, математические функции. Доступ к WinAPI. Большой массив констант. Конфигуратор.
Для тех, кто хочет выжать максимум из платформы. Удобно для создания демо.

Версии платформы будут называться в честь великих художников, музыкантов, математиков и пр.
Например, Aivazovsky, Mandelbrot, Dali, Fibonacci, Mozart, Van Gogh и т.д.

——————————

Новость 2️⃣.
Я снова изменил значение регистра EBP — базового регистра для доступа к API и структурам.
А также адрес загрузки интро. Думаю, на этот раз окончательно 😁. Плюс ко всему, на старте EDX = EBP + 0x100, что будет облегчать доступ к дальним адресам структур (палитре, константами, коду).

Расклад такой:
ebp   = 0x038E1C80 (API table)
ebp*2 = 0x071C3900 (API table 2)
epb*3 = 0x0AAA5580 (constant area)
epb*4 = 0x0E387200 (reserved)
ebp*5 = 0x11C68E80 (service data)
ebp*8 = 0x1C70E400 (reserved)
epb*9 = 0x1FFF0080 (code start + 0x80)


Структура памяти (без учёта API, констант, сервисных данных):
User textures        : 0x12000000 (6*16 MB)
Internal textures 1 : 0x18000000 (4*16 MB) — extra textures
Internal textures 2 : 0x1D000000 (2*16 MB) — random / Perlin noise
Internal fonts : 0x1F000000 (15.875 MB)
Extra variable area : 0x1FFE0000 (64 KB)
Code start address : 0x1FFF0000 (64 KB)
Large user data area : 0x20000000 (512 MB)
Frame buffer address : 0x40000000 (256 MB)
Second frame buffer : 0x50000000 (256 MB) — not fixed sometimes
Huge memory heap : 0x80000000 (2046 MB)


Код записывается по адресу 0x1FFF0000. Если его размер не превышает 64 КБ, он не перекрывает область пользовательской памяти для данных в 512 МБ. Кроме того, такой адрес позволяет использовать [ebp+ebp*8] (адрес 0x1FFF0080) для доступа к первым 256 байтам кода, а также [edx+ebp*8] для доступа к следующим 256 байтам (ну и [ebp+edx*8], [edp+edx*8]). Экономия в среднем 2 байта (иногда 1, иногда даже 3-4) при доступе к данным. Т.к. на старте ESI = code start, 128 байт перед кодом также будут в лёгком доступе (а вообще там 64 КБ для дополнительных переменных, опять же не пересекающихся с 512 МБ). Кстати, кому мало 512 МБ, те могут вызвать API-функцию а-ля malloc, с помощью которой можно выделить почти 2 ГБ дополнительной памяти (при наличии 64-битной винды).

Раньше я думал о том, чтобы загружать код по адресу 0x10000000 либо 0x20000000. Значение 0x10000080 тоже делится на 9 (при старте с позиции 0x10000000), но там могут возникнуть проблемы при резервировании младших адресов (начиная с EBP). А вот 0x20000080 уже на 9 не делится. Но в целом адрес старта 0x1FFF0000 даже лучше, т.к. как я уже сказал, в этом случае код до 64 КБ не перекрывает большой массив для данных. Использовать для фрейм буфера адреса 0x60000000 и выше тоже не стоит, т.к. это может конфликтовать с DLL (в т.ч. системными) — проверено.

Сервисные данные адресуются через [ebp+ebp*4] и [edx+ebp*4]. После 256 байт основных данных идут дополнительные 128, и там же начинается палитра, первые 32 цвета (128 байт) будут в лёгком доступе.

Но самая красота — доступ к константам: [ebp+ebp*2], [edx+ebp*2], [ebp+edx*2], [edx+edx*2], получается целый килобайт без дыр!

По-моему, получилось красиво 😉
Please open Telegram to view this post
VIEW IN TELEGRAM