EffekseerとDXライブラリの連携について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
顔芸

EffekseerとDXライブラリの連携について

#1

投稿記事 by 顔芸 » 11年前

こんにちは.
私は現在,c++用のゲームライブラリであるDXライブラリを用いて3Dシューティングを作っています.

作成中のプロジェクトにエフェクト作成支援ツールEffekseerの組み込み用ランタイムを導入したのですが,
DXライブラリ側の3Dモデルの表示とEffekseer側のエフェクトの表示がうまく両立できず困っています.

DXライブラリ側の3Dモデルの表示とEffekseer側のエフェクトの表示について,
どちらか一方のみ描画する場合には,それぞれの描画に成功します.
しかし,これらを同時に描画しようとすると,画面が真っ暗になったりEffekseer側のエフェクトが
表示されなかったりとうまくいきません.やっと同時に表示されたと思ったら,今度は添付画像のように
DXライブラリ側の3Dモデルの表示がめちゃくちゃになってしまいました.

画像

DXライブラリ側とEffekseer側のレンダリングの設定が競合していることは間違いなさそうなのですが,
どう解消したらいいのかさっぱりわかりません.

疑わしい箇所として,プログラムのメインループのソースコードを以下に示します.

コード:

while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
    ClearDrawScreen();

	// ゲームの進行
	// (エフェクトの再生,カメラの姿勢の更新処理含む)
	game.calc();

	// DXライブラリ側のカメラ行列・射影行列と
	// Effekseer側のカメラ行列・射影行列の同期
	cyncCameraMatrix();

	// 頂点バッファに溜まった頂点データを吐き出す
	RenderVertex();

	// エフェクトの更新処理
	manager->Update();
		
	// エフェクトの描画開始処理
	renderer->BeginRendering();

	// DXライブラリ側のモデル表示
	// (MV1DrawModel関数を使用)
	game.draw();

	// Effekseer側のエフェクト表示
	manager->Draw();

	// エフェクトの描画終了処理
	renderer->EndRendering();

	// DXライブラリの設定を戻す
	RefreshDxLibDirect3DSetting();
		
    ScreenFlip();
}
また,DXライブラリ側とEffekseer側の初期設定は,それぞれ以下の関数をメインループ突入前に
一度だけ呼び出すことで行っています.

コード:

void initDxLib()
{
	// 画面モード変更時のモデルハンドルの無効化を防止
	SetChangeScreenModeGraphicsSystemResetFlag(FALSE);

	// Zバッファを使用
	SetUseZBuffer3D(TRUE);
	SetWriteZBuffer3D(TRUE);

	// 裏画面を使用
	SetDrawScreen(DX_SCREEN_BACK);

	// カメラのNear/Farクリップを設定
	SetCameraNearFar(50.0f, 1000000.0f);

	// マウスカーソルを非表示に設定
	SetMouseDispFlag(FALSE);

	// マウスカーソルのウィンドウ外への移動を禁止
	SetValidMousePointerWindowOutClientAreaMoveFlag(FALSE);
}

void initEffekseer()
{
	// 描画用インスタンスの生成
	const LPDIRECT3DDEVICE9 device = (LPDIRECT3DDEVICE9)GetUseDirect3DDevice9();
	const int MAX_INSTANCE_NUM = 2000;

	renderer = EfkRenderer::Create(device, MAX_INSTANCE_NUM);

	// エフェクト管理用インスタンスの生成
	manager = EfkManager::Create(MAX_INSTANCE_NUM);

	// 描画用インスタンスから描画機能を設定
	manager->SetSpriteRenderer(renderer->CreateSpriteRenderer());
	manager->SetRibbonRenderer(renderer->CreateRibbonRenderer());
	manager->SetRingRenderer(renderer->CreateRingRenderer());
	manager->SetModelRenderer(renderer->CreateModelRenderer());
	manager->SetTrackRenderer(renderer->CreateTrackRenderer());

	// 描画用インスタンスからテクスチャの読込機能を設定
	// 独自拡張可能、現在はファイルから読み込んでいる。
	manager->SetTextureLoader(renderer->CreateTextureLoader());
	manager->SetModelLoader(renderer->CreateModelLoader());

	// DxLibに合わせて左手座標系に変更
	manager->SetCoordinateSystem(Effekseer::COORDINATE_SYSTEM_LH);

	// 何でもいいから画像読込
	int grHandle = LoadGraph("effect\\effect\\pre.jpg");
	
	// 何でもいいのでTransFragを有効にして画像を描画する。
	// こうして描画した後でないと、Effekseerは描画できない。
	DrawGraph(0, 0, grHandle, TRUE);
}
DXライブラリ側の3DモデルとEffekseer側のエフェクトの表示を両立させる方法に関して,
何かお気付きの点がございましたら,アドバイスよろしくお願い致しますm(_ _)m

