gpt4 book ai didi

c++ - 使用 C++ 使透明度不显示 opengl 中窗口后面的内容

转载 作者:行者123 更新时间:2023-11-27 23:05:32 30 4
gpt4 key购买 nike

我正在用 C++ 在 opengl 中制作二维图像,遇到了一个有趣的问题。每当我尝试在我的图像上绘制一个部分透明的多边形时,它会使窗口本身在多边形所在的位置部分透明。例如,当我运行程序(我不想要)时,我可以看到窗口后面的任何内容(例如我的代码)。我还可以看到多边形后面的图像(我确实想要)。有什么办法可以关闭“透明窗口”行为吗?我已经包含了我认为是以下代码的相关部分:

glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // I have tried 1.0f for the alpha value too
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST);
glDisable(GL_POINT_SMOOTH);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();

// other code to draw my opaque "background" object

// Draw my partially transparent quad (note: this is where the window itself becomes partially transparent)
glBegin(GL_QUADS); // Begin drawing quads
glColor4f(1.0,1.0,1.0,0.5); // Make a white quad with .5 alpha
glVertex2f(-0.5, 0.5);
glVertex2f(0.5, .05);
glVertex2f(0.5, -0.5);
glVertex2f(-0.5, -0.5);
glEnd();

其他相关信息:

  • 我正在运行 CentOS 6
  • 我是 opengl 的新手,并且在之前的开发人员之后处理代码,所以我可能会遗漏一些微不足道的东西
  • 使用的是X Windows系统

这里是进一步调试的 X Window 创建代码,问题很可能出在这里,而不是上面的 opengl 代码。

/*  The simplest possible Linux OpenGL program? Maybe...
Modification for creating a RGBA window (transparency with compositors)
by Wolfgang 'datenwolf' Draxinger

(c) 2002 by FTB. See me in comp.graphics.api.opengl

(c) 2011 Wolfgang Draxinger. See me in comp.graphics.api.opengl and on StackOverflow

License agreement: This source code is provided "as is". You
can use this source code however you want for your own personal
use. If you give this source code to anybody else then you must
leave this message in it.

--
<\___/>
/ O O \
\_____/ FTB.

--
datenwolf

------------------------------------------------------------------------*/
static void createTheWindow() {
XEvent event;
int x, y, attr_mask;
XSizeHints hints;
XWMHints *StartupState;
XTextProperty textprop;
XSetWindowAttributes attr;
static char *title = "Fix me";

/* Connect to the X server */
Xdisplay = XOpenDisplay(NULL);
if (!Xdisplay)
{
fatalError("Couldn't connect to X server\n");
}
Xscreen = DefaultScreen(Xdisplay);
Xroot = RootWindow(Xdisplay, Xscreen) ;

fbconfigs = glXChooseFBConfig(Xdisplay, Xscreen, VisData, &numfbconfigs);
for (int i = 0; i < numfbconfigs; i++)
{
visual = (XVisualInfo_CPP*) glXGetVisualFromFBConfig(Xdisplay,
fbconfigs[i]);
if (!visual)
continue;

pictFormat = XRenderFindVisualFormat(Xdisplay, visual->visual);
if (!pictFormat)
continue;

if (pictFormat->direct.alphaMask > 0)
{
fbconfig = fbconfigs[i];
break;
}
}

/* Create a colormap - only needed on some X clients, eg. IRIX */
cmap = XCreateColormap(Xdisplay, Xroot, visual->visual, AllocNone);

/* Prepare the attributes for our window */
attr.colormap = cmap;

attr.border_pixel = 0;
attr.event_mask = StructureNotifyMask | EnterWindowMask | LeaveWindowMask
| ExposureMask | ButtonPressMask | ButtonReleaseMask
| OwnerGrabButtonMask | KeyPressMask | KeyReleaseMask;

attr.background_pixmap = None;

attr_mask = CWBackPixmap | CWColormap | CWBorderPixel | CWEventMask; /* What's in the attr data */

width = DisplayWidth(Xdisplay, DefaultScreen(Xdisplay)) ;
height = DisplayHeight(Xdisplay, DefaultScreen(Xdisplay)) ;
x = width / 2, y = height / 2;
// x=0, y=10;

/* Create the window */
attr.do_not_propagate_mask = NoEventMask;
WindowHandle = XCreateWindow(Xdisplay, /* Screen */
Xroot, /* Parent */
x, y, width, height,/* Position */
1,/* Border */
visual->depth,/* Color depth*/
InputOutput,/* klass */
visual->visual,/* Visual */
attr_mask, &attr);/* Attributes*/

if (!WindowHandle)
{
fatalError("Couldn't create the window\n");
}

/* Configure it... (ok, ok, this next bit isn't "minimal") */
textprop.value = (unsigned char*) title;
textprop.encoding = XA_STRING;
textprop.format = 8;
textprop.nitems = strlen(title);

hints.x = x;
hints.y = y;
hints.width = width;
hints.height = height;
hints.flags = USPosition | USSize;

StartupState = XAllocWMHints();
StartupState->initial_state = NormalState;
StartupState->flags = StateHint;

XSetWMProperties(Xdisplay, WindowHandle, &textprop, &textprop,/* Window title/icon title*/
NULL, 0,/* Argv[], argc for program*/
&hints, /* Start position/size*/
StartupState,/* Iconised/not flag */
NULL);

XFree(StartupState);

/* Open it, wait for it to appear */
int event_base, error_base = 0;

XMapWindow(Xdisplay, WindowHandle);
// }

XIfEvent(Xdisplay, &event, WaitForMapNotify, (char*) &WindowHandle);

/* Set the kill atom so we get a message when the user tries to close the window */
if ((del_atom = XInternAtom(Xdisplay, "WM_DELETE_WINDOW", 0)) != None)
{
XSetWMProtocols(Xdisplay, WindowHandle, &del_atom, 1);
}

}

