Bishamon Personal コミュニティ

Bishamon Personal コミュニティ 掲示板(仮運営中)です。

Bishamon Personal コミュニティ » DirectX9 » BISHAMONエフェクトと元々描画していたモデルについて

BISHAMONエフェクトと元々描画していたモデルについて

Post Reply

Page: 1

Author Post
Member
Registered: Jun 2013
Posts: 18
【環境】
WindowsXP
VC++2008
---------------------
お世話になっております。
Melloと申します。

元々作っていたゲームにBISHAMONを実装しようとしています。
基礎的な内容で大変恐縮ですが、BISHAMONのエフェクトを1回でも描画すると、
元々描画していたDirectXのモデル(背景)が消えてしまいます。

レンダリングの設定?がおそらくBISHAMONのものに書き換わってしまっているのだと
思います。


Effect->Update();

if(Effect->IsExpired()) {
Effect->Reset();
}

Manager->Begin();          ←この2行の部分を1度でも実行すると、
Manager->DrawEffect(Effect);   ←DirectXで描画していたモデルが消えてしまいます
Manager->End();



元々のDirectXの描画(背景)を残したまま、エフェクトを表示する方法について何方か
ご教示お願いできないでしょうか。。
推測でも構いませんのでご意見お待ちしております。

どうかよろしくお願いいたします。
Administrator
Registered: Oct 2011
Posts: 206
Location: Tokyo
ご報告頂きありがとうございます。

BISHAMONでは、ブレンド周りの設定が変更されます。
エフェクトの描画前後にて、ブレンド周りの設定を保存・復帰するように試して頂けますでしょうか。

可能性としましては、減算でのブレンドを行っている場合、この設定が他の描画に影響し結果、色が黒(ゼロ)となり、見えなくなってているかもしれません。

何卒よろしくお願いいたします。
Member
Registered: Jun 2013
Posts: 18
ご返答ありがとうございます。大変助かります。

ブレンド周りの設定とは、以下のようなものでしょうか。


Effect->Update();

if(Effect->IsExpired()) {
Effect->Reset();
}

Manager->Begin();
Manager->DrawEffect(Effect); 
Manager->End();

//////////////ここから下の部分がブレンド周りの設定//////////////
pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
  pD3DDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE );
// アルファブレンディング
pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

// ライトの設定
D3DLIGHT9 m_light;
ZeroMemory( &m_light, sizeof(D3DLIGHT9) );
m_light.Type = D3DLIGHT_DIRECTIONAL;
m_light.Diffuse.r = 1.0f;
m_light.Diffuse.g = 1.0f;
m_light.Diffuse.b = 1.0f;
D3DXVECTOR3 mVecDir;
mVecDir = D3DXVECTOR3( 0.0f, 10.0f, 1.0f);
D3DXVec3Normalize( (D3DXVECTOR3*)&m_light.Direction, &mVecDir );
pD3DDevice->SetLight( 0, &m_light );
pD3DDevice->LightEnable( 0, TRUE );
pD3DDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
//////////////////////ブレンド周りの設定はここまで////////////////////////

pD3DDevice->BeginScene();
// モデルなどの描画関数
draw_Map();


このように再度ブレンドの設定をしてみましたが、状況は変わりませんでした。
もう少し色々弄ってみようと思いますが、現時点で何か言える事があれば、
何卒ご教示お願い致します。
Administrator
Registered: Oct 2011
Posts: 206
Location: Tokyo
設定的には問題ないように思います。

先に、
draw_Map();
を行ってから、
DrawEffect()
でも状況は変わりませんでしょうか?

事例としましては、今までありませんでしたので、原因がとても気になります。
Member
Registered: Jun 2013
Posts: 18
レスポンスありがとうございます。とても助かっています。
先にdraw_Map()を行い、DrawEffect()の実行もしてみましたが、
やはりモデルが真っ黒になってしまい、状況は変わりませんでした。
(一番最初の一瞬だけ想定したモデルが描写され、エフェクトの描画をしたら、
モデルが黒くなってしまいます)

自分のオリジナルのプログラムが悪いのかなと思いつつ、
『単純な人型モデルをXファイルで読み込んで表示するDirectXの入門サンプルプログラム』でも
試してみましたが、状況は変わりませんでした。
自分のやり方が根本的にどこか間違っているのだと思います。。。

参考までに上記のDirectX入門サンプルコードを記載します。
Window.cppにおかしい部分があればご教示お願い致します。

【Renderer.cpp】
LPDIRECT3DDEVICE9 m_pD3DDevice の初期化処理を担当


