122
я пока что-то очень примитивное хочу попробовать
но так как я ничем таким не занимался, пока не знаю
я до этого пытался сделать диггер (ну как болдердэш/еарт шейкер), но я делал максимум примитивно и спрайты двигались, по секциям, а не плавно
а вот когда в октябре я решил попробовать сделать что-то плавно, понял что тут уже что-то мудрёнее надо делать
если интересно, это я делал в том году вроде, без всякого вообще опыта в каком либо геймдеве https://youtu.be/WiYKrZTQKmI?t=128
и я тогда все сделал тупо на таймере, т.е все движения с одинаковой задержкой, и смена вроде кадров анимации тоже
но я потом пришел к выводу, что как-то иначе это надо делать, типа делать маленькую задержку, и считать количество циклов прежде чем что-то сдвинется, и как-то все это усложнило, и я интерес как обычно потерял и забросил, и сейчас даже код уже тот сложно понять будет
SilentPrayerCG
Я тебе дал пример, который ты просил, на предыдущей странице. Ты не заметил?
Mikle
да извини, не заметил, спасибо гляну
ps
глянул, текст в заголовке показывает 395
это второй метод где привязка не к фпс?
SilentPrayerCG
> это второй метод где привязка не к фпс?
Да.
Mikle
привет
ClearRect же закрашивает указанную область на спрайте?
Можешь аргументы объяснить, я опять что-то понять не могу.
pleft pright top bottom
ps
сделал тракбары, покрутил, понятно, т.е это координаты не углов, а ребер
причем я смотрел сам код clearrect-а я чую я не смогу под углы сам его переделать
pps
сделал вот так
Public Sub ClearRectMy(x As Integer, y As Integer, width As Integer, height As Integer, c As Integer) Dim PLeft, PRight, Top, Bottom As Integer PLeft = x Top = y PRight = x + width Bottom = y + height If PLeft < meLeft Then PLeft = meLeft If PRight > meRight Then PRight = meRight If PRight <= PLeft Then Exit Sub If Top < meTop Then Top = meTop If Bottom > meBottom Then Bottom = meBottom If Bottom <= Top Then Exit Sub SClearC(DataPTR(PLeft, Top), PRight - PLeft, Bottom - Top, meWidth, c) End Sub
т.е процедуру саму оставил как было, просто сконвертировал углы в стороны. не уверен можно ли как-то менее кощунски сделать, я не особо понимаю махинации в SClearC с аргументами
SilentPrayerCG
> не особо понимаю махинации в SClearC с аргументами
ByVal pDest As Int64, ByVal W As Integer, ByVal H As Integer, ByVal WD As Integer, ByVal c As Integer
pDest - указатель на приёмник. Не на начало данных, а прямо на пиксель с координатами верхнего левого угла окрашиваемой области. Поэтому туда передаётся DataPTR(PLeft, Top).
W - ширина закрашиваемой области.
H - высота закрашиваемой области.
WD - ширина спрайта приёмника.
c - цвет заливки.
С виду ты переделал правильно, только нет смысла дублировать переменные:
PLeft = x Top = y
Вообще выкини PLeft и Top, а вместо них подставь x и y.
Mikle
ок спс, с переменными понял
а скейл спрайта, кстати, никак не сделать быстрее
сейчас тупо через создание нового спрайта
я правда не уверен. пострадал ли скейл спрайта от переноса на 64
пытаюсь тулзу тут делать, хочу чтобы картинка перерисовывалась при ресайзе формы
и если сама картинка изначальная в большом размере, каждый раз получается что оригинальная картинка скейлится под размер формы, довольно медленно
не уверен, может все-таки через пикчур бокс тупо сделать, и скейлить сам контрол и двигать его туда сюда, если нужен pan и zoom
хотя в контроле тоже помоему не шибко быстро работает отрисовка нативная когда скейлишь
(хотя вот старый проект открыл, где пикчур бокс, кажется быстрее работает когда растягиваешь форму, и картинка скейлится вместе с ней, просто картинка засунутая в пикчур бокс, не рисующаяся кодом)
спрайтом если выводить, конечно все равно более гибко можно настраивать все, и можно выводить изменения в картинке быстрее, не нужно битмап из спрайта делать и закидывать его в пикчур бокс.
У меня же скейл качественный, с фильтрацией, поэтому не такой быстрый.
Mikle
ну в пикчурбоксе он тоже с фильтрацией
может он физически не пересоздает картинку, а именно как-то пересклейливает её, хз короче
Ps
если-бы был быстрый nearest neighbor я бы наверное сделал во время ресайза формы что-бы через него скейлилось просто, быстрее бы бы.
Mikle
не подскажешь еще кое что
вот я делаю евент ресайз, и в нем процедура, где создаются спрайты, скейляться, и выводятся через paintodevice на picturebox
сам picturebox скейлится вместе с формой
но если делать максимизацию окна, или резко скейлить
окно оказывается увеличенным, а вот последний паинт то девайс, рисуется не до конца контрола, а только фрагмент
т.е гарантированно на весь контрол рисуется, только если выждать после ресайза и сделать отрисовку, либо если делать её в resize ended (который не срабатывает вообще при максимизации)
я вот создал отдельный проект чисто чекнуть, событие ресайз срабатывает 1 раз примаксимизации, и размеры контролов показывает сразу те которые при максимизации, ну т.е он не показывает промежуточные размеры, их т.е нет, это просто анимация винды
но вот для паинттодевайс, похоже при максимизации (и резких рескейлах) похоже не весь контрол предоставляется
я не уверен может, это можно как-то форсировать?
и я что-то не помню раньше такой проблемы, может в вин11 что-то по другому сделали
ок. чекнул вот такой код
Imports System.Runtime.InteropServices Public Class Form1 Dim hdc As HandleRef Dim grp As Graphics Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load End Sub Private Sub Form1_HandleCreated(sender As Object, e As EventArgs) Handles Me.HandleCreated grp = sender.creategraphics hdc = New HandleRef(grp, grp.GetHdc) End Sub Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize Dim s As New Sprite(Width, Height) s.ClearBuffer(255, 100, 100, 255) s.PaintToDevice(hdc) End Sub End Class
в фреймовке 4.8 и нет 6
нормально все
видимо у меня что-то сломано, не пойму в чем дело
В общем если форма ресайзится, и спрайт рисуется на форму, то все ок.
А вот если в форме picturebox и рисуется на него, то начинаются вот эти проблемы странные.
Похоже это рендер который выводит картинку в него портит все, даже если самой картинки нет.
Проверил с панелью, с ней такой проблемы вроде нет, так что видимо панель нужно использовать.
SilentPrayerCG
Похоже, у тебя действительно какие-то проблемы не на стороне SR2D.
У меня под рукой сейчас нет подходящего компа проверить. На VB6 и Win32 подобных проблем не наблюдаю, и скорость очень неплоха по сравнению с винапишным ресайзом.
Mikle
ну с проблемой с ресайзом разобрался, где не отрисовывалось нормально, это было из-за picturebox-а, что-то он сбивал, с формой и панелью все нормально
а ты можешь скинуть мне ехешник сделанный на вб 6 (да и проект, я тупо код гляну) где ты ресайзишь картинку ресайзя форму, я чекну у себя, желательно с альфаблендом (да знаю он значительно медленнее)
и сама картинка чтобы было крупная, типа 3000 3000 к примеру
я вот сейчас все переработал, во первых если картинка больше разрешения экрана, то создается оптимизированная версия для вьюпорта, которая предварительно скейлится до разрешения экрана
(потом, если я буду делать зум, надо перегенерить её каждый раз, надо еще обдумать детали)
и сделал чтобы еще создавалась вторая версия оптимизированной картинки, совсем маленькая
и когда ресайзишь форму, отображается она, а когда перестаешь ресайзить уже рисуется нормальная.
я думаю в данном случае если и есть какието проблемы с скоростью, то наверное упирается в то что это х64 версия, и то что в ней асм вставок нет
грубо говоря я делаю так
при ресайзе: 1) создается спрайт под размер вьюпорта (панели, где картинка отображаться должна) 2) создается спрайт из загруженной картинки (оптимизированной заранее), создается сразу с пропорциональным рескейлом до размеров спрайта из шага 1) 3) затирается спрайт 1) (потом шашечки сделаю) 4) поверх спрайта 1 рисуется спрайт 2 по середине 5) паинттодевайс сам код Dim pSize As Size = CType(sender, Panel).Size ViewportImage = New Sprite(pSize.Width, pSize.Height) RescaledImage = New Sprite(OptImageLev2, ResizeP(OptImageLev2.Size, CType(sender, Panel).Size)) ViewportImage.ClearBuffer(Color.YellowGreen.ToArgb) ViewportImage.Draw(RescaledImage, pSize.Width \ 2 - RescaledImage.Width \ 2, pSize.Height \ 2 - RescaledImage.Height \ 2, Op.AlphaTest) ViewportImage.PaintToDevice(Hdc) (это динамический вывод во время ресайза, с маленьким спрайтом в optimagelev2 и рисуется альфатестом, а когда перестаешь ресайзить, все тоже самое только картинка нормальная и альфабленд) size в спрайт я сам добавил, чисто для удобства, возвращает нативный сайз функцию пропорционального рескейла мне друг помогал делать Function ResizeP(SrcSize As Size, DestSize As Size) As Size Dim cR, iR, rW, rH As Single cR = DestSize.Width / DestSize.Height iR = SrcSize.Width / SrcSize.Height If cR < iR Then rW = DestSize.Width rH = rW / iR Else rH = DestSize.Height rW = rH * iR End If Return New Size(rW, rH) End Function - ситайпы с сендером это гомеопатия наверное
ну в общем даже с оптимизациями, когда форму на весь экран делаешь (ручками не максимайзом), ощущается что фпс скейла падает
я так понимаю потомучто куча спрайтов каждый раз создается под размер вьюпорта
была конечно мысль, для вьюпорта создать 1 большой спрайт, все равно при паинттодевайсе он обрежется, но я не уверен что это как-то положительно скажется.
если скинешь свой код, я гляну, может я что-то не так придумал
На счёт асм-вставок - код ресайза их не использует, так что тут нет разницы между версиями.
Вот пример на VB6: https://disk.yandex.ru/d/axAKKGfmpDU70w
Исходный размер такой, какого размера подсунешь картинку.
Не осень понял, каким боком тут альфу прикручивать.
Mikle
ну я делаю тулзу которая будет с картинкой работать, нужно видеть сразу какая там альфа
один из инструментов её потом удалять будет (к примеру удалить все полупрозрачные пиксели и оставить только чисто не прозрачные)
сейчас гляну
чекнул
все так-же да, маленькая картинка замедляется когда форма подходит к размеру экрана (1920 на 1080)
а очень большая картинка (тупо фото с телефона, типа 3000 на 4000) в целом тормознуто скейлится
ну раз там не используются асмы значит, есть как есть)
Mikle
Public Sub New(ByVal W As Integer, ByVal H As Integer, Optional ByVal Op As SR2D.Op = SR2D.Op.Paint) MyBase.New() If Op = SR2D.Op.DefaultOp Then Op = SR2D.Op.Paint Init(W, H, Op) End Sub
а в чем смысл дефолтного оп, если он все равно паинт, и опциональный аргумент и так паинт?
я что-то смутно припоминаю, что у меня была какая-то путаница, когда я открывал пнг, и оп был альфа бленд что-ли или что-то такое
может ты менял что-то тут? вообще я чекнул исходник который в начале темы, там так-же