상세 컨텐츠

본문 제목

OpenGL MFC, WIN32 배경투명하게 transparent, glClearColor, Clear 하기

프로그래밍 관련/3D,2D DRAW 관련

by AlrepondTech 2017. 7. 14. 10:50

본문

반응형
728x170

 

 

=================================

=================================

=================================

 

 

 

OpenGL을 쓰고 항시 API를 쓰고 다시 해제해주어야 하는 API들은 는 해제 해주는것을 잊지 마세요 

예로들어 wglMakeCurrent(...)로 들자면 

 

HDC   hdc    = getHDC();

HGLRC hglrc = getHGLRCRES_GL();

 

::wglMakeCurrent(hdc, hglrc); //사용

 
//------------------------------------------
//{랜더링 코드들
 
..................................................................
 
//}
//------------------------------------------
 
::wglMakeCurrent(NULL, NULL);  //::wglMakeCurrent(hdc, NULL);  //해제

 

 

위와같이 wglMakeCurrent(...) 랜더링 부분에 Api 사용과 해제 부분을 제대로 하지 않으면 다른 

위치의 wglMakeCurrent(...) 를 사용시 문제가 생길수 있습니다.

 

 

 

=================================

=================================

=================================

 

 

 

출처: https://stackoverflow.com/questions/4052940/how-to-make-an-opengl-rendering-context-with-transparent-background

 

How to make an OpenGL rendering context with transparent background?

Rendering contexts usually have a solid color on the background (black or whatever, see the image below):

 

I'm wondering if it's possible to setup a window, with no decorations AND with the transparent background, while allowing me to render OpenGL stuff on it.

This would give the illusion that the triangle is floating on the screen. The transparent background should allow you to see the desktop or other applications that might be behind it.

Could you please exemplify with source code?

Platform: Windows (win32 only)

 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

After spending some reputation on a unsuccessful bounty to get some help on this issue, I finally realized how complex was the problem I was interested in.

The few individuals that have accomplished this task don't share much. During my research I found different ways to achieve what I was looking for. One of the most interesting ones is AeroGL, and it shows snippets of code using a technique that was not mentioned so far, which is rendering the graphics to a device-independent bitmap (DIB).

To close this thread permanently, the source code below implements that technique. The code itself is a slight modification of an application presented here (big thanks to Andrei Sapronov Y.).

The end result can be seen in the image below:

 

The code has been tested on Windows XP (32-bits) and Windows 8.1 (32-bits). Enjoy!

