使立方体旋转,使旧的消失

问题描述 投票:0回答:0

我试图创建一个带有旋转立方体的应用程序,我创建了窗口,然后当我按“p”时,我的立方体被创建,每次电脑按下“p”时,立方体就会旋转。 问题是旧的立方体仍然存在,所以我的屏幕上有无限的立方体

这里是代码

#include <Windows.h>
#include <iostream>
#include <string>   //i mean, useless, we use wide strings
#include <sstream>
#include <unordered_map>
#include <chrono>

using namespace std::this_thread; // sleep_for, sleep_until
using namespace std::chrono; // nanoseconds, system_clock, seconds

template <typename T> int sgn(T val) {
    return (T(0) < val) - (val < T(0));
}


void drawLine(float x1, float y1, float x2, float y2, HDC hdc, HWND hWnd, HBRUSH brush)
{

    RECT cuberect;
    FillRect(hdc, &cuberect, brush);
    DeleteObject(brush);
    ReleaseDC(hWnd, hdc);

    InvalidateRect(hWnd, NULL, TRUE);
    float x = x1;
    float y = y1;
    float dx = fabsf(x2 - x1);
    float dy = fabsf(y2 - y1);
    float s1 = sgn(x2 - x1);
    float s2 = sgn(y2 - y1);
    float t;
    float intercharge;
    if (dy > dx) t = dx, dx = dy, dy = t, intercharge = 1;
    else intercharge = 0;
    float e = 2 * dy - dx;
    float a = 2 * dy;
    float b = 2 * dy - 2 * dx;
    SetPixel(hdc ,x, y, RGB (0, 0, 0));
    for (int i = 1; i < dx; i++)
    {
        if (e < 0)
        {
            if (intercharge == 1) y = y + s2;
            else
            {
                x = x + s1;
                e = e + a;
            }
        }
        else
        {
            y = y + s2;
            x = x + s1;
            e = e + b;
        }
        SetPixel(hdc, x, y, RGB (0, 0, 0));
        std::cout << x << " - " << y << std::endl;
    }
}

void rotateC(float cTmp[4][3], float rmatrix[3][3])
{

    cTmp[2][0] = cTmp[0][0] * rmatrix[0][0] + cTmp[0][1] * rmatrix[0][1] + cTmp[0][2] * rmatrix[0][2];
    cTmp[2][1] = cTmp[0][0] * rmatrix[1][0] + cTmp[0][1] * rmatrix[1][1] + cTmp[0][2] * rmatrix[1][2];
    cTmp[2][2] = cTmp[0][0] * rmatrix[2][0] + cTmp[0][1] * rmatrix[2][1] + cTmp[0][2] * rmatrix[2][2];
    cTmp[3][0] = cTmp[1][0] * rmatrix[0][0] + cTmp[1][1] * rmatrix[0][1] + cTmp[1][2] * rmatrix[0][2];
    cTmp[3][1] = cTmp[1][0] * rmatrix[1][0] + cTmp[1][1] * rmatrix[1][1] + cTmp[1][2] * rmatrix[1][2];
    cTmp[3][2] = cTmp[1][0] * rmatrix[2][0] + cTmp[1][1] * rmatrix[2][1] + cTmp[1][2] * rmatrix[2][2];
    cTmp[0][0] = cTmp[2][0];
    cTmp[0][1] = cTmp[2][1];
    cTmp[0][2] = cTmp[2][2];
    cTmp[1][0] = cTmp[3][0];
    cTmp[1][1] = cTmp[3][1];
    cTmp[1][2] = cTmp[3][2];

};


//
//WndProc,    the procedure part:  (window -> messages -> machine -> render -> window)

// #define CONVERT(x) *((x) = "L"(x)) // maybe?

