DirectX截图黑屏的解决办法
好久沒有更新博客了,今天開始繼續(xù)耕耘。
生活要繼續(xù)
工作要繼續(xù)
夢(mèng)想也一定要繼續(xù)!
之前寫過一篇關(guān)于DirectX截屏的文章,其中有網(wǎng)友留言提到了截圖黑屏的問題,于是這些日子研究了一下,與大家一同分享。
為什么會(huì)黑屏?
一句話概括,黑屏是由于DDraw加速引起的!
先說一下DirectX的顯示原理,通常我們看到的屏幕上的數(shù)據(jù),都是通過Primary Surface送至顯示器的,什么是Primary Surface呢?中文叫做主顯示表面,也就是說我們當(dāng)前看到的屏幕上的圖像數(shù)據(jù)是從這個(gè)表面來的,除了主表面意外還有離屏表面,叫做OffScreenSuface。這種表面中的數(shù)據(jù)是不直接顯示在屏幕上的。常用的截屏函數(shù)也基本上是通過截取Primary Surface中的數(shù)據(jù)來實(shí)現(xiàn)的。現(xiàn)在多數(shù)的視頻播放軟件都是用DDraw寫的(現(xiàn)在DDraw已經(jīng)融合到DirectX的Graphics本分,DDraw這個(gè)詞也已經(jīng)成為歷史了。),而且使用了一種叫做Overlay的表面,我們常用的截屏函數(shù)都是截取普通的primary surface中的數(shù)據(jù),無法截取Overlay surface中的數(shù)據(jù),而微軟又沒有提供公共的API來獲取Overlay surface中的數(shù)據(jù),所以,黑屏就不足為奇了。下面就是使用了Overlay技術(shù)的Windows Media Player截圖時(shí)的黑屏現(xiàn)象。
Overlay是純硬件支持的,DDraw并不會(huì)用軟件實(shí)現(xiàn)這種功能。這種Surface的特殊之處在于,它相當(dāng)于蒙在屏幕上的一塊塑料板,也就是說,這個(gè)如果使用了這種Surface,那么它就位于所有surface的最前端。顯示設(shè)備在向屏幕顯示數(shù)據(jù)的時(shí)候,會(huì)先判斷該位置是否有Overlay,如果有,就顯示Overlay中像素,如果沒有,就使用Primary Surface中的像素。所以,當(dāng)你打開一個(gè)播放器來播放視頻,截圖的時(shí)候就會(huì)發(fā)現(xiàn)播放器窗口是黑的。原因就是這塊區(qū)域正好對(duì)應(yīng)著Overlay。當(dāng)然是截取不到的。
關(guān)于Overlay surfaces的詳細(xì)介紹,可以看這里。
如何避免截圖時(shí)黑屏
大多數(shù)軟件除了DDraw的渲染模式之外,還提供了一種Software renderer模式,也就是軟件模式,這種模式在DDraw加速不可用的時(shí)候才會(huì)使用,所以一個(gè)避免截圖黑屏的辦法就是關(guān)閉DDraw加速,強(qiáng)迫軟件使用Software renderer模式,這樣,Overlay surface就不存在了,也就不會(huì)黑屏了。具體辦法如下
方法一: 使用軟件本身的設(shè)置來禁用Overlay技術(shù),該方法只會(huì)影響該軟件本身,以常見的Windows Media Player為例,設(shè)置如下(將 使用覆蓋這個(gè)選項(xiàng)勾掉,這樣軟件就不會(huì)使用Overlay Surface了)
方法二: 使用DirectX控制面板來關(guān)閉DDraw加速,上面的方法相當(dāng)于關(guān)閉分支開關(guān),而這個(gè)方法則相當(dāng)于把總閘給關(guān)閉了,系統(tǒng)中所有其他軟件也不能使用DDraw加速了。如果安裝了DirectX SDK,那么直接在運(yùn)行欄里面輸入dxdiag即可打開DirectX控制面板,設(shè)置如下。
方法三:其實(shí)還有一種辦法,就是用程序占用Overlay surface,這種辦法太麻煩,一般人不會(huì)用,因?yàn)橐话愕莫?dú)立顯卡都支持Overlay Surface,而且支持的個(gè)數(shù)是有限的,所以,如果我們提前用程序占用了所有的Overlay Surface,那么其他程序就無法再使用了,也就不會(huì)導(dǎo)致截圖黑屏了。在使用這種方法前,應(yīng)該首先查看自己的顯卡是否支持Overlay技術(shù),以及支持多少個(gè)。如果安裝了DirectX SDK,可以依次展開:開始-程序-Microsoft DirectX SDK-DirectX Utilities-DirectX Caps Viewer,由下圖可知,我的顯卡支持一個(gè)Overlay Surface,我還沒玩過高級(jí)顯卡,沒見過支持多個(gè)Overlay的顯卡,哪位兄弟有好的顯卡,也發(fā)個(gè)圖讓小弟看看。
但是這種方法有一個(gè)弊端,就是如果軟件不支持Software Renderer模式,那么如果你先用程序占用了Overlay,再啟動(dòng)播放軟件的時(shí)候,就會(huì)導(dǎo)致錯(cuò)誤。
以上幾種辦法究其本質(zhì),實(shí)際上就是一種,都是禁止使用Overlay Surface。而且這些方法都有一個(gè)弊端,就是要求先入為主,也就是在軟件啟動(dòng)前(或者確切的說,是視頻播放前)做好設(shè)置,然后再啟動(dòng)軟件。如果視頻已經(jīng)播放(Overlay已經(jīng)被占用),那么這些方法將會(huì)統(tǒng)統(tǒng)失效。
除此之外,還可以使用現(xiàn)成的截圖軟件,很多軟件都可以處理黑屏的情況,比如HyperSnap 6就很不錯(cuò)。
如何截取Overlay中的數(shù)據(jù)?
說來這不是一個(gè)簡單的問題,我在網(wǎng)上搜索了很久,也沒找到合適的辦法,據(jù)說使用Hook技術(shù)可能會(huì)辦到,但是我對(duì)hook不太熟悉,所以也沒嘗試,希望哪位朋友有興趣可以試試,關(guān)于這個(gè)話題,google討論組上有個(gè)帖子,介紹的比較詳細(xì),感興趣的可以看看這里。
挑戰(zhàn)一下!
我這里有一個(gè)關(guān)于Overlay Surface的Demo(下載)。這個(gè)Demo來自DirectX 7的SDK,是一只飛動(dòng)的小蚊子。由于版本較老,現(xiàn)在網(wǎng)上已經(jīng)不太常見了。根據(jù)上面的研究可以斷定,能截取到這只小蚊子絕非易事,感興趣的朋友不妨試試!
References
Hardware Overlay http://www.fox-magic.com/sva_overlays.php
總結(jié)
以上是生活随笔為你收集整理的DirectX截图黑屏的解决办法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQLServer数据库文件组相关知识笔
- 下一篇: mysql connetor_pytho