Hosting DispEngine in a Rendering Canvas
A rendering canvas is the UI component your application puts on screen to display and interact with 3D content. This section explains the contract it has with the DispEngine: what the engine expects from the host control, and what the host gets back.
Overview
HiAPI does not ship a rendering canvas — your application owns it. Up to HiNc 3.2.31 the Hi.WinForm
and Hi.WpfPlus packages carried ready-made ones; both were retired, so a Windows application now hosts
DispEngine in a control of its own. Building Your Own Rendering
Canvas walks the implementation end to end and keeps a frozen
copy of the Windows Forms and WPF versions as a worked reference.
What follows is framework-independent: the engine/displayee relationship, the operations a canvas exposes, and the input it has to forward. Whatever UI toolkit hosts it — Windows Forms, WPF, Avalonia, a browser surface — the architecture below is the same.
Core Concept: DispEngine and IDisplayee
At the heart of the rendering system is the relationship between DispEngine and IDisplayee:
- DispEngine: The rendering engine that manages the OpenGL context and handles user interaction. IsGlAvailable reports whether the process obtained a usable context; a host must not obtain a
DispEnginewhile it isfalse— NC play, physics and training still run in that state, rendering does not - IDisplayee: The interface that defines objects that can be rendered by the DispEngine
This relationship is fundamental - the purpose of DispEngine is to render IDisplayee objects.
graph TD
A[IDisplayee Objects] -->|Rendered by| B
B[DispEngine] <--> C[RenderingCanvas UI Component]
Working with IDisplayee
Objects implementing IDisplayee define what gets rendered. Typically, you'll use Drawing objects or compose multiple IDisplayee objects together:
// Create a composite displayee
public class MyCompositeDisplayee : IDisplayee
{
private List<IDisplayee> _displayees = new List<IDisplayee>();
public MyCompositeDisplayee()
{
// Add various displayees
_displayees.Add(new AxesDisplayee());
_displayees.Add(new ModelDisplayee());
}
public void Display(Bind bind)
{
// Render all contained displayees
foreach (var displayee in _displayees)
{
displayee.Display(bind);
}
}
public void ExpandToBox3d(ref box3d_t box)
{
// Update bounding box based on all displayees
foreach (var displayee in _displayees)
{
displayee.ExpandToBox3d(ref box);
}
}
}
For more detailed information on creating displayees with Drawing, see the Drawing section.
Basic Usage
Your canvas owns a DispEngine and exposes it, so the rest of the application talks to the engine rather than to the control. Both shapes below are in use — take a displayee in the constructor, or let the caller assign one afterwards:
Windows Forms
// The canvas type is yours -- see Building Your Own Rendering Canvas.
var displayee = new MyCompositeDisplayee();
// Initialize the canvas with the displayee
var canvas = new MyRenderingCanvas(displayee);
// Access the DispEngine for direct manipulation
DispEngine engine = canvas.DispEngine;
// Add to a form
myForm.Controls.Add(canvas);
WPF
var displayee = new MyCompositeDisplayee();
// Initialize the canvas
var canvas = new MyRenderingCanvas();
// Set displayee objects through the DispEngine
canvas.DispEngine.Displayee = displayee;
// Add to a container
myGrid.Children.Add(canvas);
Switching Displayees at Runtime
You can dynamically change what's being displayed:
// Switch to a different displayee
renderingCanvas.DispEngine.Displayee = alternativeDisplayee;
// Or update a DispList
var displayList = new DispList();
if (showModel) displayList.Add(modelDisplayee);
if (showGrid) displayList.Add(gridDisplayee);
renderingCanvas.DispEngine.Displayee = displayList;
Key Features of DispEngine
The DispEngine provides cross-platform support for:
- Handles buffer swapping and image generation
- Mouse/pointer events
- Keyboard navigation
- Touch gestures
- Zoom, pan, and rotate operations
- Resize and Visibility changed.
- Camera positioning and orientation
- Standard views (front, top, isometric, etc.)
- Renders IDisplayee implementations
Touch and Gesture Support
The DispEngine centralizes touch handling across all platforms with a unified API that supports:
- Single-finger pan
- Two-finger rotate and scale
- Multi-finger specialized operations
The touch API is designed to be simple for UI implementations to use. Platform-specific UI components only need to capture touch events and forward them to the DispEngine.
Common Operations
// Accessing DispEngine (works on all platforms)
var engine = renderingCanvas.DispEngine;
// Set to standard views
engine.SetViewToHomeView();
engine.SetViewToFrontView();
// Manual camera manipulation
engine.Translate(dx, dy);
engine.Rotate(deltaX, deltaY);
// Resize handling
engine.Resize(width, height);
Implementation Details
For detailed implementation information, including:
- Full source code examples
- Implementation details for each platform
- Advanced touch handling
- Custom implementation guidance
See the Building Your Own Rendering Canvas guide.
See Also
- DispEngine
- IDisplayee
- DispList
- Building Your Own Rendering Canvas — what a canvas has to implement to host the engine itself
- Drawing — producing the displayees this canvas renders