HRESULT Renderer::Initialize(HWND hWnd, BOOL isFullScreen, int clientWidth, int clientHeight)
{
D3DDISPLAYMODE d3ddm;

if((m_pD3D = ::Direct3DCreate9(D3D_SDK_VERSION)) == 0){
return E_FAIL;

if(FAILED(m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) {
return E_FAIL;
}

ZeroMemory(&m_D3DPP, sizeof(D3DPRESENT_PARAMETERS));
m_D3DPP.BackBufferCount = 1;
if(isFullScreen) {
m_D3DPP.Windowed = FALSE;
m_D3DPP.BackBufferWidth = clientWidth;
m_D3DPP.BackBufferHeight = clientHeight;
}
else {
m_D3DPP.Windowed = TRUE;
}
m_D3DPP.BackBufferFormat = d3ddm.Format;
m_D3DPP.SwapEffect = D3DSWAPEFFECT_DISCARD;
m_D3DPP.EnableAutoDepthStencil = TRUE;
m_D3DPP.AutoDepthStencilFormat = D3DFMT_D16;

if(FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&m_D3DPP, &m_pD3DDevice))) {
if(FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&m_D3DPP, &m_pD3DDevice))) {
if(FAILED(m_pD3D->CreateDevice( D3DADAPTER_DEFAULT,
D3DDEVTYPE_REF, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&m_D3DPP, &m_pD3DDevice))) {
return E_FAIL;
}
}
}
return S_OK;
}


【Scene.cpp】
Xファイルの読み込み、レンダリングステートパラメータの設定、ライトの設定 を担当
(コード割愛してすみません)

【window.cpp】
ウインドウの生成とメインループの処理を担当


///ここから上はウインドウの初期化設定///
//BISHAMON設定
BMManager *manager = new BMManager(renderer.GetDevice());
BMEffect *effect = manager->CreateEffect(EFFECT_NAME);

// レンダラーオブジェクト
Renderer renderer;

// シーンオブジェクト
Scene scene;

// シーンの生成
if(FAILED(scene.Create(renderer.GetDevice()))) {
return 0;
}

// メインループ
while(TRUE) {
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if(msg.message == WM_QUIT) {
break;
}
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else {
WINDOWPLACEMENT wndpl;
GetWindowPlacement(hWnd, &wndpl);
if((wndpl.showCmd != SW_HIDE) &&
(wndpl.showCmd != SW_MINIMIZE) &&
(wndpl.showCmd != SW_SHOWMINIMIZED) &&
(wndpl.showCmd != SW_SHOWMINNOACTIVE)) {


//エフェクト更新
effect->Update();
if(effect->IsExpired()) {
effect->Reset();
}
// renderer.Initialize(hWnd, isFullScreen, CLIENT_WIDTH, CLIENT_HEIGHT);
// scene.Create(renderer.GetDevice());

//////////////////////////////ここから描画処理//////////////////////////////
renderer.m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0x20, 0x20, 0x20, 0x00), 1, 0);
renderer.m_pD3DDevice->BeginScene();
scene.Draw(renderer.GetDevice()); //Xモデルの描画

//※※BISHAMONエフェクト描画処理※※//
//(ここを実行すると、モデルが黒くなります)
manager->Begin();
manager->DrawEffect(effect);
manager->End();
/////////////////////////////////////

// 両面描画モードの指定
renderer.m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

// Z比較を行なう
renderer.m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);

// ディザリングを行なう
renderer.m_pD3DDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE);

// ライトの設定
D3DLIGHT9 mLight;
ZeroMemory( &mLight, sizeof(D3DLIGHT9) );
mLight.Type = D3DLIGHT_DIRECTIONAL;
mLight.Diffuse.r = 1.0f;
mLight.Diffuse.g = 1.0f;
mLight.Diffuse.b = 1.0f;
D3DXVECTOR3 mVecDir;
mVecDir = D3DXVECTOR3( -0.5f, -0.5f, 1.0f);
D3DXVec3Normalize( (D3DXVECTOR3*)&mLight.Direction, &mVecDir );
renderer.m_pD3DDevice->SetLight( 0, &mLight );
renderer.m_pD3DDevice->LightEnable( 0, TRUE );
renderer.m_pD3DDevice->SetRenderState( D3DRS_LIGHTING, TRUE );

//画面に描画を反映
renderer.m_pD3DDevice->EndScene();
renderer.m_pD3DDevice->Present(0, 0, 0, 0);

//////////////////////////////ここまで描画処理//////////////////////////////
}
}
}

return (int) msg.wParam;
}



