我要做这么一个东西:类似于一个桌面精灵,但不是基于GDI的,而是D3D或OPENGL实施渲染的,可能渲染各种东西。现在要把渲染后的结果透明的贴到桌面上,就是去掉要背景,而且这个窗口会在桌面上移动,就是精灵在桌面上跑来跑去,是不是在所有窗口最前面无所谓。需要保证流畅性,不能闪烁。我网上找过资料,有的是使用未公开的函数SetLayedWindowAttributes(),OPENGL方式下可以保持透明,D3D下不行,背景仍在,另外透明的时候OPENGL方式下渲的东西多了会很慢,还有就是窗口会闪烁,不像背景存在的时候那么流畅。我自己试过一种方法:D3D渲完以后,将光栅copy到一个bitmap,这个bmp由CreateDIBSection()创建并属于某个memDC,然后BitBlt到窗口DC,这样的话,windows会将它的背景透明掉,当然前提是需要调用SetLayedWindowAttributes(),不过这样感觉有些卡,帧数也不高,不太爽;我想把中间的memDC去掉,就是bmp属于窗口DC,渲完以后copy光栅到bmp,这样会少一步copy,但是窗口没有显示,不知道该怎么弄。
    我对windows的图形机制并不了解,也许出现这些问题是因为我没有调用某些还不知道的API,也许有更好的方法。望各位高手多给点建议,谢谢!

解决方案 »

  1.   

    SetLayerWindowsAttributes仍然是GDI的内容, 和dx或者opengl没有关系你说的效果直接用dx或者opengl渲染的方式做不到可以的方法就是, Render To Texture 技术, 这个在dx和opengl当中都支持
    然后把texture转成gdi的bitmap图片来处理注: dx和opengl当中有一个技术叫做覆盖表面, overlay surface, 直接输出到显示器的方法,但是这种方法和其他的3d方法一样,都是针对矩形边界的, 对于不是矩形边界的精灵无效. 只所以说这个,是应为它的效果和gdi的这个和SetLayerWindowAttributes类似(它也不是什么未公布的, 在2000系统以后才可用,以前的版本不可用而已)所以解决的方式依然是GDI
      

  2.   

    我是希望能找到某些方法,来减少GDI的中间处理、转换的过程,从而提高速度。现在的情况下,帧数跟窗口大小极为相关,640X480的窗口只有40帧,不管里面渲染了多少东西。我的CPU是Pentium IV 1.6G,而如果是400X300的窗口,就有50多帧。如果不透明的话,800X600的窗口也有100到200帧的。SetLayerWindowsAttributes的确是GDI的内容,但是我奇怪dx渲的窗口无法被透明;我试过最简单的例子,只clear背景,也透明不了,不知道我哪里做错了。
      

  3.   

    我对GDI也不了解,不知道怎么做能减少从texture转成gdi的bitmap的处理时间。目前知道一个函数
    int SetDIBitsToDevice(
      HDC hdc,                 // handle to DC
      int XDest,               // x-coord of destination upper-left corner
      int YDest,               // y-coord of destination upper-left corner 
      DWORD dwWidth,           // source rectangle width
      DWORD dwHeight,          // source rectangle height
      int XSrc,                // x-coord of source lower-left corner
      int YSrc,                // y-coord of source lower-left corner
      UINT uStartScan,         // first scan line in array
      UINT cScanLines,         // number of scan lines
      CONST VOID *lpvBits,     // array of DIB bits
      CONST BITMAPINFO *lpbmi, // bitmap information
      UINT fuColorUse          // RGB or palette indexes
    );只要渲染完毕直接调这个就可以了,不过它的速度跟先copy到memDC的bmp,再从memDC中bitblt到窗口dc的速度基本一样。我还不知道怎么去直接操作窗口dc的bmp。
      

  4.   

    窗口DC的bmp不应该被你直接操作的。否则有可能破坏屏幕上的其他内容。
      

  5.   

    如果直接操作程序窗口DC的bmp的话,不知道是不是有破坏屏幕的可能,因为我不是操作桌面DC
      

  6.   

    这个问题只有到vista下才能完美解决。vista的GDI底层基于D3D渲染,可以和你的D3D窗口很好的融合,XP下你就不要想了。