#define _WIN32_WINNT 0x0500  #include <windows.h> #include <windowsx.h> #include <GL/gl.h> #include <GL/glu.h>  #pragma comment (lib, "opengl32.lib") #pragma comment (lib, "glu32.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("WS_EX_LAYERED OpenGL");  HDC hDC;             HGLRC m_hrc;         int w(240); int h(240);   HDC pdcDIB;                  HBITMAP hbmpDIB;             void *bmp_cnt(NULL);         int cxDIB(0);  int cyDIB(0);    BITMAPINFOHEADER BIH;          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; }  // DIB -> hDC void draw(HDC pdcDest) {     assert(pdcDIB);      verify(BitBlt(pdcDest, 0, 0, w, h, pdcDIB, 0, 0, SRCCOPY)); }  void CreateDIB(int cx, int cy) {     assert(cx > 0);      assert(cy > 0);      cxDIB = cx ;     cyDIB = cy ;      int iSize = sizeof(BITMAPINFOHEADER);        memset(&BIH, 0, iSize);      BIH.biSize = iSize;     BIH.biWidth = cx;        BIH.biHeight = cy;       BIH.biPlanes = 1;        BIH.biBitCount = 24;         BIH.biCompression = BI_RGB;      if(pdcDIB)          verify(DeleteDC(pdcDIB));      pdcDIB = CreateCompatibleDC(NULL);     assert(pdcDIB);      if(hbmpDIB)          verify(DeleteObject(hbmpDIB));      hbmpDIB = CreateDIBSection(         pdcDIB,                  (BITMAPINFO*)&BIH,           DIB_RGB_COLORS,              &bmp_cnt,                NULL,         0);      assert(hbmpDIB);     assert(bmp_cnt);      if(hbmpDIB)         SelectObject(pdcDIB, hbmpDIB); }  BOOL CreateHGLRC() {     DWORD dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP;      PIXELFORMATDESCRIPTOR pfd ;     memset(&pfd,0, sizeof(PIXELFORMATDESCRIPTOR)) ;     pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);      pfd.nVersion = 1;                            pfd.dwFlags =  dwFlags ;                     pfd.iPixelType = PFD_TYPE_RGBA ;             pfd.cColorBits = 24 ;                        pfd.cDepthBits = 32 ;                        pfd.iLayerType = PFD_MAIN_PLANE ;            int PixelFormat = ChoosePixelFormat(pdcDIB, &pfd);    if (PixelFormat == 0){       assert(0);       return FALSE ;    }     BOOL bResult = SetPixelFormat(pdcDIB, PixelFormat, &pfd);    if (bResult==FALSE){       assert(0);       return FALSE ;    }     m_hrc = wglCreateContext(pdcDIB);    if (!m_hrc){       assert(0);       return FALSE;    }     return TRUE; }  LRESULT CALLBACK WindowFunc(HWND hWnd,UINT msg, WPARAM wParam, LPARAM lParam) {     PAINTSTRUCT ps;      switch(msg)      {         case WM_ERASEBKGND:             return 0;         break;          case WM_CREATE:         break;          case WM_DESTROY:             if(m_hrc)             {                 wglMakeCurrent(NULL, NULL);                 wglDeleteContext(m_hrc) ;             }             PostQuitMessage(0) ;         break;          case WM_PAINT:             hDC = BeginPaint(hWnd, &ps);             renderSC(); // OpenGL -> DIB             draw(hDC);  // DIB -> hDC             EndPaint(hWnd, &ps);         break;          case WM_SIZE:             w = LOWORD(lParam); h = HIWORD(lParam);                      wglMakeCurrent(NULL, NULL);             wglDeleteContext(m_hrc);              CreateDIB(w, h);             CreateHGLRC();             verify(wglMakeCurrent(pdcDIB, m_hrc));              initSC();             resizeSC(w, h);             renderSC();         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) (COLOR_WINDOW);     wc.lpszClassName = szAppName;      if(!RegisterClassEx(&wc))     {         MessageBox(NULL, _T("RegisterClassEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);         return FALSE;     }      HWND hWnd = CreateWindowEx(WS_EX_LAYERED, 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;     }      verify(SetLayeredWindowAttributes(hWnd, 0x0, 0, LWA_COLORKEY));      MSG msg;     while(1)      {         while (PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)){             if (GetMessage(&msg, NULL, 0, 0))             {                 TranslateMessage(&msg);                 DispatchMessage(&msg);             }             else return 0;         }     }       return (FALSE);  }
shareimprove this answer

 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

It's worth saying that this technique is not practical for complex rendering and graphics animations. Copying GPU data to the RAM for each frame is very demanding on the CPU, resulting in low FPS. Check the comments on this answer: stackoverflow.com/questions/4780756/… – karlphillip Feb 8 '11 at 16:57 
1  
Note that in Windows Vista and Windows 7 you can achieve quite the same effect as in my x11argb demo below. The PIXELFORMATDESCRIPTOR supports a new flag to enable composition. I've yet to create a demo for this, though. Not going to happen until April, though, when I've got time for that again. – datenwolf

 

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

I know this is possible with Windows 7, not sure about earlier versions.

To get rid of the window border you need to remove the WS_OVERLAPPEDWINDOW style from the window and add the WS_POPUP style:

DWORD style = ::GetWindowLong(hWnd, GWL_STYLE); style &= ~WS_OVERLAPPEDWINDOW; style |= WS_POPUP; ::SetWindowLong(hWnd, GWL_STYLE, style);

To make the background of the OpenGL window transparent, you will need to use the DwmEnableBlurBehindWindow function:

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

You will also need to specify 0 for the alpha value when calling glClearColor.

glClearColor(0.0f,0.0f,0.0f,0.0f);

Also, when creating your OpenGL context, make sure you allocate an alpha channel.

Now your background should be fully transparent. If you keep the window decorations, then the background will use the Aero blur look and you can adjust the level of transparency using the alpha value in glClearColor.

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Thank you, but DwmEnableBlurBehindWindow() is a part of DWM, which doesn't belong to the Win32 API. This solution works for Windows Vista and above. – karlphillip Nov 1 '10 at 16:09
    
@karlphilip: Pre-Vista Windows:es don't have desktop compositing, so I'm not sure you can do it nicely there.– Macke Nov 1 '10 at 16:15
    
@karlphilip. Sorry, I haven't personally gotten transparent OpenGL windows working with XP, but I remember seeing posts on the OpenGL forum about it. Trying looking through the following search results for more information: google.com/… – flashk Nov 1 '10 at 16:20
    
This was really helpful, but I want to add the following: For me the above method rendered all of the background with the default Win7 blur and fake light reflections. To get rid of the blur and get a completeley transparent window, I set the bb.hRgnBlur parameter to CreateRectRgn(0, 0, 1, 1); and bb.dwFlags to DWM_BB_ENABLE | DWM_BB_BLURREGION;. This will blur exactly one pixel and show the rest of the window (where cleared with glClear) as completely transparent. – pholz

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Since all the answers given so far target Windows only, but there's surely also a demand doing this on X11 with a composited window manager, for reference I post my example code here (also to be found at https://github.com/datenwolf/codesamples/blob/master/samples/OpenGL/x11argb_opengl/x11argb_opengl.c

/*------------------------------------------------------------------------  * 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; }

The main trick is getting the right FBConfig. You need to ask for a alpha channel and test the associated XRenderPictFormat for the presence of an alpha mask.

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

This is an old question, but since newer versions of Windows have compositing and support, as datenwolf hints, for opengl, we can use some of that special sauce for accomplishing this. Although it is also trivial with DirectX (go figure...) Microsoft did add compositing hints to opengl contexts. Yay anti-trust fears!

So instead of an inefficient copy-to-physical-memory action, we can have the compositing engine just understand how to make use of the opengl context.

So, you have to create an opengl context with a pixelformat that specifies an alpha channel and that it should use composition (line 82). Then, you use the DwmApi.h routines to enable a blurred window (line 179) with a completely invalid region specified, which will blur nothing and leave the window transparent. (You need to specify a black+transparent brush on the window class! Oddly!) Then, you actually just use opengl as you are used to using it. In the event loop, every chance you get, you can just draw and swap buffers (line 201) and remember to enable GL_BLEND! :)

Please review/fork https://gist.github.com/3644466 or just view the following code snippet based off of the OP's own answer with this technique instead (you can just plop this in an empty project):

#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);  }
shareimprove this answer

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

=================================

=================================

=================================

 

 

 

출처: http://hyena0.tistory.com/420

 

 

  363번 포스트에 대한 질문을 정리해 봅니다.
 
  질문은 3D 모델을 안드로이드에 가져왔을때
 
  배경이 검게 나오는 상황입니다.
 
  모델은 어떤 그래픽 툴에서 그렸건 상관없을 것 
 
  같네요. 지금 전 Blender 를 선호하고 있지만,
 
  익숙한 툴을 사용하는게 제일 좋을 것 같고요.
 
  어찌됐건 안드로이드에서 보이기 위한 데이터는 
 
  vertices, colors, indices 로 각각 배열값을 가지고 있을 거라고 봅니다.
 
  모델은 잘보이는 것 같고요. 단지 배경이 검게 나오는 것이 문제로 보이는데
 
  363포스트에서 코드앞에 언급했다시피, 
 
  Cube.java 와 CubeRenderer.java 를 참조하고 있습니다.
 
  Cube.java 는 단지 모델을 그리는 용도이고, CubeRenderer.java 는 
 
  렌더링하는 속성들을 가지고 있다고 볼 수 있지요.
 
  카메라와 OpenGL을 동시에 오버레이 해서 보여줄려면, 
 
  우선 OpenGL의 그리는 배경속성이 투명해야 합니다.
 
  그래서 CubeRenderer.java 파일을 한번 보겠습니다.
----------------------------------------------------------------------------
package com.google.android.XXXXXX;
 
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
 
import android.opengl.GLSurfaceView;
 
/**
 * Render a pair of tumbling cubes.
 */
 
class CubeRenderer implements GLSurfaceView.Renderer {
    public CubeRenderer(boolean useTranslucentBackground) {
        mTranslucentBackground = useTranslucentBackground;
        mCube = new Cube();
    }
 
    public void onSensor(float x, float y){
     //float dx = x - mPreviousX;
        //float dy = y - mPreviousY;
     mAngleX = x; //+= dx ;
        mAngleY = y;//+= dy ;
     //return true;
    }
    
    public void onDrawFrame(GL10 gl) {
        /*
         * Usually, the first thing one might want to do is to clear
         * the screen. The most efficient way of doing this is to use
         * glClear().
         */
 
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
 
        /*
         * Now we're ready to draw some 3D objects
         */
 
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
       
        gl.glTranslatef(0, 0, -3.0f);
        gl.glRotatef(mAngleX, 0, 1, 0);
        gl.glRotatef(mAngleY, 1, 0, 0);
 
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
 
        mCube.draw(gl);
 
    }
 