ちなみに、上記の


// renderer.Initialize(hWnd, isFullScreen, CLIENT_WIDTH, CLIENT_HEIGHT);
// scene.Create(renderer.GetDevice());


部分をコメントアウトし、LPDIRECT3DDEVICE9 m_pD3DDevice を再度初期化して
モデルを描写すると、今度はエフェクトが描画されず、モデルのみが正常に描画されます。
(この辺りが怪しいとは思っています。)

[お願い]
もし可能であれば、背景とエフェクトが正しく動作する単純かつ簡単なコード例を
書いて頂くことは出来ないでしょうか。

以下の、補足のDirectXのテストプログラムは読み解くには難解でしたので。。
(レベルが低くてすみません。)

[補足]
第3部 BISHAMONの導入と実践
⇒3-4:STGに導入してみる

上記のDirectXのテストプログラムにBISHAMONを導入してみましたが、これはちゃんと動作しています。
(背景、モデルはちゃんと表示され、攻撃がヒットした際はエフェクトが出ます)
そのためハードウェアに問題がある可能性は低そうです。
Administrator
Registered: Oct 2011
Posts: 206
Location: Tokyo
詳細な情報を頂き有難うございます。
改めて、BISHAMON内のソースコードを見直しました。

以下が、保存・復帰を行っているステータスです。

    SetRenderState(D3DRS_ALPHABLENDENABLE,
    SetRenderState(D3DRS_ALPHAFUNC,
    SetRenderState(D3DRS_ALPHAREF,
    SetRenderState(D3DRS_CULLMODE,
    SetRenderState(D3DRS_DESTBLEND,
    SetRenderState(D3DRS_SRCBLEND,
    SetRenderState(D3DRS_ZENABLE,
    SetRenderState(D3DRS_ZFUNC,
    SetRenderState(D3DRS_ZWRITEENABLE,
    SetRenderState(D3DRS_ALPHATESTENABLE,

下記が拡張などによって保存から漏れているステータスです。

    SetRenderState(D3DRS_ANTIALIASEDLINEENABLE,
    SetRenderState(D3DRS_FILLMODE,
    SetRenderState(D3DRS_LIGHTING,
    SetRenderState(D3DRS_MULTISAMPLEANTIALIAS,
    SetRenderState(D3DRS_MULTISAMPLEMASK,
    SetRenderState(D3DRS_STENCILENABLE,
    SetRenderState(D3DRS_STENCILFUNC,
    SetRenderState(D3DRS_STENCILMASK,
    SetRenderState(D3DRS_STENCILPASS,
    SetRenderState(D3DRS_STENCILREF,
    SetRenderState(D3DRS_STENCILZFAIL,

この辺り情報は早期に公開すべきであったことを反省しております。
申し訳ありませんでした。

上記のステートを保存・復帰を前後に設定しみて頂けますでしょうか?

また、もう1つ気づいたところがありました。
D3DRS_BLENDOP の設定は、BISHAMON内では設定しておりませんが、ライブラリーないでは、D3DBLENDOP_ADD であることを想定して作られております。
ADD以外の場合、描画後の結果が黒くなる原因が考えられます。

まだ未定ではありますが次期リリース時には上記漏れているステータスも保存・復帰に含めますよう修正いたします。
Member
Registered: Jun 2013
Posts: 18
返信が遅くなってしまい申し訳ございません。
admin様が記載してくださいました保存と復帰について、
以下のようにやってみましたが状況は変わりませんでした…。


// シーンの生成
if(FAILED(scene.Create(renderer.GetDevice()))) {
return 0;
}

    //保存用
DWORD render1 = 0;
DWORD render2 = 0;
DWORD render3 = 0;
DWORD render4 = 0;
DWORD render5 = 0;
DWORD render6 = 0;
DWORD render7 = 0;
DWORD render8 = 0;
DWORD render9 = 0;
DWORD render10 = 0;

DWORD render11 = 0;
DWORD render12 = 0;
DWORD render13 = 0;
DWORD render14 = 0;
DWORD render15 = 0;
DWORD render16 = 0;
DWORD render17 = 0;
DWORD render18 = 0;
DWORD render19 = 0;
DWORD render20 = 0;
DWORD render21 = 0;
DWORD render22 = 0;

//D3DRS_BLENDOPについて追記しました ※ただ、この部分をコメントアウトしても変わりません
renderer.m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
renderer.m_pD3DDevice->SetRenderState(D3DRS_BLENDOP,D3DBLENDOP_ADD);

//保存処理
renderer.m_pD3DDevice->GetRenderState(D3DRS_ALPHABLENDENABLE, &render1);
renderer.m_pD3DDevice->GetRenderState(D3DRS_ALPHAFUNC,&render2);
renderer.m_pD3DDevice->GetRenderState(D3DRS_ALPHAREF,&render3);
renderer.m_pD3DDevice->GetRenderState(D3DRS_CULLMODE,&render4);
renderer.m_pD3DDevice->GetRenderState(D3DRS_DESTBLEND,&render5);
renderer.m_pD3DDevice->GetRenderState(D3DRS_SRCBLEND,&render6);
renderer.m_pD3DDevice->GetRenderState(D3DRS_ZENABLE,&render7);
renderer.m_pD3DDevice->GetRenderState(D3DRS_ZFUNC,&render8);
renderer.m_pD3DDevice->GetRenderState(D3DRS_ZWRITEENABLE,&render9);
renderer.m_pD3DDevice->GetRenderState(D3DRS_ALPHATESTENABLE,&render10);

renderer.m_pD3DDevice->GetRenderState(D3DRS_ANTIALIASEDLINEENABLE, &render11);
renderer.m_pD3DDevice->GetRenderState(D3DRS_FILLMODE,&render12);
renderer.m_pD3DDevice->GetRenderState(D3DRS_LIGHTING,&render13);
renderer.m_pD3DDevice->GetRenderState(D3DRS_MULTISAMPLEANTIALIAS,&render14);
renderer.m_pD3DDevice->GetRenderState(D3DRS_MULTISAMPLEMASK,&render15);
renderer.m_pD3DDevice->GetRenderState(D3DRS_STENCILENABLE,&render16);
renderer.m_pD3DDevice->GetRenderState(D3DRS_STENCILFUNC,&render17);
renderer.m_pD3DDevice->GetRenderState(D3DRS_STENCILMASK,&render18);
renderer.m_pD3DDevice->GetRenderState(D3DRS_STENCILPASS,&render19);
renderer.m_pD3DDevice->GetRenderState(D3DRS_STENCILREF,&render20);
renderer.m_pD3DDevice->GetRenderState(D3DRS_STENCILZFAIL,&render21);
renderer.m_pD3DDevice->GetRenderState(D3DRS_BLENDOP, &render22);

// メインループ
while(TRUE) {
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if(msg.message == WM_QUIT) {
break;
}
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else {
WINDOWPLACEMENT wndpl;
GetWindowPlacement(hWnd, &wndpl);
if((wndpl.showCmd != SW_HIDE) &&
(wndpl.showCmd != SW_MINIMIZE) &&
(wndpl.showCmd != SW_SHOWMINIMIZED) &&
(wndpl.showCmd != SW_SHOWMINNOACTIVE)) {


//エフェクト更新
effect->Update();
if(effect->IsExpired()) {
effect->Reset();
}

//////////////////////////////ここから描画処理//////////////////////////////
renderer.m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,230,230), 1, 0);
renderer.m_pD3DDevice->BeginScene();

//※※BISHAMONエフェクト描画処理※※//
//(ここを実行すると、モデルが黒くなります)
manager->Begin();
manager->DrawEffect(effect);
manager->End();
/////////////////////////////////////
}

//復帰処理
renderer.m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, render1);
renderer.m_pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC,render2);
renderer.m_pD3DDevice->SetRenderState(D3DRS_ALPHAREF,render3); renderer.m_pD3DDevice->SetRenderState(D3DRS_CULLMODE,render4);
renderer.m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND,render5);
renderer.m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND,render6);
renderer.m_pD3DDevice->SetRenderState(D3DRS_ZENABLE,render7);
renderer.m_pD3DDevice->SetRenderState(D3DRS_ZFUNC,render8);
renderer.m_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE,render9);
renderer.m_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE,render10);
renderer.m_pD3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, render11);
renderer.m_pD3DDevice->SetRenderState(D3DRS_FILLMODE,render12);
renderer.m_pD3DDevice->SetRenderState(D3DRS_LIGHTING,render13);
renderer.m_pD3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS,render14); renderer.m_pD3DDevice->SetRenderState(D3DRS_MULTISAMPLEMASK,render15); renderer.m_pD3DDevice->SetRenderState(D3DRS_STENCILENABLE,render16);
renderer.m_pD3DDevice->SetRenderState(D3DRS_STENCILFUNC,render17);
renderer.m_pD3DDevice->SetRenderState(D3DRS_STENCILMASK,render18);
renderer.m_pD3DDevice->SetRenderState(D3DRS_STENCILPASS,render19);
renderer.m_pD3DDevice->SetRenderState(D3DRS_STENCILREF,render20);
renderer.m_pD3DDevice->SetRenderState(D3DRS_STENCILZFAIL,render21);
renderer.m_pD3DDevice->SetRenderState(D3DRS_BLENDOP, render22);

scene.Draw(renderer.GetDevice()); //Xモデルの描画

//画面に描画を反映
renderer.m_pD3DDevice->EndScene();
renderer.m_pD3DDevice->Present(0, 0, 0, 0);

//////////////////////////////ここまで描画処理//////////////////////////////



状況としては、エフェクトの描写をすると、

<現象1>モデルが黒くなる(背景色が緑等でもモデルは黒)
<現象2>モデルしか描写しない場合に比べ、エフェクト描写後は黒いモデルが小さく描写される
(現象1・現象2 共に、前回と同様の症状です)

上記のようになります。
<現象1>はともかく<現象2>は恐らくカメラの設定がエフェクトに引っ張られているのだと
推測します。
そのため、復帰処理が上手く出来ていないと考えます。
そもそも保存したレンダリングの設定群(render1~22)の設定値が間違っており、
復帰しても意味がないという可能性もあるかもしれません。
(またこれも憶測ですが、真っ黒ということは現象1はライトの処理が絡んでいるかもしれません)

まだあまりコードを弄れておらず、大変恐縮ですが、
今の段階で何か言える事がございましたら、ご教示お願いいたします。(推測でも構いません)
« Last edit by Mello on Wed Jun 19, 2013 2:34 am. »
Administrator
Registered: Oct 2011
Posts: 206
Location: Tokyo
//保存処理
renderer.m_pD3DDevice->GetRenderState(D3DRS_ALPHABLENDENABLE, &render1);
renderer.m_pD3DDevice->GetRenderState(D3DRS_ALPHAFUNC,&render2);
:
:

 //復帰処理
 renderer.m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, render1);
 renderer.m_pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC,render2);
:
:

につきまして、
  manager->Begin();
  manager->DrawEffect(effect);
  manager->End();
の直前、直後で設定するのがベストです。
また、ご提示頂いているコードを見る限り、この部分に関しては上記修正にて問題ないと思います。
上記修正でも変化がない場合は、更に別原因が考えられます。

 scene.Draw(renderer.GetDevice()); //Xモデルの描画

内にて、モデル表示に必要な
 ・シェーダー
 ・テクスチャー
   :
なども、モデルのDraw前に正しく設定されているか1つ1つ調べていく必要が御座います。
サンプルとしましては、
「第3部 BISHAMONの導入と実践」
のソースコードが一番よいサンプルコードになっていると思います。

同ケースの問題が弊社としましても、今後チュートリアルやサンプルを作る上でとても役立つと考えております。
次期リリース時のBMManager周りのコードもこの度のご報告を元に修正をしたいと思います。
Member
Registered: Jun 2013
Posts: 18
いつもありがとうございます。
返信して頂いた内容についてご教示いただきたく。
----
> //保存処理
> renderer.m_pD3DDevice->GetRenderState(D3DRS_ALPHABLENDENABLE, &render1);
> renderer.m_pD3DDevice->GetRenderState(D3DRS_ALPHAFUNC,&render2);
> :
> :
> と
>  //復帰処理
>  renderer.m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, render1);
>  renderer.m_pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC,render2);
>
> につきまして、
>   manager->Begin();
>   manager->DrawEffect(effect);
>   manager->End();
> の直前、直後で設定するのがベストです。

上記の内容は、以下のようにするのが良いということなのでしょうか。


//保存
renderer.m_pD3DDevice->GetRenderState(D3DRS_ALPHABLENDENABLE, &render1);
renderer.m_pD3DDevice->GetRenderState(D3DRS_ALPHAFUNC,&render2);
:
:
renderer.m_pD3DDevice->GetRenderState(D3DRS_STENCILZFAIL,&render21);

//復帰
renderer.m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, render1);
renderer.m_pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC,render2);
:
:
renderer.m_pD3DDevice->SetRenderState(D3DRS_STENCILZFAIL,render21);

  manager->Begin();
  manager->DrawEffect(effect);
  manager->End();

//保存
renderer.m_pD3DDevice->GetRenderState(D3DRS_ALPHABLENDENABLE, &render1);
renderer.m_pD3DDevice->GetRenderState(D3DRS_ALPHAFUNC,&render2);
:
:
renderer.m_pD3DDevice->GetRenderState(D3DRS_STENCILZFAIL,&render21);

//復帰
renderer.m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, render1);
renderer.m_pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC,render2);
:
:
renderer.m_pD3DDevice->SetRenderState(D3DRS_STENCILZFAIL,render21);



それとも、保存と復帰処理に関しては「#7 Wed Jun 19, 2013 2:20 am」に投稿したコードで
問題はなさそうということでしょうか。
(読解力が足りなく申し訳ございません。。)

とりあえずもう少し「第3部 BISHAMONの導入と実践」の
サンプルコードと比較し、一つずつ調べてみようと思います。

役に立てているならば光栄です。
自分のようにDirectX9とBishamonについての知識が浅い者でも
エフェクトを自由に使えるようになれたらすばらしいことだと思います。
« Last edit by Mello on Fri Jun 21, 2013 12:37 am. »
Member
Registered: Jun 2013
Posts: 18
間が開いてしまいましたが、未だにエフェクト描画中にモデルが黒くなってしまう事象が
解決しておらず大変困っています。。

自分のコードが独特なことが原因である可能性も考え、
まったく別のコードに組み込んでみましたが
やはり結果は変わりませんでした。

以下、オープンソースの簡単なサンプルコードにBISHAMONを組み込んだものです。
プロジェクトを新規につくり、以下のコードをコピー&ペーストすれば実行可能です。


// 2D板ポリゴン描画サンプルプログラム

#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "d3d9.lib")

#include <windows.h>
#include <tchar.h>
#include <d3d9.h>
#include <math.h>

#include "BMSDK/BMManager.h"
#include "BMSDK/BMEffect.h"
#include "BMSDK/BMBinary.h"

static const wchar_t *EFFECT_NAME = L"BMvol2_all";


struct CUSTOMVERTEX{
float x, y, z; // 頂点座標
float rhw; // 除算数
DWORD dwColor; // 頂点の色
float u, v; // テクスチャ座標
};

#define FVF_CUSTOM ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1 )

TCHAR gName[100] = _T("2D板ポリゴン描画サンプルプログラム");



// 虹色関数
DWORD RainbowRGB(DWORD num){
#define RAINBOWVAL(C) ((DWORD)((C>=1024) ?0 : (C<256) ? C : (C>768) ? (1023-C) : 255))
DWORD R = num%1536;
DWORD G = ((num%1536)+1024)%1536;
DWORD B = ((num%1536)+ 512)%1536;
return 0xff000000 + (RAINBOWVAL(R)<<16) + (RAINBOWVAL(G)<<8) + RAINBOWVAL(B);
}


// 頂点回転関数
void SetPos(float Cx, float Cy, float r, float ratio, float Ix, float Iy, float *Ox, float *Oy){
*Ox = Cx + ratio*(Ix*cos(r) - Iy*sin(r));
*Oy = Cy + ratio*(Ix*sin(r) + Iy*cos(r));
}


// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT mes, WPARAM wParam, LPARAM lParam){
if(mes == WM_DESTROY || mes == WM_CLOSE ) {PostQuitMessage(0); return 0;}
return DefWindowProc(hWnd, mes, wParam, lParam);
}


int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
// アプリケーションの初期化
MSG msg; HWND hWnd;
WNDCLASSEX wcex ={sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInstance, NULL, NULL,
(HBRUSH)(COLOR_WINDOW+1), NULL, (TCHAR*)gName, NULL};
if(!RegisterClassEx(&wcex))
return 0;

if(!(hWnd = CreateWindow(gName, gName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL)))
return 0;

// Direct3Dの初期化
LPDIRECT3D9 g_pD3D;
LPDIRECT3DDEVICE9 g_pD3DDev;
if( !(g_pD3D = Direct3DCreate9( D3D_SDK_VERSION )) ) return 0;

D3DPRESENT_PARAMETERS d3dpp = {0,0,D3DFMT_UNKNOWN,0,D3DMULTISAMPLE_NONE,0,
D3DSWAPEFFECT_DISCARD,NULL,TRUE,0,D3DFMT_UNKNOWN,0,0};

if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDev ) ) )
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDev ) ) )
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDev ) ) )
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDev ) ) )
{
g_pD3D->Release();
return 0;
}

