OpenGL窗体背景透明

一般使用OpenGL在窗体绘制图形时,绘图背景很难透明,在Google找了一段代码,实现在透明窗体上绘制图形,具有镂空的效果,像桌面精灵一样。

分享代码:

001 #define _WIN32_WINNT 0x0500
002  
003 #include <windows.h>
004 #include <windowsx.h>
005 #include <GL/gl.h>
006 #include <GL/glu.h>
007 #include <math.h>
008  
009 const float PI=3.1415926154;
010 #pragma comment (lib, "opengl32.lib")
011 #pragma comment (lib, "glu32.lib")
012 //#pragma comment (lib, "glaux.lib")
013  
014 #include <assert.h>
015 #include <tchar.h>
016  
017 #ifdef  assert
018 #define verify(expr) if(!expr) assert(0)
019 #else verify(expr) expr
020 #endif
021  
022 const TCHAR szAppName[]=_T("TransparentGL");
023 const TCHAR wcWndName[]=_T("WS_EX_LAYERED OpenGL");
024  
025 HDC hDC;
026 HGLRC m_hrc;
027 int w(240);
028 int h(240);
029  
030 HDC pdcDIB;
031 HBITMAP hbmpDIB;
032 void *bmp_cnt(NULL);
033 int cxDIB(0);
034 int cyDIB(0);
035 //BITMAPINFOHEADER BIH;
036  
037 BITMAPINFOHEADER BIH;
038  
039 void polarCoorCircle(float radius, float circlePointX, float circlePointY)
040 {
041     float i,n=360.0;
042     float t = 2*PI/n,x,y;
043     glBegin(GL_LINE_LOOP);
044     for (i=0.0; i<n; i+=0.2)
045     {
046         x = radius*sinf(t*i);
047         y = radius*cosf(t*i);
048         glVertex2f(circlePointX+x,circlePointY+y);
049     }
050     glEnd();
051 }
052  
053 BOOL initSC()
054 {
055     glEnable(GL_ALPHA_TEST);
056     glEnable(GL_DEPTH_TEST);
057     glEnable(GL_COLOR_MATERIAL);
058  
059     glEnable(GL_LIGHTING);
060     glEnable(GL_LIGHT0);
061  
062     glEnable(GL_BLEND);
063     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
064     glClearColor(0, 0, 0, 1);
065  
066     return 0;
067 }
068  
069 void resizeSC(int width,int height)
070 {
071     glViewport(0,0,width,height);
072     glMatrixMode(GL_PROJECTION);
073     glLoadIdentity();
074     //gluOrtho2D(0.0,500.0*aspect,0.0,500.0);
075     gluOrtho2D(0.0,width,0.0,height);
076     glMatrixMode(GL_MODELVIEW);
077     glLoadIdentity();
078 }
079  
080 BOOL renderSC()
081 {
082     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
083  
084     glColor3f(0, 1, 1);
085     glLineWidth(10);
086     glBegin(GL_LINES);
087     glVertex2f(0,0);
088     glVertex2f(120,120);
089     glEnd();
090     polarCoorCircle(120, 120, 120);
091     glFlush();
092  
093     return 0;
094 }
095  
096 // DIB -> hDC
097 void draw(HDC pdcDest)
098 {
099     assert(pdcDIB);
100  
101     verify(BitBlt(pdcDest, 0, 0, w, h, pdcDIB, 0, 0, SRCCOPY));
102 }
103  
104 void CreateDIB(int cx, int cy)
105 {
106     assert(cx > 0);
107     assert(cy > 0);
108  
109     cxDIB = cx ;
110     cyDIB = cy ;
111  
112     int iSize = sizeof(BITMAPINFOHEADER);
113     memset(&BIH, 0, iSize);
114  
115     BIH.biSize = iSize;
116     BIH.biWidth = cx;
117     BIH.biHeight = cy;
118     BIH.biPlanes = 1;
119     BIH.biBitCount = 24;
120     BIH.biCompression = BI_RGB;
121     if(pdcDIB)
122         verify(DeleteDC(pdcDIB));
123  
124     pdcDIB = CreateCompatibleDC(NULL);
125     assert(pdcDIB);
126  
127     if(hbmpDIB)
128         verify(DeleteObject(hbmpDIB));
129  
130     hbmpDIB = CreateDIBSection(
131         pdcDIB,
132         (BITMAPINFO*)&BIH,
133         DIB_RGB_COLORS,
134         &bmp_cnt,
135         NULL,
136         0);
137  
138     assert(hbmpDIB);
139     assert(bmp_cnt);
140  
141     if(hbmpDIB)
142         SelectObject(pdcDIB, hbmpDIB);
143 }
144  
145 BOOL CreateHGLRC()
146 {
147     DWORD dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP;
148  
149     PIXELFORMATDESCRIPTOR pfd ;
150     memset(&pfd,0, sizeof(PIXELFORMATDESCRIPTOR)) ;
151     pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
152     pfd.nVersion = 1;
153     pfd.dwFlags =  dwFlags ;
154     pfd.iPixelType = PFD_TYPE_RGBA ;
155     pfd.cColorBits = 24 ;
156     pfd.cDepthBits = 32 ;
157     pfd.iLayerType = PFD_MAIN_PLANE ;
158  
159     int PixelFormat = ChoosePixelFormat(pdcDIB, &pfd);
160     if (PixelFormat == 0){
161         assert(0);
162         return FALSE ;
163     }
164  
165     BOOL bResult = SetPixelFormat(pdcDIB, PixelFormat, &pfd);
166     if (bResult==FALSE){
167         assert(0);
168         return FALSE ;
169     }
170  
171     m_hrc = wglCreateContext(pdcDIB);
172     if (!m_hrc){
173         assert(0);
174         return FALSE;
175     }
176  
177     return TRUE;
178 }
179  
180 LRESULT CALLBACK WindowFunc(HWND hWnd,UINT msg, WPARAM wParam, LPARAMlParam)
181 {
182     PAINTSTRUCT ps;
183  
184     switch(msg)
185     {
186     case WM_ERASEBKGND:
187         return 0;
188         break;
189  
190     case WM_CREATE:
191         break;
192  
193     case WM_DESTROY:
194         if(m_hrc)
195         {
196             wglMakeCurrent(NULL, NULL);
197             wglDeleteContext(m_hrc) ;
198         }
199         PostQuitMessage(0) ;
200         break;
201  
202     case WM_PAINT:
203         hDC = BeginPaint(hWnd, &ps);
204         renderSC(); // OpenGL -> DIB
205         draw(hDC);  // DIB -> hDC
206         EndPaint(hWnd, &ps);
207         break;
208  
209     case WM_SIZE:
210         w = LOWORD(lParam); h = HIWORD(lParam);
211         wglMakeCurrent(NULL, NULL);
212         wglDeleteContext(m_hrc);
213  
214         CreateDIB(w, h);
215         CreateHGLRC();
216         verify(wglMakeCurrent(pdcDIB, m_hrc));
217  
218         initSC();
219         resizeSC(w, h);
220         renderSC();
221         break;
222  
223     default:
224         return DefWindowProc(hWnd,msg,wParam,lParam);
225     }
226  
227     return 0;
228 }
229  
230 int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR str,intnWinMode)
231 {
232     WNDCLASSEX wc;
233     memset(&wc, 0, sizeof(wc));
234     wc.cbSize = sizeof(WNDCLASSEX);
235     wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
236     wc.style = CS_HREDRAW | CS_VREDRAW;
237     wc.lpfnWndProc = (WNDPROC)WindowFunc;
238     wc.cbClsExtra  = 0;
239     wc.cbWndExtra  = 0;
240     wc.hInstance = hThisInst;
241     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
242     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
243     wc.hbrBackground = (HBRUSH) (COLOR_WINDOW);
244     wc.lpszClassName = szAppName;
245  
246     if(!RegisterClassEx(&wc))
247     {
248         MessageBox(NULL, _T("RegisterClassEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
249         return FALSE;
250     }
251  
252     HWND hWnd = CreateWindowEx(WS_EX_LAYERED, szAppName, wcWndName,
253         WS_VISIBLE | WS_POPUP, 200, 150, w, h,
254         NULL, NULL, hThisInst, NULL);
255     if(!hWnd){
256         MessageBox(NULL, _T("CreateWindowEx - failed"), _T("Error"), MB_OK | MB_ICONERROR);
257         return FALSE;
258     }
259  
260     verify(SetLayeredWindowAttributes(hWnd, 0x0, 0, LWA_COLORKEY));
261  
262     MSG msg;
263     while(1)
264     {
265         while (PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)){
266             if (GetMessage(&msg, NULL, 0, 0))
267             {
268                 TranslateMessage(&msg);
269                 DispatchMessage(&msg);
270             }
271             else return 0;
272         }
273     }
274  
275     return (FALSE);
276 }

运行后的效果:

opengl

原理:OpenGL先绘制位图,然后将位图拷贝到设备中。

但是将代码移植到MFC自定义透明控件中,发现透明效果失效。如果有能实现OpenGL透明自定义控件的方法,请赐教。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值