    public int[] getConfigSpec() {
        if (mTranslucentBackground) {
                // We want a depth buffer and an alpha buffer
                int[] configSpec = {
                        EGL10.EGL_RED_SIZE,      8,
                        EGL10.EGL_GREEN_SIZE,    8,
                        EGL10.EGL_BLUE_SIZE,     8,
                        EGL10.EGL_ALPHA_SIZE,    8,
                        EGL10.EGL_DEPTH_SIZE,   16,
                        EGL10.EGL_NONE
                };
                return configSpec;
            } else {
                // We want a depth buffer, don't care about the
                // details of the color buffer.
                int[] configSpec = {
                        EGL10.EGL_DEPTH_SIZE,   16,
                        EGL10.EGL_NONE
                };
                return configSpec;
            }
    }
 
    public void onSurfaceChanged(GL10 gl, int width, int height) {
         gl.glViewport(0, 0, width, height);
 
         /*
          * Set our projection matrix. This doesn't have to be done
          * each time we draw, but usually a new projection needs to
          * be set when the viewport is resized.
          */
 
         float ratio = (float) width / height;
         gl.glMatrixMode(GL10.GL_PROJECTION);
         gl.glLoadIdentity();
         gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
    }
 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        /*
         * By default, OpenGL enables features that improve quality
         * but reduce performance. One might want to tweak that
         * especially on software renderer.
         */
        gl.glDisable(GL10.GL_DITHER);
 
        /*
         * Some one-time OpenGL initialization can be made here
         * probably based on features of this particular context
         */
         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
                 GL10.GL_FASTEST);
 
         if (mTranslucentBackground) {
             gl.glClearColor(0,0,0,0);
         } else {
             gl.glClearColor(1,1,1,1);
         }
         gl.glEnable(GL10.GL_CULL_FACE);
         gl.glShadeModel(GL10.GL_SMOOTH);
         gl.glEnable(GL10.GL_DEPTH_TEST);
    }
    private boolean mTranslucentBackground;
    private Cube mCube;
    public float mAngleX;
    public float mAngleY;
}
 
  위의 코드에서 녹색으로 표시된 부분이 투명한 처리를 하는 부분입니다.
 
즉, 363포스트에서 camGL 클래스에서 초기 생성시에 투명처리를 위해 아래와 같이 하는 부분이 있습니다.
 

                  mRenderer = new CubeRenderer(true);

        

        mGLSurfaceView = new GLSurfaceView(this);

                  //translucent

        mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);

        mGLSurfaceView.getHolder().setFormat(PixelFormat.RGBA_8888);

        mGLSurfaceView.setRenderer(mRenderer);

 

translucent 부분이 투명처리하는 부분인데, 카메라부분인 preview 객체를 생성하지 않으면 바탕화면 위에


도형이 그려지는 것을 볼 수 있어야 합니다. 확인하려면, preview 객체 생성부분을 주석처리해서 확인해 보십시오.
만약 거기서도 바탕화면이 투명처리가 안된다면, 다음을 확인해 보시기 바랍니다. (AndroidManifest.xml, 적색코드)

 

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

      package="com.google.android.XXXXX"

      android:versionCode="1"

      android:versionName="1.0">

    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <activity android:name=".XXXXX"

                  android:label="@string/app_name"

                  

android:theme="@android:style/Theme.Translucent">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>

    <uses-sdk android:minSdkVersion="3" />

</manifest> 


한번 해보시고 결과를 댓글로 남겨주세요.

 

 

 

반응형

 

728x90

 

=================================

=================================

=================================

 

 

 

출처: http://liveupdate.tistory.com/109

 

 

 

GLSurfaceView 배경 투명하게 만들기

 

관련소스 : APIDemos/src/com.example.android.apis.graphics/TranslucentGLSurfaceViewActivity.java

 

GLSurfaceView는 기본 값이 알파채널이 적용되지 않아서,

glClearColor( 0,0,0,0 ); 으로 해도 투명값이 설정되지 않는다.

 

EGL을 통해 SurfaceView를 핸들링하므로, 뷰 생성후 EGL, SurfaceView관련 설정만 하면 알파값을 사용할  있다.

 

GLSurfaceView myView = new GLSurfaceView(this);

 

// 픽셀포맷을 32비트포맷(8,8,8,8)으로 변경한다.

myView.setEGLConfigChooser( 8, 8, 8, 8, 16, 0);

 

