fbpx

C++: Munching Squares

Bjarne-stroustrup
 


Render a graphical pattern where each pixel is colored by the value of ‘x xor y’ from an arbitrary color table.

Msquares cpp2.png

#include <windows.h>
#include <string>

//--------------------------------------------------------------------------------------------------
using namespace std;

//--------------------------------------------------------------------------------------------------
const int BMP_SIZE = 512;

//--------------------------------------------------------------------------------------------------
class myBitmap
{
public:
	myBitmap() : pen( NULL ), brush( NULL ), clr( 0 ), wid( 1 ) {}
	~myBitmap()
	{
		DeleteObject( pen );
		DeleteObject( brush );
		DeleteDC( hdc );
		DeleteObject( bmp );
	}

	bool create( int w, int h )
	{
		BITMAPINFO    bi;
		ZeroMemory( &bi, sizeof( bi ) );
		bi.bmiHeader.biSize        = sizeof( bi.bmiHeader );
		bi.bmiHeader.biBitCount    = sizeof( DWORD ) * 8;
		bi.bmiHeader.biCompression = BI_RGB;
		bi.bmiHeader.biPlanes      = 1;
		bi.bmiHeader.biWidth       =  w;
		bi.bmiHeader.biHeight      = -h;

		HDC dc = GetDC( GetConsoleWindow() );
		bmp = CreateDIBSection( dc, &bi, DIB_RGB_COLORS, &pBits, NULL, 0 );
		if( !bmp ) return false;

		hdc = CreateCompatibleDC( dc );
		SelectObject( hdc, bmp );
		ReleaseDC( GetConsoleWindow(), dc );

		width = w; height = h;
		return true;
	}

	void clear( BYTE clr = 0 )
	{
		memset( pBits, clr, width * height * sizeof( DWORD ) );
	}

	void setBrushColor( DWORD bClr )
	{
		if( brush ) DeleteObject( brush );
		brush = CreateSolidBrush( bClr );
		SelectObject( hdc, brush );
	}

	void setPenColor( DWORD c ) { clr = c; createPen(); }

	void setPenWidth( int w )   { wid = w; createPen(); }

	void saveBitmap( string path )
	{
		BITMAPFILEHEADER fileheader;
		BITMAPINFO       infoheader;
		BITMAP           bitmap;
		DWORD            wb;

		GetObject( bmp, sizeof( bitmap ), &bitmap );
		DWORD* dwpBits = new DWORD[bitmap.bmWidth * bitmap.bmHeight];

		ZeroMemory( dwpBits, bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD ) );
		ZeroMemory( &infoheader, sizeof( BITMAPINFO ) );
		ZeroMemory( &fileheader, sizeof( BITMAPFILEHEADER ) );

		infoheader.bmiHeader.biBitCount = sizeof( DWORD ) * 8;
		infoheader.bmiHeader.biCompression = BI_RGB;
		infoheader.bmiHeader.biPlanes = 1;
		infoheader.bmiHeader.biSize = sizeof( infoheader.bmiHeader );
		infoheader.bmiHeader.biHeight = bitmap.bmHeight;
		infoheader.bmiHeader.biWidth = bitmap.bmWidth;
		infoheader.bmiHeader.biSizeImage = bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD );

		fileheader.bfType    = 0x4D42;
		fileheader.bfOffBits = sizeof( infoheader.bmiHeader ) + sizeof( BITMAPFILEHEADER );
		fileheader.bfSize    = fileheader.bfOffBits + infoheader.bmiHeader.biSizeImage;

		GetDIBits( hdc, bmp, 0, height, ( LPVOID )dwpBits, &infoheader, DIB_RGB_COLORS );

		HANDLE file = CreateFile( path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
		WriteFile( file, &fileheader, sizeof( BITMAPFILEHEADER ), &wb, NULL );
		WriteFile( file, &infoheader.bmiHeader, sizeof( infoheader.bmiHeader ), &wb, NULL );
		WriteFile( file, dwpBits, bitmap.bmWidth * bitmap.bmHeight * 4, &wb, NULL );
		CloseHandle( file );

		delete [] dwpBits;
	}

	HDC getDC() const     { return hdc; }
	int getWidth() const  { return width; }
	int getHeight() const { return height; }

private:
	void createPen()
	{
		if( pen ) DeleteObject( pen );
		pen = CreatePen( PS_SOLID, wid, clr );
		SelectObject( hdc, pen );
	}

	HBITMAP bmp;
	HDC     hdc;
	HPEN    pen;
	HBRUSH  brush;
	void    *pBits;
	int     width, height, wid;
	DWORD   clr;
};
//--------------------------------------------------------------------------------------------------
class mSquares
{
public:
	mSquares()
	{
		bmp.create( BMP_SIZE, BMP_SIZE );
		createPallete();
	}

	void draw()
	{
		HDC dc = bmp.getDC();
		for( int y = 0; y < BMP_SIZE; y++ )
		for( int x = 0; x < BMP_SIZE; x++ )
		{
			int c = ( x ^ y ) % 256;
			SetPixel( dc, x, y, clrs[c] );
		}

		BitBlt( GetDC( GetConsoleWindow() ), 30, 30, BMP_SIZE, BMP_SIZE, dc, 0, 0, SRCCOPY );
		//bmp.saveBitmap( "f:\\rc\\msquares_cpp.bmp" );
	}

private:
	void createPallete()
	{
		for( int x = 0; x < 256; x++ )
		clrs[x] = RGB( x<<1, x, x<<2 );//rand() % 180 + 50, rand() % 200 + 50, rand() % 180 + 50 );
	}

	unsigned int clrs[256];
	myBitmap bmp;
};
//--------------------------------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
	ShowWindow( GetConsoleWindow(), SW_MAXIMIZE );
	srand( GetTickCount() );
	mSquares s; s.draw();
	return system( "pause" );
}
//--------------------------------------------------------------------------------------------------

SOURCE

Content is available under GNU Free Documentation License 1.2.