Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Immediate Mode in Doodle Canvas #168

Open
wants to merge 44 commits into
base: main
Choose a base branch
from

Conversation

VOSID8
Copy link
Contributor

@VOSID8 VOSID8 commented Jun 23, 2024

Theory

Retained Mode: The Doodle library supports retained mode, operating on a declarative principle. In this mode, the application constructs images using graphics primitives like shapes and lines, which are then stored as a model in memory. Users interact with this model to add, remove, or modify elements, while the library handles the redrawing. Retained mode maintains a hierarchy where each element’s position is relative to others. In Doodle, relationships between elements are managed through the Shape algebra, allowing operations like on, beside, and similar commands to organize elements.

The Need for Immediate Mode: While retained mode provides a robust solution for constructing and managing complex images, some tasks require more flexibility and direct control. Retained mode can be restrictive for dynamic image manipulation, generative art, and real-time graphics, where the scene model may become cumbersome or resource-intensive. To address these needs, immediate mode has been introduced in Doodle Canvas, enabling developers to bypass the stored scene model and directly issue drawing commands.

Immediate Mode: Doodle now includes an immediate mode, offering a procedural approach to graphics rendering. In immediate mode, the application directly issues image manipulation commands for each frame or operation, without retaining a model in memory. This approach is particularly effective for tasks requiring real-time rendering, interactive graphics, or dynamic transformations. The Immediate object serves as the core interface for this mode, providing methods for drawing and manipulating images directly, giving developers more control and flexibility in image processing.

Integrating Immediate Mode with Retained Mode: With the introduction of immediate mode, Doodle now combines the strengths of both paradigms. A new algebra Raster allows users to embed immediate mode drawing within the retained mode structure. This feature lets users create a Picture that can be positioned relative to other Pictures using operations like above or on. The contents of this Picture are generated either through Retained mode or dynamically through a user-defined function that has access to a Immediate. Drawing operations within this function are relative to the origin of the Picture, offering procedural flexibility. The resulting Picture can then be integrated into the retained mode hierarchy, enabling seamless interaction between both modes. This hybrid approach allows for the dynamic rendering and fine control of immediate mode while maintaining the organizational clarity of retained mode.

Implementation

Existing Retained Mode

val retained =
  Picture.circle(10).at(100, 100)
    .on(Picture.circle(10).at(0, 0))

We can rewrite the above with Immediate Mode as

val immediate =
   (gc: Immediate) => {
     gc.circle(100, 100, 10)
     gc.circle(0, 0, 10)

Both will return the same output as
image

Raster Algebra Implemented

trait Raster[A] extends Algebra {
  def raster(width: Int, height: Int)(f: A => Unit): Drawing[Unit]
}

User can use Raster as following to combine Immediate with Retained Mode

val twoCircles =
  (gc: Immediate) => {
      gc.circle(100, 100, 10)
      gc.fill(Color.blue)
      gc.circle(0, 0, 10)
      gc.fill(Color.pink)
  }

val redSquare = Picture.square(80).fillColor(Color.red)

val masterpiece = raster(100, 100)(twoCircles).beside(redSquare)

Which would give output as

image

Immediate object implements 39 methods covering a wide range of drawing functionalities. These include creating shapes (like circles, rectangles, polygons), path operations (like arc, line, and curves), transformations, clipping, coloring and text rendering.

Example

image

The following image is create using Immediate mode along with Retained Mode. Retained Mode is used to draw trees and put everything together in a compositional manner whereas buildings and the road is drawn using Doodle Canvas Immediate Mode. The code for this picture can be found within CanvasImmediateMode.scala file within this PR

Note: This PR is part of Google Summer of Code'24 (Doodle Canvas)

@VOSID8 VOSID8 changed the title Working on Canvas backend, implementing raster Immediate Mode in Canvas Doodle Aug 18, 2024
@VOSID8 VOSID8 marked this pull request as ready for review August 20, 2024 14:52
@VOSID8 VOSID8 changed the title Immediate Mode in Canvas Doodle Immediate Mode in Doodle Canvas Aug 20, 2024
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.

2 participants