Давно занимаюсь разработкой софтверного движка 2D графики для VB6.
SR2D предназначен для использования при создании оконных 2D приложений. На настоящий момент SR2D состоит из модуля modSR2D, класса SR2D_Sprite и DLL - SR2D.dll. Класс SR2D_Sprite предназначен для хранения двумерного изображения с альфа каналом, различных его преобразований и отображения на форму или любой контрол, обладающий hDC. Для использования необходимо подключить к проекту указанные модуль и класс, а DLL разместить в папке проекта. Движок не использует для работы никаких API, кроме SetDiBitsToDevice, используемой для вывода изображения на экран и нескольких ф-ций GDI+ для чтения и сохранения файлов. SR2D.dll на 10% написана на C++ и на 90% на ассемблере с активным применением MMX. Это - набор API-подобных stdcall ф-ций.
Движок свободен для некоммерческого и коммерческого использования. Единственное условие - не переименовывать SR2D.dll. То, что движок "для VB6" - не критично, модуль modSR2D и класс SR2D_Sprite фактически являются портом SR2D.dll для VB6, для использования SR2D с любым языком достаточно перевести порт.
Я только что зарелизил версию 3.1 SR2D, тут несколько небольших примеров: SR2D_3_1 287 кБ.
Пока полноценного ReadMe нет, но можно смотреть старый ReadMe, от версии 2.0, изменения вполне логичны и понятны без доп. описания, тут движок, ReadMe и несколько примеров для версии 2.0: SR2D_2_0 400 кБ.
Что нового по сравнению с версией 2.0: 1. Добавился оператор OpBlend (интерполяция источника и приёмника). 2. Теперь использовать маску можно не только с любым оператором, но и с MulAddS2X, ClearBuffer, MoveBit, MoveByte, DrawDPBM, DrawEBM. 3. В DrawDPBM добавился точечный источник света. 4. Загрузка из файла средствами GDI+, соответственно поддержка .bmp, .jpg, .png и т. д. форматов. 5. Сохранение в .bmp, .jpg, .png с альфаканалом (кроме .jpg) и без него. 6. При загрузке можно задавать трансформации - масштабирование (с фильтрацией), поворот, отражение. 7. Появился поворот спрайта на произвольный угол, в том числе с АА. 8. ColorKey теперь задаётся не только при загрузке, но и через метод AddColorKey. "Add" потому, что таких ключей можно задавать сколько угодно, все указанные цвета станут прозрачными. 9. Новый метод MaskInterSector позволяет находить площадь пересечения масок. Удобно применять для коллизий, задавая в качестве маски альфаканал.
Примеры готовых игр, на старой версии: BriX 58 кБ.
Добавлено (04.11.2011, 14:09) --------------------------------------------- Сделал пример рисования кистью и некоторых других технологий, применимых в графических редакторах: Paint и пример анимации: Anim
Добавлено (24.11.2011, 10:16) --------------------------------------------- Скринсейвер, фигуры Лиссажу в 3D: Stars Выключение по движению мышки я убрал специально. Управление: Space - смена рисунка. Escape - выход.
Добавлено (25.01.2012, 14:47) --------------------------------------------- Портировал третью версию SR2D на C# и vb.net. Пример пока один - DPBM: SR2D_CS SR2D_NET
Сообщение отредактировал -Mikle- - Суббота, 04 Февраля 2012, 17:50
Версия 3.2: VB6 vb.net C# 1. В этой версии исправлен баг с сохранением в файл в Win7-64. 2. Изменён синтаксис команды LoadFromObject. Теперь она называется LoadFromIPicture, вместо параметра:
Code
Source As Variant
теперь два параметра:
Code
Src As IPicture, ByVal hDC As Long
Благодаря этому я избавился от позднего связывания, получил возможность грузить не только с PictureBox или Form, но и с любого контрола, не обладающего hDC, например с ImageBox. Вторым параметром можно передавать hDC формы или, к примеру, рабочего стола. 3. Добавилась процедура DrawLine. Меняя параметр DotStep, можно рисовать прерывистые линии, если установить параметр IsXor = True, то цвет будет получаться как Dest Xor Color. Если использовать Color = &H808080, то получается в любом случае цвет, контрастный с приёмником, если DrawLine с IsXor = True применить повторно, то приёмник полностью восстанавливается, можно не перерисовывать.
AGENTX001, я бы хотел сделать порт и для Delphi-Pascal, но я их почти не знаю. А для того, чтобы не просто перевести, а учесть особенности конкретного языка, его нужно знать хорошо. Например, порты под C# и vb.net у меня отличаются от порта под VB6, это учёт особенностей конкретной платформы. Так же перевести на Паскаль я сам не смогу, но был бы рад помощи.
Всё верно, мощные видеокарты, но и мощные процессоры, всё больше графических задач, с которыми вполне справляется CPU. А софт. рендер - это простота: одной командой Dim Spr As New SR2D_Sprite создаём спрайт, одной командой Spr.LoadFromFile загружаем в него изображение, одной командой Spr.PaintToDevice отображаем его на форму или контрол. Кроме того - это независимость от версии дров, установленной версии DirectX и т. п. Кроме того - это лёгкий и быстрый доступ к полученному изображению, без всяких тормозных Lock.
Всё верно, мощные видеокарты, но и мощные процессоры, всё больше графических задач, с которыми вполне справляется CPU. А софт. рендер - это простота:
Я когда так от SDL отказался, когда сравнил скорость его софтверной отрисовки со скоростью хардверной OpenGL. Разница была колоссальная. В любом случае, работа достойна уважения.
В планах нет открытия исходников? Интересует именно MMX. Многие вопросы по Windows отпадут, если посмотреть тут
AGENTX001, я помню, просто, чтобы грамотно составить ТЗ, нужно самому хоть немного в него въехать, а времени что-то совсем мало. Плохо, что у нас с тобой нет языков, которые бы мы оба знали, чтобы было, на чём давать примеры. Нохчи, исходники не скрываю, какие именно ф-ции интересуют?
Вращение/масштабирование спрайтов(насколько я понял реализовано на асме), интересует как проводилась оптимизация. Плюс, если я ничего не путаю, в test.exe реализован Bump и для чего понадобился MMX. Многие вопросы по Windows отпадут, если посмотреть тут
Сообщение отредактировал Нохчи - Пятница, 22 Июня 2012, 14:31
void RESIZE(unsigned char* src, unsigned char* dest, int ws, int hs, int wd, int hd) { int xx, yy; int x, y; int ixx, iyy; int ix, iy; int cx, cy; int cxy, cc; int pin, pout, p; int b, g, r, a; int *ikx, *iky; int *kx, *ky;
cx = (ws - 1) / wd + 2; cy = (hs - 1) / hd + 2; x = cx * wd; y = cy * hd;
if (ws >= wd) { cxy = ws; pin = 0; pout = 1; p = 0; for(;;) { cc = pout * ws - pin * wd; if (cc >= wd) { kx[p] = wd; } else { kx[p] = cc; ikx[p] = pin; p = pout * cx; pout += 1; kx[p] = wd - cc; } ikx[p] = pin; pin += 1; if (pin >= ws) break; p += 1; } } else { cxy = wd; for (x = 0; x < wd; x++) { p = x * 2; kx[p + 1] = x * (ws - 1) % (wd - 1); ikx[p] = x * (ws - 1) / (wd - 1); kx[p] = wd - kx[p + 1]; ikx[p + 1] = (ikx[p] + 1) % ws; } }
if (hs >= hd) { cxy *= hs; pin = 0; pout = 1; p = 0; for(;;) { cc = pout * hs - pin * hd; if (cc >= hd) { ky[p] = hd; } else { ky[p] = cc; iky[p] = pin; p = pout * cy; pout += 1; ky[p] = hd - cc; } iky[p] = pin; pin += 1; if (pin >= hs) break; p += 1; } } else { cxy *= hd; for (y = 0; y < hd; y++) { p = y * 2; ky[p + 1] = y * (hs - 1) % (hd - 1); iky[p] = y * (hs - 1) / (hd - 1); ky[p] = hd - ky[p + 1]; iky[p + 1] = (iky[p] + 1) % hs; } }
iyy = 0; for (yy = 0; yy < hd; yy++) { ixx = 0; for (xx = 0; xx < wd; xx++) { b = g = r = a = 0; iy = iyy; for (y = 1; y <= cy; y++) { ix = ixx; for (x = 1; x <= cx; x++) { b += src[(ikx[ix] + iky[iy] * ws) * 4 + 0] * kx[ix] * ky[iy]; g += src[(ikx[ix] + iky[iy] * ws) * 4 + 1] * kx[ix] * ky[iy]; r += src[(ikx[ix] + iky[iy] * ws) * 4 + 2] * kx[ix] * ky[iy]; a += src[(ikx[ix] + iky[iy] * ws) * 4 + 3] * kx[ix] * ky[iy]; ix += 1; } iy += 1; } dest[(xx + yy * wd) * 4 + 0] = b / cxy; dest[(xx + yy * wd) * 4 + 1] = g / cxy; dest[(xx + yy * wd) * 4 + 2] = r / cxy; dest[(xx + yy * wd) * 4 + 3] = a / cxy; ixx += cx; } iyy += cy; } return; }
src - указатель на буфер источник, dest - указатель на буфер приёмник, ws - Width источника, hs - Height источника, wd - Width приёмника, hd - Height приёмника.
Это произвольный ресайз с билинейной интерполяцией для ARGB, если альфа не нужна, то, с точки зрения быстродействия, лучше всё равно использовать 32 бита XRGB, а в коде можно закомментировать эти две строки:
Вращение могу дать вечером, на работе у меня нет исходников, а прототип на VB6 можно посмотреть в этой теме: Алгоритмы обработки изображений
В test.exe действительно бамп, точнее DPBM, бывает ещё EBM. MMX очень хорош для одновременного выполнения одинаковых действий над четырьмя целыми числами, например, при суммировании цветов. В MMX не нужно отслеживать переполнение, там автоматом работает НАСЫЩЕНИЕ.