← Documentation Home

4) Drawing, Camera, and Buffers

Back to Tutorials

Goal: build a small scene that demonstrates primitive drawing, local transforms, clipping, and reusable off-screen content.


Step 1: Learn the Primitive Toolkit

SetDrawColor(80, 180, 255)
DrawLine(40, 80, 220, 80)
DrawRect(40, 100, 180, 80)
DrawFilledRect(260, 100, 180, 80)
DrawCircle(560, 140, 64, 48)

SetDrawColor affects lines, outlined and filled rectangles, and circles. The last DrawCircle argument is the segment count: small values make polygons, while larger values make a smoother outline.

Step 2: Draw in Local Coordinates

PushDrawState()
SetDrawOffset(400, 300)
SetDrawRotation(30.0)

SetDrawColor(255, 190, 70)
DrawFilledRect(-60, -20, 120, 40)
DrawLine(0, 0, 90, 0)

PopDrawState()

The shape is defined around local origin 0, 0, rotated, then moved to 400, 300. PushDrawState/PopDrawState contain the transform so later UI drawing is unaffected.

Step 3: Treat the Offset as a Camera

If the player is at world position playerX, playerY, center the camera by translating the world in the opposite direction:

PushDrawState()
SetDrawOffset( _
    (ScreenWidth() / 2) - playerX, _
    (ScreenHeight() / 2) - playerY _
)

' Draw all world objects here using world coordinates.
DrawFilledRect(playerX - 16, playerY - 16, 32, 32)

PopDrawState()

Draw the HUD after PopDrawState so it stays anchored to screen coordinates.

Step 4: Clip a Viewport

SetClipRegion(40, 40, 300, 180)
SetDrawColor(40, 100, 180)
DrawFilledRect(0, 0, 500, 300)
SetDrawColor(255, 255, 255)
DrawCircle(330, 130, 90, 48)
ClearClipRegion()

Only pixels inside the 300 × 180 region are rendered. Always clear or restore the clip before drawing unrelated content.

Step 5: Pre-render a Reusable Buffer

Dim panel As Integer
panel = CreateBuffer(220, 80)

If panel <> 0 Then
    SetBufferTarget(panel)
    Cls()
    SetDrawColor(24, 34, 60, 230)
    DrawFilledRect(0, 0, 220, 80)
    SetDrawColor(100, 210, 255)
    DrawRect(0, 0, 220, 80)
    ClearBufferTarget()
End If

Render content that changes rarely into a buffer once, then reuse it with DrawBuffer. This is useful for UI panels, minimaps, and composed effects.

Checkpoint: Transform Playground

Graphics(800, 600, False)
SetClsColor(10, 14, 25)

Dim fontRef As Integer
Dim panel As Integer
Dim angle As Double
Dim running As Boolean

fontRef = LoadFont("", 18)
panel = CreateBuffer(240, 72)
running = True

If panel <> 0 Then
    SetBufferTarget(panel)
    Cls()
    SetDrawColor(25, 38, 68, 235)
    DrawFilledRect(0, 0, 240, 72)
    SetDrawColor(80, 200, 255)
    DrawRect(0, 0, 240, 72)
    ClearBufferTarget()
End If

Do
    angle = angle + (60.0 * FrameDelta())

    Cls()

    SetClipRegion(40, 80, 720, 420)
    SetDrawColor(28, 45, 72)
    DrawFilledRect(40, 80, 720, 420)

    PushDrawState()
    SetDrawOffset(400, 290)
    SetDrawRotation(angle)
    SetDrawColor(255, 185, 65)
    DrawFilledRect(-90, -25, 180, 50)
    SetDrawColor(255, 255, 255)
    DrawCircle(0, 0, 110, 64)
    PopDrawState()
    ClearClipRegion()

    If panel <> 0 Then
        DrawBuffer(panel, 24, 16)
    End If
    SetTextColor(235, 240, 255)
    DrawText(fontRef, 40, 530, "ESC exits. The scene is clipped; the HUD is not.")

    Flip()
    If KeyHit(KEY_ESC) Then
        running = False
    End If
Loop Until Not running

FreeBuffer(panel)
FreeFont(fontRef)

Choosing the Right State Tool

  • Use PushDrawState/PopDrawState around a camera, rotated object, clipped panel, or alternate target.
  • Use ClearClipRegion when only the clip must be removed.
  • Use ClearBufferTarget when only off-screen targeting must end.
  • Use ResetDrawState as an explicit return to screen defaults. It does not discard saved stack entries.

Try It Yourself

Turn the rotating rectangle into a clock hand, create a second clipped viewport, and compare circles drawn with 3, 6, 16, and 64 segments.

Functions Introduced

SetDrawColor, DrawCircle, PushDrawState, PopDrawState, SetDrawOffset, SetDrawRotation, SetClipRegion, and CreateBuffer.


Navigation: Previous | Course outline | Next: Input, Assets, and Audio