Функция WINAPI SetPixel()
очень медленная, но она позволяет задавать цвет для отдельного пикселя.
Функции WINAPI, такие как LineTo()
и Polyline()
, используют цвет пераэто выбирается в контексте устройства, который является одним цветом.
При использовании этих функций рисование выполняется намного быстрее, чем SetPixel()
, но выбор отдельного цвета пикселя теряется.
Какможно ли указать цвет для каждого отдельного пикселя и получить выгоду от скорости, аналогичной скорости Polyline()
?
Рассмотрим следующий код:
#include <Windows.h>
#include <math.h>
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR lpCmdLine,
int iCmdShow)
{
const char szAppName[] = "App";
const char szWinName[] = "Draw gfx";
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wndclass.lpfnWndProc = WndProc;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
return 0;
}
HWND hwnd;
hwnd = CreateWindow(
szAppName,
szWinName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
if (!hwnd)
{
return 0;
}
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
static POINT apt[256];
static int iApt = sizeof(apt) / sizeof(*apt);
static int cxClient;
static int cyClient;
HDC hdc;
PAINTSTRUCT ps;
switch (message)
{
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
HPEN hPen;
hPen = CreatePen(PS_SOLID, 1, RGB(255, 215, 0));
SelectObject(hdc, hPen);
// Set the array of points
for (int i = 0; i < iApt; i++)
{
apt[i].x = i * cxClient / iApt;
apt[i].y = (cyClient / 4 * (1 - sin((2 * 3.14159) * i / iApt)));
}
//draw using Polyline()
Polyline(hdc, apt, iApt);
// draw using SetPixel()
int b;
b = 0;
for (int i = 0; i < iApt; i++)
{
// descend 100 pixels to not overwrite previous curve
apt[i].y += 100;
// draw
SetPixel(hdc, apt[i].x, apt[i].y, RGB(0, 0, b));
b++;
}
DeleteObject(hPen);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(
hwnd,
message,
wParam,
lParam);
}
PS: я знаю, чтовторая кривая пунктирная, в отличие от результата Polyline (), но сейчас это не мое дело.