Вело-изобретателиФорумSR2D - софтовый 2D движок

SR2D, тестируем x64 версию. (20 стр)

Страницы: 116 17 18 19 20 21 Следующая »
#285
10:44, 30 июля 2025

Mikle
Ну как в фотошопе хотел. Или не так должно быть?
Я может не ту логику применяю.

Я ожидал, что если есть спрайт, который полностью прозрачный, если на него рисовать частично не прозрачный спрайт, то те пиксели (пиксели спрайта который рисуешь) у которых альфа больше 0 наложатся поверх

Изображение

вот я сделал пример
вот код

     Sprite sp_back1 = new Sprite(320, 320);
            sp_back1.ClearBuffer(0);
            Sprite sp_back2 = new Sprite(320, 320);
            sp_back2.ClearBuffer(0);

            Sprite sp_checker = new Sprite(@"r:\sprite_checker.png");

            sp_back1.Draw(sp_checker, 20, 20, SR2D.Op.AlphaBlend);
            sp_back2.Draw(sp_checker, 20, 20, SR2D.Op.AlphaTest);

            sp_back1.SaveToFile("_sprite_alpha_blend.png", System.Drawing.Imaging.ImageFormat.Png, true);
            sp_back2.SaveToFile("_sprite_alpha_test.png", System.Drawing.Imaging.ImageFormat.Png, true);

может я логику не правильную применяю, но альфа тест же работате как я ожидаю, почему альфа бленд, там где 255, просто всё 0 остается.

#286
9:51, 31 июля 2025

SilentPrayerCG
> почему альфа бленд, там где 255, просто всё 0 остается.
Потому, что альфабленд не трогает альфаканал. Если сохранять в файл с выключенной альфой - будет вполне нормальная картинка.
А вот правильное это поведение, или нет - вопрос открытый, и фотошоп тут, боюсь, не ориентир. Он, например, в тех местах, где альфа равна нулю, уничтожает информацию о цвете, в результате, если такой спрайт отображать с масштабированием, то на краях изображения получаются артефакты.
Ну а с альфатестом всё просто - это вообще не блендинг, а трафарет, либо старое изображение, либо новое.
Напиши, какое практическое применение ты планируешь, тогда станет понятнее, как правильно.
Например - нужно скомбинировать несколько спрайтов в один, условно, из деревьев сделать лес, чтобы накладывать его одним действием. Для этой задачи никакой стандартный вариант работы с альфаканалом не подходит, я когда-то занимался этим вопросом, и в самом первом SR2D был оператор AlphaCombine с довольно сложной формулой.

#287
11:50, 31 июля 2025

Mikle
Ну вот допустим, у меня есть спрайт с полупрозрачностью и я хочу его нарисовать на пустом спрайте, сохранив при этом полупрозрачность, сейчас то это не получится же.

#288
12:25, 31 июля 2025

SilentPrayerCG
> у меня есть спрайт с полупрозрачностью и я хочу его нарисовать на пустом спрайте, сохранив при этом полупрозрачность
Можно нарисовать с помощью OpPaint - перенесёт всё, включая альфаканал.

#289
15:16, 31 июля 2025

Mikle
OnPaint это оператор?

я сейчас просто не пойму что вообще происходит если на прозрачном спрайте рисовать...
типа альфа не смешивается вообще..., в моем понимании если в спрайте куда рисуешь альфа 0, а ты рисуешь спрайтом у которого альфа 128, то в этой точке будет 128 а не 0
а если спрайт на котором рисуешь 128 альфа, а ты рисуешь альфой 30, то видимо должна быть альфа больше 128, я так понимаю по формуле альфабленда.. где-то у меня была она... не могу найти

в общем я сделал еще тест с bitmap и graphics
и вот там оно по умолчанию ведет себя так как я ожидал

я еще сделал шашечки в центре полупрозрачными

     Bitmap bmp0 = new Bitmap(320, 320);
            Bitmap bmp1 = new Bitmap(@"r:\sprite_checker.png");

            bmp0.SetResolution(72, 72);
            bmp1.SetResolution(72, 72);

            Graphics gra = Graphics.FromImage(bmp0);

            gra.Clear(Color.FromArgb(0));

            gra.DrawImage(bmp1, 20, 20);

            bmp0.Save(@"r:\___BMP_ALPHA_TEST.png", System.Drawing.Imaging.ImageFormat.Png);