bool lbutton = false;
short x = 0, y = 0, px = 0, py = 0;
const int size = 10;
static int dotx = 50;
static int doty = 50;
int width = 1024;
int height = 512;
COLORREF white = RGB(255, 255, 255);
float angle = 0;
HBRUSH whitebrush = CreateSolidBrush(RGB(255, 255, 255));

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { //hWnd = handle to window, msg = message (like WM_SIZE or WM_QUIT). wparal and lparam contain additional data

    //
    //dot creation
    HDC device_context = GetDC(hWnd);
    static COLORREF color = RGB(255, 0, 0);
    int oldx = dotx;
    int oldy = doty;
    RECT pixelmovementrect = { oldx, oldy, oldx + size, oldy + size };
    HDC hdc = GetDC(hWnd);
    bool w = false, a = false, s = false, d = false; 

    switch (msg) {  // switch cases on changing msg value

    case WM_CREATE:

        SetTimer(hWnd, 1, 20, NULL); //the third arg is the n of milliseconds

        break;


    case WM_TIMER:

        oldx = dotx;
        oldy = doty;

        if (GetAsyncKeyState('W') & 0x8000) {

            doty--;

            FillRect(hdc, &pixelmovementrect, whitebrush);
            DeleteObject(whitebrush);
            ReleaseDC(hWnd, hdc);

            InvalidateRect(hWnd, NULL, TRUE);
        }
        if (GetAsyncKeyState('A') & 0x8000) {

            dotx--;

            FillRect(hdc, &pixelmovementrect, whitebrush);
            DeleteObject(whitebrush);
            ReleaseDC(hWnd, hdc);

            InvalidateRect(hWnd, NULL, TRUE);
        }
        if (GetAsyncKeyState('S') & 0x8000) {

            doty++;

            FillRect(hdc, &pixelmovementrect, whitebrush);
            DeleteObject(whitebrush);
            ReleaseDC(hWnd, hdc);

            InvalidateRect(hWnd, NULL, TRUE);
        }
        if (GetAsyncKeyState('D') & 0x8000) {
            
            if (dotx < (300 - size)) {

                dotx++;

            }

            FillRect(hdc, &pixelmovementrect, whitebrush);
            DeleteObject(whitebrush);
            ReleaseDC(hWnd, hdc);

            InvalidateRect(hWnd, NULL, TRUE);
        }
        if (GetAsyncKeyState('P') & 0x8000) {

            int cubewidth = 1024; // window width
            int cubeheight = 512; // window height

            int matrix[8][3]{ //vertici

                    {63,63,63},
                    {63,-63,63},
                    {-63,-63,63},
                    {-63,63,63},
                    {63,63,-63}, //
                    {63,-63,-63}, //
                    {-63,-63,-63},
                    {-63,63, -63}

            };

            int vector[12][2]{

                    {0,1}, //linea da vertice 0 a vertice 1
                    {1,2},
                    {2,3},
                    {3,0},
                    {4,5},
                    {5,6},
                    {6,7},
                    {7,4},
                    {0,4},
                    {1,5},
                    {2,6},
                    {3,7}

            };

            float xt1, yt1, xt2, yt2, zt1, zt2, flenght = 500, rotspeed = -0.015, dime = 1, osX = 0, osY = 0;
            bool exit = true;

            float rmatrix1[3][3]{ {1,      0,     0},
                      {0, cos(angle),sin(angle)},
                      {0,-sin(angle),cos(angle)} };

            float rmatrix2[3][3]{ { cos(angle),0,sin(angle)},
                                  {      0,1,0     },
                                  {-sin(angle),0,cos(angle)} };

            float rmatrix3[3][3]{ { cos(angle),sin(angle),0},
                                  {-sin(angle),cos(angle),0},
                                  {0,      0,     1} };

            float cTmp[4][3];

            for (int i = 0; i < 12; i++) {

                // MoveToEx(dev_con_cube, int(cTmp[0][0] * dime + (cubewidth / 2) + osX), int(cTmp[0][1] * dime + (cubeheight / 2) + osY), nullptr);
                // LineTo(dev_con_cube, int(cTmp[1][0] * dime + (cubewidth / 2) + osX), int(cTmp[1][1] * dime + (cubeheight / 2) + osY));
                // EndPaint(hWnd, &paints);

                cTmp[0][0] = matrix[vector[i][0]][0],
                    cTmp[0][1] = matrix[vector[i][0]][1],
                    cTmp[0][2] = matrix[vector[i][0]][2],
                    cTmp[1][0] = matrix[vector[i][1]][0],
                    cTmp[1][1] = matrix[vector[i][1]][1],
                    cTmp[1][2] = matrix[vector[i][1]][2];

                //rotateC(cTmp, rmatrix1);
                rotateC(cTmp, rmatrix2);
                rotateC(cTmp, rmatrix3);

                cTmp[0][0] = (cTmp[0][0] * flenght) / (cTmp[0][2] + flenght);
                cTmp[1][0] = (cTmp[1][0] * flenght) / (cTmp[1][2] + flenght);
                cTmp[0][1] = (cTmp[0][1] * flenght) / (cTmp[0][2] + flenght);
                cTmp[1][1] = (cTmp[1][1] * flenght) / (cTmp[1][2] + flenght);

                //
                // MoveToEx(dev_con_cube, int(cTmp[0][0] * dime + (cubewidth / 2) + osX), int(cTmp[0][1] * dime + (cubeheight / 2) + osY), nullptr);
                // LineTo(dev_con_cube, int(cTmp[1][0] * dime + (cubewidth / 2) + osX), int(cTmp[1][1] * dime + (cubeheight / 2) + osY));
                // EndPaint(hWnd, &paints);
                drawLine(int(cTmp[0][0] * dime + (cubewidth / 2) + osX), int(cTmp[0][1] * dime + (cubeheight / 2) + osY), int(cTmp[1][0] * dime + (cubewidth / 2) + osX), int(cTmp[1][1] * dime + (cubeheight / 2) + osY), hdc, hWnd, whitebrush);


                // sleep_for(nanoseconds(1000000000));
                // sleep_until(system_clock::now() /* + seconds(1) */ );

                //drawLine(cTmp[0][0] * d + (width / 2) + osX, cTmp[0][1] * d + (height / 2)  + osY, """" cTmp[1][0] * d + (width / 2) + osX, cTmp[1][1] * d + (height / 2) + osY, renderer);
                std::cout << "--|" << (int)cTmp[0][0] << " | " << (int)cTmp[0][1] << " | " << (int)cTmp[1][0] << " | " << (int)cTmp[1][1] << "|--" << std::endl;
            }

            angle += rotspeed;
            rotspeed -= 0.5;

        }

        break;

    /*
    case WM_SIZE: //should make it paint only pixels were not existent
    {
        HDC reshdc = GetDC(hWnd);
        RECT rect;
        HBRUSH brush = CreateSolidBrush(RGB(255, 255, 255));
        GetClientRect(hWnd, &rect);
        FillRect(reshdc, &rect, brush);
        DeleteObject(brush);
        
    }

    break;

    */

    case WM_LBUTTONDOWN:
    {
        std::cout << "fnc called" << std::endl;

        HDC device_context = GetDC(hWnd);
        x = LOWORD(lParam);
        y = HIWORD(lParam);

        if (!lbutton) {

            px = LOWORD(lParam);
            py = HIWORD(lParam);
            std::cout << px << "|" << py << "|" << x << "|" << y << "|" << lbutton << std::endl; //yes
            lbutton = true;
            std::cout << px << "|" << py << "|" << x << "|" << y << "|" << lbutton << std::endl; //yes

        }
        else {

            HPEN penna = CreatePen(PS_SOLID, 5, RGB(0, 0, 150));
            SelectObject(device_context, penna);
            MoveToEx(device_context, px, py, nullptr);
            LineTo(device_context, x, y);
            ReleaseDC(hWnd, device_context);
            std::cout << px << "|" << py << "|" << x << "|" << y << "|" << lbutton << std::endl; //yes
            lbutton = false;
            std::cout << px << "|" << py << "|" << x << "|" << y << "|" << lbutton << std::endl; //yes

        }
        std::cout << px << "|" << py << "|" << x << "|" << y << "|" << lbutton << std::endl; //yes

        SetWindowText(hWnd, L"second title");    //pass handle to window

        std::wstring titolo = L" X: " + std::to_wstring(x) + L" Y: " + std::to_wstring(y);
        SetWindowText(hWnd, titolo.c_str());

    }
    break;


    case WM_LBUTTONUP:
    {
        SetWindowText(hWnd, L"uwu");
    }

    break;

    /* case WM_MOUSEMOVE: //godo worka
    {
        unsigned short xPos = LOWORD(lParam);
        unsigned short yPos = HIWORD(lParam);

        std::wstring titolo = L" X: " + std::to_wstring(xPos) + L" Y: " + std::to_wstring(yPos);
        SetWindowText(hWnd, titolo.c_str());

    }

    */

    case WM_CLOSE:  //case window get closed
    {
        PostQuitMessage(69); //  "the task ended with code 0"
    }

    break;

    case WM_PAINT:
    {

        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);

        for (int i = 0; i < size; i++)
        {
            for (int j = 0; j < size; j++)
            {
                SetPixel(hdc, dotx + i, doty + j, color);
            }
        }

        MoveToEx(hdc, 300, 0, nullptr);
        LineTo(hdc, 300, 300);
        
        EndPaint(hWnd, &ps);

    }
    
    case WM_KEYUP:
    {

        if (wParam == 'F') {

            SetWindowText(hWnd, L"third title");
            MessageBox(hWnd, L"jgjfgdfg", L"uuuvloa", MB_OK);

        }

    }

    break;

    case WM_CHAR:
    {
        if (wParam != 'w') {

            std::wstring title = L"aaaaa";    //strings are 8 bit (like abcdef), LPCWSTR is wchar_t* so 16bit so chinese things, wstring is wide string so it is wchar* array and not char* array
            title.push_back((wchar_t)wParam);
            SetWindowTextW(hWnd, title.c_str());    // https://stackoverflow.com/questions/22990044/lpcwstr-error-is-there-a-better-solution

        }

    }

    break;


    }

    return DefWindowProc(hWnd, msg, wParam, lParam);

}