開発環境等:
Microsoft Visual C++ 2010 Express
DXライブラリVer 3.10e
Effekseer0.610

参考サイト:
DXライブラリ公式 http://homepage2.nifty.com/natupaji/DxLib/
Effekseer公式 https://sites.google.com/site/effekseer/

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: EffekseerとDXライブラリの連携について

#2

投稿記事 by softya(ソフト屋) » 11年前

過去ログにDXライブラリとEffekseerの組み合わせは何度か出ていますが検索されましたか? 参考になると思いますが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

顔芸

Re: EffekseerとDXライブラリの連携について

#3

投稿記事 by 顔芸 » 11年前

ご回答ありがとうございます.

はい,たしかに過去ログでEffekseerに関する質問があったため参考にさせていただきました.
しかしどのトピックについても,話題にしている問題が今回の質問の趣旨とは若干異なっており,
解決策の発見に関して直接の助けにはなりませんでした.

web全体で見てもEffekseerとDXライブラリの連携に関する技術的な情報は比較的少なく,
「effekseer dxlib」と検索してもあまり具体的な解説ページなどは探し当てられませんでした.
完成したゲームの動画などは見られるのですが・・・

困りました・・(´・_・)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: EffekseerとDXライブラリの連携について

#4

投稿記事 by softya(ソフト屋) » 11年前

レンダーステート的に不安なので、
// DXライブラリ側のモデル表示
// (MV1DrawModel関数を使用)
game.draw();
をもっと前にしませんか?
game.calc();直後とか。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

顔芸

Re: EffekseerとDXライブラリの連携について

#5

投稿記事 by 顔芸 » 11年前

それがですね・・BeginRenderingとEndRedneringではさまれた部分にgame.draw()を置かないと
エフェクトが消えてしまうんです・・

ついでにBeginRenderingとEndRedneringの間でも,Effekseer側のDrawを後に置かないと失敗します.

一応参考までに変更したメインループと実行結果を.

コード:

while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
	ClearDrawScreen();

	game.calc();
	game.draw();
	cyncCameraMatrix();

	RenderVertex();
	manager->Update();

	renderer->BeginRendering();
	manager->Draw();
	renderer->EndRendering();

	RefreshDxLibDirect3DSetting();

	ScreenFlip();
}
画像

EndRenderingの直後にDXライブラリ側の設定を復元している割には上記のような状態なので,
私も何かがおかしいなぁとは思っているのですが・・

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: EffekseerとDXライブラリの連携について

#6

投稿記事 by softya(ソフト屋) » 11年前

とりあえず、DXライブラリVer 3.10eが古いので新しくしてみましょうか。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

顔芸

Re: EffekseerとDXライブラリの連携について

#7

投稿記事 by 顔芸 » 11年前

