feat(demo): add WindingOrderDemo to test backface culling
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Sun, 15 Mar 2026 18:40:36 +0000 (20:40 +0200)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Sun, 15 Mar 2026 18:40:36 +0000 (20:40 +0200)
- Add minimal demo with CCW triangle (front face, visible)
- Update AGENTS.md with winding order guidelines and run command

AGENTS.md
src/main/java/eu/svjatoslav/sixth/e3d/examples/WindingOrderDemo.java [new file with mode: 0644]

index 8b6057f..899d46f 100644 (file)
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -40,6 +40,9 @@ java -cp target/sixth-3d-demos.jar eu.svjatoslav.sixth.e3d.examples.life_demo.Ma
 
 # Run Point Cloud Galaxy demo
 java -cp target/sixth-3d-demos.jar eu.svjatoslav.sixth.e3d.examples.galaxy_demo.PointCloudDemo
+
+# Run Winding Order demo (tests backface culling)
+java -cp target/sixth-3d-demos.jar eu.svjatoslav.sixth.e3d.examples.WindingOrderDemo
 ```
 
 ### Testing
@@ -67,6 +70,7 @@ src/main/java/eu/svjatoslav/sixth/e3d/examples/
 ├── TextEditorDemo.java
 ├── TextEditorDemo2.java
 ├── RainingNumbersDemo.java
+├── WindingOrderDemo.java    - Tests winding order & backface culling
 └── package-info.java
 ```
 
@@ -116,6 +120,13 @@ public class MyShape extends AbstractCompositeShape {
 
 Implement `MouseInteractionController` for mouse events, or extend input tracker classes for keyboard input.
 
+### Polygon Winding Order
+
+When creating triangles with backface culling enabled, use CCW winding in screen space:
+- Vertex order: top → lower-left → lower-right (as seen from camera)
+- `signedArea < 0` = front-facing = visible
+- See `WindingOrderDemo.java` for a minimal example
+
 ## Documentation
 
 Always make sure that documentation in`doc/index.org` stays up to date.
diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/WindingOrderDemo.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/WindingOrderDemo.java
new file mode 100644 (file)
index 0000000..d81426f
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Sixth 3D engine demos. Author: Svjatoslav Agejenko.
+ * This project is released under Creative Commons Zero (CC0) license.
+ *
+ */
+package eu.svjatoslav.sixth.e3d.examples;
+
+import eu.svjatoslav.sixth.e3d.geometry.Point3D;
+import eu.svjatoslav.sixth.e3d.gui.ViewFrame;
+import eu.svjatoslav.sixth.e3d.gui.ViewPanel;
+import eu.svjatoslav.sixth.e3d.renderer.raster.Color;
+import eu.svjatoslav.sixth.e3d.renderer.raster.ShapeCollection;
+import eu.svjatoslav.sixth.e3d.renderer.raster.shapes.basic.solidpolygon.SolidPolygon;
+
+/**
+ * Demo to test winding order and backface culling documentation.
+ * <p>
+ * Creates one triangle with CCW winding (front face) following the docs:
+ * <ul>
+ *   <li>upper-center → lower-left → lower-right</li>
+ *   <li>Backface culling enabled</li>
+ * </ul>
+ * <p>
+ * Expected: green triangle visible (CCW = front face).
+ */
+public class WindingOrderDemo {
+
+    public static void main(String[] args) {
+        ViewFrame viewFrame = new ViewFrame();
+        ViewPanel viewPanel = viewFrame.getViewPanel();
+        ShapeCollection shapes = viewPanel.getRootShapeCollection();
+
+        double size = 150;
+
+        Point3D upperCenter = new Point3D(0, -size, 0);
+        Point3D lowerLeft = new Point3D(-size, +size, 0);
+        Point3D lowerRight = new Point3D(+size, +size, 0);
+
+        SolidPolygon triangle = new SolidPolygon(upperCenter, lowerLeft, lowerRight, Color.GREEN);
+        triangle.setBackfaceCulling(true);
+
+        shapes.addShape(triangle);
+
+        viewPanel.getCamera().getTransform().setTranslation(new Point3D(0, 0, -500));
+
+        viewPanel.ensureRenderThreadStarted();
+    }
+}
\ No newline at end of file