Direct3D9 в VB6.

Автор обещает много интересных штучек.

Модератор: The trick

Old_Maple
Обычный пользователь
Обычный пользователь
 
Сообщения: 54
Зарегистрирован: 25.10.2016 (Вт) 12:03

Re: Direct3D9 в VB6.

Сообщение Old_Maple » 17.03.2017 (Пт) 8:10

Спасибо, Mikle! Все правильно заработало!
Veritas est aeterna!

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Direct3D9 в VB6.

Сообщение The trick » 06.05.2018 (Вс) 23:58

Обновление.

Новые примеры:
  • Простая сцена (камера, процедурная генерация, выбор мышью, трансформации);
  • "Лазерные" линии;
  • Рендеринг в отдельном потоке.
Исправлены баги в функциях:
  • D3DXMatrixTranspose;
  • D3DXMatrixRotationQuaternion;
  • D3DXVec2Length.
Изменения:
  • Изменен прототип для функции D3DXPlaneIntersectLine, вместо генерации ошибки функция возвращает значение;
  • Изменено поведение функции D3DXQuaternionToAxisAngle, теперь она может принимать ненормализованные кватернионы.

UA6527P

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Direct3D9 в VB6.

Сообщение Mikle » 02.02.2020 (Вс) 13:29

Я оптимизировал MatrixInverse почти в 2 раза по быстродействию, есть мысли на счёт дальнейшей оптимизации.
Пока так:
Код: Выделить всё
Public Function MatrixDeterminant(pM As D3DMATRIX) As Single
  Dim Minor   As D3DVECTOR4
  Dim v1      As D3DVECTOR4
  Dim v2      As D3DVECTOR4
  Dim v3      As D3DVECTOR4

  v1.x = pM.m11:  v1.y = pM.m21:  v1.z = pM.m31:  v1.w = pM.m41
  v2.x = pM.m12:  v2.y = pM.m22:  v2.z = pM.m32:  v2.w = pM.m42
  v3.x = pM.m13:  v3.y = pM.m23:  v3.z = pM.m33:  v3.w = pM.m43

  v4Cross Minor, v1, v2, v3
  MatrixDeterminant = -(pM.m14 * Minor.x + pM.m24 * Minor.y + pM.m34 * Minor.z + pM.m44 * Minor.w)
End Function

Public Function MatrixInverse(mOut As D3DMATRIX, Determinant As Single, Mtrx As D3DMATRIX) As Boolean
  Dim a       As Long
  Dim i       As Long
  Dim j       As Long
  Dim v       As D3DVECTOR4
  Dim Vec(2)  As D3DVECTOR4
  Dim Det     As Single
  Dim M(3, 3) As Single
  Dim o(3, 3) As Single
  Dim IDet    As Single

  Det = MatrixDeterminant(Mtrx)
  If Det = 0 Then Exit Function

  Determinant = Det
  IDet = 1 / Det
  MemCpy M(0, 0), Mtrx, 64

  For i = 0 To 3
    For j = 0 To i - 1
      Vec(j).x = M(j, 0)
      Vec(j).y = M(j, 1)
      Vec(j).z = M(j, 2)
      Vec(j).w = M(j, 3)
    Next j
    For j = i To 2
      Vec(j).x = M(j + 1, 0)
      Vec(j).y = M(j + 1, 1)
      Vec(j).z = M(j + 1, 2)
      Vec(j).w = M(j + 1, 3)
    Next j

    v4Cross v, Vec(0), Vec(1), Vec(2)

    o(0, i) = v.x * IDet
    o(1, i) = v.y * IDet
    o(2, i) = v.z * IDet
    o(3, i) = v.w * IDet
    IDet = -IDet
  Next i
  MemCpy mOut, o(0, 0), 64
  MatrixInverse = True
End Function

