при использовании direct2d и белые пиксели становятся серыми

#c #colors #rendering #direct2d

#c #Цвет #рендеринг #direct2d

Вопрос:

Я использую c и direct2d для создания приложения Windows. Я пытаюсь рисовать прямоугольники с помощью функции DrawRectangle. Проблема в том, что когда я рисую белый прямоугольник на темной поверхности, он становится серым, даже если альфа установлена на 1.0f. Это также происходит, когда я рисую черный на светлой поверхности. Я хочу, чтобы цвет на экране был именно таким, какой я ввел. Как мне это сделать?

 void Graphics::DrawRect(RECT rect, float r, float g, float b, float a)
{
    m_Brush->SetColor(D2D1::ColorF(r, g, b, a));
    m_RenderTarget->DrawRectangle(D2D1::Rect(rect.left, rect.top, rect.right, rect.bottom), m_Brush);
}
  

это моя кисть:

 m_RenderTarget->CreateSolidColorBrush(D2D1::ColorF(0, 0, 0, 0), amp;m_Brush);
  

и это вызов функции:

 graphics->DrawRect(currentRenderRect, 1.0f, 1.0f, 1.0f, 1.0f);
  

РЕДАКТИРОВАТЬ
это весь мой графический класс:

.h

 class Graphics
{
public:
    Graphics();
    ~Graphics();

    bool Initialize(HWND windowHandle);

    void BeginDraw() { m_RenderTarget->BeginDraw(); }
    void EndDraw()   { m_RenderTarget->EndDraw();   }

    void ClearScreen(float r, float g, float b, float a);
    void DrawCircle(float x, float y, float radius, float r, float g, float b, float a);
    void DrawLine(float x0, float y0, float x1, float y1, float r, float g, float b, float a);
    void DrawRect(RECT rect, float r, float g, float b, float a);
    void DrawDashRect(RECT rect, float r, float g, float b, float a);
    void DrawFilledRect(RECT rect, float r, float g, float b, float a);
    void DrawBitmap(ID2D1Bitmap* bitmap);
    void DrawBitmap(ID2D1Bitmap* bitmap, RECT rect);

    ID2D1Bitmap* CreateBitmap(HBITMAP bitmap);

private:

    ID2D1Factory*           m_Factory;
    ID2D1HwndRenderTarget*  m_RenderTarget;
    ID2D1SolidColorBrush*   m_Brush;
    ID2D1StrokeStyle*       m_DashStrokeStyle;

    int m_WindowWidth;
    int m_WindowHeight;
};
  

.cpp

 #include "Graphics.h"

Graphics::Graphics()
{
    m_Factory         = NULL;
    m_RenderTarget    = NULL;
    m_Brush           = NULL;
    m_WhiteBrush      = NULL;
    m_DashStrokeStyle = NULL;
}

Graphics::~Graphics()
{
    if (m_Factory)
        m_Factory->Release();

    if (m_RenderTarget)
        m_RenderTarget->Release();

    if (m_Brush)
        m_Brush->Release();

    if (m_WhiteBrush)
        m_WhiteBrush->Release();

    if (m_DashStrokeStyle)
        m_DashStrokeStyle->Release();
}

bool Graphics::Initialize(HWND windowHandle)
{
    HRESULT res;
        
    res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, amp;m_Factory);

    if (res != S_OK)
        return false;

    RECT rect;
    GetClientRect(windowHandle, amp;rect);

    m_WindowWidth   = rect.right - rect.left;
    m_WindowHeight  = rect.bottom - rect.top;

    res = m_Factory->CreateHwndRenderTarget(
        D2D1::RenderTargetProperties(),
        D2D1::HwndRenderTargetProperties(windowHandle, D2D1::SizeU(m_WindowWidth, m_WindowHeight)),
        amp;m_RenderTarget);

    if (res != S_OK)
        return false;

    m_RenderTarget->CreateSolidColorBrush(D2D1::ColorF(0, 0, 0, 0), amp;m_Brush);

    if (res != S_OK)
        return false;

    m_RenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), amp;m_WhiteBrush);

    if (res != S_OK)
        return false;

    float dashes[] = { 3, 3 };

    res = m_Factory->CreateStrokeStyle(
        D2D1::StrokeStyleProperties(
            D2D1_CAP_STYLE_FLAT,
            D2D1_CAP_STYLE_FLAT,
            D2D1_CAP_STYLE_ROUND,
            D2D1_LINE_JOIN_MITER,
            10.0f,
            D2D1_DASH_STYLE_CUSTOM,
            0.0f),
        dashes,
        ARRAYSIZE(dashes),
        amp;m_DashStrokeStyle
    );

    if (res != S_OK)
        return false;
}

