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))
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
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
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)
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 aPicture
that can be positioned relative to otherPictures
using operations likeabove
oron
. The contents of this Picture are generated either through Retained mode or dynamically through a user-defined function that has access to aImmediate
. Drawing operations within this function are relative to the origin of thePicture
, offering procedural flexibility. The resultingPicture
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
We can rewrite the above with Immediate Mode as
Both will return the same output as![image](https://github.com/user-attachments/assets/7e0faa6d-c1cd-447e-bbc5-431d2e044a82)
Raster Algebra Implemented
User can use Raster as following to combine Immediate with Retained Mode
Which would give output as
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
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 PRNote: This PR is part of Google Summer of Code'24 (Doodle Canvas)