DirectX9 Windows-Desktop-App проблемы с прозрачностью - PullRequest
0 голосов
/ 18 марта 2019

Я написал простое приложение DirectX9 (код ниже), которое отлично работает как минимум для 25 установок Windows 10, но на одной фон окна просто черный, а не прозрачный (с тестовой прорисовкой на нем).

Все системы работают на выделенных графических процессорах NVIDIA (серии 10), поэтому проблем не должно быть, и они используют последнюю версию Windows 10 с последними драйверами Nvidia.

Обходной путь - добавитьОт LWA_COLORKEY до SetLayeredWindowAttributes, но я хотел бы знать, как я могу исправить систему вместо использования LWA_COLORKEY.(Потому что добавление LWA_COLORKEY стоит большой производительности).

SetLayeredWindowAttributes(hWnd, 0, 255, LWA_ALPHA | LWA_COLORKEY);

Это пример, который может повторить проблему:

#pragma once
#include <Windows.h>
#include <string>
#include <iostream>

// DirectX9
#pragma warning( push )
#pragma warning( disable : 4005)
#include <d3d9.h>
#include <d3dx9.h>
#include <Dwmapi.h> 
#include <TlHelp32.h>
#include <Directxmath.h>
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "Dwmapi.lib")
#pragma warning( pop ) 

using namespace std;
using namespace DirectX;

int s_width = 800;
int s_height = 600;
#define CENTERX (GetSystemMetrics(SM_CXSCREEN)/2)-(s_width/2)
#define CENTERY (GetSystemMetrics(SM_CYSCREEN)/2)-(s_height/2)
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
HWND hWnd;
LPD3DXFONT pFont;

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

void initD3D(HWND hWnd)
{
    d3d = Direct3DCreate9(D3D_SDK_VERSION);

    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow = hWnd;
    d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
    d3dpp.BackBufferWidth = s_width;
    d3dpp.BackBufferHeight = s_height;
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
    d3dpp.FullScreen_RefreshRateInHz = 0;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    d3dpp.MultiSampleQuality = DEFAULT_QUALITY;

    d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);

    D3DXCreateFont(d3ddev, 50, 0, FW_BOLD, 1, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial", &pFont);
}

void DrawString(int x, int y, DWORD color, LPD3DXFONT g_pFont, const char *fmt, ...)
{
    RECT FontPos = { x, y, x + 120, y + 16 };
    char buf[1024] = { '\0' };
    va_list va_alist;

    va_start(va_alist, fmt);
    vsprintf_s(buf, fmt, va_alist);
    va_end(va_alist);
    g_pFont->DrawText(NULL, buf, -1, &FontPos, DT_NOCLIP, color);
}

void render()
{
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0);
    d3ddev->BeginScene();

    DrawString(10, 50, D3DCOLOR_ARGB(100, 255, 0, 0), pFont, "Test rendering");

    d3ddev->EndScene();
    d3ddev->Present(NULL, NULL, NULL, NULL);
}

int main()
{
    RECT rc = { 0 };
    HINSTANCE hInstance = GetModuleHandle(NULL);

    WNDCLASSEX wc;
    ZeroMemory(&wc, sizeof(WNDCLASSEX));
    wc.cbClsExtra = NULL;
    wc.cbWndExtra = NULL;
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.hInstance = NULL;
    wc.lpfnWndProc = WindowProc;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 0, 0));
    wc.lpszClassName = "WindowClass";
    RegisterClassEx(&wc);

    hWnd = CreateWindowExA(WS_EX_LAYERED | WS_EX_TRANSPARENT, "WindowClass", "Title", WS_POPUP | WS_VISIBLE, rc.left, rc.top, s_width, s_height, NULL, NULL, hInstance, NULL);

    SetLayeredWindowAttributes(hWnd, 0, 255, LWA_ALPHA);

    //DWM_BLURBEHIND bb = { DWM_BB_ENABLE | DWM_BB_BLURREGION, true, CreateRectRgn(0, 0, -1, -1), true };
    //if (DwmEnableBlurBehindWindow(hWnd, &bb) != S_OK)

    MARGINS margin = { -1 };
    DwmExtendFrameIntoClientArea(hWnd, &margin);


    initD3D(hWnd);
    MSG msg;
    while (TRUE)
    {
        render();

        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        if (msg.message == WM_QUIT)
            exit(0);
    }

    return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_PAINT:
    {
    }break;

    case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    } break;
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
}
...