ShowWindow(hWnd, nCmdShow);


// 頂点(初期位置)の設定
float Ratio = 1.0f;
float width = 240.0f * Ratio;
float height = 180.0f * Ratio;
CUSTOMVERTEX v[4]=
{
{ width/2, -height/2, 0.0f, 1.0f, 0x00000000, 0.0f, 0.0f},
{ width/2, height/2, 0.0f, 1.0f, 0x000000ff, 0.0f, 1.0f},
{-width/2, -height/2, 0.0f, 1.0f, 0x00000300, 1.0f, 0.0f},
{-width/2, height/2, 0.0f, 1.0f, 0x00000400, 1.0f, 1.0f}
};

// 頂点バッファの作成
IDirect3DVertexBuffer9* pVertex;
if(FAILED(g_pD3DDev->CreateVertexBuffer( sizeof(CUSTOMVERTEX)*4, D3DUSAGE_WRITEONLY, FVF_CUSTOM, D3DPOOL_MANAGED, &pVertex, NULL))){
g_pD3DDev->Release(); g_pD3D->Release();
return 0;
}

float Cx, Cy, t=0;
DWORD Rainbow = 0;
CUSTOMVERTEX CurV[4];
memcpy(CurV, v, sizeof(CUSTOMVERTEX)*4);


//BISHAMON設定
BMManager *manager = new BMManager(g_pD3DDev);
BMEffect *effect = manager->CreateEffect(EFFECT_NAME);
int testcount = 0;


// メッセージ ループ
int i;
do{
Sleep(1);
if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ){ DispatchMessage(&msg);}





// 頂点位置と色の計算(適当な計算です)
// 頂点情報CurVを確定するのが目的
t += 0.03146f/2;
Ratio = 1.5f+cos(t);
SetPos(320, 240, t*1.23, Ratio, 64, 64, &Cx, &Cy);
for(i=0; i<4; i++){
SetPos(Cx, Cy, t, Ratio, v[i].x, v[i].y, &CurV[i].x, &CurV[i].y);
CurV[i].dwColor = RainbowRGB(v[i].dwColor+(Rainbow++)*(i+1));
}

// 頂点バッファに頂点を書き込みできた時にだけ描画
void *pData;
if(SUCCEEDED(pVertex->Lock(0, sizeof(CUSTOMVERTEX)*4, (void**)&pData, 0))){
memcpy(pData, CurV, sizeof(CUSTOMVERTEX)*4);
pVertex->Unlock();

////
//エフェクト更新
effect->Update();
if(effect->IsExpired()) {
effect->Reset();
}
////

// Direct3Dの処理
g_pD3DDev->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
g_pD3DDev->BeginScene();


// 描画
g_pD3DDev->SetStreamSource(0, pVertex, 0, sizeof(CUSTOMVERTEX));
g_pD3DDev->SetFVF(FVF_CUSTOM);
g_pD3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);


//※※BISHAMONエフェクト描画処理※※//
//(ここを実行すると、モデルが黒くなります)
manager->Begin();
manager->DrawEffect(effect);
manager->End();

g_pD3DDev->EndScene();
g_pD3DDev->Present( NULL, NULL, NULL, NULL );
}
}while(msg.message != WM_QUIT);

pVertex->Release();
g_pD3DDev->Release();
g_pD3D->Release();

return 0;
}


上記のコードにおいても、BISHAMONエフェクトの描画中は、
長方形の部分だけ、真っ黒に描画されてしまいます。

【お願い】
大変お手数をおかけして申し訳ないのですが、
上記コードを修正したコードを全文で載せていただけないでしょうか。

(「この部分をこうやって直すと良いです」という形式ですと、
おそらくこれまでの様に解決できない可能性が考えられるため)

【考え】
ちなみに原因となっている部分は、やはり以下の部分で、
エフェクトの描画を始めると長方形が真っ黒になります。

manager->Begin();
manager->DrawEffect(effect);
manager->End();



また、上記部分に該当するXACTGame(BISHAMON版)に
導入されているソースでは、以下のようになっており、カメラの制御等はしていますが、
ご教示いただいております「SetRenderState関連のコード(保存と復帰関連)」
は元々のコードにあったもの以外、プロジェクト全体で検索しても
付け足されていないように見えます。
サンプルでは別の部分で保存と復帰をしているということでしょうか。


//game.cpp内
g_BMManager.DrawAllEffect(g_Camera.GetViewMatrix(), g_Camera.GetProjMatrix());

//DrawAllEffect関数本体
void BMManager::DrawAllEffect(const D3DXMATRIX* viewMatrix, const D3DXMATRIX* projMatrix)
{
if (s_instance == NULL){
// 既に破棄されているとき
return;
}

// Camera 情報更新
ml::matrix44 view(
viewMatrix->_11, viewMatrix->_12, viewMatrix->_13, viewMatrix->_14,
viewMatrix->_21, viewMatrix->_22, viewMatrix->_23, viewMatrix->_24,
viewMatrix->_31, viewMatrix->_32, viewMatrix->_33, viewMatrix->_34,
viewMatrix->_41, viewMatrix->_42, viewMatrix->_43, viewMatrix->_44);
ml::matrix44 proj(
projMatrix->_11, projMatrix->_12, projMatrix->_13, projMatrix->_14,
projMatrix->_21, projMatrix->_22, projMatrix->_23, projMatrix->_24,
projMatrix->_31, projMatrix->_32, projMatrix->_33, projMatrix->_34,
projMatrix->_41, projMatrix->_42, projMatrix->_43, projMatrix->_44);

SetView(view);
SetProjection(proj);

// Effect 描画処理
Begin();
BMEffectListType::iterator ite = listEffect.begin();
BMEffectListType::iterator end = listEffect.end();
for ( ; ite != end ; ++ite ){
BMEffect* effect = reinterpret_cast<BMEffect*>(*ite);
if ( effect != NULL ){
DrawEffect(effect);
}
}
End();
}


[補足]
※元のサンプルコードはこちらのサイト様のものです
http://marupeke296.com/index.html
DirectX9技術編-> その2 座標変換済み頂点で2D板ポリゴンを描画 サンプルプログラム
Administrator
Registered: Oct 2011
Posts: 206
Location: Tokyo
サンプルを頂きありがとうございます。

ざっと拝見しますと描画設定がデフォルトままであったりなど気になるところがありました。

BISHAMON 内の不具合の可能性も十分ありますので、弊社内でも調査させて頂き纏めてお答えしたいと思います。
現在、業務が込み合っておりますため、しばらくお時間を頂いても宜しいでしょうか?

何卒よろしくお願いいたします。
Member
Registered: Jun 2013
Posts: 18
業務がお忙しい中まことに申し訳ございません。回答お待ちしております。
もう此処以外に頼れる場所が無いため、皆様だけが頼りです。
(エフェクト作業でずっと詰まっているため、別途サポート費用が必要でもお願いしたいレベルです。)

御社の環境では上記のサンプルは正常に動いたのか気になるところですが、
ひとまず今週末まで正座でお待ちしております。
(正常に動いている場合は、こちらの環境特有の問題が考えられるため)
おそらくBISHAMONのバグというよりも私が凡ミスをしているだけだと考えてはいますが…。

※御社のお盆休みにも入ってしまうと思うので、
 週末時点で進捗状況や回答の目処感等、
 分かればで良いので可能であればコメントいただけると幸いです。
« Last edit by Mello on Tue Aug 06, 2013 11:25 pm. »
Administrator
Registered: Oct 2011
Posts: 206
Location: Tokyo
長らくお待たせいたしました。
下記コードによって回避できることがわかりましたのでご報告致します。


//※※BISHAMONエフェクト描画処理※※//
//(ここを実行すると、モデルが黒くなります)
manager->Begin();
manager->DrawEffect(effect);
manager->End();

//------ 追加コード ------
g_pD3DDev->SetVertexShader(NULL);
g_pD3DDev->SetPixelShader(NULL);
g_pD3DDev->SetTexture(0,NULL);
g_pD3DDev->SetTexture(1,NULL);
g_pD3DDev->SetTexture(2,NULL);
//------ 追加コード ------

g_pD3DDev->EndScene();
g_pD3DDev->Present( NULL, NULL, NULL, NULL );



シェーダー、およびテクスチャーの設定を解除することで回避出来ました。
こちらの修正をEnd() 後に設定する必要がないよう、DX9版SDKのソースコードにも反映させて頂きました。
次期バージョンアップにて、上記の追加コードがなくても良いようにしました。

こちらで試して頂けますでしょうか。
この度はいろいろありがとうございました。
« Last edit by admin on Fri Aug 09, 2013 9:30 pm. »
Member
Registered: Jun 2013
Posts: 18
上記コードを追加したことによって想定した描画処理になりました。
本当にありがとうございました!
固定機能パイプラインとの共存についてというトピックに記載がありますね。。
ちゃんと読み込めて折らず申し訳ございません。

別のテストプログラムでも今のところ問題ありません。これから本番コードにも入れてみようと思います。
また何かあれば質問をしてしまうかもしれませんが、その時はよろしくお願いいたします。
« Last edit by Mello on Sat Aug 10, 2013 10:08 am. »

Post Reply

Page: 1

Bishamon Personal コミュニティ » DirectX9 » BISHAMONエフェクトと元々描画していたモデルについて

Bishamon Personal コミュニティ is powered by UseBB 1 Forum Software