April 5, 2008
WikiSlow Setting Pixels
#wiki
Slow Setting Pixels
Step by Step
In this example what we see is, if we use native function of quickdraw which sets pixels, it is going to be slower. The reason for this, we are using too much calculations all at once and also we are not even using direct memory access to the pixels. Thus giving us a poor performance.
void DrawToBuffer(void) {
long x , y;
Point mousepoint;
unsigned short distance;
unsigned char R,G,B;
RGBColor ourColor;
count++;
SetPortWindowPort(ourWindow);
GetMouse(&mousepoint);
SetPort(ourBuffer);
for(x=0;x<640;x++){
for(y=0;y<480;y++){
distance = sqrt((x-mousepoint.h)*(x-mousepoint.h)+(y-mousepoint.v)*(y-mousepoint.v));
// x minus xmouse and square root in the end. this is slowing down since we are using so much calculations.
R = distance+mousepoint.h+count;
// giving R,G and B some values that change with the distance from the mouse
G = distance+mousepoint.v+count;
B = mousepoint.h;
ourColor.red = R*256;
// an RGBColor expects numbers in the range of an unsigned short
ourColor.green =G*256;
// so we need to make our numbers bigger
ourColor.blue = B*256;
SetCPixel(x,y,&ourColor); // drawing through this function, this is coming from quickdraw.
/* but it is very slow, what that means to us is, if we use operating system's native
drawing functions it will be still so slow. In order to bypass that, we should low level,
and getting colors for the pixels directly from the memory.
*/
}
}
}
In order to make this faster we are going to use our SetPixel function in the next example.
Source Code
void Initialize(void); // function prototypes
void DrawLine( void );
void doEventLoop( void );
void DrawToBuffer(void);
void CopyToWindow (void);
//globals
WindowPtr ourWindow;
Rect windRect;
GWorldPtr ourBuffer;
int count=0;
void DrawToBuffer(void) // this is where the interesting stuff happens, this is where we actually set our pixels
{
long x , y;
Point mousepoint;
unsigned short distance;
unsigned char R,G,B;
RGBColor ourColor;
count++;
SetPortWindowPort(ourWindow);
GetMouse(&mousepoint);
SetPort(ourBuffer);
for(x=0;x<640;x++){
for(y=0;y<480;y++){
distance = sqrt((x-mousepoint.h)*(x-mousepoint.h)+(y-mousepoint.v)*(y-mousepoint.v));
// x minus xmouse and square root in the end. this is slowing down since we are using so much calculations.
R = distance+mousepoint.h+count; // giving R,G and B some values that change with the distance from the mouse
G = distance+mousepoint.v+count;
B = mousepoint.h;
ourColor.red = R*256; // an RGBColor expects numbers in the range of an unsigned short,
ourColor.green =G*256; // so we need to make our numbers bigger
ourColor.blue = B*256;
SetCPixel(x,y,&ourColor); // drawing through this function, this is coming from quickdraw.
// but it is very slow, what that means to us is, if we use operating system's native drawing functions it will
// be still so slow. In order to bypass that, we should low level, and getting colors for the pixels directly from the memory.
}
}
}
void CopyToWindow (void){ // copy all our buffer to the window, completely replaceing
// everything that was there
Rect sourceRect,destRect;
SetPortWindowPort(ourWindow);
GetPortBounds( GetWindowPort(ourWindow), &destRect );
GetPortBounds( ourBuffer, &sourceRect );
CopyBits( GetPortBitMapForCopyBits( ourBuffer ), GetPortBitMapForCopyBits(GetWindowPort(ourWindow)),
&sourceRect, &destRect, srcCopy, NULL );
}
void main( void )
{
Initialize();
doEventLoop();
}
void Initialize(void){
OSErr error;
SetRect(&windRect,100,100,740,580);
InitCursor();
ourWindow = NewCWindow( 0L, &windRect, "\pSlow Setting Pixels", true, noGrowDocProc,(WindowPtr)-1L, true, 0L );
if ( ourWindow == nil ) ExitToShell();
ShowWindow( ourWindow );
SetPortWindowPort( ourWindow );
SetRect(&windRect,0,0,640,480);
error =NewGWorld(&ourBuffer, 32, &windRect, nil, nil,0 ); // creating our offscreen buffer
if (error != noErr ) ExitToShell();
}
/*************** The Event Loop ***************/
void doEventLoop()
{
EventRecord anEvent;
WindowPtr evtWind;
short clickArea;
Rect screenRect;
Point thePoint;
for (;;)
{
if (WaitNextEvent( everyEvent, &anEvent, 0, nil ))
{
if (anEvent.what == mouseDown)
{
clickArea = FindWindow( anEvent.where, &evtWind );
if (clickArea == inDrag)
{
GetRegionBounds( GetGrayRgn(), &screenRect );
DragWindow( evtWind, anEvent.where, &screenRect );
}
else if (clickArea == inContent)
{
if (evtWind != FrontWindow())
SelectWindow( evtWind );
else
{
thePoint = anEvent.where;
GlobalToLocal( &thePoint );
//Handle click in window content here
}
}
else if (clickArea == inGoAway)
if (TrackGoAway( evtWind, anEvent.where ))
return;
}
}
DrawToBuffer(); // after checking for various events we call our drawing finctions
CopyToWindow();
}
}
Continue Reading
Back to Archive