Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Compiled and tested with Microsoft Visual C++ 2010 Express.
- // To run this, you'll need to setup your own Win32 Project.
- // 1) First step is to create a new project: click on File->New->Project
- // 2) Make sure the Win32 template is set and Select Win32 Project. Set the name to floral_pattern and the location wherever you'd like
- // 3) For your setting, Make sure the Application type is set to "Windows Application". Hit finished
- // 4) Copy and paste this file into floral_pattern.cpp
- // 5) Compile and execute the program
- //
- // When the window is up, press a key to have it redraw at a different time of year/day
- #include "stdafx.h"
- #include <math.h>
- #include "floral_pattern.h"
- #define MAX_LOADSTRING 100
- // Global Variables:
- HINSTANCE hInst; // current instance
- TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
- TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
- // Forward declarations of functions included in this code module:
- ATOM MyRegisterClass(HINSTANCE hInstance);
- BOOL InitInstance(HINSTANCE, int);
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
- const int WINDOW_WIDTH = 1600;
- const int WINDOW_HEIGHT = 800;
- enum Seasons
- {
- SUMMER,
- SUMMER_NIGHT,
- AUTUMN,
- AUTUMN_NIGHT,
- WINTER,
- WINTER_NIGHT,
- NUMBER_OF_SEASONS
- };
- int currentSeason = SUMMER;
- struct vec2
- {
- vec2( const float initX, const float initY )
- {
- x = initX;
- y = initY;
- }
- void Rotate( const float angle )
- {
- const float rad = angle * ( 3.14159265f / 180.0f );
- const float cosAngle = cos( rad );
- const float sinAngle = sin( rad );
- float newX = ( x * cosAngle ) + ( y * sinAngle );
- float newY = ( x * -sinAngle ) + ( y * cosAngle );
- float len = sqrt( newX * newX + newY * newY );
- x = newX / len;
- y = newY / len;
- }
- float x, y;
- };
- struct PenList
- {
- HPEN stemPen;
- HPEN foliagePen1;
- HPEN foliagePen2;
- };
- // draws a line
- void FloraLine( HDC hdc, HPEN pen, const float startX, const float startY, const float endX, const float endY )
- {
- SelectObject( hdc, pen );
- MoveToEx( hdc, (int)startX, (int)startY, NULL );
- LineTo( hdc, (int)endX, (int)endY );
- }
- // recursively draws a leaf
- void LeafRecurse( HDC hdc, int recursionlevel, const float smallestLength, const float leafLength, const float branchAngle, const vec2 & pos, const vec2 & dir, float length, HPEN foliagePen, HPEN stemPen )
- {
- if ( length < smallestLength )
- {
- return;
- }
- // Draw the current stem
- vec2 currentBranchEnd( pos );
- currentBranchEnd.x += dir.x * length;
- currentBranchEnd.y += dir.y * length;
- FloraLine( hdc, stemPen, pos.x, pos.y, currentBranchEnd.x, currentBranchEnd.y );
- // recursively draw an off shoot
- vec2 sideBranch( pos );
- sideBranch.x += ( dir.x * length * 0.5f );
- sideBranch.y += ( dir.y * length * 0.5f );
- vec2 sideBranchDir( dir );
- if ( ( recursionlevel & 1 ) == 0 )
- {
- sideBranchDir.Rotate( branchAngle * 5 );
- LeafRecurse( hdc, recursionlevel + 1, leafLength, leafLength, branchAngle, sideBranch, sideBranchDir, length * 0.7f, foliagePen, foliagePen );
- }
- else
- {
- sideBranchDir.Rotate( -branchAngle * 5 );
- LeafRecurse( hdc, recursionlevel + 1, leafLength, leafLength, branchAngle, sideBranch, sideBranchDir, length * 0.7f, foliagePen, foliagePen );
- }
- // continue drawing the current stem
- vec2 nextStemBranchDir( dir );
- nextStemBranchDir.Rotate( branchAngle );
- LeafRecurse( hdc, recursionlevel + 1, smallestLength, leafLength, branchAngle, currentBranchEnd, nextStemBranchDir, length * 0.9f, foliagePen, stemPen );
- }
- // recursively draws a tree
- void TreeRecurse( HDC hdc, const float smallestLength, const float leafLength, const vec2 & position, const vec2 & direction, float length, const PenList & penList )
- {
- if ( length < smallestLength )
- {
- // leaves, alternate colors
- return;
- }
- // draw the current stem
- vec2 currentBranchEnd( position );
- currentBranchEnd.x += ( direction.x * length );
- currentBranchEnd.y += ( direction.y * length );
- float childBranchLen = length / 1.2f;
- if ( length > leafLength )
- {
- FloraLine( hdc, penList.stemPen, position.x, position.y, currentBranchEnd.x, currentBranchEnd.y );
- }
- else
- {
- if ( rand() % 3 )
- {
- FloraLine( hdc, penList.foliagePen1, position.x, position.y, currentBranchEnd.x, currentBranchEnd.y );
- }
- else
- {
- FloraLine( hdc, penList.foliagePen2, position.x, position.y, currentBranchEnd.x, currentBranchEnd.y );
- }
- }
- // left branch
- vec2 secondBranchDir( direction );
- secondBranchDir.Rotate( 25 + ( ( rand() % 10 ) - 5.0f ) );
- TreeRecurse( hdc, smallestLength, leafLength, currentBranchEnd, secondBranchDir, childBranchLen, penList );
- // right branch
- vec2 thirdBranchDir( direction );
- thirdBranchDir.Rotate( -25 + ( ( rand() % 10 ) - 5.0f ) );
- TreeRecurse( hdc, smallestLength, leafLength, currentBranchEnd, thirdBranchDir, childBranchLen, penList );
- }
- // main entry point for drawing
- void FloraMain( HDC hdc )
- {
- HPEN whitePen = CreatePen( PS_SOLID, 1, RGB( 255, 255, 255 ) );
- HPEN stemPen;
- HPEN foliagePen;
- HPEN redLeafPen;
- HPEN yellowLeafPen;
- HPEN snowPen;
- HBRUSH blueBrush = CreateSolidBrush( RGB( 100, 195, 253 ) );
- HBRUSH yellowBrush = CreateSolidBrush( RGB( 255, 255, 0 ) );
- HBRUSH whiteBrush = CreateSolidBrush( RGB( 255, 255, 255 ) );
- HBRUSH blackBrush = CreateSolidBrush( RGB( 0, 0, 0 ) );
- HBRUSH foliageBrush;
- HBRUSH snowBrush;
- HBRUSH redBrush;
- if ( currentSeason != SUMMER_NIGHT && currentSeason != AUTUMN_NIGHT && currentSeason != WINTER_NIGHT )
- {
- redLeafPen = CreatePen( PS_SOLID, 1, RGB( 252, 178, 0 ) );
- snowPen = CreatePen( PS_SOLID, 1, RGB( 255, 255, 255 ) );
- yellowLeafPen = CreatePen( PS_SOLID, 1, RGB( 255, 255, 0 ) );
- stemPen = CreatePen( PS_SOLID, 1, RGB( 185, 122, 87 ) );
- snowBrush = CreateSolidBrush( RGB( 255, 255, 255 ) );
- redBrush = CreateSolidBrush( RGB( 252, 178, 0 ) );
- if ( currentSeason != WINTER )
- {
- foliageBrush = CreateSolidBrush( RGB( 0, 128, 0 ) );
- foliagePen = CreatePen( PS_SOLID, 1, RGB( 0, 128, 0 ) );
- }
- else
- {
- foliageBrush = whiteBrush;
- foliagePen = snowPen;
- }
- // draw sky
- RECT box;
- box.bottom = 600;
- box.top = 0;
- box.left = 0;
- box.right = 1600;
- FillRect( hdc, &box, blueBrush );
- // draw sun
- SelectObject( hdc, yellowBrush );
- Ellipse( hdc, 250, 50, 350, 150 );
- // draw sun beams
- const vec2 sunLocation( 300.0f, 100.0f );
- vec2 sunBeamDirection( 0.0f, 1.0f );
- for ( int i = 0; i < 36; i++ )
- {
- sunBeamDirection.Rotate( 10.0f );
- FloraLine( hdc, yellowLeafPen, sunLocation.x + ( sunBeamDirection.x * 55 ), sunLocation.y + ( sunBeamDirection.y * 55 ), sunLocation.x + ( sunBeamDirection.x * 85 ), sunLocation.y + ( sunBeamDirection.y * 85 ) );
- }
- }
- else
- {
- const int darken = 2;
- stemPen = CreatePen( PS_SOLID, 1, RGB( 185 >> darken, 122 >> darken, 87 >> darken ) );
- yellowLeafPen = CreatePen( PS_SOLID, 1, RGB( 255 >> darken, 255 >> darken, 0 ) );
- snowPen = CreatePen( PS_SOLID, 1, RGB( 255 >> 2, 255 >> 2, 255 >> darken ) );
- redLeafPen = CreatePen( PS_SOLID, 1, RGB( 252 >> darken, 178 >> darken, 0 ) );
- redBrush = CreateSolidBrush( RGB( 252 >> darken, 178 >> darken, 0 ) );
- snowBrush = CreateSolidBrush( RGB( 255 >> darken, 255 >> darken, 255 >> darken ) );
- if ( currentSeason != WINTER_NIGHT )
- {
- foliageBrush = CreateSolidBrush( RGB( 0, 32, 0 ) );
- foliagePen = CreatePen( PS_SOLID, 1, RGB( 0, 32, 0 ) );
- }
- else
- {
- foliageBrush = whiteBrush;
- foliagePen = snowPen;
- }
- // draw sky
- RECT box;
- box.bottom = 600;
- box.top = 0;
- box.left = 0;
- box.right = 1600;
- FillRect( hdc, &box, blackBrush );
- // moon
- SelectObject( hdc, whiteBrush );
- Ellipse( hdc, 250, 50, 350, 150 );
- // stars
- vec2 starPositions[] = { vec2( 50, 50 ), vec2( 200, 200 ), vec2( 400, 150 ), vec2( 500, 75 ), vec2( 725, 85 ),
- vec2( 800, 25 ), vec2( 1200, 75 ), vec2( 1400, 100 ), vec2( 900, 125 ), vec2( 1300, 170 ), vec2( 69, 160 ),
- vec2( 610, 165 ), vec2( 1069, 109 ), vec2( 1510, 200 ) };
- for ( int i = 0; i < 14; i++ )
- {
- FloraLine( hdc, whitePen, starPositions[i].x + 0, starPositions[i].y + 0, starPositions[i].x - 2, starPositions[i].y + 7 );
- FloraLine( hdc, whitePen, starPositions[i].x - 2, starPositions[i].y + 7, starPositions[i].x + 3, starPositions[i].y + 2 );
- FloraLine( hdc, whitePen, starPositions[i].x + 3, starPositions[i].y + 2, starPositions[i].x - 3, starPositions[i].y + 2 );
- FloraLine( hdc, whitePen, starPositions[i].x - 3, starPositions[i].y + 2, starPositions[i].x + 2, starPositions[i].y + 7 );
- FloraLine( hdc, whitePen, starPositions[i].x + 2, starPositions[i].y + 7, starPositions[i].x + 0, starPositions[i].y + 0 );
- }
- }
- // draw ground
- RECT box;
- box.left = 0;
- box.right = 1600;
- box.bottom = 800;
- box.top = 600;
- PenList penList;
- if ( currentSeason == AUTUMN || currentSeason == AUTUMN_NIGHT )
- {
- penList.foliagePen1 = yellowLeafPen;
- penList.foliagePen2 = redLeafPen;
- FillRect( hdc, &box, redBrush );
- }
- else if ( currentSeason == WINTER || currentSeason == WINTER_NIGHT )
- {
- penList.foliagePen1 = foliagePen;
- penList.foliagePen2 = foliagePen;
- FillRect( hdc, &box, snowBrush );
- }
- else
- {
- penList.foliagePen1 = foliagePen;
- penList.foliagePen2 = foliagePen;
- FillRect( hdc, &box, foliageBrush );
- }
- penList.stemPen = stemPen;
- // trees
- TreeRecurse( hdc, 10, 20, vec2( 700.0f, 600.0f ), vec2( 0.0f, -1.0f ), 80.0f, penList );
- TreeRecurse( hdc, 5, 15, vec2( 200.0f, 600.0f ), vec2( 0.0f, -1.0f ), 40.0f, penList );
- // more trees
- LeafRecurse( hdc, 0, 5,4, 5.0f, vec2( 1200, 600 ), vec2( 0.0f, -1.0f ), 40.0f, penList.foliagePen1, stemPen );
- LeafRecurse( hdc, 0, 5,4, 3.0f, vec2( 1400, 600 ), vec2( 0.0f, -1.0f ), 35.0f, penList.foliagePen2, stemPen );
- DeleteObject( stemPen );
- DeleteObject( foliagePen );
- DeleteObject( redLeafPen );
- DeleteObject( yellowLeafPen );
- DeleteObject( whitePen );
- DeleteObject( snowPen );
- DeleteObject( blueBrush );
- DeleteObject( foliageBrush );
- DeleteObject( yellowBrush );
- DeleteObject( whiteBrush );
- DeleteObject( blackBrush );
- DeleteObject( snowBrush );
- DeleteObject( redBrush );
- }
- int APIENTRY _tWinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPTSTR lpCmdLine,
- int nCmdShow)
- {
- UNREFERENCED_PARAMETER(hPrevInstance);
- UNREFERENCED_PARAMETER(lpCmdLine);
- // TODO: Place code here.
- MSG msg;
- HACCEL hAccelTable;
- // Initialize global strings
- LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
- LoadString(hInstance, IDC_FLORAL_PATTERN, szWindowClass, MAX_LOADSTRING);
- MyRegisterClass(hInstance);
- // Perform application initialization:
- if (!InitInstance (hInstance, nCmdShow))
- {
- return FALSE;
- }
- hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_FLORAL_PATTERN));
- // Main message loop:
- while (GetMessage(&msg, NULL, 0, 0))
- {
- if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- return (int) msg.wParam;
- }
- //
- // FUNCTION: MyRegisterClass()
- //
- // PURPOSE: Registers the window class.
- //
- // COMMENTS:
- //
- // This function and its usage are only necessary if you want this code
- // to be compatible with Win32 systems prior to the 'RegisterClassEx'
- // function that was added to Windows 95. It is important to call this function
- // so that the application will get 'well formed' small icons associated
- // with it.
- //
- ATOM MyRegisterClass(HINSTANCE hInstance)
- {
- WNDCLASSEX wcex;
- wcex.cbSize = sizeof(WNDCLASSEX);
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.lpfnWndProc = WndProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = hInstance;
- wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FLORAL_PATTERN));
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wcex.lpszMenuName = MAKEINTRESOURCE(IDC_FLORAL_PATTERN);
- wcex.lpszClassName = szWindowClass;
- wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
- return RegisterClassEx(&wcex);
- }
- //
- // FUNCTION: InitInstance(HINSTANCE, int)
- //
- // PURPOSE: Saves instance handle and creates main window
- //
- // COMMENTS:
- //
- // In this function, we save the instance handle in a global variable and
- // create and display the main program window.
- //
- BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
- {
- HWND hWnd;
- hInst = hInstance; // Store instance handle in our global variable
- hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
- 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);
- if (!hWnd)
- {
- return FALSE;
- }
- ShowWindow(hWnd, nCmdShow);
- UpdateWindow(hWnd);
- return TRUE;
- }
- //
- // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
- //
- // PURPOSE: Processes messages for the main window.
- //
- // WM_COMMAND - process the application menu
- // WM_PAINT - Paint the main window
- // WM_DESTROY - post a quit message and return
- //
- //
- LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- int wmId, wmEvent;
- PAINTSTRUCT ps;
- HDC hdc;
- switch (message)
- {
- case WM_KEYDOWN:
- {
- RECT rect;
- rect.left = 0;
- rect.top = 0;
- rect.right = WINDOW_WIDTH;
- rect.bottom = WINDOW_HEIGHT;
- InvalidateRect( hWnd, &rect, true );
- break;
- }
- case WM_COMMAND:
- wmId = LOWORD(wParam);
- wmEvent = HIWORD(wParam);
- // Parse the menu selections:
- switch (wmId)
- {
- case IDM_ABOUT:
- DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
- break;
- case IDM_EXIT:
- DestroyWindow(hWnd);
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- break;
- case WM_PAINT:
- hdc = BeginPaint(hWnd, &ps);
- FloraMain( hdc );
- EndPaint(hWnd, &ps);
- currentSeason++;
- if ( currentSeason >= NUMBER_OF_SEASONS )
- {
- currentSeason = SUMMER;
- }
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- return 0;
- }
- // Message handler for about box.
- INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- UNREFERENCED_PARAMETER(lParam);
- switch (message)
- {
- case WM_INITDIALOG:
- return (INT_PTR)TRUE;
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, LOWORD(wParam));
- return (INT_PTR)TRUE;
- }
- break;
- }
- return (INT_PTR)FALSE;
- }
Advertisement
Add Comment
Please, Sign In to add comment