Изображение

и теперь странность... если стоит альфа ТЕСТ, то почему-то на выходе ПОЛУпрозрачность сохраняется, т.е поведение которое я ожидал от альфаБЛЕНДа в данном случае 🤔

#290
15:39, 31 июля 2025

SilentPrayerCG
> если стоит альфа ТЕСТ, то почему-то на выходе ПОЛУпрозрачность сохраняется, т.е поведение которое я ожидал от альфаБЛЕНДа в данном случае
Ты путаешь полупрозрачность, как свойство картинки, с полупрозрачностью в операторе наложения.
Первое - это просто наличие альфаканала, а второе - это блендинг по альфе источника при наложении. Формула такая:

cD=cS*aS+cD*(1-aS)

cD - Color Dest, aS - Alpha Src и т. д. Числа из диапазона 0..255 приведены к 0..1 float.
То есть:

R=RS*aS+RD*(1-aS)
G=GS*aS+GD*(1-aS)
B=BS*aS+BD*(1-aS)

Это три цветовые компоненты. Если так же наложить и альфу:

a=aS*aS+aD*(1-aS)

То мы на месте альфы получим её квадрат (если aD=0, как в твоём первом примере), в любом случае - на то значение, которое тебе требуется.
SilentPrayerCG
> если спрайт на котором рисуешь 128 альфа, а ты рисуешь альфой 30, то видимо должна быть альфа больше 128

a=(30/255*30/255+128/255*(1-30/255))*255=116,470588235294

Как видишь, выходит меньше 128.

#291
16:33, 31 июля 2025

Ладно, пускай так будет. Я уже запутался.

Прошло более 10 месяцев
#292
(Правка: 16:35) 16:23, 15 июня 2026

SR2D

Public Sub SetLockRect(Optional ByVal LRLeft As Integer = -1, Optional ByVal LRRight As Integer = -1, Optional ByVal LRTop As Integer = -1, Optional ByVal LRBottom As Integer = -1)
    If LRLeft >= 0 And LRLeft < meWidth Then meLeft = LRLeft Else meLeft = 0
    If LRRight > LRLeft And LRRight <= meWidth Then meRight = LRRight Else meRight = meWidth
    If LRTop >= 0 And LRTop < meHeight Then meTop = LRTop Else meTop = 0
    If LRBottom > LRTop And LRBottom <= meHeight Then meBottom = LRBottom Else meBottom = meHeight
  End Sub

тут есть довольно грубая ошибка (извиняюсь за резкость устал искать) которая позволяет задать отрицательную границу которая например при рисовании линии с отриц значением позволет послать в DLL задачу в которой правая граница может быть левее и низ выше верха из за чего жёсткий ступор вплоть до синего экрана иногда получается.
Сегодня случайно словил когда скроллинг колёсика мыши наконец сделал и стал проекции гонять в хвост и гриву в результате чего словил копытом по системному блоку от этой ошибки
И теперь из принципа не скажу в чём ошибка  в ближайшее время - маленькая мстя после целого дня отслеживания этой ошибки!!!!!!!!!

для справки в SR2D версии 3.2 то же самое:

Public Sub SetLockRect(Optional ByVal Left As Long = -1, Optional ByVal Right As Long = -1, Optional ByVal Top As Long = -1, Optional ByVal Bottom As Long = -1)
  If Left >= 0 And Left < meWidth Then meLeft = Left Else meLeft = 0
  If Right > Left And Right <= meWidth Then meRight = Right Else meRight = meWidth
  If Top >= 0 And Top < meHeight Then meTop = Top Else meTop = 0
  If Bottom > Top And Bottom <= meHeight Then meBottom = Bottom Else meBottom = meHeight
End Sub

лишний текст пока не убрал - устал после мозгового штурма и множестВА вылетов системы

#293
16:28, 15 июня 2026

