I was reading up on the math for drawing a circle and it made sense, but to translate that too C++ was nonsensical. It appears there is some underlying math or computer functions I'm missing when using
SetPixel(hdc, x, y , COLOREF bg);
in Win32 API GDI.
However, I managed to find code that did draw a circle but I don't really understand what it does on any level apart from the radius float value
and *
operator has something to do with the circle drawing.
Could someone please explain exactly what this is doing and how you figured it out?
//THIS CODE:
float radius = 120.0;
for(int y =-radius; y<=radius; y++)
for(int x =-radius; x<=radius; x++)
if(x*x+y*y <= radius*radius)
SetPixel(DCWindowHandle, 200+x, 200+y, red);
//SCROLL DOWN HERE TO SEE IT IN USE:
#include <windows.h>
LRESULT CALLBACK WndProc(HWND , UINT , WPARAM , LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Marble Engine");
HWND WindowHandle;
MSG Message;
WNDCLASS WindowClass;
WindowClass.style = CS_HREDRAW | CS_VREDRAW;
WindowClass.lpfnWndProc = WndProc;
WindowClass.cbClsExtra = 0;
WindowClass.cbWndExtra = 0;
WindowClass.hInstance = hInstance;
WindowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WindowClass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
WindowClass.lpszMenuName = NULL;
WindowClass.lpszClassName = szAppName;
if(!RegisterClass (&WindowClass))
{
MessageBox(NULL, TEXT("This Program Requires Nothing!"),
szAppName, MB_ICONERROR);
return 0;
}
WindowHandle = CreateWindow(szAppName,
TEXT ("The Shit Program!"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(WindowHandle, iCmdShow);
UpdateWindow(WindowHandle);
while(GetMessage(&Message, NULL, 0, 0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return Message.wParam;
}
LRESULT CALLBACK WndProc(HWND WindowHandle, UINT Message, WPARAM wParam, LPARAM lParam)
{
HDC DCWindowHandle;
PAINTSTRUCT PaintStruct;
RECT rect;
TCHAR * text = TEXT("Hello there this is test!");
COLORREF red = RGB(255, 0, 0);
switch(Message)
{
case WM_CREATE:
DCWindowHandle = GetDC(WindowHandle);
ReleaseDC(WindowHandle, DCWindowHandle);
return 0;
case WM_PAINT:
{
DCWindowHandle = BeginPaint(WindowHandle, &PaintStruct);
GetClientRect(WindowHandle, &rect);
DrawText(DCWindowHandle, TEXT("Bother!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
float radius = 120.0;
for(int y =-radius; y<=radius; y++)
for(int x =-radius; x<=radius; x++)
if(x*x+y*y <= radius*radius)
SetPixel(DCWindowHandle, 200+x, 200+y, red);
EndPaint( WindowHandle, &PaintStruct);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(WindowHandle, Message, wParam , lParam);
}
It's one of the more inefficient ways to draw a circle. What it does is go through, one by one, all the pixels in a square whose sides are the same length as the diameter of the circle. If distance from the pixel to the centre of the square is less than or equal to the radius of the circle then it colours that pixel red. All other pixels in the square are left unmodified.