#pragma comment (linker, "/entry:WinMainCRTStartup /subsystem:console")  //show console

//
//entry point

int WINAPI WinMain(
    _In_ HINSTANCE hInstance,   //hinstance is a pointer (class HINSTANCE) to an object holding infos (like an handle)
    _In_opt_ HINSTANCE hPrevInstance,   //always null
    _In_ LPSTR lpCmdLine,   //pass params with cmd (string args but in a single string)
    _In_ int nCmdShow   //changing this value the app will be showed or not, or displayed in different ways
) {

    std::cout << "aaaa" << std::endl;

    const auto pClassName = L"title";

    //
    //register window class
    WNDCLASSEX wc = { 0 }; //created window object ("wc" is the object name)
    wc.cbSize = sizeof(wc); // type UINT, size of the structure (the window)
    wc.style = CS_OWNDC;    // type UINT, style of the window (point 2 of header comment -> msdn docs) owndc = allocates a unique device context for each window in the class (0x0020) basic windows gdi
    wc.lpfnWndProc = WndProc;    //type WNDPROC, pointer to window procedure, must use "callwindowproc", watch the video #2 of the playlist for more info, DEFaultWINDOWPROCedure
    wc.cbClsExtra = 0;  // type int, number of bites to allocate following window-class structure, the os initialise them to zero
    wc.cbWndExtra = 0;  // type int, number of extra bytes to allocate following the window instance, bytes initialised to zero (by os). if an app uses WNDCLASSEX to register a dialog box created by using the class directive in the resource file, it musrt set this member to DLGWINDOWEXTRA
    wc.hInstance = hInstance;   // type HINSTANCE, handle to the instance
    wc.hIcon = nullptr;   // type HICON, handle to class icon, it must be handle to an icon resource, if it's NULL the system provides a default icon
    wc.hCursor = nullptr;   // type HCURSOR, handle to the class cursor, must be handle to cursor resource, if this member is NULL an app must explicitly set the cursor shape whenever the mouse moves into the app window
    wc.hbrBackground = nullptr;    // type HBRUSH, handle to class background brush, this member can be a handle to the brush to be used for painting the background, or it can be a color value. A color value must be one of the following standard system colors (the value 1 must be added to the chosen color). If a color value is given, you must convert it to one of the HBRUSH types you can find on link 2 of point 2 of header comment
    wc.lpszMenuName = nullptr;    // type LPCTSTR, specify the resource name of the class menu, if it's null the app will have no default menu
    wc.lpszClassName = pClassName;    // type LPCTSTR, changes the behavior depending on use, more info on the link 2 of point 2 of header comment
    wc.hIconSm = nullptr;   // a handle to a small icon associated with window class, if NULL the system searches the icon resource speciied by hIcon

    RegisterClassEx(&wc); //register class extended (extended version)

    //
    //create window instance

    HWND hWnd = CreateWindowEx( //pass there parameters requested, some are from default window and not extended, like style. hWnd is an handle

        0, pClassName, // dwExStyle, class name (DWORD, LPCWSTR)
        L"window name", // window name (LPCWSTR)
        WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_THICKFRAME, // dw style (DWORD)
        100, 100, width, height,  // position x, position y, width, height (int)
        nullptr, nullptr, hInstance, nullptr // hWndParent, hMenu, hInstance, lpParam ( HWND, HMENU, HINSTANCE, LPVOID ) 


    );

    //
    //show window
    ShowWindow(hWnd, 5);  // 2 instead of 5 does not create background; 5 = SW_SHOW

    //
    //message pump, making the window responsable via input (messages), video #3
    MSG msg; //struct MSG (message),    the behavior is default because we used defaultwindowsprocedure (DefWindowProc) when we registered window class, that includes functs like WindowsMessageClose, but it doesn't work without msg because maybe u have 2 windows, you click to close one and both closes
    BOOL gResult;

    while ((gResult = GetMessage(&msg, nullptr, 0, 0)) > 0) { //passing params: [out] LPMSG lpmsg, [in, optional] HWND hwnd, [in] UINT wmsgfiltermin, [in] UINT wmsgfiltermax

        // 3rd point of docs header comment
        TranslateMessage(&msg);  // [in] const MSG *lpMsg,    pointer to msg structure that contains message information retrieved from calling threads message queu using getmessage or peekmessage
        DispatchMessage(&msg);  // same args as TranslateMessage, it dispatches a message retrieved with GetMessage

    }

    if (gResult == -1) {

        return -1;

    }
    else {

        return msg.wParam;  // WM_QUIT: https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-quit

    }

    return 0;

}

我除了有一个立方体,一个红色立方体,白色背景。 每次我单击“p”时,它应该“旋转”(创建一个新的立方体,但角度不同) 发生了什么:新的立方体被创建,旧的立方体仍然存在

c++ winapi visual-c++
© www.soinside.com 2019 - 2024. All rights reserved.