AgonConsole8 / agon-vdp

Official Firmware for the Agon Console8: ESP32 VDP
MIT License
38 stars 17 forks source link

Triangle strips, and/or filled path PLOTs #159

Closed stevesims closed 5 months ago

stevesims commented 7 months ago

Currently we support single filled triangles.

triangle strips are a system whereby if you draw a triangle with points a, b and c, then the next triangle in the strip will use points b, c and d, the next triangle after that uses c, d and e and so on

Owing to the nature of the PLOT system, in which every PLOT command pushes coordinates to a stack for use in subsequent commands, this behaviour is already supported by the VDP. however, it could be supported in a more efficient manner.

the underlying vdp-gl graphics system supports filled paths, rather than just filled triangles. rather than filling one triangle at a time in a triangle strip, we could instead bundle multiple triangles together into a single path to be filled. this will reduce the number of graphics operations for vdp-gl to handle down to a single "fill path" for a triangle strip, rather than the current multiple triangle fill operations.

the basic algorithm for converting a triangle strip into a path is to alternate pushing points between the beginning and end of the points list. the path would be committed and drawn when a VDU command that is not another "plot triangle strip" command is detected. the "plot triangle strip" command handler can look ahead at the next byte in the command stream - if there are no subsequent commands available, or if the next command is not a PLOT call, then the strip should be "committed" to be drawn.

it is suggested that this should be implemented using a separate PLOT code. a limitation of transforming a triangle strip into a single filled path is that overlapping triangles will not result in a path that matches individually drawn triangles, therefore it's not "safe" or compatible to just bundle together triangles drawn with the existing triangle fill call into a fill path. the behaviour of a "triangle strip" plot is therefore subtly different from a regular "triangle" plot

(the primary problem with trying to make this work with the existing triangle PLOT code is detecting overlapping lines. if a simple/efficient way can be found to detect overlaps, then on detecting an overlap the current strip should be "committed" and a new strip started. this would allow the existing triangle plots to remain completely compatible with their current behaviour, even with the new GCOL paint modes, and arguably negate the need for a separate/new PLOT code.)

a similar PLOT command to just build up an arbitrary path to fill (rather than a triangle strip) can potentially be achieved in a very similar manner - the primary difference would just be to keep pushing points to the end of the points list, rather than alternating. this PLOT command however would have the risk of the path not being completed thru data not being available from the command comms stream. either the advice would be to only use such a PLOT command from a buffer (where you can guarantee all points would be available), or a more sophisticated strategy would be needed to ensure points are properly collected.

stevesims commented 7 months ago

This library may have a routine that could be used to detect line intersections: https://github.com/OneLoneCoder/olcUTIL_Geometry2D

what we need to check for is if a new point is contained within one of the existing triangles, which this function will do: https://github.com/OneLoneCoder/olcUTIL_Geometry2D/blob/66df05517f3895829e59a4f03e1562afa7ba2d56/olcUTIL_Geometry2D.h#L1055 see also: https://jsfiddle.net/PerroAZUL/zdaY8/1/

we'd also need to check whether the potential new line overlaps any of the existing lines: https://github.com/OneLoneCoder/olcUTIL_Geometry2D/blob/66df05517f3895829e59a4f03e1562afa7ba2d56/olcUTIL_Geometry2D.h#L1260

stevesims commented 6 months ago

An experimental path fill PLOT command can be found in #160

given the difficulty in ensuring that data sent for a triangle strip would create a valid path, and currently our only option for handling them is to convert to a filled path, there seems at this time to be little advantage in supporting triangle strips, especially if filled paths are supported.

stevesims commented 5 months ago

experimental filled path has been released as part of 2.7.0

closing this issue, as it is unlikely that we will support triangle strips - that optimisation probably isn't worth it