たしかに・・ということでDXライブラリのバージョンをVer3.12aに上げてきました.
しかし結果は変わりませんでした・・('A'

1枚目の画像を見た感じZバッファの設定が無効化されているような気がするのですがどうでしょうか.
まさかフラグがいちいちリセットされるのかなぁと思ってSetUseZBuffer3D関数とSetWriteZBuffer3D関数を
メインループの中に入れてみたりしたのですがやはりだめでした.

他に見た目に関して言えば,1枚目の画像ではテクスチャの画素数がなぜか落ちているようでした.
壁に近づいてよく見るとピクセルが明らかに大きくなっていて,遠めに見ても地面の草なんかがジラジラして
見えます.

一体なにがどうなっているのやら・・

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: EffekseerとDXライブラリの連携について

#8

投稿記事 by softya(ソフト屋) » 11年前

見た目でわかるのはZバッファ上は、エフェクトと地形は全く別の位置にある(エフェクトが奥)として扱われている様にも見えます。
2つは同じZバッファ空間で合成可能なものですよね? カメラからの距離がZ値として同等かと言う意味です。

他に気になるのは
// カメラのNear/Farクリップを設定
SetCameraNearFar(50.0f, 1000000.0f);
も極端なのでテスト的にfarを小さくしてみてください。表示できたらバッファの精度の問題です。
ただ、地形のZ処理はうまく働いているように見えるので違う気がしてなりません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

顔芸

Re: EffekseerとDXライブラリの連携について

#9

投稿記事 by 顔芸 » 11年前

Near/Farクリップの値を変えてみたら画面が真っ暗になったので元にもどしたのですが,
なぜか真っ暗なまま/(^o^)\

明らかにそこしか触っていないのでDXライブラリのバージョンを3.10eに戻してみたところ,
とりあえず1枚目の画像の状態に戻りました.

改めてDXライブラリのバージョンを3.12aに更新→ソースコードは変更せずにビルド→1枚目の画像の状態
Near/Farクリップの値を変えてビルド→真っ暗→Near/Farクリップの値を元に戻してビルド→やっぱり真っ暗

変更がないうちはコンパイラがバイナリを更新しないから動いて(いるように見え)たけど,
Near/Farクリップ値の修正をトリガーに3.10eと3.12aの差分が顕在化したということでしょうか.

ちょっとDXライブラリの修正箇所とにらめっこしてきます・・

アバター
びす
記事: 31
登録日時: 13年前

Re: EffekseerとDXライブラリの連携について

#10

投稿記事 by びす » 11年前

以前触った時に、サンプルでは

コード:

DrawGraph(0, 0, grHandle, TRUE);
を毎フレーム呼んでいた気がしますが、それをしていないのが原因ではありませんか?

顔芸

Re: EffekseerとDXライブラリの連携について

#11

投稿記事 by 顔芸 » 11年前

以前触った時に、サンプルでは

コード:

DrawGraph(0, 0, grHandle, TRUE);
を毎フレーム呼んでいた気がしますが、それをしていないのが原因ではありませんか?
なんてこった・・ダウンロードしてきたEffekseerのランタイムサンプルを直接書き換えて保存してしまっていました.
元のソースのつもりで見ていたものは誤りで,たしかにDrawGraph関数を毎フレーム呼び出していましたね・・

それに加えて,DrawGraph関数で描画していた画像がデフォルトの透過色(0, 0, 0)と微妙にマッチしていなくて
画面が真っ暗になったと錯覚していましたorz

これらの点を踏まえて,最終的に以下のようにメインループのソースコードを変更したところ,全てうまくいきました.

コード:

while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
{
	// 1. 画面のクリア
	ClearDrawScreen();
		
	game.calc();

	// 2. DXライブラリ側のモデル表示
	// (MV1DrawModel関数を使用)
	game.draw();

	// 3. 透過フラグを立てて画像を描画
	// (黒一色(RGB = (0, 0, 0))の画像を用意!)
	DrawGraph(0, 0, grHandle, TRUE);

	RenderVertex();

	manager->Update();
		
	cyncCameraMatrix();

	// 4. エフェクトの描画開始処理
	renderer->BeginRendering();

	// 5. Effekseer側のエフェクト表示
	manager->Draw();

	// 6. エフェクトの描画終了処理
	renderer->EndRendering();
		
	// 7. DXライブラリの設定を戻す
	RefreshDxLibDirect3DSetting();
		
	// 8. 裏画面を表画面に反映
	ScreenFlip();
}
実行順序が重要なものに番号を振っておきました.
厳密に検証したわけではないのであくまで参考までにということで;;

実行結果は以下のようになりました.
画像

過去のトピックは参考にならなかった等と大口を叩いておいて,結局既出の解決策で解決できてしまいました;;
なんともお恥ずかしい・・('A'

softya(ソフト屋)さん,お騒がせして申し訳ありませんでしたm(_ _)m
びすさんも,重要なアドバイスを与えていただき本当にありがとうございましたm(_ _)m

今回の質問はこれにて解決とさせていただきます.また質問させていただく機会があるかもしれませんが
その時はまたご回答いただけると幸いです.それでは失礼します!

閉鎖

“C言語何でも質問掲示板” へ戻る