以下是 VisData 的设置:

static int VisData[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE,
GLX_WINDOW_BIT, GLX_DOUBLEBUFFER, True, GLX_RED_SIZE, 1, GLX_GREEN_SIZE,
1, GLX_BLUE_SIZE, 1, GLX_ALPHA_SIZE, 1, GLX_DEPTH_SIZE, 1,
None
};

这里是创建渲染上下文的地方:

static void createTheRenderContext() {
/* See if we can do OpenGL on this visual */
int dummy;
if (!glXQueryExtension(Xdisplay, &dummy, &dummy))
{
fatalError("OpenGL not supported by X server\n");
}

/* Create the OpenGL rendering context */
RenderContext = glXCreateNewContext(Xdisplay, fbconfig, GLX_RGBA_TYPE, 0,
True);
if (!RenderContext)
{
fatalError("Failed to create a GL context\n");
}

GLXWindowHandle = glXCreateWindow(Xdisplay, fbconfig, WindowHandle, NULL);

/* Make it current */
if (!glXMakeContextCurrent(Xdisplay, GLXWindowHandle, GLXWindowHandle,
RenderContext))
{
fatalError("glXMakeCurrent failed for window\n");
}
}

最佳答案

棘轮怪胎建议(Windows 中的 Aero Glass 效果)并非偶然发生,因为必须手动启用 DWM 透明度才能发生这种情况。

但是在 X11/GLX 中,完全有可能以默认具有 Alpha channel 的视觉模式结束。如果您想真正获得一个有或没有 alpha channel 的窗口,代码会比大多数工具包做的要复杂一些。

您正在使用的代码看起来非常熟悉。具体来说,它似乎源 self 写的关于如何创建一个透明窗口的代码示例(你知道这是怎么回事),即这段代码:

https://github.com/datenwolf/codesamples/blob/master/samples/OpenGL/x11argb_opengl/x11argb_opengl.c

按键序列是这样的:

   fbconfigs = glXChooseFBConfig(Xdisplay, Xscreen, VisData, &numfbconfigs);
fbconfig = 0;
for(int i = 0; i<numfbconfigs; i++) {
visual = (XVisualInfo*) glXGetVisualFromFBConfig(Xdisplay, fbconfigs[i]);
if(!visual)
continue;

pict_format = XRenderFindVisualFormat(Xdisplay, visual->visual);
if(!pict_format)
continue;

fbconfig = fbconfigs[i];
if(pict_format->direct.alphaMask > 0) {
break;
}
}

它所做的是,它会选择一个 X11 视觉对象,该视觉对象与先前选择的 FBConfig 之一相匹配,并且还包含一个 alpha 掩码。

如果我不得不打赌,我怀疑您传递给 glXChooseFBConfigVisData 数组没有指定 alpha channel 。所以发生的情况是,您最终可能会得到一个具有 X11 alpha 掩码的窗口,但没有可供 OpenGL 访问的 alpha channel 。

因为我从未打算将该代码用于没有 alpha channel 的窗口,因此如果 VisData 确实选择了 alpha channel ,则此代码仅执行最初预期的操作。

您现在有两个选择:

  • 实现补充测试if(pict_format->direct.alphaMask == 0 && no_alpha_in(VisData)) break;

  • 在 VisData 中选择一个 alpha channel ,并使用 OpenGL glClearColor(…,…,…,1.0f);

  • 将 alpha channel 清除为 1.0

关于c++ - 使用 C++ 使透明度不显示 opengl 中窗口后面的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23829839/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com