Problem
Cube node shape (LP_SHAPE_TYPE = CUBE) renders correctly via the C API (no crash, no black canvas — fixed in #48), but looks identical to the default flat rectangles. The 3D extruded-cube appearance that the mode is supposed to provide is not visible.
Root cause
CommandScreen::DrawCube (CAPI.cpp) receives CubeDepthLevel nodeDepth and CubeDepthLevel parentDepth — depth information (extrusionLevel + groupRecursionDepth) that tells a 3D-capable renderer how far each node should be extruded. But the implementation discards both and emits a single flat filled rectangle (opcode 4) with the base colour:
void DrawCube(float posX, float posY, float sizeX, float sizeY,
CubeDepthLevel nodeDepth, CubeDepthLevel parentDepth, // ← ignored
const Color& color, const Color& outlineColor, int iThickness) override {
// just a flat rect, depth discarded
push(4, x1, y1, x2, y2, colorToARGB(color));
}
How it could be implemented through the C ABI
The int[] command buffer supports 6 opcodes (clear, circle, line, rect outline, rect filled, text). There is no "cube" opcode, but 3D-looking cubes can be decomposed into multiple shaded rectangles using existing opcodes:
Option A: Multi-quad cube decomposition (recommended)
In DrawCube, emit 2–3 visible faces per cube as separate opcode-4 rectangles with depth-based shading:
┌──────┐
│ top │ ← lighter shade (extrusionLevel * offset upward)
├──────┤
│front │ ← base colour
│ │ │ right │ ← darker shade (offset rightward)
└──────┘
- Top face: base colour lightened by ~20%, offset upward by
extrusionLevel * k pixels. Opcode 4 (filled rect).
- Front face: base colour, full size. Opcode 4.
- Right face: base colour darkened by ~20%, offset rightward by
extrusionLevel * k pixels. Opcode 4.
- Outline: opcode 3 on the front face bounds.
The extrusionLevel controls how far each cube is "pushed back" — deeper nodes get smaller offsets (receding into the distance), creating the extruded depth illusion.
Pros: uses existing opcodes only; looks genuinely 3D; all C-API frontends benefit immediately.
Cons: 3–4 draw commands per node instead of 1 (perf consideration for large node trees); shading formula is in the C API layer rather than the view.
Option B: New cube opcode in the command buffer
Add opcode 6: [6, x1, y1, x2, y2, extrusionLevel, groupRecursionDepth, fillARGB, outlineARGB, thickness]
Frontends decode it and render with platform-native 3D if desired, or fall back to flat.
Pros: most flexible; frontends can do proper OpenGL/Metal 3D.
Cons: changes the frozen C API command buffer format; every frontend must update.
Option C: Depth-shaded single rectangle
Darken/lighten the fill colour based on extrusionLevel — emit a single opcode-4 rect. Creates a subtle depth gradient but doesn't look like actual cubes.
Pros: minimal change, no perf impact.
Cons: doesn't achieve the visual goal.
Recommendation
Option A — it's self-contained in CommandScreen::DrawCube, uses existing opcodes, and gives the best visual result. The depth data (CubeDepthLevel) is already available; it just needs colour manipulation + positional offsets.
Problem
Cube node shape (
LP_SHAPE_TYPE = CUBE) renders correctly via the C API (no crash, no black canvas — fixed in #48), but looks identical to the default flat rectangles. The 3D extruded-cube appearance that the mode is supposed to provide is not visible.Root cause
CommandScreen::DrawCube(CAPI.cpp) receivesCubeDepthLevel nodeDepthandCubeDepthLevel parentDepth— depth information (extrusionLevel+groupRecursionDepth) that tells a 3D-capable renderer how far each node should be extruded. But the implementation discards both and emits a single flat filled rectangle (opcode 4) with the base colour:How it could be implemented through the C ABI
The
int[]command buffer supports 6 opcodes (clear, circle, line, rect outline, rect filled, text). There is no "cube" opcode, but 3D-looking cubes can be decomposed into multiple shaded rectangles using existing opcodes:Option A: Multi-quad cube decomposition (recommended)
In
DrawCube, emit 2–3 visible faces per cube as separate opcode-4 rectangles with depth-based shading:extrusionLevel * kpixels. Opcode 4 (filled rect).extrusionLevel * kpixels. Opcode 4.The
extrusionLevelcontrols how far each cube is "pushed back" — deeper nodes get smaller offsets (receding into the distance), creating the extruded depth illusion.Pros: uses existing opcodes only; looks genuinely 3D; all C-API frontends benefit immediately.
Cons: 3–4 draw commands per node instead of 1 (perf consideration for large node trees); shading formula is in the C API layer rather than the view.
Option B: New cube opcode in the command buffer
Add opcode 6:
[6, x1, y1, x2, y2, extrusionLevel, groupRecursionDepth, fillARGB, outlineARGB, thickness]Frontends decode it and render with platform-native 3D if desired, or fall back to flat.
Pros: most flexible; frontends can do proper OpenGL/Metal 3D.
Cons: changes the frozen C API command buffer format; every frontend must update.
Option C: Depth-shaded single rectangle
Darken/lighten the fill colour based on
extrusionLevel— emit a single opcode-4 rect. Creates a subtle depth gradient but doesn't look like actual cubes.Pros: minimal change, no perf impact.
Cons: doesn't achieve the visual goal.
Recommendation
Option A — it's self-contained in
CommandScreen::DrawCube, uses existing opcodes, and gives the best visual result. The depth data (CubeDepthLevel) is already available; it just needs colour manipulation + positional offsets.