Re: GraphFilterが効かない ( No.1 ) |
- 名前:管理人 日時:2017/05/26 00:53
DXライブラリのプログラマブルシェーダー機能ではなく IDirect3DDevice9 のインターフェースを
直接使用してシェーダー処理を行っているのでしょうか?
GraphFilter で何をしているかといいますと、色々な処理を行っていますので一言で申し上げるのは難しいです
( GraphFilter と GraphFilterBlt との違いは、フィルターの結果をフィルター処理に使用した画像に書き戻すかどうかです )
ダウンロードページからDXライブラリのソースをダウンロードできますので、その中の
DxGraphicsFilter.cpp, DxGraphicsFilter.h, Windows\DxGraphicsFilterD3D9.cpp, Windows\DxGraphicsFilterD3D9.h,
Windows\DxGraphicsFilterD3D11.cpp, Windows\DxGraphicsFilterD3D11.h で GraphFilter の処理を行っていますので、
よろしければご覧になってみてください m(_ _)m
|
Re: GraphFilterが効かない ( No.2 ) |
- 名前:N 日時:2017/05/26 23:23
詳しく調べてみたところ、小さなソースコードで現象を確認しました。
どうやら、SetUsePlatformTextureFormat関数を用いて指定したフォーマットで画像を作成していたのが原因だったようです。
バグか仕様かは存じ上げませんが、ここに報告させていただきます。
int screen, gHandle;
//640*480のウィンドウモードで起動
ChangeWindowMode(1);
SetGraphMode(640, 480, 32);
//DirectX9に制限
SetUseDirect3DVersion(DX.DX_DIRECT3D_9EX);
//ライブラリ初期化
if (DxLib_Init() == -1) return;
//画像を読み込み
gHandle = DX.LoadGraph("graph.bmp");
//描画対象スクリーンをA32B32G32R32Fで作成
SetUsePlatformTextureFormat(22);
screen = MakeScreen(640, 480);
SetDrawScreen(screen);
DrawGraph(0, 0, gHandle, 0);
//フィルターを掛ける
GraphFilter(screen, DX_GRAPH_FILTER_GAUSS, 16, 1400);
//結果を画面に表示
SetDrawScreen(DX_SCREEN_BACK);
ClearDrawScreen();
DrawGraph(0, 0, screen, 0);
ScreenFlip();
WaitKey();
//終了
DxLib_End();
> DXライブラリのプログラマブルシェーダー機能ではなく IDirect3DDevice9 のインターフェースを
> 直接使用してシェーダー処理を行っているのでしょうか?
いえ、そのようなことはありません。(というかDirectXを扱う勇気がないゆえにDXライブラリを使わせていただいている次第です)
|
Re: GraphFilterが効かない ( No.3 ) |
- 名前:管理人 日時:2017/05/27 23:19
載せていただいたプログラムは私の環境では正常に動作しました
( ガウスフィルタが適用された画像が画面に表示されました )
原因はわかりませんが、仰るとおり SetUsePlatformTextureFormat が関係しているような気がします
SetUsePlatformTextureFormat( 22 ); の代わりに
SetDrawValidFloatTypeGraphCreateFlag( TRUE ) ;
SetCreateGraphChannelBitDepth( 32 ) ;
SetCreateDrawValidGraphChannelNum( 4 ) ;
を記述した場合でも正常に動作しないでしょうか?
あと、よろしければお使いのPCに搭載されているグラフィックスデバイスを教えてください m(_ _)m
( 私のPCには GeForce GTX 660 Ti が搭載されています )
> いえ、そのようなことはありません。(というかDirectXを扱う勇気がないゆえにDXライブラリを使わせていただいている次第です)
承知しました
|
Re: GraphFilterが効かない ( No.4 ) |
- 名前:N 日時:2017/05/28 13:05
そちらの手元では現象が確認できないのですか......
一応、前回載せたプログラムについての補足をしておきますと、
フォーマット指定 → スクリーン作成 → フィルター
の順では、動作しませんでしたが、
スクリーン作成 → フォーマット指定 → フィルター
の順では動作しましたので、フィルター処理時に適用されているフォーマットが影響しているということではなさそうです。
>SetUsePlatformTextureFormat( 22 ); の代わりに
>
> SetDrawValidFloatTypeGraphCreateFlag( TRUE ) ;
> SetCreateGraphChannelBitDepth( 32 ) ;
> SetCreateDrawValidGraphChannelNum( 4 ) ;
>
>を記述した場合でも正常に動作しないでしょうか?
そちらの場合は問題なく動作しておりますゆえ、今はそれで代用しております。
今のところ、A2B10G10R10のようなフォーマットを使う予定はないので、今のプロジェクトは問題なく進められると思います。
>あと、よろしければお使いのPCに搭載されているグラフィックスデバイスを教えてください m(_ _)m
>( 私のPCには GeForce GTX 660 Ti が搭載されています )
CPU内臓の、Intel HD Graphicsのみです。CPUは第六世代のCOREi5です
|
Re: GraphFilterが効かない ( No.5 ) |
- 名前:管理人 日時:2017/05/28 20:21
> 一応、前回載せたプログラムについての補足をしておきますと、
> フォーマット指定 → スクリーン作成 → フィルター
> の順では、動作しませんでしたが、
> スクリーン作成 → フォーマット指定 → フィルター
> の順では動作しましたので、フィルター処理時に適用されているフォーマットが影響しているということではなさそうです。
フォーマット指定はスクリーン作成前に行うことで効果が発揮されますので、後者の場合は恐らく
スクリーンはデフォルトの ARBG各8bit整数型 の 32bit フォーマットになっていると思います
> そちらの場合は問題なく動作しておりますゆえ、今はそれで代用しております。
> 今のところ、A2B10G10R10のようなフォーマットを使う予定はないので、今のプロジェクトは問題なく進められると思います。
SetDrawValidFloatTypeGraphCreateFlag( TRUE ) ; + SetCreateGraphChannelBitDepth( 32 ) ; +
SetCreateDrawValidGraphChannelNum( 4 ) ; の場合は、実際に指定された精度のテクスチャが使用できない場合は
より精度の低いフォーマットでテクスチャが作成されますので、ARGB各32bit浮動小数点数型 のテクスチャが
作成されていない可能性があります
A32B32G32R32F の精度が必要な処理をされている場合は不具合が発生する可能性がありますが、
問題はありませんでしょうか?
> CPU内臓の、Intel HD Graphicsのみです。CPUは第六世代のCOREi5です
CPUは第六世代のCOREi5の GPU は Intel HD Graphics 530 辺りの DirectX12 にも対応しているGPUなので、
A32B32G32R32F に対応している筈ですね…
DXライブラリを使用したプログラムを実行した際に作成される Log.txt の中に、以下のような
『使用するテクスチャのフォーマット』の出力があるのですが、
1239: 描画用 ABGR 浮動小数点 32 ビット型カラーフォーマットは D3DFMT_A32B32G32R32F です
ARGB 各32bit 浮動小数点数型のテクスチャに対応している場合は上記のように D3DFMT_A32B32G32R32F と表示されます
よろしければ Nさんの環境で実行した場合も D3DFMT_A32B32G32R32F となっているかどうかご確認いただけないでしょうか
あと、正常に動作しない原因がDXライブラリのバグである場合は最新バージョンのDXライブラリでは
直っている可能性もありますので、もし最新バージョンのDXライブラリをお使いではありませんでしたら
こちらの暫定最新版をお試しください m(_ _)m
https://dxlib.xsrv.jp/temp/DxLibVCTest.exe // Windows版 VisualC++ 用
https://dxlib.xsrv.jp/temp/DxLibBCCTest.exe // Windows版 BorlandC++ 用
https://dxlib.xsrv.jp/temp/DxLibBCC2Test.exe // Windows版 C++ Builder 10.1 Berlin 用
https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.exe // Windows版 MinGW 用
https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用
https://dxlib.xsrv.jp/temp/DxLibMakeTest.exe // ソース
(中身を既存のライブラリのファイルに上書きして、BCCをお使いの
場合は『再構築』を、VCをお使いの場合は『リビルド』をして下さい)
 |
