Just to throw my 2 cents worth in here.
 
I have been looking at Pygame GUIs recently, with an eye toward using one or another in my game project.  My game project
uses OpenGL, making it superficially hostile to any of the GUIs, in that pygame OpenGL displays do not support the blit or fill methods, nor the sprite rendering mechanisms.
 
My tentative plan was to create a psuedo-surface for the display, emulating via texture mapping the few surface methods used by the GUI.  My initial investigation told me that Ocemp v0.8 only used fewer than a half dozen surface methods on the display instance itself, with blit and fill doing the lion's share of the work.  Emulating this set of methods is a reasonable task.
 
For my purposes, Ocemp maintaining the current renderer works.   The alternatives, at first review, all seem to make OpenGL compatibility a more difficult job.  Writing an OpenGL renderer specific to Ocemp would be a very big job, too much for my resources.  At worst, I could stick with 0.8 forever.
 
Anyway, that's 2 cents worth.
David Keeney
 
On 12/13/05, Marcus von Appen <marcus@sysfault.org> wrote:
On, Tue Dec 13, 2005, Benjamin Olsen wrote:

> Well, may as well get some use out of this mailing list, right?
>
> Marcus, you'd mentioned to me that you don't like the inefficient way
> some of the objects are rendered. I assume you're working on changing
> some of those areas right now. I'd like to know what you have in mind,
> because I also have some ideas on how to make the process more
> efficient.

Funny, that you just wrote that mail today. I am currently in the
process of evaluating three possibilities on a theoretical base. I
wanted to describe those three on the mailing list tomorrow to get
possible feedback before starting with one of them. So just wait a few
more hours :-).

The two major ones are currently:

* Completely sprite based - widgets are not drawn on container surfaces,
but use the sprite engine
* Async updates with partial area redrawing in any widget (especially
Bins and Containers).

I'll explain my ideas about those tomorrow in detail.

> Part of it is something I noticed when trying to fix up my chat example.
> To get the chat window to stay scrolled at the bottom, I added:
>       self.chatwindow.vscrollbar.value =
> self.chatwindow.vscrollbar.maximum
> to:
> ChatScreen.addText in guiclient.py.
>
> However, I noticed that this always kept the window scrolled down to the
> previously added line. The problem, of course, is that the rect of the
> ScrollWindow's contents has not actually changed until the Renderer
> updates everything. So the solution was to make call
> self.chatwindow.draw() before setting the scrollbar's value.

As you might have seen, this is done with an enforced update() in the
latest release. I am not sure, if you are familiar with the sprite
concept of pygame, thus I'll give an rough explanation of it here and
how it applies to OcempGUI.

Every widget inherits from the pygame.Sprite class and supports its
necessary methods such as the update() method, which takes care of
redrawing the widget, if its dirty (widget.dirty == True). Within this
method the rect and eventarea attributes of the widget are updated by
the return value of the draw() method.

The Renderer and RenderLayer classes take care of delegating the update
mechanisms by using a time based approach of 40 frames per second by
default. In every update cycle the RenderLayer updates its attached
sprites (widgets) and - if they changed in any way - adds their old and
new rect contents to a list, which will be passed back to the
pygame.display.update() method.  Thus it is (more or less) guaranteed,
that rendering is basically a bit more efficient than updating the whole
screen as done in previous versions.

The misbehaviour you noticed is caused by those mechanisms. The update
loop has not updated the ScrolledWindow appropriately, when the
assignment of the maximum value is done. You can see such a weird
behaviour in several widgets (mostly Bins and Containers) by playing
around with the Renderer.timer attribute.

> I'm not sure if this causes that objects draw() to be called twice,
> though. If it does, that's obviously inefficient. The other thing is,
> I

In this case it is as the update() mechanism does that afterwards, too.

> would propose that every object needs to know the size of its rect any
> time a change is made. That doesn't mean it needs to be blitted to the
> screen surface every time (in fact, I hope you're looking at
> pygame.display.update(), to only update dirty rects), but in order for
> objects to interact more accurately, their rect sizes should always be
> up to date.

I know about that issue and had to see it, when I played around with
very low and high frame rates. I did not take care of it for now as it
would have meant rewriting the RenderLayer class completely and messing
around with too many critical parts. Thus I left it aside in favour for
a stable release tree.

The major issue for 0.2.0 was and is to get rid of it and use a better
rendering implementation, which does not influence the basic
pygame.Sprite mechanisms (so that the widgets can be used without the
Renderer).

This however does not mean, that the Renderer will use a sprite concept
then (with time-bound updates) as it would limit the design
possibilities too much.

Regards
Marcus





--
dkeeney@travelbyroad.net
Pitcher's Duel -> pduel.sourceforge.net