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

2024-03-27

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

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

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

能用源码举例说明一下吗?

平台:Windows(仅win32)


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

完成这项任务的少数人不分享太多 https://web.archive.org/web/20120615071641/http://coreytabaka.com/programming/cube-demo/。在我的研究过程中,我发现了不同的方法来实现我所寻找的目标。最有趣的之一是AeroGL,它表明代码片段 http://www.jose.it-berater.org/smfforum/index.php?topic=2844.0使用迄今为止尚未提及的技术,即将图形渲染到与设备无关的位图 http://msdn.microsoft.com/en-us/library/dd183494(VS.85).aspx (DIB).

要永久关闭此线程,下面是源代码实现该技术。代码本身是对所提供的应用程序的轻微修改here http://www.rsdn.ru/article/opengl/layeredopengl.xml(非常感谢安德烈·萨普罗诺夫 Y.).

最终结果如下图所示:

该代码已在 Windows XP(32 位)和 Windows 8.1(32 位)上进行了测试。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); 
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何制作具有透明背景的OpenGL渲染上下文? 的相关文章

  • 是否允许将类模板类型参数键入相同的名称?

    这似乎可以在 MSVC 中按预期编译甚至工作 但它是合法的 C 代码吗 它是否能保证执行此处所期望的操作 即将模板类型导出到结构体的同名用户 template
  • 用户控件内所有控件均为空

    我有一个 UserControl 它使用 UserControl 以及其他控件 In the ascx文件我有以下代码
  • 访问“if”语句之外的变量

    我怎样才能使insuranceCost以外可用if陈述 if this comboBox5 Text Third Party Fire and Theft double insuranceCost 1 在 if 语句之外定义它 double
  • 如何在不实例化一个类的情况下检查它是否继承了另一个类? [复制]

    这个问题在这里已经有答案了 假设我有一个如下所示的类 class Derived some inheritance stuff here 我想在我的代码中检查类似的内容 Derived is SomeType 但看起来像is运算符需要 De
  • 如何在编译C代码时禁用警告?

    我正在使用 32 位 Fedora 14 系统 我正在使用编译我的源代码gcc 有谁知道如何在编译c代码时禁用警告 EDIT 是的 我知道 最好的办法是修复这些警告以避免任何未定义 未知的行为 但目前在这里 我第一次编写了巨大的代码 并且在
  • Paradox 表 - Oledb 异常:外部表不是预期的格式

    我正在使用 Oledb 从 Paradox 表中读取一些数据 我遇到的问题是 当我将代码复制到控制台应用程序时 代码可以工作 但在 WinForms 中却不行 两者都以 x86 进行调试 我实际上只是复制代码 在 WinForms 应用程序
  • 有没有办法使用 i387 fsqrt 指令获得正确的舍入?

    有没有办法使用 i387 fsqrt 指令获得正确的舍入 除了改变精确模式在 x87 控制字中 我知道这是可能的 但这不是一个合理的解决方案 因为它存在令人讨厌的重入型问题 如果 sqrt 操作中断 精度模式将出错 我正在处理的问题如下 x
  • 序列化和反序列化 Visual Studio 解决方案文件 - 或以编程方式编辑?

    我想以编程方式添加和删除项目 解决方案文件夹和其他项目 例如解决方案的资源文件 但我不确定最好的方法是什么 对于那些不知道的人 高度简化 解决方案文件 sln 通常如下所示 Microsoft Visual Studio Solution
  • 在 MATLAB 中创建共享库

    一位研究人员在 MATLAB 中创建了一个小型仿真 我们希望其他人也能使用它 我的计划是进行模拟 清理一些东西并将其变成一组函数 然后我打算将其编译成C库并使用SWIG https en wikipedia org wiki SWIG创建一
  • C# datagridview 列转入数组

    我正在用 C 构建一个程序 并在其中包含一个 datagridview 组件 datagridview 有固定数量的列 2 我想将其保存到两个单独的数组中 但行数确实发生了变化 我怎么能这样做呢 假设一个名为 dataGridView1 的
  • 操纵 setter 以避免 null

    通常我们有 public string code get set 如果最终有人将代码设置为 null 我需要避免空引用异常 我尝试这个想法 有什么帮助吗 public string code get set if code null cod
  • 您可以在一个 Windows Azure 实例上部署多个 Web 应用程序吗?

    是否可以在一个 windows azure 小型计算实例中运行一堆 Web 应用程序 我正在考虑使用 Azure 作为放置一堆处于开发和非生产状态的项目 Web 应用程序 的地方 有些实际上已经被封存了 但我想在某个地方有一个活跃的实例 我
  • 格式化货币

    在下面的示例中 逗号是小数点分隔符 我有这个 125456 89 我想要这个 125 456 89 其他示例 23456789 89 gt 23 456 789 89 Thanks 看看这个例子 double value 12345 678
  • 错误左值需要作为赋值C++的左操作数

    整个程序基本上只允许用户移动光标 如果用户位于给定的坐标范围 2 2 内 则允许用户键入输入 我刚刚提供了一些我认为足以解决问题的代码 我不知道是什么导致了这个问题 你能解释一下为什么会发生吗 void goToXY int int 创建一
  • 如何使用收益返回和递归获得字母的每个组合?

    我有几个像这样的字符串列表 可能有几十个列表 1 A B C 2 1 2 3 3 D E F 这三个仅作为示例 用户可以从几十个具有不同数量元素的类似列表中进行选择 再举个例子 这对于用户来说也是一个完全有效的选择 25 empty 4 1
  • TPL 数据流块下游如何获取源生成的数据?

    我正在使用 TPL Dataflow 处理图像 我收到处理请求 从流中读取图像 应用多次转换 然后将生成的图像写入另一个流 Request gt Stream gt Image gt Image gt Stream 为此 我使用块 Buff
  • 在 C++ 和 Windows 中使用 XmlRpc

    我需要在 Windows 平台上使用 C 中的 XmlRpc 尽管我的朋友向我保证 XmlRpc 是一种 广泛可用的标准技术 但可用的库并不多 事实上 我只找到一个库可以在 Windows 上执行此操作 另外一个库声称 您必须做很多工作才能
  • 如何设置 CMake 与 clang 交叉编译 Windows 上的 ARM 嵌入式系统?

    我正在尝试生成 Ninja makefile 以使用 Clang 为 ARM Cortex A5 CPU 交叉编译 C 项目 我为 CMake 创建了一个工具链文件 但似乎存在错误或缺少一些我无法找到的东西 当使用下面的工具链文件调用 CM
  • 启动画面后主窗口出现在其他窗口后面

    我有一个带有启动屏幕的 Windows 窗体应用程序 当我运行该应用程序时 启动屏幕显示正常 消失并加载应用程序的主窗体 但是 当我加载主窗体时 它出现在包含该应用程序的 Windows 资源管理器目录下 这是运行启动画面然后运行主窗体的代
  • FindAsync 很慢,但是延迟加载很快

    在我的代码中 我曾经使用加载相关实体await FindAsync 希望我能更好地遵守 C 异步指南 var activeTemplate await exec DbContext FormTemplates FindAsync exec

随机推荐

  • Mjpeg 在最近的 Mobile Safari 上损坏了?

    我正在处理来自 IP 摄像机的实时 mjpeg 流 发现最近发布的 Mobile Safari 似乎对 mjpeg 的支持被破坏了 我正在使用一个带有嵌入图像的简单 HTML 测试页面 如下所示 img src http ip addres
  • 使用流复制文件

    以下示例演示如何使用流复制文件 private void copyWithStreams File aSourceFile File aTargetFile boolean aAppend log Copying files with st
  • Android底部导航视图项目图标大小[重复]

    这个问题在这里已经有答案了 I need to do a bottom navigation view in Android like this I tried and now I have something like this 如何增加
  • 在 Clojure 中实现 cron 类型调度程序

    我正在寻找任何可以在给定时间触发事件的 clojure 方法 例如 我希望一个特定的进程在上午 9 30 启动 然后我可以触发另一个进程在半小时后开始运行 等等 提前致谢 更新2 感谢 arthur ulfeoldt 和 unknown p
  • 是否可以将 Camera2 与 Google Vision API 一起使用

    是否可以仅使用 Camera2 和 Google Vision API 来检测人脸 我找不到整合它的方法 是的 可以将 Camera2 API 与 Google Vision API 一起使用 首先 Google Vision API 人脸
  • 使用 SDK 在 azure 函数中将 Azure blob 存储转换为 JSON

    我正在尝试创建一个计时器触发器 azure 函数 该函数从 blob 获取数据 聚合数据 并将聚合结果放入 cosmosDB 中 我之前尝试使用 azure 函数中的绑定来使用 blob 作为输入 但我被告知这是不正确的 请参阅此线程 Az
  • 如何以编程方式读取 EF DbContext 元数据?

    我有使用 EF CodeFirst 5 的应用程序 dll 版本 4 4 0 0 在 net 4 0 上 我需要能够读取实体元数据 以便我可以针对给定的条目类型获取以下信息 哪些属性是一对多关系 引用实体 哪些属性是多对一关系 引用当前实体
  • 从 SQL Server 中的日期时间字段中获取“日期”

    我有一个日期列 其中日期以格式显示2009 11 18 10 55 28 370 我只想从该值中获取日期 而不是时间 我怎么做 如果您使用的是 SQL Server 2008 则现在有 DATE 数据类型 让它变得更加自然 SELECT C
  • PHP Curl 收到 502:错误网关错误

    在浏览器中 该 url 有效 当我尝试使用 PHP curl 时 我得到了 502 Bad Gateway error 这是我的代码 ch curl init curl setopt ch CURLOPT URL url query str
  • popen vs system:popen 和 system 一样邪恶吗?

    popen 缓冲输出 而系统则不缓冲 这是唯一的区别吗 据我所知 popen 和 system 都通过 shell 运行命令 然而 popen 是evil http www cplusplus com forum articles 1115
  • 使用“using”关键字使继承的构造函数公开[重复]

    这个问题在这里已经有答案了 我正在尝试测试我的类的受保护方法和构造函数 为此 我尝试对其进行子类化 并使用 C 11 将其成员重新导出为 publicusing关键词 class Foo protected Foo int i void r
  • 添加对 CountVectorizer (sklearn) 的词干支持

    我正在尝试使用 sklearn 将词干添加到 NLP 中的管道中 from nltk stem snowball import FrenchStemmer stop stopwords words french stemmer French
  • Keycloak java.lang.NoClassDefFoundError:使用 Springboot 的 java/security/acl/Group

    因此 我们正在构建一个带有 Keycloak 集成的 Spring Boot 后端 但是在 docker swarm 服务上运行后端时出现以下错误 2020 06 29 21 17 51 694 ERROR 1 nio 3304 exec
  • MigraDoc C# 在同一行左右对齐

    我有一个带有单元格的表格 其中我想要两个文本 第一个文本左对齐 第二个文本右对齐 位于同一单元格的同一行上 我尝试使用 MigraDoc 重现此单元 但没有成功 我只能添加左右对齐的两个文本 但不能在同一行上 这是我的代码 Cell cel
  • 在 Python 中向已运行的 cmd 发送命令

    我有一个Python脚本可以绕过Windows中的UAC 绕过用户帐户控制 然后我需要能够以某种方式与打开的 CMD 进行通信并向其传递命令 例如 回声测试 我只能找到打开新命令并与其通信的代码 然而 这并没有帮助 因为我需要与我通过 UA
  • 如何在没有 UDID 的情况下跟踪 iOS5 上的下载

    谁知道如何在没有 UDID 的情况下跟踪 iOS 应用程序下载 通过网络广告 我认为这是不可能的 特别是如果用户从网站转到 AppStore 但一家名为 WDA 的公司似乎使这成为可能 http www lovefortech com 20
  • 无法序列化会话 Bean - 引发警告

    我正在使用 EclipseLink JPA 2 0 在 netbeans 中运行 JSF Primefaces tomcat 6 0 32 的环境 我的应用程序工作正常 但每次运行它时 我都会收到很多警告 指出无法序列化我的会话 bean
  • autovacuum (VACUUM) 是这个 PostgreSQL UPDATE 查询偶尔需要几个小时才能完成运行的原因吗?

    此 sql 查询通常只需要几分钟即可运行 update import parts ip set part manufacturer id pslc part manufacturer id from parts part supplier
  • Go 中的结构体大小

    我正在研究 Go 它看起来很有前途 我想弄清楚如何获取 go 结构的大小 例如 例如 type Coord3d struct X Y Z int64 我当然知道它是 24 个字节 但我想以编程方式知道它 您有任何想法如何做到这一点吗 罗杰已
  • 如何制作具有透明背景的OpenGL渲染上下文?

    渲染上下文通常在背景上有纯色 黑色或其他颜色 请参见下图 我想知道是否可以设置一个没有装饰且具有透明背景的窗口 同时允许我在其上渲染 OpenGL 内容 这会给人一种三角形漂浮在屏幕上的错觉 透明背景应该允许您看到桌面或可能位于其后面的其他