Re: GraphFilterが効かない ( No.6 ) |
- 名前:N 日時:2017/05/29 04:17
> フォーマット指定はスクリーン作成前に行うことで効果が発揮されますので、後者の場合は恐らく
> スクリーンはデフォルトの ARBG各8bit整数型 の 32bit フォーマットになっていると思います
はい、存じております。
GraphFilterの内部で指定したフォーマットが影響を及ぼしているのではないかという推測からテストしたのですが、はずれだったようでした
最新版に置き換えて、改めてテストして参りました。
> ARGB 各32bit 浮動小数点数型のテクスチャに対応している場合は上記のように D3DFMT_A32B32G32R32F と表示されます
> よろしければ Nさんの環境で実行した場合も D3DFMT_A32B32G32R32F となっているかどうかご確認いただけないでしょうか
以下の出力がありましたになっていました
1417: ABGR 浮動小数点 32 ビット型カラーフォーマットは D3DFMT_A32B32G32R32F です
問題なさそうですよね。。。
また、GraphFilterBltについても改めて、先のプログラムの描画部分を以下のようにして試してみたところ、正常にぼかされた画像になりました。
GraphFilterと〜〜Bltに違いが生まれるということは、ハードの性能の問題ではなく、内部の実装に原因があるのではないでしょうか。
(バグの疑いをかけているようで申し訳ございません)
//描画対象スクリーンをA32B32G32R32Fで作成
SetUsePlatformTextureFormat(22);
screen = MakeScreen(640, 480, 1);
screen2 = MakeScreen(640, 480, 1);
SetDrawScreen(screen);
DrawGraph(0, 0, gHandle, 0);
//フィルターを掛ける
GraphFilterBlt(screen, screen2, DX_GRAPH_FILTER_GAUSS, 16, 1400);
ソースコードを追えていないので、あくまで私の推測なのですが、
〜Bltではライブラリの外で描画先スクリーンを作りますけれど、GraphFilterでは内部で結果を描画するためのスクリーンを用意しているのではありませんか?
フォーマットを直接指定したスクリーンハンドルを渡したことでその部分が正常に動作しなくなっているのではないか、と思ったのですが、、、
これまた推測なのですが、
もしGraphBlend関数が私の推測しているような実装方法なら、入力されたスクリーンと出力用スクリーンのフォーマットを揃える必要があると思いますが、
SetUsePlatformTextureFormatを使ったスクリーンだと(ハードウェアによっては)正常にフォーマットを復元できない、とか、、、
 |
