GUI design

H

hkhellhkhell

Hi
Here is my current design:

In the drawing function, i declared an array : PIXEL[1024][768], the
drawing function will keep drawing every pixel in the array to the
screen.

There are many kind of component in my GUI library, all of them have an
OnPaint() method. The drawing function will pass a pointer to each
component like OnPaint(Pixel+(x+y*768)), then component draw whatever
they like to that array.

Is it good?

thanks
from Peter ([email protected])
 
A

Alexei A. Frounze

Hi
Here is my current design:

In the drawing function, i declared an array : PIXEL[1024][768],

Right in *that* function? And you're gonna allocate such a huge array every
time that function is called? Are you serious?
the
drawing function will keep drawing every pixel in the array to the
screen.

I'm a bit confused. Why should it not draw directly to the screen then? I'm
asking this because it seems like you first allocate the buffer, draw in it
the entire element and then copy out of this buffer only a fraction of the
buffer (very likely a fraction of the element if it's obscured by something)
to the screen. I wouldn't like drawing into the buffer pixels that won't be
displayed.
There are many kind of component in my GUI library, all of them have
an OnPaint() method. The drawing function will pass a pointer to each
component like OnPaint(Pixel+(x+y*768)),

I'm not sure how to interpret "Pixel+(x+y*768)".
then component draw whatever
they like to that array.

Is it good?

First of all, what you have outlined is too little. Like it's been
mentioned, you must deal with clipping, so, in the design there must also be
a place for computation of what's visible and what's not. Second, unless you
refine it, it's gonna be bloody slow. I should've probably provided an
option in my windowing demo that would redraw everything from back to front
without any clipping whatsoever. That would probably show the difference in
performance and visual quality and you'd not have such a question. :)

Alex
 
G

Gernot Frisch

In the drawing function, i declared an array : PIXEL[1024][768], the
drawing function will keep drawing every pixel in the array to the
screen.

You should make that:
class Screen
{
Screen(int w, int h);
~Screen();
void Put(int x, int y, PIXEL p);
PIXEL* m_pScreen;
int m_w, m_h;
};

Screen::Screen(int w, int h)
{
m_pScreen = new PXIEL[w*h];
m_w = w; m_h = h;
}

Screen::~Screen()
{
delete[]m_pScreen;
}

void Screen::put(int x, int y, PIXEL p)
{
if(x<0 || x>=m_w) return;
if(y<0 || y>=m_h) return;
m_pScreen[x+y*m_w] = p;
}



This way you have a dynamic memory allocation (1024x768 is quite a
thing for static memory). Also you can have several screens with
different resolutions. The Put function will only put pixels that are
visible (not crashing your program if you access pixel (-1,-1).

Well, it's just a thought.
-Gernot
 
A

Alexei A. Frounze

Gernot Frisch wrote:
....
Screen::Screen(int w, int h)
{
m_pScreen = new PXIEL[w*h];
m_w = w; m_h = h;
}

The negative arguments are allowed in the above code but obviously not
welcome.

Alex
 
H

hkhellhkhell

Alexei A. Frounze 寫é“:
Hi
Here is my current design:

In the drawing function, i declared an array : PIXEL[1024][768],

Right in *that* function? And you're gonna allocate such a huge array every
time that function is called? Are you serious?
the
drawing function will keep drawing every pixel in the array to the
screen.

I'm a bit confused. Why should it not draw directly to the screen then? I'm
asking this because it seems like you first allocate the buffer, draw in it
the entire element and then copy out of this buffer only a fraction of the
buffer (very likely a fraction of the element if it's obscured by something)
to the screen. I wouldn't like drawing into the buffer pixels that won't be
displayed.

If i do that, i can do some "whole screen" effect. In mac, when you
press F11, it transparent the whole screen.

I'm not sure how to interpret "Pixel+(x+y*768)".


First of all, what you have outlined is too little. Like it's been
mentioned, you must deal with clipping, so, in the design there must also be
a place for computation of what's visible and what's not. Second, unless you
refine it, it's gonna be bloody slow. I should've probably provided an
option in my windowing demo that would redraw everything from back to front
without any clipping whatsoever. That would probably show the difference in
performance and visual quality and you'd not have such a question. :)

Alex


My basic idea is, os keep a pixel array, the display card driver keep
putting every pixel to the screen. At the same time, the os graphic
engine also modify the pixel array, for example, when there is a new
window comes or you closed a window.

Dan
 
M

Matt

Hi
Here is my current design:

In the drawing function, i declared an array : PIXEL[1024][768], the
drawing function will keep drawing every pixel in the array to the
screen.

There are many kind of component in my GUI library, all of them have an
OnPaint() method. The drawing function will pass a pointer to each
component like OnPaint(Pixel+(x+y*768)), then component draw whatever
they like to that array.

Is it good?

thanks
from Peter ([email protected])
Peter,

your method will work, but it will, as others have said, be very slow.
the method would be fine for something like a microcontroller, where
processing power is limited, but for a PC, where you expect speed, this
would be incredibly slow.

By looping around your putpixel() routine, you are repeatedly redrawing
pixels which have not changed, rather than concentrating on those that
have.

Think about it this way; Every high level drawing function MUST be
designed to check whether the thing being drawn is totally inside the
window, totally outside it, or partway in and partway outside. it can
then crop off the bits that would otherwise be outside the drawing area,
(or more importantly, outside your array of pixels!) This makes high
level functions slow. It is therefore important to avoid simple
functions like putpixel(), which only place a single pixel once the
checks are done, in preference for bitblit() which does the same tests,
but then puts perhaps 10000 pixels.

What you could do is this:

Each high level drawing function is given a pointer to your
pixel_buffer, and access to two x,y coordinates, the top_left, and
bottom_right points. These are initialised to impossible values
(top_left set to the bottom right of the screen and vice-versa.) Each
drawing function then checks to see if the thing it has to draw is
inside the valid range of pixels (in other words, on the screen) and
draws what it can to your pixel_buffer. It then updates the top_left and
bottom_right values to the extremes of a box containing the object. Each
drawing function can expand the region, but not shrink it. When all of
your functions have finished, the two points define a box containing all
the parts of the screen that need to be updated. You then bitblit() only
this rectangle to the screen.

Obviously, this process can be made asynchronous, by interrupting the
drawing process and bitblitting what has changed so far, then
continuing, but this is more complex.

Hope this helps

matt
 
A

Alexei A. Frounze

Matt wrote:
....
your method will work, but it will, as others have said, be very slow.
the method would be fine for something like a microcontroller, where
processing power is limited, but for a PC, where you expect speed,
this would be incredibly slow.

On a microcontroller it would just ... be even slower than on a PC.
Microcontrollers themselves are usually much slower than a PC's CPU. As you
say, the key is whether what happens is the same as what's expected.
However, if I want a device to respond to an event or interrupt quickly and
meet the deadlines no matter what, a PC, even if it's 10 or 50 times faster
than those microcontrollers or dedicated CPUs, isn't the right choice,
because neither its firmware nor OS guarantee anything, yet you have little
control over the two. You don't know what's in the BIOS and on the
motherboard and you don't know what's installed under the OS and what other
devices are attached and how all that worsens the latency.

Alex
 
M

Matt

Alexei said:
Matt wrote:
...

On a microcontroller it would just ... be even slower than on a PC.
Microcontrollers themselves are usually much slower than a PC's CPU. As
you say, the key is whether what happens is the same as what's expected.
However, if I want a device to respond to an event or interrupt quickly
and meet the deadlines no matter what, a PC, even if it's 10 or 50 times
faster than those microcontrollers or dedicated CPUs, isn't the right
choice, because neither its firmware nor OS guarantee anything, yet you
have little control over the two. You don't know what's in the BIOS and
on the motherboard and you don't know what's installed under the OS and
what other devices are attached and how all that worsens the latency.

Alex
Alex, I agree that on a micro controller the code would run even slower.
However, from years of experience programming them, I know that the main
issues with a microcontroller are often a) the simplicity of the code,
as code space is limited, and b) latency. The latency, being longer by
the nature of the slow speed, is better to be consistent. Because of
this, a simple interrupt driven routine that loops through all of the
pixels and draws one at a time would work better than one that tried to
bitblit.

As a general method for drawing to the screen on a PC, it is going to
run hundreds of times slower, due to all the overheads.

The good thing about microcontrollers, as you say, is that nothing
happens that you do not know about, so you can be certain that your code
will always respond in a known period.

Matt
 
M

Maxim S. Shatskih

In the drawing function, i declared an array : PIXEL[1024][768], the

Pixel is not the lowest-level primitive for GUI, BitBlt is :)
 
