आंशिक रूप से पारदर्शी विंडो ओपनजीएल / विन 32 - सी ++, winapi, opengl

मैंने इस मुश्किल (आला) विषय पर हर मौजूदा प्रश्न को पढ़ा है, लेकिन मैं अटक गया हूं। मेरे पास ओपनजीएल संदर्भ वाला एक Win32 विंडो है। मैं चाहता हूं कि मेरी खिड़की आंशिक रूप से पारदर्शी हो।

मेरा परिणाम अब तक है कि पूरी तरह सेखिड़की पारदर्शी है। मैं केवल काला क्षेत्र पारदर्शी होना चाहता हूं, ताकि मैं कुछ 3 डी वस्तुओं को आकर्षित कर सकूं और वे देखेंगे कि वे खिड़की से आ रहे हैं।

यहां छवि विवरण दर्ज करें

सबसे पहले, मेरी खिड़की कक्षा में, मैंने एचआरबी बैकग्राउंड को काले रंग में सेट किया है।

Windows::WindowClass windowClass;
windowClass.cbSize = sizeof(Windows::WindowClass);
windowClass.style = Windows::CS_VREDRAW | Windows::CS_HREDRAW;
windowClass.lpfnWndProc = WndProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = moduleHandle;
windowClass.hIcon = Windows::LoadIcon(0u, (X*)Windows::IDI_QUESTION);
windowClass.hCursor = Windows::LoadCursor(0u, (X*)Windows::IDC_ARROW);
windowClass.hbrBackground = Windows::CreateSolidBrush(0x00000000);
windowClass.lpszMenuName = nullptr;
windowClass.lpszClassName = (X*)name;
windowClass.hIconSm = Windows::LoadIcon(0u, (X*)Windows::IDI_QUESTION);

मैंने अपनी विंडो WS_EX_LAYERED ध्वज के साथ बनाई है।

windowHandle = Windows::CreateWindow(Windows::WS_EX_LAYERED, (X*)name, "", Windows::WS_POPUP, w / 4, h / 4, w / 2, h / 2, 0u, 0u, moduleHandle, 0u);

मेरे पिक्सेल प्रारूप में, मैंने अल्फा और संरचना सक्षम की है।

PixelFormatDescriptor format;
format.nSize = sizeof(PixelFormatDescriptor);
format.nVersion = 1;
format.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_SUPPORT_COMPOSITION;
format.iPixelType = PFD_TYPE_RGBA;
format.cColorBits = 32;
format.cRedBits = 0;
format.cRedShift = 0;
format.cGreenBits = 0;
format.cGreenShift = 0;
format.cBlueBits = 0;
format.cBlueShift = 0;
format.cAlphaBits = 8;
format.cAlphaShift = 0;
format.cAccumBits = 0;
format.cAccumRedBits = 0;
format.cAccumGreenBits = 0;
format.cAccumBlueBits = 0;
format.cAccumAlphaBits = 0;
format.cDepthBits = 24;
format.cStencilBits = 8;
format.cAuxBuffers = 0;
format.iLayerType = PFD_MAIN_PLANE;
format.bReserved = 0;
format.dwLayerMask = 0;
format.dwVisibleMask = 0;
format.dwDamageMask = 0;

मैंने धुंध क्षेत्र "चाल" की कोशिश की है, लेकिन इसका कोई प्रभाव नहीं है। मेरा परिणाम कोड के इस टुकड़े से संबंधित नहीं है।

struct DwmBlurBehind
{
U4 dwFlags;
S4 fEnable;
X* blurRegionHandle;
S4 fTransitionOnMaximized;
};

DwmBlurBehind blurBehind;
blurBehind.dwFlags = Windows::DWM_BB_ENABLE | Windows::DWM_BB_BLURREGION;
blurBehind.fEnable = true;
blurBehind.blurRegionHandle = Windows::CreateRectRgn(0, 0, -1, -1);
blurBehind.fTransitionOnMaximized = false;
Windows::DwmEnableBlurBehindWindow(windowHandle, &blurBehind);

Finally, I have set the LWA_COLORKEY and LWA_ALPHA विशेषताएँ। यही कारण है कि मुझे प्रभाव प्रदर्शित किया। हालांकि, रंग कुंजी को ध्यान में नहीं रखा जाता है (मैंने गैर-शून्य मानों को भी आजमाया है)।

Windows::SetLayeredWindowAttributes(windowHandle, 0, 170, Windows::LWA_COLORKEY | Windows::LWA_ALPHA);

