nathanielbabiak 2021-12-28 13:30 (Edited)
Just a quick update on this.
There's plenty of speed for 10 polys at 20 to 30 fps (so the math was right, not a surprise). I've got 12 polys at 30+ FPS, plenty of speed remains for the skybox, plane, and game. There's still a page-flip bug (commented-out on line 103). If fixed, the program would run faster in cases when the CPU isn't max'd out.
Arrow keys adjust camera/object/projection settings, hold A, B, or A+B to change what's adjusted. Angles are degrees... I'm not yet sure what the units are for position X/Y/Z adjustments, because the z-position changes dynamically with adjustments to field-of-view.
On line 17 you can adjust the test from 3D to 2D. For that one, use touchscreen and keyboard 'C' and 'R'. Even the 2D test is improved from the last one.
As before, there's still two pre-calc arrays I'm not super-comfortable with. They're 16k and 20k elements each. I think it breaks the spirit of LowRes NX, but I've left them in for speed to save a few clock cycles.
McPepic 2021-12-28 15:27
Thanks so much for sharing! I’m super excited about this project and can’t wait to see what comes of this. Keep up the good work, Nate! (I’m not entirely sure how this works, so I’ll just have to look over the code some more to understand it)
G-9 2021-12-28 16:21 (Edited)
whoah truly amazing
was8bit 2021-12-28 16:26
ヾ(๑╹◡╹)ノ"
( ◠‿◠ )
)^o^(
(*☻-☻*)
nathanielbabiak 2021-12-28 17:21 (Edited)
Thank you all!
@McPepic,
The display driver ("sprite expansion") is described here in the three paragraphs containing "technique" (use CTRL+F).
The upload here is kind'a similar, although I intend a few significant differences.
nathanielbabiak 2021-12-29 06:30 (Edited)
Today's upload rasterizes triangles crazy-fast, pixel-perfect, and with screen clipping. This proof of concept is actually faster than predicted by my initial estimates.
Perspective projection (3D) is next. I've been thinking about using LowRes for old-school projection for two years, ever since I uploaded this. At the time, I was planning a game in the style of 1984's Elite Dangerous using the Pxl Library, but that display driver is just too slow.
The rotation, projection, and HSD (hidden surface determination) code is actually written already, just not imported, checked, or optimized.
More to come...
nathanielbabiak 2021-12-29 06:39 (Edited)
Ultimately, I'm hoping others might take attempt developing in 3D also. Towards that goal, here's a quick write-up. My next upload will do all this, but the narrative just makes it easier to follow along.
(There's two separate topics that won't be addressed here: rotation and projection. For rotation, I'm not sure yet if matrices or quaternions will be faster.)
Objects are made of triangles. The goal is to determine which triangles to draw, which to skip drawing, and how to layer them on-screen overtop one another.
Only allow rigid objects. For example, an airplane could have wings, but the control surfaces would not move.
Group the triangles of a single object together, and clip entire objects (groups of triangles) if the whole object is off-screen. (Don't attempt to predict if individual triangles will be clipped. LowRes is pretty slow, so the best we can hope for is something looking like 1993's Star Fox. LowRes is too slow for full scenes, so just don't worry about it.)
Limit all objects to convex polyhedron. These polyhedron have a special property: their triangles facing towards the camera get shown, their triangles facing away from the camera don't, and their triangles never overlap.
Perform back-face culling (the determination of which surfaces are facing away from the camera). With your mind's eye, imagine viewing each triangle from the outside of the object, then order the three points of the triangle counter-clockwise (X1,Y1,Z1)
, (X2,Y2,Z2)
, and (X3,Y3,Z3)
.
4.1. (Determine the orientation/rotation of each triangle.) Pre-calculate the normal vector of each triangle's cross product (VX0,VY0,VZ0)
on (A:=2->1) x (B:=3->1)
as:
AX = X2 - X1
AY = Y2 - Y1
AZ = Z2 - Z1
BX = X3 - X1
BY = Y3 - Y1
BZ = Z3 - Z1
VX0 = AY * BZ - AZ * BY
VY0 = AZ * BX - AX * BZ
VZ0 = AX * BY - AY * BX
4.2. (Determine the location of each triangle.) Pre-calculate each triangle's centroid (CX0,CY0,CZ0)
as:
CX0 = ( X1 + X2 + X3 ) / 3
CY0 = ( Y1 + Y2 + Y3 ) / 3
CZ0 = ( Z1 + Z2 + Z3 ) / 3
4.3. At runtime, calculate each triangle's rotation of the cross product (VX,VY,VZ)
, and calculate each triangle's rotation and translation of the centroid (CX,CY,CZ)
relative to the camera. This will be explained separately - it's hard!
4.4. At runtime, calculate each triangle's dot product S
between (VX,VY,VZ)
and (CX,CY,CZ)
as:
S = VX * CX + VY * CY + VZ * CZ
4.5. If S>0
the triangle is facing the camera, if S<0
it's facing away, and if S=0
the camera is on the triangle's plane (meaning only the edge of the triangle is visible). Thus, use SGN(S)
to decide whether to draw the triangle or not.
(BX0,BY0,BZ0)
. At runtime, rotate/translate during step 4.3 above to get (BX,BY,BZ)
relative to the camera, then use the painter's algorithm to draw objects layered farthest to closest by their BZ
value.SWAP
instructions inside. (No code listing for this one, you'll see it in my upload soon.)6.1. The antenna has depth, so you'll always show its graphic. If its associated anchor triangle yields S>0
, then use the painter's algorithm and layer the antenna in front of the remainder of the rigid body. If its associated anchor triangle yields S<0
, then put it behind instead. The 'graphic' is just more triangles (although the word 'triangle' was avoided until now to prevent confusing the 'graphic' with the anchor triangle).
6.2. The dot (pixel pattern) doesn't have depth, so it doesn't always need shown. If its associated anchor triangle yields S>0
, show it, but otherwise just don't draw.
6.3. Note that the antenna will always be perpendicular to its anchor triangle, but the anchor triangle doesn't need shown as part of the rigid body. You could define an anchor triangle specifically to get some oblique rotation (rather than limiting your antennas to right-angles from the body's triangles), but never display it. Just make sure to rotate any anchor triangles with step 4.3 above.
That's everything! Basically just keep track of the different types of coordinate triples and you'll be good-to-go.
moechofe 2022-01-01 22:24
good stuff
nathanielbabiak 2022-01-05 06:02 (Edited)
Today's upload implements #1 through #4. For rotations, ultimately matrices were faster, they're shown in the M_ROTATE_xxxx
subprograms. For projection, that's shown in M_PROJECT_DRAW
.
LowRes isn't fast enough to multiply homogenous 4x4 matrices, so I couldn't copy-paste the code from legacy OpenGL. I was forced to cobble together a state machine using 3x3 matrices instead (I still referenced legacy OpenGL tutorials to get the math right, but it was much harder than I expected!)
More to come...
Mrlegoboy 2022-02-09 19:04
this is way better than anything previous. i wish i never got an android so i could do something with this.
GAMELEGEND 2022-04-08 05:25 (Edited)
woah woah hold on there Mrlegoboy
just take a look at this https://lowresnx.inutilis.com/topic.php?id=2323#post-16194
i got the linux version of lowres running on my android device and these are the steps
the best part is is that works on a non rooted device