M

Maxim S. Shatskih

I'm a bit confused. Why should it not draw directly to the screen then? I'm
asking this because it seems like you first allocate the buffer, draw in it
the entire element and then copy out of this buffer only a fraction of the
buffer (very likely a fraction of the element if it's obscured by something)
to the screen.

I think Vista's Desktop Composition works this way.
 
A

Alexei A. Frounze

Maxim said:
I think Vista's Desktop Composition works this way.

IMO, an OS that's not a memory/power hog, must be able to do direct drawing
with transparency off and provide the transparency as an option. I don't
know exactly how this whole transparency thing works in Vista, but this
shouldn't be complicated -- the OS should still let the application know
when it's time to redraw and what and the OS may have an optional buffer on
behalf of each window for the transparency. The key is that it should be
designed to and work w/o such a buffer in the first place but allow for it.

Alex
 
S

Simon Felix

Alexei said:
IMO, an OS that's not a memory/power hog, must be able to do direct
drawing with transparency off and provide the transparency as an option.
I don't know exactly how this whole transparency thing works in Vista,
but this shouldn't be complicated -- the OS should still let the
application know when it's time to redraw and what and the OS may have
an optional buffer on behalf of each window for the transparency. The
key is that it should be designed to and work w/o such a buffer in the
first place but allow for it.

vista essentally knows two completly different ways to get things on screen:
- "classic way" (aero basic, windows classic, ...): every app draws it's
stuff when it's asked to do so
- "dwm way" (aero glass): every app draws something whenever it wants.
the graphics is stored in main memory & graphics memory. the whole
screen is redrawn whenever something changes, but the applications
obviously aren't required to redraw the window contents. that mean's it
uses more gpu and less cpu power. and you can make use of all the fancy
3d-capabilities of your gpu.



regards,
simon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,059
Latest member
cryptoseoagencies

Latest Threads

Top