如何避免SetPixel()但仍然能够为每个像素指定颜色?

时间:2019-01-03 13:18:45

标签: c++ winapi

WINAPI函数SetPixel()的运行速度很慢,但是它可以为单个像素指定颜色。

诸如LineTo()Polyline()之类的WINAPI函数使用在设备上下文中选择的笔的颜色,它是一种颜色。

重新排序以绘制这些功能比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);
}

P.S .: 我知道第二条曲线是点划线的,与Polyline()的结果不同,但这不是我现在关注的问题。

0 个答案:

没有答案