Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //////////////////////////////////////////////////////////////////////////
- #pragma comment(lib, "gdiplus.lib") // Dolaczamy biblioteke gdiplus
- #define _USE_MATH_DEFINES
- #include <windows.h> //Plik naglowkowy zawierający definicje funkcji, typy danych oraz makra WinAPI
- #include <gdiplus.h> //Plik naglowkowy GDIPlus
- #include <math.h>
- using namespace Gdiplus; //Uzywamy przestrzeni nazw GDI
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
- {
- MSG msg;
- HWND hWnd;
- WNDCLASS wndClass;
- wndClass.style = CS_HREDRAW | CS_VREDRAW; //Styl okna - bedzie sie odmalowywalo przy kazdym przesunieciu lub zmianie rozdzielczosci
- wndClass.lpfnWndProc = WndProc; //Wskazujemy procedure przetwarzajaca komunikaty okna
- wndClass.cbClsExtra = 0;
- wndClass.cbWndExtra = 0;
- wndClass.hInstance = hInstance; //Ustawiamy w oknie instancje naszego programu
- wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // Ladujemy z zasobow systemowych
- wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); // Domyslny kursor i ikone
- wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // Kolor tla okna
- wndClass.lpszMenuName = NULL; // Nie tworzymy menu
- wndClass.lpszClassName = TEXT("GettingStarted"); // Nazwa klasy okna, wyswietlana w naglowku okna
- RegisterClass(&wndClass); //Rejestrujemy klase okna w systemie
- hWnd = CreateWindow(
- TEXT("GettingStarted"), // window class name
- TEXT("Getting Started"), // window caption
- WS_OVERLAPPEDWINDOW, // window style
- CW_USEDEFAULT, // initial x position
- CW_USEDEFAULT, // initial y position
- 800, // initial x size
- 600, // initial y size
- NULL, // parent window handle
- NULL, // window menu handle
- hInstance, // program instance handle
- NULL); // creation parameters
- RECT rect = { 0, 0, 800, 600 }; //Tworzymy prostokat o wymiarach 800x600
- AdjustWindowRect(&rect, GetWindowLong(hWnd, GWL_STYLE), FALSE); //Skalujemy okno tak aby obszar roboczy faktycznie mial 800x600px
- SetWindowPos(hWnd, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE);
- GdiplusStartupInput gdiplusStartupInput; //Struktura zawierajaca parametry startowe
- ULONG_PTR gdiplusToken; // Wskaznik pod ktory zostanie przypisany token
- // Initializacja GDI
- GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
- ShowWindow(hWnd, nCmdShow); //Wyswietlamy okno
- UpdateWindow(hWnd);
- /*
- Ponizej znajduje sie petla wiadomosci. Odbieramy
- wiadomosci od systemu za pomoca funkcji GetMessage
- i przekazujemy je do procedury okna.
- */
- while (GetMessage(&msg, NULL, 0, 0)) {
- DispatchMessage(&msg);
- }
- GdiplusShutdown(gdiplusToken);
- return (int)msg.wParam;
- }
- VOID DrawGrid(HDC hdc){
- Graphics graphics(hdc);
- Pen pen(Color(255, 0, 0, 0));
- for (int i = 0; i < 40 * 20; i = i + 20){
- graphics.DrawLine(&pen, i, 0, i, 600);
- }
- for (int i = 0; i < 30 * 20; i = i + 20){
- graphics.DrawLine(&pen, 0, i, 800, i);
- }
- }
- VOID DrawPixel(HDC hdc, int x, int y, int blackness){
- Graphics graphics(hdc);
- SolidBrush solidBrush(Color(blackness, 0, 0, 0));
- graphics.FillRectangle(&solidBrush, x + 1, y + 1, 19, 19);
- }
- struct MyPixel
- {
- int mBlackness;
- };
- MyPixel mFrontBuffer[40][30];
- VOID Present(HDC hdc){
- for (int i = 0; i < 40; i++){
- for (int j = 0; j < 30; j++){
- DrawPixel(hdc, i * 20, j * 20, mFrontBuffer[i][j].mBlackness);
- }
- }
- }
- VOID Mix(){
- int counter = 0;
- for (int i = 0; i < 40; i++){
- for (int j = 0; j < 30; j++){
- mFrontBuffer[i][j].mBlackness = counter;
- if (counter == 255) counter = 0;
- else{
- counter++;
- }
- }
- }
- }
- VOID SimpleLine(int x0, int y0, int x1, int y1, int blackness){
- double dy = y1 - y0;
- double dx = x1 - x0;
- double a = dy / dx;
- double b = y0 - a * x0;
- for (int i = x0; i <= x1; i++){
- int y = a * i + b;
- mFrontBuffer[i][y].mBlackness = blackness;
- }
- }
- VOID Bresenham(int x0, int y0, int x1, int y1, int blackness){
- if (x1 < x0){
- int tempX, tempY;
- tempX = x0;
- tempY = y0;
- x0 = x1;
- x1 = tempX;
- y0 = y1;
- y1 = tempY;
- }
- int dx = x1 - x0;
- int dy = y1 - y0;
- int da = 2 * dy;
- int db = 2 * dy - 2 * dx;
- int d = 2 * dy - dx;
- while (x0 <= x1){
- mFrontBuffer[x0][y0].mBlackness = blackness;
- if (d < 0) {
- x0++;
- d += da;
- }
- else {
- x0++;
- y0++;
- d += db;
- }
- }
- }
- VOID FloodFill(int x, int y, int borderColor, int fillColor){
- boolean border = (mFrontBuffer[x][y].mBlackness == borderColor);
- if (!border && mFrontBuffer[x][y].mBlackness != fillColor){
- mFrontBuffer[x][y].mBlackness = fillColor;
- if (x - 1 >= 0) FloodFill(x - 1, y, borderColor, fillColor);
- if (x + 1 < 40) FloodFill(x + 1, y, borderColor, fillColor);
- if (y - 1 >= 0) FloodFill(x, y - 1, borderColor, fillColor);
- if (y + 1 < 30) FloodFill(x, y + 1, borderColor, fillColor);
- }
- }
- VOID OnPaint(HDC hdc)
- {
- DrawGrid(hdc);
- //Mix();
- //SimpleLine(0, 0, 39, 14, 128); // gray - simple line
- //Bresenham(0, 10, 39, 24, 255); // black - Bresenham
- Present(hdc);
- }
- int GetSquare(int pixel){
- int square = pixel / 20;
- if (pixel % 20 == 0) square--;
- return square;
- }
- struct Vector2D{
- float tab[3];
- Vector2D(){
- tab[0] = 0;
- tab[1] = 0;
- tab[2] = 1;
- };
- Vector2D(int arg_x, int arg_y){
- tab[0] = arg_x;
- tab[1] = arg_y;
- tab[2] = 1;
- }
- };
- float DegToRad(float a){
- return M_PI * a / 180;
- }
- struct MyMatrix{
- float tab[3][3];
- void Clear(){
- for (int i = 0; i < 3; i++){
- for (int j = 0; j < 3; j++){
- tab[i][j] = 0;
- }
- }
- }
- MyMatrix(){
- Clear();
- }
- void Identity(){
- for (int i = 0; i < 3; i++){
- tab[i][i] = 1;
- }
- }
- void Translate(int x, int y){
- Clear();
- Identity();
- tab[0][2] = x;
- tab[1][2] = y;
- }
- void Rotate(float a){
- Clear();
- tab[0][0] = cos(a);
- tab[0][1] = -sin(a);
- tab[1][0] = sin(a);
- tab[1][1] = cos(a);
- tab[2][2] = 1;
- }
- };
- Vector2D Multiply(MyMatrix mat, Vector2D vec){
- Vector2D toReturn = Vector2D();
- for (int i = 0; i < 3; i++){
- toReturn.tab[i] = 0;
- for (int j = 0; j < 3; j++){
- toReturn.tab[i] += vec.tab[j] * mat.tab[i][j];
- }
- }
- return toReturn;
- }
- MyMatrix MultiplyMatrix(MyMatrix m1, MyMatrix m2){
- MyMatrix toReturn = MyMatrix();
- for (int i = 0; i < 3; i++){
- for (int j = 0; j < 3; j++){
- toReturn.tab[i][j] = m1.tab[i][0] * m2.tab[0][j] + m1.tab[i][1] * m2.tab[1][j] + m1.tab[i][2] * m2.tab[2][j];
- }
- }
- return toReturn;
- }
- VOID DrawTranslatedPixel(int x, int y, MyMatrix matrix){
- mFrontBuffer[x][y].mBlackness = 128;
- Vector2D translatedVector;
- translatedVector = Multiply(matrix, Vector2D(x, y));
- if ((int)translatedVector.tab[0] < 40 && (int)translatedVector.tab[1] < 30){
- mFrontBuffer[(int)translatedVector.tab[0]][(int)translatedVector.tab[1]].mBlackness = 255;
- }
- }
- LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- HDC hdc;
- PAINTSTRUCT ps;
- int x, y;
- int lPressed = false;
- switch (msg)
- {
- case WM_PAINT:
- hdc = BeginPaint(hwnd, &ps);
- OnPaint(hdc);
- EndPaint(hwnd, &ps);
- return 0;
- case WM_DESTROY:
- PostQuitMessage(0); // Ta funkcja dodaje do kolejki wiadomosci WM_QUIT
- return 0;
- case WM_LBUTTONDOWN:
- {
- x = LOWORD(lParam);
- y = HIWORD(lParam);
- MyMatrix m1, m2;
- m1.Rotate(DegToRad(15));
- m2.Translate(5, 5);
- DrawTranslatedPixel(GetSquare(x), GetSquare(y), MultiplyMatrix(m1, m2));
- RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE);
- }
- break;
- case WM_RBUTTONDOWN:
- {
- x = LOWORD(lParam);
- y = HIWORD(lParam);
- MyMatrix m11, m22;
- m11.Rotate(DegToRad(15));
- m22.Translate(5, 5);
- DrawTranslatedPixel(GetSquare(x), GetSquare(y), MultiplyMatrix(m22, m11));
- FloodFill(GetSquare(x), GetSquare(y), 255, 128);
- RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE);
- }
- break;
- }
- // wszystkie inne wiadomosci sa obslugiwane w sposob domyslny
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement