2012-02-20 32 views
7

Tôi muốn ứng dụng một ứng dụng với màn hình splash trên Linux.Làm thế nào để làm cho cửa sổ trong suốt trên linux

Tôi muốn sử dụng X11 và glx (ứng dụng OpenGL).

Tôi đã tìm thấy cách xóa đường viền xung quanh cửa sổ, nhưng tôi không thể tìm cách làm cho nó trong suốt. Làm thế nào tôi có thể thực hiện điều này?

+0

Tùy thuộc vào ý nghĩa của bạn bằng 'minh bạch'. Sự đơn giản "đơn giản" (các cửa sổ không phải chữ nhật) có thể đạt được với phần mở rộng [XShape] (http://en.wikipedia.org/wiki/Shape_extension). Tính minh bạch "Nâng cao" (trộn cửa sổ với nội dung màn hình cơ bản) yêu cầu một trình quản lý tổng hợp. –

+0

Cảm ơn bạn đã bình luận Tôi cần "nâng cao" trancparency Không thể mở liên kết thứ hai – themean

+0

Bạn có sử dụng bất kỳ cửa sổ lib nào cả? Hoặc chỉ là bản X11 và glx? –

Trả lời

1

Đây chắc chắn là điều bạn sẽ muốn tải xuống GPU. Tôi sẽ không khuyên bạn nên trực tiếp sử dụng lib X11 vì lý do hiệu suất. Hãy để OpenGL làm điều đó. Tôi đã tìm thấy liên kết sau cho glXChooseVisua l.

Ngoài ra, here là một S.O. câu hỏi có thể hữu ích.

Hơn nữa, this là dành cho cửa sổ nhưng vẫn nên áp dụng.

+0

Xin lỗi tôi không thể mở "glXChooseVisual" liên kết đối với liên kết thứ hai "ở đây" tôi không thể tìm thấy bất kỳ tài liệu tham khảo để XFixesCreateRegion chức năng đối với liên kết thứ ba "này" nó was very helpful tôi tìm kiếm chính xác cho somthing như SetLayeredWindowAttributes nhưng cho x11 – themean

+0

Tôi đang cố gắng với điều này Thuộc tính Atom = XInternAtom (m_Display, "_ NET_WM_WINDOW_OPACITY", False); unsigned int Opacity = 0xffffffff; XChangeProperty (m_Display, m_Window, thuộc tính, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) & Opacity, 1); này tương tự như GTK + gdk_x11_window_set_opacity nhưng điều này không làm việc cho tôi Tôi đang trên debian 6 thể vấn đề là hệ điều hành hoặc cửa sổ mgr – themean

+0

Ok sau khi thiết lập một số tùy chọn trên KDE nó làm việc nhưng bây giờ tôi không thể kiểm soát độ mờ đục của hình ảnh bên trong cửa sổ – themean

7