Re: GraphFilterが効かない ( No.7 ) |
- 名前:管理人 日時:2017/05/30 01:56
> GraphFilterの内部で指定したフォーマットが影響を及ぼしているのではないかという推測からテストしたのですが、はずれだったようでした
はい、GraphFilter の内部には SetUsePlatformTextureFormat などの設定は影響を与えません
> 以下の出力がありましたになっていました
> 1417: ABGR 浮動小数点 32 ビット型カラーフォーマットは D3DFMT_A32B32G32R32F です
> 問題なさそうですよね。。。
ご確認いただきありがとうございます
確かに対応していますね…
> また、GraphFilterBltについても改めて、先のプログラムの描画部分を以下のようにして試してみたところ、正常にぼかされた画像になりました。
> GraphFilterと〜〜Bltに違いが生まれるということは、ハードの性能の問題ではなく、内部の実装に原因があるのではないでしょうか。
> (バグの疑いをかけているようで申し訳ございません)
> ソースコードを追えていないので、あくまで私の推測なのですが、
> 〜Bltではライブラリの外で描画先スクリーンを作りますけれど、GraphFilterでは内部で結果を描画するためのスクリーンを用意しているのではありませんか?
> フォーマットを直接指定したスクリーンハンドルを渡したことでその部分が正常に動作しなくなっているのではないか、と思ったのですが、、、
> これまた推測なのですが、
> もしGraphBlend関数が私の推測しているような実装方法なら、入力されたスクリーンと出力用スクリーンのフォーマットを揃える必要があると思いますが、
> SetUsePlatformTextureFormatを使ったスクリーンだと(ハードウェアによっては)正常にフォーマットを復元できない、とか、、、
原因を調べたところ概ねNさんのご推測の通りでした
GraphFilter 内部で用意している作業用スクリーンを作成する際に、GraphFilter に渡された画像が浮動小数点型かどうかを
判定しているのですが、SetUsePlatformTextureFormat で A32B32G32R32F が指定されていた場合は整数型と判定されてしまっていました
GeForce GTX 660 Ti では問題なく動作して、Intel HD Graphics では正常に動作しなかったのは、
描画結果を GraphFilter に渡された画像に転送する際に Direct3D 9 の StretchRect という API を使用するのですが、
フォーマットが一致している場合はほぼ間違いなく転送が成功するのですが、フォーマットが一致していない場合は
転送が成功するかどうかはグラフィックスデバイスとドライバ次第という代物なので、整数型テクスチャから浮動小数点型テクスチャへの
StretchRect による転送に GeForce GTX 660 Ti は対応していて、Intel HD Graphics は対応していなかった、ということなのだと思います
と、私も推測を述べてしまいましたが、それはこちらの修正版が Nさんの環境で正常に動作した場合となります
お手数で申し訳ありませんが、よろしければこちらの修正版をお試しになってみてください m(_ _;m
https://dxlib.xsrv.jp/temp/DxLibVCTest.exe // Windows版 VisualC++ 用
https://dxlib.xsrv.jp/temp/DxLibBCCTest.exe // Windows版 BorlandC++ 用
https://dxlib.xsrv.jp/temp/DxLibBCC2Test.exe // Windows版 C++ Builder 10.1 Berlin 用
https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.exe // Windows版 MinGW 用
https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用
https://dxlib.xsrv.jp/temp/DxLibMakeTest.exe // ソース
(中身を既存のライブラリのファイルに上書きして、BCCをお使いの
場合は『再構築』を、VCをお使いの場合は『リビルド』をして下さい)
 |
Re: GraphFilterが効かない ( No.8 ) |
- 名前:N 日時:2017/06/03 22:18
うーん、置き換えて試してみましたが、まだ効果が現れません。。
|
Re: GraphFilterが効かない ( No.9 ) |
- 名前:管理人 日時:2017/06/04 18:38
|
Re: GraphFilterが効かない ( No.10 ) |
- 名前:N(解決) 日時:2017/06/04 23:41
出来ました! 丁寧な対応ありがとうございました
|