ilteris kaplan blog

Archive of blog posts since 2005

April 5, 2008

Wiki

Setting 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