// 렌더러 설정

myView.setRenderer( new MyRenderer() );

 

// 서비스포맷을 설정한다.

myView.getHolder().setFormat( PixelFormat.TRANSLUCENT );

 

이처럼 간단히 픽셀포맷만 변경하면된다.

 

이후 렌더러에서 glClearColor( 0, 0,0,0 ); 하면 배경은 투명으로 처리됨을 확인할 수 있다.

 



출처: http://liveupdate.tistory.com/109 [Live Update]

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://hyena0.tistory.com/421

 

 

  iPhone 에서 OpenGL 로 AR 기능을
 
  사용하려고 하면 필수적으로 OpenGL 의 
 
  모델 도형을 투명한 배경위에 보여줘야 합니다.
 
  그래서 설정해야 할 것들이 몇가지 있습니다.
 
  우선 기본 설정에서 RGBA8 로 해주고, 
 
  배경의 색깔을 모두 지운 후 alpha 에 투명값을 
 
  설정하는 겁니다. "0" 으로 말이죠.
 
  다시 정리하면 아래 코드를 볼 수 있습니다.
 

// The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:

- (id)initWithCoder:(NSCoder*)coder {

    

    if ((self = [super initWithCoder:coder])) {

CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;

 

eaglLayer.opaque = NO;//no - transparent

eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:

[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBackingkEAGLColorFormatRGBA8kEAGLDrawablePropertyColorFormatnil];

 

context = [[EAGLContext allocinitWithAPI:kEAGLRenderingAPIOpenGLES1];

 

if (!context || ![EAGLContext setCurrentContext:context]) {

[self release];

return nil;

}

 

animating = FALSE;

displayLinkSupported = FALSE;

animationFrameInterval = 1;

displayLink = nil;

animationTimer = nil;

 

// A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer

// class is used as fallback when it isn't available.

NSString *reqSysVer = @"3.1";

NSString *currSysVer = [[UIDevice currentDevicesystemVersion];

if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)

displayLinkSupported = TRUE;

 

[self setupView];

 

}

 

return self;

}

 

해당 코드는 일반적으로 제공되는 OpenGL 코드인데, eaglLayer.opaque = NO 로 설정해야 투명한 배경을


얻을 수 있습니다. 또한 도형을 그리는 부분에서는 배경화면의 색깔을 투명으로 지정해야 합니다.

 

        glBindFramebufferOES(GL_FRAMEBUFFER_OESviewFramebuffer);

glClearColor(0.0f0.0f0.0f0.0f);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 


여기서 glClear(Red, Green, Blue, alpha) 값을 보시면 모두 0 으로 설정하면 됩니다.
그런데 이렇게 하고서 투명처리가 안되어 무지 고생을 했습니다.
알고 봤더니 인터페이스 빌더에서 해당 OpenGL 을 그리는 View 의 배경색이 흰색으로 설정되어 있었습니다.

 


 


그래서 위와 같이 View 를 선택한 뒤, 배경색 팔레트에서 Opacity 값을 0 으로 설정하면 
View 자체가 투명한 색을 가지게 됩니다.
그러면 아래와 같은 투명배경의 도형을 카메라와 같이 볼 수 있게 됩니다.


 

 

=================================

=================================

=================================

 

 

 

출처: https://stackoverflow.com/questions/34387682/win32-api-transparent-opengl-overlay-clickthrough

 

win32 api transparent opengl overlay Clickthrough

 
 

i try to create a transparent window with opengl rendering insite. but because it is "WS_EX_TOPMOST" it will catch all mouse input how can i tell windows to ignore my window and send all inputs to the next Window in Z-order below my window.

Stuff i already tried:

  1. WS_EX_LAYERED will break my opengl Rendering
  2. offscreen rendring in a buffer its pretty slow because i have to use BitBlt(Sometimes i will get a software Opgengl Context)
  3. WM_NCHITTEST returning HTNOWHEREif (!RegisterClassEx(&wc)) error();
  4. m_OverlayWindow = CreateWindowEx(WS_EX_TOPMOST | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE, L"TESTA", L"hello", WS_VISIBLE | WS_POPUP, 0, 0, m_DesktopRect.right, m_DesktopRect.bottom, NULL, NULL, NULL, NULL); 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(m_OverlayWindow, &bb); g_OverlayWindow = m_OverlayWindow; EnableWindow(m_OverlayWindow, FALSE); PIXELFORMATDESCRIPTOR pfd1 = { sizeof(PIXELFORMATDESCRIPTOR), 1, // Version Number PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_SUPPORT_COMPOSITION | PFD_DOUBLEBUFFER, // Format Must Support Composition PFD_TYPE_RGBA, // Request An RGBA Format 32, // Select Our Color Depth 0, 0, 0, 0, 0, 0,................... m_hDC = GetDC(m_OverlayWindow); int nPixelFormat = ChoosePixelFormat(m_hDC, &pfd1); SetPixelFormat(m_hDC, nPixelFormat, &pfd1); m_OpenGlContext = wglCreateContext(m_hDC); wglMakeCurrent(m_hDC, m_OpenGlContext); const GLubyte *GLVersionString = glGetString(GL_VERSION); glEnable(GL_ALPHA_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(0, 0, 0, 0);
  5. 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 = NULL; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = NULL;//LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)CreateSolidBrush(0x00000000); wc.lpszClassName = L"TESTA";

 

 

=================================

=================================

=================================

 

 

 

출처: https://www.codeproject.com/Articles/9064/Yet-Another-Transparent-Static-Control

 

 

 

Introduction

There are many ways to develop a transparent static control. I like two approaches in particular, because they are simple and they get the job done. When you think about placing a static control with a transparent background on your window, the one important thing you have to consider is, whether the background is static or dynamic. The problem of having a static control changes depending on what is displayed in the background.

Method 1

If the background is static, then the best approach is to make a copy of the area on the parent window behind the static control before it is drawn for the first time, and then simply copy the image back to the parent every time the static control needs to be redrawn. The advantage of this approach is its flicker free display every time the static control is changed.

LRESULT CTransparentStatic2::OnSetText(WPARAM wParam,LPARAM lParam) {     LRESULT Result = Default();    Invalidate();    UpdateWindow();    return Result; }  HBRUSH CTransparentStatic2::CtlColor(CDC* pDC, UINT /*nCtlColor*/) {    pDC->SetBkMode(TRANSPARENT);    return (HBRUSH)GetStockObject(NULL_BRUSH); }  BOOL CTransparentStatic2::OnEraseBkgnd(CDC* pDC) {    if (m_Bmp.GetSafeHandle() == NULL)    {       CRect Rect;       GetWindowRect(&Rect);       CWnd *pParent = GetParent();       ASSERT(pParent);       pParent->ScreenToClient(&Rect); //convert our corrdinates to our parents        //copy what's on the parents at this point       CDC *pDC = pParent->GetDC();       CDC MemDC;       MemDC.CreateCompatibleDC(pDC);       m_Bmp.CreateCompatibleBitmap(pDC,Rect.Width(),Rect.Height());       CBitmap *pOldBmp = MemDC.SelectObject(&m_Bmp);        MemDC.BitBlt(0,0,Rect.Width(),Rect.Height(),pDC,Rect.left,Rect.top,SRCCOPY);        MemDC.SelectObject(pOldBmp);        pParent->ReleaseDC(pDC);    }    else //copy what we copied off the parent the first time back onto the parent    {       CRect Rect;       GetClientRect(Rect);       CDC MemDC;       MemDC.CreateCompatibleDC(pDC);       CBitmap *pOldBmp = MemDC.SelectObject(&m_Bmp);       pDC->BitBlt(0,0,Rect.Width(),Rect.Height(),&MemDC,0,0,SRCCOPY);       MemDC.SelectObject(pOldBmp);    }     return TRUE; }

Method 2

The other approach comes in handy when the parent window's background is dynamic. If the parent window's background is constantly changing then the above approach will not look too nice. So instead of all the copying, what the static control should do is invalidate the area of the parent where the control resides every time its text is changed. This method is much simpler than the one before, but it could flicker if the text is changed at a rapid rate.

LRESULT CTransparentStatic::OnSetText(WPARAM wParam,LPARAM lParam)  {    LRESULT Result = Default();    CRect Rect;    GetWindowRect(&Rect);    GetParent()->ScreenToClient(&Rect);    GetParent()->InvalidateRect(&Rect);    GetParent()->UpdateWindow();    return Result;  }  HBRUSH CTransparentStatic::CtlColor(CDC* pDC, UINT /*nCtlColor*/)  {    pDC->SetBkMode(TRANSPARENT);    return (HBRUSH)GetStockObject(NULL_BRUSH);  }

Keep an eye out for a Transparent Edit control and Transparent Listbox.

 

 

=================================

=================================

=================================

 

 

반응형
그리드형


관련글 더보기

댓글 영역