void Graphics::ClearScreen(float r, float g, float b, float a)
{
    m_RenderTarget->Clear(D2D1::ColorF(r, g, b, a));
}

void Graphics::DrawCircle(float x, float y, float radius, float r, float g, float b, float a)
{
    m_Brush->SetColor(D2D1::ColorF(r, g, b, a));
    m_RenderTarget->DrawEllipse(D2D1::Ellipse(D2D1::Point2F(x, y), radius, radius), m_Brush);
}

void Graphics::DrawLine(float x0, float y0, float x1, float y1, float r, float g, float b, float a)
{
    m_Brush->SetColor(D2D1::ColorF(r, g, b, a));
    m_RenderTarget->DrawLine(D2D1::Point2F(x0, y0), D2D1::Point2F(x1, y1), m_Brush);
}

void Graphics::DrawRect(RECT rect, float r, float g, float b, float a)
{
    m_Brush->SetColor(D2D1::ColorF(r, g, b, a));
    m_RenderTarget->DrawRectangle(D2D1::Rect(rect.left, rect.top, rect.right, rect.bottom), m_Brush);
}

void Graphics::DrawDashRect(RECT rect, float r, float g, float b, float a)
{
    m_Brush->SetColor(D2D1::ColorF(r, g, b, a));
    m_RenderTarget->DrawRectangle(D2D1::Rect(rect.left, rect.top, rect.right, rect.bottom), m_Brush, 1.0f, m_DashStrokeStyle);
}


void Graphics::DrawFilledRect(RECT rect, float r, float g, float b, float a)
{
    m_Brush->SetColor(D2D1::ColorF(r, g, b, a));
    m_RenderTarget->FillRectangle(D2D1::Rect(rect.left, rect.top, rect.right, rect.bottom), m_Brush);
}

void Graphics::DrawBitmap(ID2D1Bitmap* bitmap)
{
    m_RenderTarget->DrawBitmap(bitmap, D2D1::Rect(0, 0, m_WindowWidth, m_WindowHeight), 1.0f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, NULL);
}

void Graphics::DrawBitmap(ID2D1Bitmap* bitmap, RECT rect)
{
    m_RenderTarget->DrawBitmap(bitmap, D2D1::Rect(rect.left   1, rect.top   1, rect.right - 1, rect.bottom - 1), 1.0f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, D2D1::Rect(rect.left   1, rect.top   1, rect.right - 1, rect.bottom - 1));
}

ID2D1Bitmap* Graphics::CreateBitmap(HBITMAP bitmap)
{
    BITMAP bmpSizeInfo;

    GetObject(bitmap, sizeof(BITMAP), amp;bmpSizeInfo);

    BITMAPINFO bmpData;

    memset(amp;bmpData, 0, sizeof(BITMAPINFO));
    bmpData.bmiHeader.biSize = sizeof(bmpData.bmiHeader);
    bmpData.bmiHeader.biHeight = -bmpSizeInfo.bmHeight;
    bmpData.bmiHeader.biWidth = bmpSizeInfo.bmWidth;
    bmpData.bmiHeader.biPlanes = bmpSizeInfo.bmPlanes;
    bmpData.bmiHeader.biBitCount = bmpSizeInfo.bmBitsPixel;

    char* pBuff = new char[bmpSizeInfo.bmWidth * bmpSizeInfo.bmHeight * 4];

    HDC hDc = CreateCompatibleDC(0);
    GetDIBits(hDc, bitmap, 0, bmpSizeInfo.bmHeight, (void*)pBuff, amp;bmpData, DIB_RGB_COLORS);

    D2D1_BITMAP_PROPERTIES bmpPorp;

    bmpPorp.dpiX = 0.0f;
    bmpPorp.dpiY = 0.0f;
    bmpPorp.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
    bmpPorp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;

    ID2D1Bitmap* pBmpFromH;

    D2D1_SIZE_U bmpSize = { bmpSizeInfo.bmWidth, bmpSizeInfo.bmHeight };

    m_RenderTarget->CreateBitmap(bmpSize, pBuff, 4 * bmpSizeInfo.bmWidth, bmpPorp, amp;pBmpFromH);

    delete[] pBuff;

    return pBmpFromH;
}
  

Спасибо.

Комментарии:

1. DrawRectangle пропускает аргументы и т. Д. это может быть связано с чем-то еще в вашем коде, пожалуйста, опубликуйте полностью воспроизводимый проект.

2. Причина может заключаться в том, что вы рисуете с тем, что считаете точными координатами, например (0,0,10,10), и вы ожидаете, что прямоугольник полностью покроет пиксель 0,0. Попробуйте вместо этого сдвинуться на 0,5f, например (0,5f, 0,5f, 10,5f, 10,5f).