私は、Xlibフォームでのアルファチャンネル処理を実証するstackoverflowとGitHubからコピーされた2つのソースコードを持っています。最初は単純なXlib、次にOpenGLです。しかし、私は誤って作業しています。Linux Xlibの誤ったアルファハンドリング
アルファチャンネルの値を0に設定すると、黒だけでなく透明になるはずですが、色が白に近いほどアルファチャンネルが少なくなります。色を白に設定すると、ウィンドウはアルファチャンネルを完全に無視しています。 0x00808080は半透明です。
私は何が間違っているのか分かりませんが、問題が何であるか教えていただけますか?マシンに問題があるのでしょうか?ここで
は、最初のコードスニペットです:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
int main(int argc, char* argv[])
{
Display* display = XOpenDisplay(NULL);
XVisualInfo vinfo;
XMatchVisualInfo(display, DefaultScreen(display), 32, TrueColor, &vinfo);
XSetWindowAttributes attr;
attr.colormap = XCreateColormap(display, DefaultRootWindow(display), vinfo.visual, AllocNone);
attr.border_pixel = 0;
attr.background_pixel = 0x00ffffff;
Window win = XCreateWindow(display, DefaultRootWindow(display), 0, 0, 300, 200, 0, vinfo.depth, InputOutput, vinfo.visual, CWColormap | CWBorderPixel | CWBackPixel, &attr);
XSelectInput(display, win, StructureNotifyMask);
GC gc = XCreateGC(display, win, 0, 0);
Atom wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", 0);
XSetWMProtocols(display, win, &wm_delete_window, 1);
XMapWindow(display, win);
int keep_running = 1;
XEvent event;
while (keep_running) {
XNextEvent(display, &event);
switch(event.type) {
case ClientMessage:
if (event.xclient.message_type == XInternAtom(display, "WM_PROTOCOLS", 1) && (Atom)event.xclient.data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", 1))
keep_running = 0;
break;
default:
break;
}
}
XDestroyWindow(display, win);
XCloseDisplay(display);
return 0;
}
そして、ここでは、第二次のとおりです。
/*
____ _____
/\__ \ /\ ___\
\/__/\ \ \ \ \__/_
\ \ \ \ \____ \
_\_\ \ \/__/_\ \
/\ _____\ /\ _____\
\/______/ \/______/
Copyright (C) 2011 Joerg Seebohn
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program demonstrates how an X11 window with OpenGL support
can be drawn transparent.
The title bar and window border drawn by the window manager are
drawn opaque.
Only the background of the window which is drawn with OpenGL
glClearColor(0.7, 0.7, 0.7, 0.7) ;
glClear(GL_COLOR_BUFFER_BIT) ;
is 30% transparent.
Compile it with:
gcc -std=gnu99 -o test testprogram.c -lX11 -lGL
*/
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
Display * display = XOpenDisplay(0) ;
const char * xserver = getenv("DISPLAY") ;
if (display == 0)
{
printf("Could not establish a connection to X-server '%s'\n", xserver) ;
exit(1) ;
}
// query Visual for "TrueColor" and 32 bits depth (RGBA)
XVisualInfo visualinfo ;
XMatchVisualInfo(display, DefaultScreen(display), 32, TrueColor, &visualinfo);
// create window
Window win ;
GC gc ;
XSetWindowAttributes attr ;
attr.colormap = XCreateColormap(display, DefaultRootWindow(display), visualinfo.visual, AllocNone) ;
attr.event_mask = ExposureMask | KeyPressMask ;
attr.background_pixmap = None ;
attr.border_pixel = 0 ;
win = XCreateWindow( display, DefaultRootWindow(display),
50, 300, 400, 100, // x,y,width,height : are possibly opverwriteen by window manager
0,
visualinfo.depth,
InputOutput,
visualinfo.visual,
CWColormap|CWEventMask|CWBackPixmap|CWBorderPixel,
&attr
) ;
gc = XCreateGC(display, win, 0, 0) ;
// set title bar name of window
XStoreName(display, win, "Transparent Window with OpenGL Support") ;
// say window manager which position we would prefer
XSizeHints sizehints ;
sizehints.flags = PPosition | PSize ;
sizehints.x = 50 ; sizehints.y = 300 ;
sizehints.width = 400 ; sizehints.height = 100 ;
XSetWMNormalHints(display, win, &sizehints) ;
// Switch On >> If user pressed close key let window manager only send notification >>
Atom wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", 0) ;
XSetWMProtocols(display, win, &wm_delete_window, 1) ;
{
// change foreground color to brown
XColor xcol ;
xcol.red = 153 * 256 ; // X11 uses 16 bit colors !
xcol.green = 116 * 256 ;
xcol.blue = 65 * 256 ;
XAllocColor(display, attr.colormap, &xcol) ;
XGCValues gcvalues ;
gcvalues.foreground = xcol.pixel ;
XChangeGC(display, gc, GCForeground, &gcvalues) ;
}
// create OpenGL context
GLXContext glcontext = glXCreateContext(display, &visualinfo, 0, True) ;
if (!glcontext)
{
printf("X11 server '%s' does not support OpenGL\n", xserver) ;
exit(1) ;
}
glXMakeCurrent(display, win, glcontext) ;
// now let the window appear to the user
XMapWindow(display, win) ;
int isUserWantsWindowToClose = 0 ;
while(!isUserWantsWindowToClose)
{
int isRedraw = 0 ;
/* XPending returns number of already queued events.
* If no events are queued XPending sends all queued requests to the X-server
* and tries to read new incoming events. */
while(XPending(display) > 0)
{
// process event
XEvent event ;
XNextEvent(display, &event) ;
switch(event.type)
{ // see 'man XAnyEvent' for a list of available events
case ClientMessage:
// check if the client message was send by window manager to indicate user wants to close the window
if ( event.xclient.message_type == XInternAtom(display, "WM_PROTOCOLS", 1)
&& event.xclient.data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", 1)
)
{
isUserWantsWindowToClose = 1 ;
}
break;
case KeyPress:
if (XLookupKeysym(&event.xkey, 0) == XK_Escape)
{
isUserWantsWindowToClose = 1 ;
}
break ;
case Expose:
isRedraw = 1 ;
break ;
default:
// do nothing
break ;
}
}
// ... all events processed, now do other stuff ...
if (isRedraw)
{ // needs redraw
// use opengl to clear background in (transparent) light grey
glClearColor(1, 1, 1, 0) ;
glClear(GL_COLOR_BUFFER_BIT) ;
glXSwapBuffers(display, win) ;
glXWaitGL() ;
// draw string with X11
XDrawString(display, win, gc, 10, 20, "Hello ! ", 7) ;
}
// ... do something else ...
}
XDestroyWindow(display, win) ;
win = 0 ;
XCloseDisplay(display) ;
display = 0 ;
return 0 ;
}
再描画について:openglで白(透明)にして、前後を反転してから、xlibを使ってその上に茶色の文字列を描画します。私が正しいとすれば、既に描かれたサーフェス(アルファに関係なく白です)と文字列をブレンドすることはありません。これを行うには、XRenderライブラリが提供する機能を使用してブレンド操作を指定する必要があります。 – Andreas
いいえ、あなたは誤解しました。文字列ではなく背景色です。 背景色のアルファチャンネルをゼロに設定した場合、他のチャンネルが何を含んでいても、背景は完全に透明でなければなりません。 しかし、他のチャンネルを黒以外に設定すると、背景が完全に透明ではありません。 (色が明るいほど、背景が透明になりません) – jsr
Ok。あなたは背景の背後に何を持っていたいですか? – Andreas