Skip to content

Render triangulated polygons in OpenGL - #68

Open
pmeems wants to merge 1 commit into
polygon-triangulation-corefrom
polygon-triangulation-opengl
Open

pmeems wants to merge 1 commit into
polygon-triangulation-corefrom
polygon-triangulation-opengl

Conversation

@pmeems

@pmeems pmeems commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

Phase 2 of the polygon triangulation plan: the OpenGL backend now consumes the Core-prepared triangle meshes instead of GL_POLYGON, so concave polygons, interior rings and multipart geometries render on the GPU.

Depends on #66 (stacked; base branch is polygon-triangulation-core).

What changed

  • Polygon fills use indexed triangle rendering through the OpenGL 1.1 client-side vertex-array API (glVertexPointer, glDrawElements, glEnableClientState); no GL_POLYGON remains.
  • Outlines are drawn from the original rings of VectorRenderScene, so exterior, hole and multipart boundaries are preserved and internal triangle edges are never outlined.
  • The convexity and single-ring restrictions are removed; scenes are accepted when every polygon has a usable mesh (complete triangles, in-range indices, finite coordinates). A polygon without a mesh — for example when Core triangulation failed — makes the whole frame report S_FALSE so the coordinator falls back to GDI, never an incorrect GL_POLYGON approximation.
  • The rendering coordinator, GDI fallback, framebuffer handling, 64 MiB staging budget and all existing safeguards are unchanged; no COM interface changes.

Tests

  • New coverage: concave/L-shaped polygons, one and multiple interior rings, multipart polygons, missing-mesh fallback, no visible internal triangle edges, and GDI/OpenGL pixel equivalence on a concave holed scene. Geometry support decisions are also tested GPU-independently through a test-access hook.
  • Debug | x64 builds with no new Level 4 warnings; MapWinGIS.Core.Tests: 311 passed (1 pre-existing network skip); MapWinGIS.ActiveX.Tests: 65 passed (2 pre-existing skips).

Memory

  • .ai/memory/architecture/activex.md: replaced the "convex single-ring only" limit with the mesh-based backend contract. No new memory files.

- Fill polygons with indexed triangle meshes via glVertexPointer and glDrawElements
- Draw outlines from the original rings instead of triangle edges
- Accept concave, holed and multipart scenes; drop the convexity checks
- Reject scenes whose polygons lack a usable fill mesh so the coordinator falls back to GDI
- Extend renderer tests with concave, holed, multipart and GDI-equivalence coverage
- Update the ActiveX architecture memory to the mesh-based rendering model
@pmeems
pmeems added this pull request to stack #69 November 12, 2026 18:22

@Julian-MW Julian-MW left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found one rendering-order regression in the OpenGL path. See the inline comment.

for (std::size_t index = 0; index < count; ++index)
/// Draws the original ring boundaries of one layer as outlines.
/// Triangle edges are not polygon boundaries and are never drawn.
void DrawLayerOutlines(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Preserve polygon painter order within a layer. DrawLayerFills currently renders every polygon in the layer before DrawLayerOutlines renders any of their boundaries. The GDI backend (and the previous OpenGL implementation) processes polygons one at a time, filling and outlining each polygon before moving to the next. When two polygons in the same layer overlap, this split pass leaves the earlier polygon's outline visible on top of the later polygon's fill, whereas GDI correctly covers it. Please keep fill/outline ordering per polygon (while still using that polygon's mesh for the fill), and add an overlapping-polygons-in-one-layer parity test.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Drawing all fills before outlines exposes earlier polygon boundaries over later overlapping fills, regressing the previous OpenGL and GDI rendering order.

1 open issue
What changed in this PR

This PR connects the OpenGL backend to the Core triangulation introduced in #66, enabling GPU rendering of concave polygons, holes, and multipart geometry without COM interface changes.

Changes:

  • Replaces GL_POLYGON fills with indexed triangles and draws outlines from original rings.
  • Validates meshes and falls back to GDI when any polygon lacks a usable mesh.
  • Adds geometry-support and rendering tests, including sampled GDI/OpenGL comparisons.

Builds and tests were not run during this review.

File Description
tests/​MapWinGIS.ActiveX.Tests/​VectorLayerRendererTests.cpp Adds mesh preparation, rendering checks, and fallback coverage.
tests/​MapWinGIS.ActiveX.Tests/​OpenGlVectorLayerRendererTestAccess.h Exposes scene-support checks without an OpenGL context.
src/​MapWinGIS.ActiveX/​OpenGlVectorLayerRenderer.h Documents mesh-based rendering and declares the support hook.
src/​MapWinGIS.ActiveX/​OpenGlVectorLayerRenderer.cpp Validates meshes, renders indexed fills, and outlines original rings.
.ai/​memory/​architecture/​activex.md Updates the documented OpenGL support contract.

Review effort: Balanced

_lastFailureReason = L"OpenGL could not allocate its vertex buffers.";
return fillsResult;
}
DrawLayerOutlines(layer.scene, *transform);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants