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
|