и да кстати нашёл способ отслеживать скроллинг колеса мыши в VB6 и этот способ в других языках работает тоже. Способ защищён от зависания очереди сообщений системы и работает в разных окнах. В общем балуясь этим скролингом и смог задать условия для срабатывания ошибки случайно гоняя проекции разных объектов в визуальном пространстве

#294
19:28, 15 июня 2026

Neirapik
> нашёл способ отслеживать скроллинг колеса мыши в VB6 и этот способ в других языках работает тоже
Да я уже давно пользуюсь таким, код формы:

Option Explicit

Private Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" (ByRef lpMsg As WinMSG, ByVal hWnd As Long, ByVal uMsgFilterMin As Long, ByVal uMsgFilterMax As Long, ByVal uRemoveMsg As Long) As Long
Private Declare Function WaitMessage Lib "user32" () As Long

Private Type WinMSG
  hWnd As Long
  uMessage As Long
  wParam As Long
  lParam As Long
  dwTime As Long
  mX As Long
  mY As Long
End Type

Const PM_NOREMOVE As Long = 0
Const WM_MOUSEWHEEL As Long = &H20A
Const PM_REMOVE As Long = 1
Dim MSG As WinMSG
Dim Wheel As Long

Private Sub Form_Load()
  Me.Show
  While DoEvents
    WaitMessage
    If PeekMessage(MSG, hWnd, WM_MOUSEWHEEL, WM_MOUSEWHEEL, PM_REMOVE) Then
      If MSG.wParam < 0 Then
        Form_MouseWheel -1
      Else
        Form_MouseWheel 1
      End If
    End If
  Wend
End Sub

Sub Form_MouseWheel(ByVal nScroll As Long)
  Wheel = Wheel + nScroll
  Me.Caption = Wheel
End Sub

Neirapik
> есть довольно грубая ошибка (извиняюсь за резкость устал искать) которая позволяет задать отрицательную границу
Что-то не могу подобрать параметры. Дай пример входных данных для ошибки.
И, даже если так, это не столько ошибка, сколько уязвимость.

#295
(Правка: 8:56) 8:39, 16 июня 2026

Sr2D 3.2  32бит

Private Sub Command1_Click()
Dim Spr2 As New SR2D_Sprite
  Spr2.Init 500, 500
  Spr2.ClearBuffer 0

  Spr2.SetLockRect 300, 379, -9, -7
  Spr2.DrawLine 310, -9, 370, 6, 255
End Sub

запускал из VB6. редактор виснет и закрыть получается только через аварийное окошко
компилированный exe не пробывал запускать

#296
8:51, 16 июня 2026

у примера с мышкой интересный спецэффект - форма открывается снова если закрыть

#297
8:55, 16 июня 2026

надо будет это завернуть в UserControl с внешним видом как у таймера только вместо секундомера мышку нарисовать

#298
(Правка: 9:25) 9:17, 16 июня 2026

завернул и работает, но теперь другой фокус покус - работает только один экземпляр тот который последний запущен, и в режиме редакции т.к. является контролом тоже запускается но не отлавливает событие 

и при потере фокуса у окна на котором находится контрол событий колеса мыши - события перестают отлавливаться. При возврате фокуса на форму счётчик поворотов колеса снова начинает работать.
Вывод: способ работает только для одной формы

#299
9:24, 16 июня 2026

Neirapik
> у примера с мышкой интересный спецэффект - форма открывается снова если закрыть
Странно. Почему у меня не открывается?

SetLockRect, навскидку, правильнее так:

Public Sub SetLockRect(Optional ByVal Left As Long = -1, Optional ByVal Right As Long = -1, Optional ByVal Top As Long = -1, Optional ByVal Bottom As Long = -1)
  If Left >= 0 And Left < meWidth Then meLeft = Left Else meLeft = 0
  If Right > meLeft And Right <= meWidth Then meRight = Right Else meRight = meWidth
  If Top >= 0 And Top < meHeight Then meTop = Top Else meTop = 0
  If Bottom > meTop And Bottom <= meHeight Then meBottom = Bottom Else meBottom = meHeight
End Sub
Страницы: 116 17 18 19 20 21 Следующая »
Вело-изобретателиФорумSR2D - софтовый 2D движок