OpenGL In C# 02 使用FBO的方式绘制OpenGL窗体 并在XP下实现全透明

    FBO即是Frame Buffer Object 帧缓冲区,使用它可以在一个不显示的显存上进行OpenGL图形的绘制,然后根据需要把图形数据从显存中提取出来,也可以直接当做纹理使用。

    如果将数据提取到内存中,则可以绘制到位图上、绘制到控件上或者使用UpdateLayeredWindow函数实现在Windows XP上的全透明显示,不过由于从显存提取数据,并且再写入,导致此方式的效率颇为低。

先介绍一下UpdateLayeredWindow函数,用来实现分层的窗口,使用指定的混合方式将输入的图形绘制到窗体上,可以实现透明显示,如果绘制一个毛玻璃的纹理,可以实现像Windows 7透明窗体类似的效果。

[DllImport(User32, ExactSpelling = true, SetLastError = true)]
        public static extern bool UpdateLayeredWindow(IntPtr hwnd,                  //窗体的Handle
                                                      IntPtr hdcDst,                //屏幕的DC
                                                      ref Point pptDst,             //窗体在屏幕的位置 如果不变设置Null
                                                      ref Size psize,               //窗体的大小 不变设置Null
                                                      IntPtr hdcSrc,                //要绘制的图形的DC
                                                      ref Point pprSrc,             //显示点的模式
                                                      Int32 crKey,                  //指定色彩模式
                                                      ref BLENDFUNCTION pblend,     //指定混合模式
                                                      Int32 dwFlags                 //指定混合方式
                                                     );

    此外还需要重写一下窗体的CreateParams属性,把窗体设置为分层的窗体。

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cparam = base.CreateParams;
                cparam.ExStyle |= 0x00080000; //WS_EX_LAYERED
                return cparam;
            }
由于FBO或者是DIB方式进行OpenGL绘制性能实在不佳,所以以后的绘制都将采用Native模式。

我把一些常用的Win32函数和OpenGL函数以及常量抄了一遍,做了一个TOpenGL的类库,以后需要用的地方就引用一下就好了,这样就方便多了。

这次增加了一个类,能使用WPF的绘制方法把字符串绘制到内存,再加载到纹理,最后通过OpenGL进行显示,完美支持中文,速度也挺快的。

使用WPF需要添加3个引用: WindowBase、PresentationCore 和 PresentationFrameWork。

}

    使用这种模式的窗体不会触发OnPaint事件,鼠标键盘操作也需要编程者自己处理,这样的结构最适合进行个性化的窗口的设计,可惜的是。。。效率实在低,如果窗体太大的话感觉更加明显。

   

        public void SetBitmap()
        {
            //  Set the read buffer.
            gl.ReadBuffer(OpenGL.GL_COLOR_ATTACHMENT0_EXT);

            gl.ReadPixels(0, 0, Width, Height, OpenGL.GL_BGRA,
                OpenGL.GL_UNSIGNED_BYTE, dibSection.Bits);

            IntPtr screenDc = Win32.GetDC(IntPtr.Zero);

            try
            {
                Win32.Size size = new Win32.Size(Width, Height);
                Win32.Point pointSource = new Win32.Point(0, 0);
                Win32.Point topPos = new Win32.Point(0, 0);
                Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION();
                blend.BlendOp = Win32.AC_SRC_OVER;
                blend.BlendFlags = 0;
                blend.SourceConstantAlpha = 255;
                blend.AlphaFormat = Win32.AC_SRC_ALPHA;

                Win32.UpdateLayeredWindow(Handle, screenDc, ref topPos, ref size, dibSectionDeviceContext, ref pointSource, 0, ref blend, Win32.ULW_ALPHA);
            }
            finally
            {

            }
        }


    使用此SetBitmap函数可以将数据从显存设置到当前的透明窗口。

    例程还是绘制了一个红叉,嘿嘿,下面一节就开始涉及到绘制了。

    工程下载地址:http://download.csdn.net/detail/tianyu2202/4361494

    原创内容,欢迎转载,转载请注明出处:http://blog.csdn.net/tianyu2202/

    有兴趣的朋友可以下载本节的测试代码具体的看一下实现过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值