मैं मिश्रण सक्षम करने के लिए मत भूलना।

GL::Enable(GL::BLEND);
GL::BlendFunc(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA);

उत्तर:

उत्तर № 1 के लिए 1

आप जो करना चाहते हैं वह विंडो कंपोजिटिंग की आवश्यकता है जो विंडोज विस्टा के आसपास रहा है, इसलिए अनिवार्य रूप से विंडोज़ के हर संस्करण को आप परवाह करना है (विंडोज एक्सपी और पहले ईओएल हैं)।

लेने के लिए महत्वपूर्ण कदम है, "ब्लू बैहिंड विंडो" को सक्षम करके डीडब्ल्यूएम इंट्रा विंडो कंपोजिटिंग को सक्षम करने के लिए और एक का उपयोग करें WM_POPUP खिड़की; यदि आप उपयोग नहीं करते हैं WM_POPUP शैली खिड़की प्रबंधक सजावट आकर्षित करेगा और आपके ओपनजीएल प्रतिपादन उस से ऊपर "होवर" होगा।

        DWM_BLURBEHIND bb = {0};
bb.dwFlags = DWM_BB_ENABLE;
bb.fEnable = TRUE;
bb.hRgnBlur = NULL;
DwmEnableBlurBehindWindow(hWnd, &bb);

MARGINS margins = {-1};
impl_DwmExtendFrameIntoClientArea(hWnd, &margins);

इसके बाद आपको पिक्सेलफॉर्मेट डिस्क्रिप्टर चयन का उपयोग करने के बजाय नए "विशेषता" API का उपयोग करके ओपनजीएल संदर्भ बनाना होगा। विशेषता API के साथ आप एक का चयन कर सकते हैं पारदर्शक साथ में अल्फा खिड़की प्रारूप।

int attribs[] = {
WGL_DRAW_TO_WINDOW_ARB, TRUE,
WGL_DOUBLE_BUFFER_ARB, TRUE,
WGL_SUPPORT_OPENGL_ARB, TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_TRANSPARENT_ARB, TRUE,
WGL_COLOR_BITS_ARB, 32,
WGL_RED_BITS_ARB, 8,
WGL_GREEN_BITS_ARB, 8,
WGL_BLUE_BITS_ARB, 8,
WGL_ALPHA_BITS_ARB, 8,
WGL_DEPTH_BITS_ARB, 24,
WGL_STENCIL_BITS_ARB, 8,
0, 0
};

INT iPF;
UINT num_formats_choosen;
if( !wglChoosePixelFormatARB(
hDC,
attribs,
NULL,
1,
&iPF,
&num_formats_choosen) ) {
fprintf(stderr, "error choosing proper pixel formatn");
return NULL;
}
if( !num_formats_choosen ) {
return NULL;
}

PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
/* now this is a kludge; we need to pass something in the PIXELFORMATDESCRIPTOR
* to SetPixelFormat; it will be ignored, mostly. OTOH we want to send something
* sane, we"re nice people after all - it doesn"t hurt if this fails. */
DescribePixelFormat(hDC, iPF, sizeof(pfd), &pfd);

if( !SetPixelFormat(hDC, iPF, &pfd) ) {
fprintf(stderr, "error setting proper pixel formatn");
ReleaseDC(hWnd, hDC);
DestroyWindow(hWnd);

return NULL;
}

मुझे इसके लिए एक पूर्ण कामकाजी उदाहरण मिला है wglarb गिटहब पर रैपर भंडार: https://github.com/datenwolf/wglarb/blob/master/test/layered.c


जवाब के लिए 2 № 2

आप को कॉल याद आ रही है UpdateLayeredWindow । आईआईआरसी, कुछ अजीब व्यवहार में UpdateLayeredWindow परिणाम नहीं बुला रहा है। YMMV।

अधिक जानकारी यहाँ


जवाब के लिए 0 № 3

के अनुसार SetLayeredWindowAttributes डॉक्टर आपको पास करने की जरूरत है

एक COLORREF संरचना जो निर्दिष्ट करता हैहोने के लिए पारदर्शिता रंग कुंजी स्तरित खिड़की लिखते समय प्रयोग किया जाता है। द्वारा चित्रित सभी पिक्सेल इस रंग में खिड़की पारदर्शी होगी। COLORREF उत्पन्न करने के लिए, उपयोग करें आरजीबी मैक्रो।

इस फ़ंक्शन में अपने कॉल के दूसरे पैरामीटर की समीक्षा करें।


संबंधित सवाल
सबसे लोकप्रिय