渲染上下文通常在背景上具有纯色(黑色或其他颜色,请参见下图):
我想知道是否有可能设置一个窗口,没有装饰和透明的背景,同时允许我在上面渲染OpenGL的东西。
这会给人一种三角形漂浮在屏幕上的错觉。透明背景应允许您看到桌面或可能在其后面的其他应用程序。
你能举例说明一下源代码吗?
平台: Windows (仅限win32)
发布于 2010-10-30 03:07:42
我知道这在Windows7上是可能的,但不确定更早的版本。
要去除窗口边框,您需要从窗口中移除WS_OVERLAPPEDWINDOW
样式并添加WS_POPUP
样式:
DWORD style = ::GetWindowLong(hWnd, GWL_STYLE);
style &= ~WS_OVERLAPPEDWINDOW;
style |= WS_POPUP;
::SetWindowLong(hWnd, GWL_STYLE, style);
要使OpenGL窗口的背景透明,需要使用DwmEnableBlurBehindWindow
函数:
DWM_BLURBEHIND bb = {0};
bb.dwFlags = DWM_BB_ENABLE;
bb.fEnable = true;
bb.hRgnBlur = NULL;
DwmEnableBlurBehindWindow(hWnd, &bb);
在调用glClearColor
时,还需要将Alpha值指定为0。
glClearColor(0.0f,0.0f,0.0f,0.0f);
此外,在创建OpenGL上下文时,请确保分配了alpha通道。
现在你的背景应该是完全透明的。如果保留窗口装饰,则背景将使用空气模糊外观,您可以使用glClearColor
中的Alpha值调整透明度级别。
发布于 2012-09-06 05:43:42
这是一个古老的问题,但由于新版本的Windows有合成和对opengl的支持,正如datenwolf所暗示的那样,我们可以使用一些特殊的调料来实现这一点。尽管这对于DirectX来说也是微不足道的(如图所示)微软确实在opengl上下文中添加了合成提示。耶,反垄断的恐惧!
因此,我们可以让合成引擎只了解如何利用opengl上下文,而不是低效的复制到物理内存的操作。
因此,您必须使用指定alpha通道的像素格式创建一个opengl上下文,并且它应该使用合成(第82行)。然后,使用DwmApi.h例程启用一个模糊窗口(第179行),其中指定了一个完全无效的区域,这将模糊任何内容并使窗口保持透明。(您需要在窗口类上指定一个black+transparent笔刷!奇怪!)然后,您实际上只是使用opengl,就像您习惯使用它一样。在事件循环中,只要有机会,您就可以绘制和交换缓冲区(第201行),并记住启用GL_BLEND!:)
请查看/fork https://gist.github.com/3644466,或者只查看基于OP自己的答案的以下代码片段,而不是使用此技术(您可以将其放在一个空项目中):
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <windowsx.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <dwmapi.h>
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")
#pragma comment (lib, "dwmapi.lib")
#include <assert.h>
#include <tchar.h>
#ifdef assert
#define verify(expr) if(!expr) assert(0)
#else verify(expr) expr
#endif
const TCHAR szAppName[]=_T("TransparentGL");
const TCHAR wcWndName[]=_T("TransparentGL");
HDC hDC;
HGLRC m_hrc;
int w = 240;
int h = 240;
BOOL initSC() {
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0, 0, 0, 0);
return 0;
}
void resizeSC(int width,int height) {
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW );
glLoadIdentity();
}
BOOL renderSC() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();
glColor3f(0, 1, 1);
glBegin(GL_TRIANGLES); // Drawing Using Triangles
glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top
glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
glEnd();
glPopMatrix();
glFlush();
return 0;
}
BOOL CreateHGLRC(HWND hWnd) {
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_SUPPORT_COMPOSITION | // Format Must Support Composition
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
32, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
8, // An Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
24, // 16Bit Z-Buffer (Depth Buffer)
8, // Some Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
HDC hdc = GetDC(hWnd);
int PixelFormat = ChoosePixelFormat(hdc, &pfd);
if (PixelFormat == 0) {
assert(0);
return FALSE ;
}
BOOL bResult = SetPixelFormat(hdc, PixelFormat, &pfd);
if (bResult==FALSE) {
assert(0);
return FALSE ;
}
m_hrc = wglCreateContext(hdc);
if (!m_hrc){
assert(0);
return FALSE;
}
ReleaseDC(hWnd, hdc);
return TRUE;
}
LRESULT CALLBACK WindowFunc(HWND hWnd,UINT msg, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT ps;
switch(msg) {
case WM_CREATE:
break;
case WM_DESTROY:
if(m_hrc) {
wglMakeCurrent(NULL, NULL);
wglDeleteContext(m_hrc) ;
}
PostQuitMessage(0) ;
break;
default:
return DefWindowProc(hWnd,msg,wParam,lParam);
}
return 0;
}
int WINAPI _tWinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR str,int nWinMode) {
WNDCLASSEX wc;
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WindowFunc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hThisInst;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)CreateSolidBrush(0x00000000);
wc.lpszClassName = szAppName;
if(!RegisterClassEx(&wc)) {
MessageBox(NULL, _T("RegisterClassEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
HWND hWnd = CreateWindowEx(WS_EX_APPWINDOW, szAppName, wcWndName,
WS_VISIBLE | WS_POPUP, 200, 150, w, h,
NULL, NULL, hThisInst, NULL);
if(!hWnd) {
MessageBox(NULL, _T("CreateWindowEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
return FALSE;
}
DWM_BLURBEHIND bb = {0};
HRGN hRgn = CreateRectRgn(0, 0, -1, -1);
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
bb.hRgnBlur = hRgn;
bb.fEnable = TRUE;
DwmEnableBlurBehindWindow(hWnd, &bb);
CreateHGLRC(hWnd);
HDC hdc = GetDC(hWnd);
wglMakeCurrent(hdc, m_hrc);
initSC();
resizeSC(w, h);
ReleaseDC(hWnd, hdc);
MSG msg;
while(1) {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
HDC hdc = GetDC(hWnd);
wglMakeCurrent(hdc, m_hrc);
renderSC();
SwapBuffers(hdc);
ReleaseDC(hWnd, hdc);
}
}
return (FALSE);
}
发布于 2010-11-02 08:36:09
如果允许对OpenGL窗口进行分层,这将非常容易。但他们不是,所以你必须去找其他的东西。
你可以做的就是创建一个分层窗口(WS_EX_LAYERED + SetLayeredWindowAttributes() --如果你不知道的话就用Google 'em )来处理透明度,和一个隐藏的OpenGL窗口来渲染。将OpenGL场景渲染到离屏缓冲区,读回并与分层窗口共享,然后将其比特(GDI函数)渲染到分层窗口。
对于非常复杂的东西来说,这可能太慢了,但会给你带来你所要求的效果,并且可以在Windows2000和更高版本上工作。
编辑:在创建实际的屏幕外缓冲区时,帧缓冲区对象(FBO)可能是最好的选择。你可以直接在隐藏的OpenGL窗口上绘图,尽管我记得有人发帖说因为像素所有权的原因而遇到了麻烦--推荐使用FBO。您也可以使用像素缓冲区(Pbuffer),但这些是一种过时的(标记为“遗留”),FBO被认为是现代的方式来做到这一点。FBO应该为您提供硬件加速(如果支持),而不会限制您特定的OpenGL版本。您需要一个FBO上下文才能使用它,因此您必须创建隐藏的OpenGL窗口并从那里设置OpenGL。
以下是关于FBO的一些资源:
Guide (适用于mac,但可能会有所帮助)
https://stackoverflow.com/questions/4052940
复制相似问题