Конференция "Начинающим" » ЧИсла меньше машинного эпсилон
 
  • dmk © (03.05.18 21:19) [40]
    В видео рендер в одном потоке. В многопоточном варианте раза в 3-10 быстрее.
    Зависит от процессора.
  • dmk © (03.05.18 21:22) [41]
    Тут еще немного видео:
    https://yadi.sk/i/R2eitAvY3SJRKH
  • Redmond (05.05.18 00:24) [42]
    Супер! Когда же уже разработка будет доступна для простых смертных? :3
    И надо бы-то наваять сайт проекта, хоть на Юкозе или (логичнее) на SourceForge'е...

    А вот бы вы сделали быструю функцию (можно без исходников, в dll) которая могёт быстро отрисовать битмап на другом битмапе как "quad-2-quad"...
  • dmk © (05.05.18 10:30) [43]
    >которая могёт быстро отрисовать битмап на другом битмапе

    Это тоже самое, что вверху, только в цикле:
    //Первый байт пиксела $FF000000 - альфа накладываемого изображения
    procedure BlendDataScLine(sA, dA: QWord; dLen: dword; dOpacity: byte);
    const
     ShufMask: uint64 = $0100010001000100;

    asm
     .NOFRAME
     xor r10, r10
     mov r10d, dLen

     movq mm6, ShufMask //Формирование маски умножения
     mov r8, dA //Адрес назначения

    @NextPixel:
     pxor mm0, mm0 //Очистка регистров умножения
     pxor mm1, mm1 //Очистка регистров умножения

     punpcklbw mm0, [sA] //Читаем исходный (налогаемый) пиксел
     punpcklbw mm1, [r8] //Читаем конечный пиксел
     psrld mm0, 8 //Сдвиг вправо для очистки старших бит
     psrld mm1, 8 //Сдвиг вправо для очистки старших бит

     //Смешиваем альфу с прозрачностью .........
     pextrw eax, mm0, 3 //Извлечем альфу из 4-го слова исходного пиксела sA
     inc eax //Прибавим единицу, чтобы корректно разделить на 256
     movzx r11d, dOpacity //Компонента прозрачности
     mul eax, r11d //Умножаем
     shr ax, 8 //Делим на 256
     mov dx, ax //<- ADif - величина цвета обратная альфе
     xor ax, $FF //Инвертируем альфу

     //Формируем маски умножения
     inc eax //Прибавим единицу, чтобы корректно разделить на 256
     movd mm2, eax
     pshufb mm2, mm6 //<- mm2: формируем 64-битную альфа-маску

     inc edx //Прибавим единицу, чтобы корректно разделить на 256
     movd mm3, edx
     pshufb mm3, mm6 //<- mm3: формируем маску разницы ADif

     //Смешиваем пикселы
     pmullw mm1, mm2 //dA Pixel * Alpha = lpBR, lpBG, lpBB
     pmullw mm0, mm3 //sA Pixel * ADif
     paddusw mm0, mm1 //sAPixel + dAPixel
     psrlw mm0, 8 //mm0 div 256

     packuswb mm0, mm0 //Транслируем слова в байты
     movd [r8], mm0  //Пишем обратно

     add r8, 4 //dA + 4
     add sA, 4 //sA + 4
     dec r10
     jnz @NextPixel
    end;


    Рисует один битмап на другом с альфой и прозрачностью.
    procedure TBitmap64.DrawSprite32(dSprite: TBitmap64; dX, dY: integer; dOpacity: byte);
    var
     x, y: integer;
     dR, IR: TRegion;
     fi: boolean;
     sA, dA: QWord;
     fX, fY: integer;

    begin
     //Регион спрайта
     dR := Region(dX, dY, dSprite.Width, dSprite.Height);

     if RegionIntersect(CR, dR, @IR) then
     begin
       //Регион полность в регионе отсечения
       fi := (IR.W = dSprite.Width) and (IR.H = dSprite.Height);

       //Регион виден полностью
       if fi then
       begin
         fX := dX;
         fY := dY;

         //Адрес начала строки спрайта
         sA := dSprite.PAddress32(0, 0);
         //Адрес начала строки вывода спрайта
         dA := PAddress32(fX, fY);

         for y := 0 to dSprite.Height - 1 do
         begin
           //Смешиваем строки
           BlendDataScLine(sA, dA, dSprite.Width, dOpacity);
           //Следующая скан-линия спрайта
           Inc(sA, dSprite.ScLen);
           //Следующая скан-линия вывода
           Inc(dA, ScLen);
           //Строка вывода
           Inc(fY);
         end;
       end
       else
       //Регион виден не полностью
       begin
         fX := dX;
         fY := dY;
         x := 0;
         y := 0;

         //Отсечение по X слева
         if (dX < FClipRegion.X) then
         begin
           fX := FClipRegion.X;
           x := (FClipRegion.X - dX);
         end;

         //Отсечение по Y сверху
         if (dY < FClipRegion.Y) then
         begin
           fY := FClipRegion.Y;
           y := (FClipRegion.Y - dY);
         end;

         //Адрес начала строки спрайта
         sA := dSprite.PAddress32(x, y);
         //Адрес начала строки вывода спрайта
         dA := PAddress32(fX, fY);

         for y := IR.Y to IR.EY do
         begin
           //Смешиваем строки
           BlendDataScLine(sA, dA, IR.W, dOpacity);
           //Следующая скан-линия вывода
           Inc(dA, ScLen);
           //Следующая скан-линия вывода
           Inc(sA, dSprite.ScLen);
           //Строка вывода
           Inc(fY);
         end;//for
       end;
     end;
    end;
  • dmk © (05.05.18 11:11) [44]
    Вот результат работы BlendDataScLine:
    https://yadi.sk/i/EDIiJHfL3VNJAY

    Адрес пиксела вычисляется так:
    function TBitmap64.PAddress32(x, y: integer): QWord;
    begin
     Result := FBitmap.MemAddr + (y * FBitmap.ScanLength) + (x shl 2);
    end;


    Тут работы на пару вечеров, если вы программист :)
    А dll будет позже. Пока пилю. Я же не программер. Просто хобби.
  • Redmond (06.05.18 14:30) [45]
    Не, "quad-2-quad" - это полное аффинное преобразование. С:
    Произвольный 4-х-угольник в произвольный 4-х-угольник.
  • dmk © (06.05.18 16:15) [46]
    Можно и так. Только исходников пока нет.
 
Конференция "Начинающим" » ЧИсла меньше машинного эпсилон
Есть новые Нет новых   [134427   +34][b:0][p:0]