Private Sub v4Cross(vOut As D3DVECTOR4, v1 As D3DVECTOR4, v2 As D3DVECTOR4, v3 As D3DVECTOR4)
  vOut.x = v1.y * (v2.z * v3.w - v3.z * v2.w) - v1.z * (v2.y * v3.w - v3.y * v2.w) + v1.w * (v2.y * v3.z - v2.z * v3.y)
  vOut.y = -(v1.x * (v2.z * v3.w - v3.z * v2.w) - v1.z * (v2.x * v3.w - v3.x * v2.w) + v1.w * (v2.x * v3.z - v3.x * v2.z))
  vOut.z = v1.x * (v2.y * v3.w - v3.y * v2.w) - v1.y * (v2.x * v3.w - v3.x * v2.w) + v1.w * (v2.x * v3.y - v3.x * v2.y)
  vOut.w = -(v1.x * (v2.y * v3.z - v3.y * v2.z) - v1.y * (v2.x * v3.z - v3.x * v2.z) + v1.z * (v2.x * v3.y - v3.x * v2.y))
End Sub

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Direct3D9 в VB6.

Сообщение The trick » 03.02.2020 (Пн) 17:31

Спасибо! Я писал эти функции основываясь на исходниках то ли Wine, то ли ReactOS, но и там были несоответствия вроде бы с реальными из d3dx (я даже по-моему у тебя спрашивал), приходилось реверсить.
UA6527P

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Direct3D9 в VB6.

Сообщение The trick » 28.12.2020 (Пн) 23:32

Обновление.


  • Добавлена библиотека d3dxvb.tlb;
  • Добавлен пример CornerPin (перспективная трансформация по 4 точкам);
  • Добавлен пример Raymarching на HLSL шейдерах.

Изображение
Изображение
UA6527P

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Direct3D9 в VB6.

Сообщение Mikle » 29.12.2020 (Вт) 10:10

Вот это новогодний подарок!

Old_Maple
Обычный пользователь
Обычный пользователь
 
Сообщения: 54
Зарегистрирован: 25.10.2016 (Вт) 12:03

Re: Direct3D9 в VB6.

Сообщение Old_Maple » 16.03.2021 (Вт) 9:03

Искренне хочу The trik поблагодарить за обновление!
Мне, как и Mikle пришлось кое-что оптимизировать в части матриц и кватернионов. Там много операций делений, которые пришлось заменить умножением (разумеется, в тех случаях, где деление на одну и туже переменную происходит несколько раз), например norm. Вычисляя norm не как значение функции (norm = D3DXxxx(args)), а обратную ей (norm = 1! / D3DXxxx(args)), с последующим домножением norm к переменным. Производительность поднялась в среднем на 25-30%... Может еще как-то можно оптимизировать? ;-)
Veritas est aeterna!

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Direct3D9 в VB6.

Сообщение Хакер » 26.09.2022 (Пн) 21:59

Думаю, функцию D3DXMatrixPerspectiveFovXH, коль уж мы сами её реализовываем в обёртке, надо было сделать так, чтобы она принимала Width и Height вместо Aspect.

Потому что она либо несовместима с D3DXMatrixPerspectiveFovXH из обёртки над DX8, либо не совместима с одноимённой функцией из статической библиотеки DX9.

А так, если кто-то портирует код — не важно, с DX8VB или с DX9 на другом языке — в обоих случаях человек запнётся о несовместимость по набору параметров и вынужден будет задуматься и подправить код соответствующим его случаю образом.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Direct3D9 в VB6.

Сообщение Mikle » 26.09.2022 (Пн) 22:32

Хакер писал(а):если кто-то портирует код — не важно, с DX8VB или с DX9 на другом языке — в обоих случаях человек запнётся о несовместимость по набору параметров

Вроде, набор тот же самый, в том же порядке. Только в d3dx9 смысл aspect поменяли на обратный - в DX8VB было height/width, а в d3dx9 стало width/height. И это не только у The trick, но и в многочисленных d3dx9_xx.dll.
Возможно, это в DX8VB, библиотеке для VB, закралась ошибка, я сишные исходники по DX8 не смотрел.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Direct3D9 в VB6.

Сообщение Хакер » 26.09.2022 (Пн) 23:49

