我试图创建一个带有旋转立方体的应用程序,我创建了窗口,然后当我按“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”时,它应该“旋转”(创建一个新的立方体,但角度不同) 发生了什么:新的立方体被创建,旧的立方体仍然存在