April 5, 2008
WikiSetting Pixels
#wiki
Setting Pixels
Step by Step
Source Code
void Initialize(void); // function prototypes
void DrawLine( void );
void doEventLoop( void );
void DrawToBuffer(void);
void CopyToWindow (void);
int ourRandom( int min, int max );
void ourSetPixel(unsigned short horizontal,unsigned short vertical,unsigned char R,unsigned char G,unsigned char B,unsigned short rowbytes,Ptr pixbase);
//globals
WindowPtr ourWindow;
Rect windRect;
GWorldPtr ourBuffer;
int count=0;
unsigned short gSquares[640*2][480*2];
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 rowBytes,distance;
Ptr PixMapBase;
PixMapHandle ourPixmap;
/*
struct PixMap {
Ptr baseAddr;
short rowBytes;
Rect bounds;
short pmVersion;
short packType;
long packSize;
Fixed hRes;
Fixed vRes;
short pixelType;
short pixelSize;
short cmpCount;
short cmpSize;
long planeBytes;
CTabHandle pmTable;
long pmReserved;
};
*/
unsigned char R,G,B;
count-=5;
GetMouse(&mousepoint);
ourPixmap=GetGWorldPixMap(ourBuffer); // getting the pixel map of our buffer GWorld so that we can access the pixels
rowBytes = ((**(ourPixmap)).rowBytes) & 0x7fff; /// masking:
// we need to mask first two bits. Gives us the length of the row.
// getting the number of bytes in each row of the pixel map.
// This is then used to
// calculate the location in memory of specific pixels
PixMapBase = GetPixBaseAddr(ourPixmap ); // getting the base address in memory of the begining of the pixel data
for(x=0;x<640;x++){
for(y=0;y<480;y++){
distance = gSquares[640+(x-mousepoint.h)][480+(y-mousepoint.v)]; // getting the distance from the mouse to the pixels using our squares[][] array
R = distance+count+mousepoint.h; // giving R,G and B some values that change with the distance from the mouse
G = distance+count+mousepoint.v;
B = mousepoint.h;
ourSetPixel(x,y,R,G,B,rowBytes,PixMapBase);
// calling our method that set individual pixels and expects : X coordinate of the pixel,
// y coordinate of the pixel, R value, G value, B value, the number of bytes in each row of the pixel map, the base
// address in memory of the begining of the pixel data
}
}
}
void ourSetPixel(unsigned short horizontal,unsigned short vertical,unsigned char R,unsigned char G,unsigned char B,unsigned short rowbytes,Ptr pixbase){
Ptr AdressOfRed; // we can use unsigned char *AddressOfRed instead!
AdressOfRed = rowbytes * vertical +pixbase+horizontal*4+1;
// every pixel has 4 bytes so we are multiplying 4 and adding 1 for alpha since ARGB.
*(AdressOfRed)=R;
*(AdressOfRed+1)=G;
*(AdressOfRed+2)=B;
}
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;
short x, y;
SetRect(&windRect,100,100,740,580);
InitCursor();
ourWindow = NewCWindow( 0L, &windRect, "\pSetting 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();
for(x=-640;x<640;x++){ // repeating for all posible conditions -640 to 640 and -480 to 480
for(y=-480;y<480;y++){
gSquares[x+640][y+480] = sqrt(x*x+y*y); // calculating all distances and palcing in a global 2D array , this way we only
} // calculate the square root once instead of every frame.
}
}
/*************** 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();
}
}
int ourRandom( int min, int max ){ // method that returns a random number between min and max
return( (Random()+32768) /((32768*2/) (max-min)))+ min;
}
Continue Reading
Back to Archive