gpt4 book ai didi

c - 如何制作具有透明背景的 OpenGL 渲染上下文?

转载 作者:太空宇宙 更新时间:2023-11-04 04:57:28 28 4
gpt4 key购买 nike

渲染上下文通常在背景上有纯色(黑色或其他颜色,见下图):

alt text

我想知道是否可以设置一个没有装饰且具有透明背景的窗口,同时允许我在其上渲染 OpenGL 内容。

这会给人一种三角形漂浮在屏幕上的错觉。透明背景应该能让您看到桌面或可能隐藏在它后面的其他应用程序。

能否请您举例说明源代码?

平台:Windows(仅限 win32)

最佳答案

在一个不成功的赏金上花费了一些声望以在这个问题上获得一些帮助之后,我终于意识到我感兴趣的问题有多么复杂。

完成这项任务的少数人don't share much .在我的研究过程中,我发现了不同的方法来实现我正在寻找的东西。最有趣的一个是 AeroGL,它显示 snippets of code使用目前尚未提及的技术,将图形渲染到 device-independent bitmap (DIB)。

要永久关闭此线程,下面的源代码 实现了该技术。代码本身是对提供的应用程序的轻微修改 here (非常感谢 Andrei Sapronov Y.)。

最终结果如下图所示:

enter image description here

代码已经在 Windows XP(32 位)和 Windows 8.1(32 位)上进行了测试。尽情享受吧!

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

关于c - 如何制作具有透明背景的 OpenGL 渲染上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4424036/

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