Đây là câu trả lời thực sự của câu hỏi của tôi

 /*------------------------------------------------------------------------ 
    * A demonstration of OpenGL in a ARGB window 
    * => support for composited window transparency 
    * 
    * (c) 2011 by Wolfgang 'datenwolf' Draxinger 
    *  See me at comp.graphics.api.opengl and StackOverflow.com 

    * 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. 
    * 
    * This program is based on the simplest possible 
    * Linux OpenGL program by FTB (see info below) 

     The simplest possible Linux OpenGL program? Maybe... 

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

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

    ------------------------------------------------------------------------*/ 

    #include <stdlib.h> 
    #include <stdio.h> 
    #include <string.h> 
    #include <math.h> 

    #include <GL/gl.h> 
    #include <GL/glx.h> 
    #include <GL/glxext.h> 
    #include <X11/Xatom.h> 
    #include <X11/extensions/Xrender.h> 
    #include <X11/Xutil.h> 

    #define USE_CHOOSE_FBCONFIG 

    static void fatalError(const char *why) 
    { 
     fprintf(stderr, "%s", why); 
     exit(0x666); 
    } 

    static int Xscreen; 
    static Atom del_atom; 
    static Colormap cmap; 
    static Display *Xdisplay; 
    static XVisualInfo *visual; 
    static XRenderPictFormat *pict_format; 
    static GLXFBConfig *fbconfigs, fbconfig; 
    static int numfbconfigs; 
    static GLXContext render_context; 
    static Window Xroot, window_handle; 
    static GLXWindow glX_window_handle; 
    static int width, height; 

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

    static int isExtensionSupported(const char *extList, const char *extension) 
    { 

     const char *start; 
     const char *where, *terminator; 

     /* Extension names should not have spaces. */ 
     where = strchr(extension, ' '); 
     if (where || *extension == '\0') 
     return 0; 

     /* It takes a bit of care to be fool-proof about parsing the 
     OpenGL extensions string. Don't be fooled by sub-strings, 
     etc. */ 
     for (start = extList; ;) { 
     where = strstr(start, extension); 

     if (!where) 
      break; 

     terminator = where + strlen(extension); 

     if (where == start || *(where - 1) == ' ') 
      if (*terminator == ' ' || *terminator == '\0') 
     return 1; 

     start = terminator; 
     } 
     return 0; 
    } 

    static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg) 
    { 
     return d && e && arg && (e->type == MapNotify) && (e->xmap.window == *(Window*)arg); 
    } 

    static void describe_fbconfig(GLXFBConfig fbconfig) 
    { 
     int doublebuffer; 
     int red_bits, green_bits, blue_bits, alpha_bits, depth_bits; 

     glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_DOUBLEBUFFER, &doublebuffer); 
     glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_RED_SIZE, &red_bits); 
     glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_GREEN_SIZE, &green_bits); 
     glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_BLUE_SIZE, &blue_bits); 
     glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_ALPHA_SIZE, &alpha_bits); 
     glXGetFBConfigAttrib(Xdisplay, fbconfig, GLX_DEPTH_SIZE, &depth_bits); 

     fprintf(stderr, "FBConfig selected:\n" 
     "Doublebuffer: %s\n" 
     "Red Bits: %d, Green Bits: %d, Blue Bits: %d, Alpha Bits: %d, Depth Bits: %d\n", 
     doublebuffer == True ? "Yes" : "No", 
     red_bits, green_bits, blue_bits, alpha_bits, depth_bits); 
    } 

    static void createTheWindow() 
    { 
     XEvent event; 
     int x,y, attr_mask; 
     XSizeHints hints; 
     XWMHints *startup_state; 
     XTextProperty textprop; 
     XSetWindowAttributes attr = {0,}; 
     static char *title = "FTB's little OpenGL example - ARGB extension by WXD"; 

     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); 
     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; 
     } 
     } 

     if(!fbconfig) { 
     fatalError("No matching FB config found"); 
     } 

     describe_fbconfig(fbconfig); 

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

     attr.colormap = cmap; 
     attr.background_pixmap = None; 
     attr.border_pixmap = None; 
     attr.border_pixel = 0; 
     attr.event_mask = 
     StructureNotifyMask | 
     EnterWindowMask | 
     LeaveWindowMask | 
     ExposureMask | 
     ButtonPressMask | 
     ButtonReleaseMask | 
     OwnerGrabButtonMask | 
     KeyPressMask | 
     KeyReleaseMask; 

     attr_mask = 
     CWBackPixmap| 
     CWColormap| 
     CWBorderPixel| 
     CWEventMask; 

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

     window_handle = XCreateWindow( Xdisplay, 
       Xroot, 
       x, y, width, height, 
       0, 
       visual->depth, 
       InputOutput, 
       visual->visual, 
       attr_mask, &attr); 

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

    #if USE_GLX_CREATE_WINDOW 
     int glXattr[] = { None }; 
     glX_window_handle = glXCreateWindow(Xdisplay, fbconfig, window_handle, glXattr); 
     if(!glX_window_handle) { 
     fatalError("Couldn't create the GLX window\n"); 
     } 
    #else 
     glX_window_handle = window_handle; 
    #endif 

     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; 

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

     XSetWMProperties(Xdisplay, window_handle,&textprop, &textprop, 
      NULL, 0, 
      &hints, 
      startup_state, 
      NULL); 


     XFree(startup_state); 

     XMapWindow(Xdisplay, window_handle); 
     XIfEvent(Xdisplay, &event, WaitForMapNotify, (char*)&window_handle); 

     if ((del_atom = XInternAtom(Xdisplay, "WM_DELETE_WINDOW", 0)) != None) { 
     XSetWMProtocols(Xdisplay, window_handle, &del_atom, 1); 
     } 
    } 

    static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) 
    { 
     fputs("Error at context creation", stderr); 
     return 0; 
    } 

    static void createTheRenderContext() 
    { 
     int dummy; 
     if (!glXQueryExtension(Xdisplay, &dummy, &dummy)) { 
     fatalError("OpenGL not supported by X server\n"); 
     } 

    #if USE_GLX_CREATE_CONTEXT_ATTRIB 
     #define GLX_CONTEXT_MAJOR_VERSION_ARB  0x2091 
     #define GLX_CONTEXT_MINOR_VERSION_ARB  0x2092 
     render_context = NULL; 
     if(isExtensionSupported(glXQueryExtensionsString(Xdisplay, DefaultScreen(Xdisplay)), "GLX_ARB_create_context")) { 
     typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); 
     glXCreateContextAttribsARBProc glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte *) "glXCreateContextAttribsARB"); 
     if(glXCreateContextAttribsARB) { 
      int context_attribs[] = 
      { 
      GLX_CONTEXT_MAJOR_VERSION_ARB, 3, 
      GLX_CONTEXT_MINOR_VERSION_ARB, 0, 
      //GLX_CONTEXT_FLAGS_ARB  , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, 
      None 
      }; 

      int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler); 

      render_context = glXCreateContextAttribsARB(Xdisplay, fbconfig, 0, True, context_attribs); 

      XSync(Xdisplay, False); 
      XSetErrorHandler(oldHandler); 

      fputs("glXCreateContextAttribsARB failed", stderr); 
     } else { 
      fputs("glXCreateContextAttribsARB could not be retrieved", stderr); 
     } 
     } else { 
      fputs("glXCreateContextAttribsARB not supported", stderr); 
     } 

     if(!render_context) 
     { 
    #else 
     { 
    #endif 
     render_context = glXCreateNewContext(Xdisplay, fbconfig, GLX_RGBA_TYPE, 0, True); 
     if (!render_context) { 
      fatalError("Failed to create a GL context\n"); 
     } 
     } 

     if (!glXMakeContextCurrent(Xdisplay, glX_window_handle, glX_window_handle, render_context)) { 
     fatalError("glXMakeCurrent failed for window\n"); 
     } 
    } 

    static int updateTheMessageQueue() 
    { 
     XEvent event; 
     XConfigureEvent *xc; 

     while (XPending(Xdisplay)) 
     { 
     XNextEvent(Xdisplay, &event); 
     switch (event.type) 
     { 
     case ClientMessage: 
      if (event.xclient.data.l[0] == del_atom) 
      { 
      return 0; 
      } 
     break; 

     case ConfigureNotify: 
      xc = &(event.xconfigure); 
      width = xc->width; 
      height = xc->height; 
      break; 
     } 
     } 
     return 1; 
    } 

    /* 6----7 
     /| /| 
     3----2 | 
     | 5--|-4 
     |/ |/ 
     0----1 

    */ 

    GLfloat cube_vertices[][8] = { 
     /* X  Y  Z Nx Ny Nz S T */ 
     {-1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 0 
     { 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0}, // 1 
     { 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0}, // 2 
     {-1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0}, // 3 

     { 1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0}, // 4 
     {-1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0}, // 5 
     {-1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0}, // 6 
     { 1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0}, // 7 

     {-1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0}, // 5 
     {-1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 0.0}, // 0 
     {-1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 1.0}, // 3 
     {-1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0}, // 6 

     { 1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 1 
     { 1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0}, // 4 
     { 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0}, // 7 
     { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0}, // 2 

     {-1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0}, // 5 
     { 1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 1.0, 0.0}, // 4 
     { 1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 1.0, 1.0}, // 1 
     {-1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0}, // 0 

     {-1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 3 
     { 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0}, // 2 
     { 1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 1.0}, // 7 
     {-1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0}, // 6 
    }; 

    static void draw_cube(void) 
    { 
     glEnableClientState(GL_VERTEX_ARRAY); 
     glEnableClientState(GL_NORMAL_ARRAY); 
     glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

     glVertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][0]); 
     glNormalPointer(GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][3]); 
     glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat) * 8, &cube_vertices[0][6]); 

     glDrawArrays(GL_QUADS, 0, 24); 
    } 

    float const light0_dir[]={0,1,0,0}; 
    float const light0_color[]={78./255., 80./255., 184./255.,1}; 

    float const light1_dir[]={-1,1,1,0}; 
    float const light1_color[]={255./255., 220./255., 97./255.,1}; 

    float const light2_dir[]={0,-1,0,0}; 
    float const light2_color[]={31./255., 75./255., 16./255.,1}; 

    static void redrawTheWindow() 
    { 
     float const aspect = (float)width/(float)height; 

     static float a=0; 
     static float b=0; 
     static float c=0; 

     glDrawBuffer(GL_BACK); 

     glViewport(0, 0, width, height); 

     // Clear with alpha = 0.0, i.e. full transparency 
     glClearColor(0.0, 0.0, 0.0, 0.0); 
     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 

     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
     glFrustum(-aspect, aspect, -1, 1, 2.5, 10); 

     glMatrixMode(GL_MODELVIEW); 
     glLoadIdentity(); 

     glEnable(GL_DEPTH_TEST); 
     glEnable(GL_CULL_FACE); 

     glEnable(GL_BLEND); 
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

     glLightfv(GL_LIGHT0, GL_POSITION, light0_dir); 
     glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color); 

     glLightfv(GL_LIGHT1, GL_POSITION, light1_dir); 
     glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_color); 

     glLightfv(GL_LIGHT2, GL_POSITION, light2_dir); 
     glLightfv(GL_LIGHT2, GL_DIFFUSE, light2_color); 

     glTranslatef(0., 0., -5.); 

     glRotatef(a, 1, 0, 0); 
     glRotatef(b, 0, 1, 0); 
     glRotatef(c, 0, 0, 1); 

     glEnable(GL_LIGHT0); 
     glEnable(GL_LIGHT1); 
     glEnable(GL_LIGHTING); 

     glEnable(GL_COLOR_MATERIAL); 
     glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); 

     glColor4f(1., 1., 1., 0.5); 

     glCullFace(GL_FRONT); 
     draw_cube(); 
     glCullFace(GL_BACK); 
     draw_cube(); 

     a = fmod(a+0.1, 360.); 
     b = fmod(b+0.5, 360.); 
     c = fmod(c+0.25, 360.); 

     glXSwapBuffers(Xdisplay, glX_window_handle); 
    } 

    int main(int argc, char *argv[]) 
    { 
     createTheWindow(); 
     createTheRenderContext(); 

     while (updateTheMessageQueue()) { 
     redrawTheWindow(); 
     } 

     return 0; 
    } 

