Morphic graphics, Displaying fonts & canvases

sig siguctua at gmail.com
Tue Apr 24 04:08:12 UTC 2007


I managed to make somewhat stable GLDisplayScreen.
A GLCanvas class currently fully supports drawings using Canvas
protocol, but only basic things from BalloonCanvas protocol.
For most morphs Canvas protocol is enough to draw: all menus/system
browsers shown correctly without any artifacts.

Now about problems.
As i said before, the problem lies in different approach for
preserving state in OpenGL while drawing on screen.
While using blitting drawings its ok to copy canvas for preserving
clipping/transforming states in OpenGL its nearly impossible task.
Consider following example:

Most morphs when drawing itself doing following:
- drawing self
- (optionally) clipping current area by its boundaries
- (optionally) translating position
- (optionally) draws submorphs.

A compatible approach:

aCanvas clipBy: rect during: [  ...  draw submorphs .. ]
aCanvas translateBy: rect during: [  ... draw submorphs ... ]

An incompatible approach:
| tempCanvas |
tempCanvas := aCanvas copyOffset: translateRect.
submorphs do: [ :morph |  tempCanvas drawMorph: morph ]

In first example its easy to preserve states: i can simply do
transformation/clipping before entering block and then when it
finished revert them back.

In second sample things are different: when i creating a temporary
canvas i should copy all state from original canvas plus additional
transformation/clipping and draw all future commands under this new
state, while in original canvas i must draw without any changes.

This leads to fully reloading OpenGL state (transform
matrix/clipping/flags/e.t.c) each time a new draw command issued,
because i can't presume when tempCanvas will be in use and when the
original canvas. I can't even presume the order at which they will be
drawn on screen.

So as long as its possible i started changing the code in morphs to
use first approach instead of second which doing same things but
allows me managing states accurately in OpenGL.

I my vision a canvas must represent a full state of display medium. I
see little areas where state preserving during copying can be handled
correctly. Most of devices/drawing protocols are built on idea of
sequential pipeline of commands. And if you don't follow these rules
you get a white snow in result.

Btw , BalloonCanvas class especially introduces new
#preserveStateduring: method which must be used by anyone who wants to
draw correctly on screen.

Some notes about clipping: i do clipping using stencil buffer. for
those who don't know what is it consider a single pixel is consists of
RGB or RGBA components. By adding stencil component, you receive RGB+S
or RGBA+S - this is additional bits for each pixel in buffer for
special operations like clipping.
And since OpenGL stores it on per-pixel basis and drawing to it can be
done by regular draw commands we can have any forms of clipping area,
not just rectangular.
So, we can introduce a new clipping methods like this one for example:

Canvas drawClipArea: aBlock drawContents: aBlock.

in fact, the default clipBy:during: is the simplified version of above
- its draws a rectangle in  pixel buffer, but modifies only S
component keeping the color components unchanged. Then second block
draws in color components while keeps S component unchanged.
If you noticed, preserving the clipping state will require an enormous
amount of time and space  - you need to copy S component for each
pixel to do that.



More information about the Squeak-dev mailing list