|
Post by Roger Cabo on Jan 15, 2024 20:49:22 GMT 1
Long ago, I was fascinated by the Commodore Flight Sim, which displayed the entire world using just 16 white lines on a blue-green background. You can watch it here.. It's pretty funny to see it nowadays. www.youtube.com/watch?v=uCehXfpJVUA These days, we have the ultimate UHD 3D solutions provided by GPU vendors. Nevertheless, with the assistance of Chat GPT, I've been able to construct the fundamental structures and mathematical components required. One crucial step was aligning everything with Unity3D as the basic coordinate reference to facilitate result comparisons. I'm currently in the midst of engine calculations, addressing z-buffers, quaternions, and transformations to enable object rotation and movement similar to Unity3D. I'm not entirely certain if I'll be able to resolve all the complex issues in the end. The engine currently consists of approximately 1000 lines of code without optimization at this stage. One particularly intricate feature is triangle screen clipping. ChatGPT wasn't able to provide assistance with this due to its complexity. So, I came up with a very clever and efficient solution. I encapsulated each triangle with a bounding box and compared the aligned box with the screen rectangle. It's not perfect but incredibly helpful. Additionally, it's important to disable triangles that are beyond the camera's far distance and below the camera's position. The initial solution has proven to be an amazing aid. My primary objective is to overcome Unity's limitation of a maximum display distance of 4000 meters without camera jiggle and jerks, extending it to approximately 9,999,999,999.99999 meters while calculating with five decimal places. So I reach a distance by about +/-99.000.000 kilometers with fraction of 0.0001. Not optimized
Function IsTriangleVisibleOnScreen(ByRef tri2D As Tri2D, screenWidth As Double, screenHeight As Double) As Boolean Dim minX As Double, minY As Double, maxX As Double, maxY As Double ' Initialisiere die Min- und Max-Werte mit den Koordinaten des ersten Punktes minX = tri2D.p(0).x maxX = tri2D.p(0).x minY = tri2D.p(0).y maxY = tri2D.p(0).y ' Finde die Min- und Max-Werte für X und Y Dim i As Integer For i = 1 To 2 If tri2D.p(i).x < minX Then minX = tri2D.p(i).x If tri2D.p(i).x > maxX Then maxX = tri2D.p(i).x If tri2D.p(i).y < minY Then minY = tri2D.p(i).y If tri2D.p(i).y > maxY Then maxY = tri2D.p(i).y Next i ' Überprüfe, ob das AABB außerhalb des Bildschirms liegt If maxX < 0 || minX > screenWidth || maxY < 0 || minY > screenHeight Then Return False Else Return True End If End Function This is my first try to display 2 triangles as a carpet in front of the cam. And this is what Unity3d does. A great way to compare if your stuff fails or not.
|
|
|
Post by dragonjim on Jan 16, 2024 10:29:34 GMT 1
This looks very promising. 👍
|
|
|
Post by Roger Cabo on Jan 16, 2024 21:06:58 GMT 1
Thank you!
It's not only the renderer.. it use the transform logic of unity3d, means all objects are created in a hierarchy and can be rotated, moved, scaled by parent and child objects separately. And I like to add all the 3D trigonometric functions as well, step by step.
At a later stage could be possible to integrate opengl.
|
|
|
Post by Roger Cabo on Jan 16, 2024 22:52:26 GMT 1
Big question!
I have an really amazing optimization to draw a clipped (screen space) triangle. I defined a screen by memory allocation, by Dim Screen%(_X *_Y) : ScreenAdr% = V:Screen%(0)
Now...
I like to copy this memory ScreenAdr% area by BMOVE or BitBlt into a render texture and display by D2EndDraw Is this possible anyhow?
|
|
|
Post by dragonjim on Jan 16, 2024 23:31:13 GMT 1
I haven't got time to try it out but, as long as the rendered object is a Bitmap, then I suppose, logically at least, it should...
|
|
|
Post by (X) on Jan 17, 2024 14:28:20 GMT 1
I think you should look into using DIBs. Peter Heinzig uses them extensively to modify BMP to perform blurr, sharpen etc. He uses assembly language in some of his demos so they may even be faster than normal.
|
|
|
Post by Roger Cabo on Jan 17, 2024 17:53:51 GMT 1
Thank you.. X
Here is a test case for DIBs. Requires about 6.5ms on my fast system.. that's a bit ungly. Perhaps dragonjim has an additional idea to use GDI in this case anyhow?
// Clearing the memory takes about 0.5ms. That's great on a 4K display! MemZero RenderBmpRamAdr, bminfo.bmh.biWidth * bminfo.bmh.biHeight * 4 // Fastest for clr the memory. I think..
In the end it will be possible to use openGL for Final rendering in the code. But as I know it starts to CAM jiggle > 4000m slightly raise up with every 100m dramatically. For small environments below 1000*1000m it works perfect..
This demos show about 6ms to draw a 4K Image.. that too long unfortunately..
$Library "gfawinx" $Library "UpdateRT" $Library "direct2d"
// ........................................................................................................ // Calculate speed of passing a bitmap to D2D // ........................................................................................................
OpenW 1, 0, 0, _X, _Y, ~15
Global Object Win1RT Set Win1RT = D2GetRT(Win_1.hWnd) Set Me = Win_1
// ........................................................................................................
// Create a bitmap in the PC Ram Type BITMAPINFOHEADER - DWord biSize - Long biWidth, biHeight - Word biPlanes, biBitCount - DWord biCompression, biSizeImage - Long biXPelsPerMeter, biYPelsPerMeter - DWord biClrUsed, biClrImportant End Type
Type BITMAPINFO bmh As BITMAPINFOHEADER End Type
Global bminfo As BITMAPINFO
bminfo.bmh.biSize = SizeOf(bminfo.bmh) bminfo.bmh.biWidth = _X bminfo.bmh.biHeight = _Y bminfo.bmh.biPlanes = 1 bminfo.bmh.biBitCount = 32 // ... biCompression, biSizeImage, biXPelsPerMeter, biYPelsPerMeter, biClrUsed, und biClrImportant = 0
Global RenderBmpRamAdr As Long
// ... Create a Bitmap in the PC Ram Global RenderDib As Handle = CreateDIBSection(Null, bminfo, DIB_RGB_COLORS, V:RenderBmpRamAdr, Null, 0)
''' Draw something into the RAM Bitmap Global Object D2DRenderBMP // ..........................
Global t# = Timer Global counter% Global frames#
$StepOff
FontSize = 18 Do D2BeginDraw Win1RT, D2C_Black RenderLoop() D2EndDraw // do not enable to calculate speed PeekEvent Until Me Is Nothing
Proc RenderLoop() counter%++ Dim td# = Timer // LByte (A|R|G|B) MemZero RenderBmpRamAdr, bminfo.bmh.biWidth * bminfo.bmh.biHeight * 4 // fastest for clr the memory. // D2Bitmap takes about 6ms on my machine.. that's pretty long.. // The bitmap musst pass through the north bridge into the GPU.. But the bandwidth through the north-bridge is about 320GB/s.. peanuts for the system normally Set D2DRenderBMP = D2Bitmap(RenderDib, WICBitmapUsePremultipliedAlpha /* <--- fastest */) // D2Put 0, 0, D2DRenderBMP td# = (Timer - td#) * 1000 If Timer - t# > 1 t# = Timer // ~158 on UHD. ~260 on HD Print AT(1, 1); " Times per second: " & counter Print AT(1, 2); " Required ms " & 1000 / counter Print AT(1, 3); " Direct time of call ms " & td# counter% = 0 EndIf EndProc
|
|
|
Post by Roger Cabo on Jan 20, 2024 23:57:20 GMT 1
Goal: www.youtube.com/watch?v=ftfERePINcIAnother attempt. The biggest challenges are drawing and clipping polygons and their sizes, and writing polygon drawing data from 2D and 3D into the z-buffer. Of course, these are all tasks a graphics card can handle. However, to really move a camera in space, to rotate the camera point, matrices are required that inversely transform the world, which also works for me so far. In a new attempt, I will see if I can manage to prepare the object data so that I can display it with D2D or OpenGL. Sadly, with a tear in my eye, as the size of the visible world can only be a maximum of 9999m. Even for this, the calculation must be in double, so that the results do not get camera floating point jitter problems when we have reached the end of our world. I would prefer to have an "unlimited space" available, with double, but D2D and OpenGL do not provide this. Certainly, there are some tricks, like shifting parts of the world to the camera, but this is not easily feasible.
Une autre tentative. Les plus grands défis sont le dessin et le découpage de polygones et leurs tailles, ainsi que l'écriture des données de dessin de polygones de 2D et 3D dans le z-buffer. Bien sûr, ce sont toutes des tâches qu'une carte graphique peut gérer. Cependant, pour vraiment déplacer une caméra dans l'espace, pour faire tourner le point de la caméra, des matrices sont nécessaires qui transforment inversement le monde, ce qui fonctionne aussi pour moi jusqu'à présent. Dans une nouvelle tentative, je verrai si je peux préparer les données d'objet pour que je puisse les afficher avec D2D ou OpenGL. Malheureusement, avec une larme à l'œil, car la taille du monde visible ne peut être que de 9999m maximum. Même pour cela, le calcul doit être en double, pour que les résultats n'obtiennent pas de problèmes de jitter de point flottant de la caméra lorsque nous avons atteint la fin de notre monde. Je préférerais avoir un "espace illimité" disponible, avec double, mais D2D et OpenGL ne le permettent pas. Certes, il existe quelques astuces, comme le déplacement de parties du monde vers la caméra, mais cela n'est pas facilement réalisable.
Another issue with the display, and when moved with the mouse, are the clippings and the hiding of polygons that get very large values through the calculation. Un autre problème avec l'affichage, et lorsqu'il est déplacé avec la souris, sont les clippings et la dissimulation de polygones qui obtiennent des valeurs très grandes à travers le calcul. Quaternion_11.G32 (28.1 KB)
|
|
|
Post by Roger Cabo on Jan 21, 2024 20:11:00 GMT 1
There is a bug in the world My goal was to use Quaternion and calculate the world rotation with these algorithms. Then use the double precision to display the D2D/OPenGL triangles.. So you got a great precision up to 9999meter.. over all. The transformations al correct in every axis.. but each time I move the mouse in a small clockwise circle the the camera axis rotates slowly as well. And when rotation the mouse in small circles CCW, the Z axis rotated in the other direction..
Il y a un bug dans le monde Mon objectif était d'utiliser les Quaternions et de calculer la rotation du monde avec ces algorithmes. Puis d'utiliser la précision double pour afficher les triangles D2D/OpenGL... Ainsi, vous obtenez une grande précision jusqu'à 9999 mètres, sur tout. Les transformations sont correctes dans chaque axe... mais chaque fois que je bouge la souris en petit cercle dans le sens des aiguilles d'une montre, l'axe de la caméra tourne lentement également. Et lorsque je tourne la souris en petits cercles dans le sens contraire des aiguilles d'une montre, l'axe Z tourne dans l'autre direction..
These function are involved into the rotation: Proc MouseLookAround(x#, y#) Proc Transform_Rotate(ByRef t As Transform, ByRef deltaRotation As Quaternion) Function I_QuatMultiply(ByRef q1 As Quaternion, ByRef q2 As Quaternion) As Quaternion Function NormalizeQuaternion(ByRef q As Quaternion) As Quaternion Move the mouse in small circles and you will see the strange effect.. CHATGPT_Rotate.G32 (21.4 KB)
|
|
|
Post by Roger Cabo on Jan 22, 2024 10:53:24 GMT 1
If I didn't get this to work, then I must stop this project. ChatGPT din't find the error as well..
that's really frustrating..
|
|
|
Post by scalion on Jan 22, 2024 10:55:56 GMT 1
Wow you are in the deep working ! Why don't you use your own matrix system and simplify the calculations. This is what I did with my STL file program. I defined my 3x3 matrix (instead of 4x4) as a simple rotation matrix. I don't use a translation matrix (4x4) and that solves a lot of problems. For information, a 3x3 matrix is this:
You rotate your matrix in x,y or z and to obtain the new position of point i use this function :
Function Matrix_Apply(ByRef M As Matrix_Struct, ByRef x As Double, ByRef y As Double, ByRef z As Double) Local Double xNew, yNew, zNEw xNew = M.Xx * x + M.Yx * y + M.Zx * z yNew = M.Xy * x + M.Yy * y + M.Zy * z zNEw = M.Xz * x + M.Yz * y + M.Zz * z x = xNew y = yNew z = zNEw EndFunc
|
|
|
Post by Roger Cabo on Jan 22, 2024 14:22:49 GMT 1
Wow you are in the deep working ! Why don't you use your own matrix system and simplify the calculations. This is what I did with my STL file program. I defined my 3x3 matrix (instead of 4x4) as a simple rotation matrix. I don't use a translation matrix (4x4) and that solves a lot of problems. For information, a 3x3 matrix is this:
You rotate your matrix in x,y or z and to obtain the new position of point i use this function :
Function Matrix_Apply(ByRef M As Matrix_Struct, ByRef x As Double, ByRef y As Double, ByRef z As Double) Local Double xNew, yNew, zNEw xNew = M.Xx * x + M.Yx * y + M.Zx * z yNew = M.Xy * x + M.Yy * y + M.Zy * z zNEw = M.Xz * x + M.Yz * y + M.Zz * z x = xNew y = yNew z = zNEw EndFunc
Yes I thought about.. from what I know there is a Gimbal lock error happen on 3 mats mostly.. while the camera is facing 2 coordinates at nearly 0. You rotate the world around the 0,0,0 position.. for a camera movement you need an inverse world translation. The view matrix should represent the inverse transformation of the camera's position and orientation. For example, if you rotate the camera to the right, the view matrix should apply a leftward rotation to the entire scene. Rotation around world zero 0,0,0 does not have any problems for any reasons.. If you have some time, you should test moving the camera freely around on all axis at the same time with your vector3..
Oui, j'y ai pensé... d'après ce que je sais, une erreur de verrouillage de cardan se produit principalement sur 3 matrices... lorsque la caméra fait face à 2 coordonnées presque égales à 0. Tu fais tourner le monde autour de la position 0,0,0... pour un mouvement de la caméra, tu as besoin d'une translation inverse du monde. La matrice de vue doit représenter la transformation inverse de ta position et de ton orientation de la caméra. Par exemple, si tu tournes la caméra vers la droite, la matrice de vue doit appliquer une rotation vers la gauche à l'ensemble de la scène. La rotation autour de l'origine du monde à 0,0,0 ne pose aucun problème pour quelque raison que ce soit... Si tu as un peu de temps, tu devrais essayer de déplacer la caméra librement sur tous les axes en même temps. Avec ta routine vec3.
This is the complete functionality to rotate the word into any direction.. // move the world x and y, but this have a sightly bad rotation about z... if z=0 anyway Proc MouseLookAround(x#, y#, z#) Dim sensitivity# = 2 Dim deltaX As Integer Dim deltaY As Integer Dim deltaZ As Integer deltaX = x - lastMouseX // Differenz deltaY = y - lastMouseY // Differenz deltaZ = z - lastMouseZ // Differenz lastMouseX = x lastMouseY = y lastMouseZ = z
Dim deltaRotation As Quaternion Dim v3 As Vector3 v3 = NEW_Vector3(deltaY * sensitivity * Time_deltaTime#, deltaX * sensitivity * Time_deltaTime#, deltaZ * sensitivity * Time_deltaTime#) deltaRotation = I_EulerToQuaternion(v3)
/// anwenden der delta-Rotation auf die aktuelle kamera-rotation Cam.transform.rotation = I_QuatMultiply(Cam.transform.rotation, deltaRotation)
/// normalisieren des resultierenden quaternions Cam.transform.rotation = NormalizeQuaternion(Cam.transform.rotation) EndProc
Function I_QuatMultiply(ByRef q1 As Quaternion, ByRef q2 As Quaternion) As Quaternion Dim result As Quaternion result.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z result.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y result.y = q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x result.z = q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w Return result End Function
Function NormalizeQuaternion(q As Quaternion) As Quaternion Dim length As Double length = Sqrt(q.w * q.w + q.x * q.x + q.y * q.y + q.z * q.z) If length <> 0 Return Quaternion(q.w / length, q.x / length, q.y / length, q.z / length) Else Return Quaternion(1, 0, 0, 0) ' Einheitsquaternion zurückgeben, um Division durch Null zu vermeiden End If End Function
|
|
|
Post by (X) on Jan 22, 2024 17:08:29 GMT 1
I asked BING... We are developing programs in GB32 (GFA-BASIC 32 for Windows. It would be great to work out a GB32 based "virtual world" with easy to access camera movements and object behaviour: LIGHT, CAMERA ACTION. Do you have any suggestions?
|
|
|
Post by Roger Cabo on Jan 22, 2024 19:37:50 GMT 1
ChatGPT would say: Learn math at first until you know 10% of Einstein!
|
|