tôi thực hiện việc này từ this liên kết tôi dành 10-15 phút để tìm sự khác biệt giữa các ví dụ này và mã của tôi và 3-4 giờ để có được trên của tôi nhớ rằng tôi phải thay đổi một cái gì đó trên KDE Thank cho ân cần quan tâm

+0

Ok công việc này tốt, nhưng tôi có thêm một vấn đề nữa. Khi cửa sổ không viền thì không thể trong suốt 100%. Tôi đạt được cửa sổ không viền với [this] (http://stackoverflow.com/questions/1904445/borderless-windows-on-linux) – themean

+0

Lưu ý rằng các hướng dẫn biên dịch có thể được tìm thấy trong câu hỏi được liên kết. – Seanny123

1

để có một cửa sổ trong suốt dưới X11, bạn cần

  • một máy chủ X11 với phần mở rộng hợp
  • một người quản lý tổng hợp
  • một ARGB trực quan cho cửa sổ của bạn

Bạn không cần phải sử dụng OpenGL trực tiếp: người quản lý tổng hợp có thể sử dụng nó để làm cho màn hình.

Nếu bạn đang đi trong đường dẫn GTK, có một cái nhìn để

  • gdk_x11_display_composite
  • gdk_screen_is_composited
  • gdk_display_supports_composite
  • gdk_screen_get_rgba_visual
  • gdk_screen_get_rgba_colormap

Nhưng bạn cũng có thể sử dụng Qt hoặc bộ công cụ khác.

Các vấn đề liên quan