Mikle писал(а):Вроде, набор тот же самый, в том же порядке.

Сейчас да, а я предлагаю сделать так, чтобы набор и порядок был неодинаковый и при тупом копипасте ничего не компилировалось, что заставило бы человека обратить внимание на это место.

Это как Option Explicit: зелёные новички его ненавидят, потому что он постоянно портит им жизнь, а опытные понимают, что это спасительная и правильная вещь.

Я предлагаю сделать искуственную ловушку для потенциальной ошибки, касающейся интерптерации параметра aspect.

aspect в DX8VB (именно в этой обёртке над DX8, созданной для VB-программистов) вычисляется не так, как в целом в DX8.

Либо нужно в модулях Анатолия интерпретировать параметр aspect так, как это делала DX8VB, чтобы при портировании VB-проектов с DX8 на DX9 не пришлось менять height/width на width/height, потому что необходимость такой замены вообще не очевидна для VB-программиста, выполняющего портирование. И даже пробный запуск не покажет, что в коде что-то не так, если графика выводится на квадратный Viewport. Но тогда справедливо возмутятся люди, портирующие DX9-зависимый код с C++ на VB6: почему при смене языка поменялось поведение DX-овский функций.

Либо нужно делать, как Анатолий сделал сейчас, и воспринимать aspect так, как воспринимает его DX9 (и DX8, но не DX8VB). Но тогда нет прозрачности при переходе с DX8VB на решение Анатолия.

Я же предлагаю третий вариант: ни вашим, ни нашим. Убрать спорный и противоречивый аргумент aspect и заменить его на Width и Height. Пусть вызывающая сторона передаёт Width и Height, а функция сама рассчитывает aspect внутри себя, делая это так, как ей надо для правильного получения лементов матрицы.

Во-первых, это не даст заработать коду, написанному путём копипаста. Человеку придётся добраться до неработающей строчке. напрячь голову и передать Width туда, как функция ждёт Width, и Height туда, куда функция ждёт Height, что будет гарантировать правильность расчёта aspect ratio вне зависимости от того, портировали код из DX8VB-основанного проекта (где надо было делить высоту на ширину), или из DX9-зависимого сишного проекта (где надо было делать ширину на высоту).

Во-вторых, это даст самодокументируемость на уровне IntelliSense подсказок. Человек только начинает писать аргументы и по всплывающей подсказке видит, что вот тут у нас должна быть ширина, тут высота. Перепутать невозможно. А так, даже если бы в DX8VB не было путаницы и различия с D3DX8, всегда можно перепутать, как именно считать aspect (что на что делить).

И даже если в той функции, откуда предполагается выхываь D3DXMatrixPerspectiveFovXH, исходных значений Width и Height уже не достать, потому что они были известны где-то уровнем выше, а в текущую функцию пришли уже в поделённом друг на друга виде (как одно число), это не создаёт безвыходную ситуацию и не вынуждает кого бы то ни было переписывать всю цепочку вызовов от того места, где поделали Width и Height, до того места, где вызывают D3DXMatrixPerspectiveFovXH.

Достаточно просто вместо Width и Height передать (1; Aspect) или (Aspect; 1), в зависимости от того, что на что делили условными десятью уровнями выше по иерархии вызовов.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Direct3D9 в VB6.

Сообщение Mikle » 27.09.2022 (Вт) 8:31

Можно просто переименовать Aspect в WidthDivHeight
Да, при простой копипасте кода из dx8vb всё ещё будут проблемы, зато сохранится совместимость со всем остальным dx8 и dx9 кодом, которого гораздо больше.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Direct3D9 в VB6.

Сообщение Хакер » 27.09.2022 (Вт) 14:22

Mikle писал(а): зато сохранится совместимость со всем остальным dx8 и dx9 кодом, которого гораздо больше.

Так она и не теряется, достаточно в качестве одного из двух новых параметров передавать единичку, и по старому рассчитанный aspect в качестве оставшегося.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Пред.

Вернуться в The trick

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

    TopList