Skip to content

Cube mode renders flat (no 3D depth) via C API — depth info discarded #49

Description

@willwade

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions