DXLibにおける3DとSetDrawScreen()の共存方法

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
史上最悪のデスペナ
記事: 521
登録日時: 15年前

DXLibにおける3DとSetDrawScreen()の共存方法

#1

投稿記事 by 史上最悪のデスペナ » 14年前

こちらを参考に、
描画可能グラフィックを作成して文字列を描画し、それを裏画面に画像として貼り付けたのですが
メイン画面に描画しているのが2Dであれば思った通りの描画がされますが3Dだと不思議な挙動をします。
20111215081919567.png
これが・・・
20111215081919820.png
こんな感じ
追跡したところ、どうも

コード:

    SetDrawScreen(ChatScreen);
        Draw系関数
    SetDrawScreen(DX_SCREEN_BACK);
でおかしくなっているようです。
ちなみに、エラーが発生しているわけではないようです。
また、SSではチャット関係をモデル描画の後にしていますが、
モデル描画の前にすると今度はカメラが変な位置になり、キー操作でカメラを動かせなくなります。
どうしたらいいでしょうか?

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

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#2

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

私のコードはZバッファをいじっているので、今のコードのままだと3D描画処理後にやらないと3Dがちゃんと描画されなくなります。
それと文字を描画するだけならZバッファの処理は不要です。

ただ、その前に3DにおけるZバッファについてどのぐらい理解されていますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 15年前

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#3

投稿記事 by 史上最悪のデスペナ » 14年前

softya(ソフト屋) さんが書きました:私のコードはZバッファをいじっているので、今のコードのままだと3D描画処理後にやらないと3Dがちゃんと描画されなくなります。
だと思い、モデル描画の後に持ってきたのです。
softya(ソフト屋) さんが書きました:3DにおけるZバッファについてどのぐらい理解されていますか?
カメラからの距離という認識です。
なので、こんな場合、
20111215081919567.png
20111215081919567.png (109.84 KiB) 閲覧数: 8349 回
きちんと設定してあれば塀はテントの向こう側にあるので重なった部分の塀は描画されない。
しかし、設定していないとテントに隠れた部分の塀が重なって見えてしまう。
モデルに半透明がある場合、描画順序を考えないと期待通りの効果は得られない。

という感じでしょうか

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

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#4

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

あっ申し訳ない元のコードってZバッファを使うの止めたコードでしたね。ってことはZバッファは関係ないです。
SetDrawScreen(ChatScreen);
なにもしない
SetDrawScreen(DX_SCREEN_BACK);
だけでもおかしくなりますか?

【補足】
ちなみにMV1DrawModelの説明に
「MV1DrawModel」
http://homepage2.nifty.com/natupaji/DxL ... .html#R2N1
引用: 因みに、Zバッファを使用した現状の3Dレンダリングでは半透明の描画物は視点から最も離れているものから順に描画しないと正常な見た目になりませんので、 もし描画するモデルの中に半透明の部分が含まれている場合は視点からの距離を考慮した上で MV1DrawFrame や MV1DrawMesh で描画する必要があります。 ( DXライブラリ自体にZソートの機能はありません )

とありますので、自分でZソートは必要ですよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 15年前

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#5

投稿記事 by 史上最悪のデスペナ » 14年前

返信が遅くなってすみません。
softya(ソフト屋) さんが書きました:SetDrawScreen(ChatScreen);
なにもしない
SetDrawScreen(DX_SCREEN_BACK);
だけでもおかしくなりますか?

コード:

前略

//描画
{
    3Dモデル描画
}

//チャット
{
    SetDrawScreen(ChatScreen);
    SetDrawScreen(DX_SCREEN_BACK);

    //SPC.PC_C.Size_は可変のウィンドウサイズです。
    DrawExtendGraph( 0, 3*SPC.PC_C.Size_Y/4, SPC.PC_C.Size_X/4, SPC.PC_C.Size_Y, ChatScreen, TRUE );
}

後略
としたところ、同じ現象が確認されました。 DrawExtendGraphをコメントアウトしても同様です。
MakeScreenをする際にSetDrawValidAlphaChannelGraphCreateFlagをコメントアウトしても変わりませんでした。

ちなみに、
普通にLoadGraphしたものをDrawGraphした場合、

コード:

DrawGraph( 0, 0, a, TRUE );
MV1DrawModel( Map );
MV1DrawModel( Building );
であれば、地面も建物もないとこにのみaが描画され、あるとこには地面や建物が描画されます。

コード:

MV1DrawModel( Map );
DrawGraph( 0, 0, a, TRUE );
MV1DrawModel( Building );
この場合は、建物がないとこにはaが描画され、あるとこには建物が描画されます。

このように、きちんと狙い通りの動きをするようです。

VC++が使える環境に無かったので書けなかったのですが、質問する前に

コード:

extern int	SetUseZBufferFlag( int Flag ) ;	// Zバッファを有効にするか、フラグをセットする( 2Dと3D描画に影響 )
extern int	SetWriteZBufferFlag( int Flag ) ;	// Zバッファに書き込みを行うか、フラグをセットする( 2Dと3D描画に影響 )
extern int	SetZBufferCmpType( int CmpType /* DX_CMP_NEVER 等 */ ) ;// Z値の比較モードをセットする( 2Dと3D描画に影響 )今回はDX_CMP_ALWAYSを使用
という、DxLib.h内の関数を以下のように使ってみたのですが、上手くいかなかったことも追記しておきます。

コード:

SetUseZBufferFlag( TRUE ) ;	// Zバッファを有効にするか、フラグをセットする( 2Dと3D描画に影響 )
SetWriteZBufferFlag(TRUE ) ;	// Zバッファに書き込みを行うか、フラグをセットする( 2Dと3D描画に影響 )
SetZBufferCmpType( DX_CMP_ALWAYS ) ;// Z値の比較モードをセットする( 2Dと3D描画に影響 )

BackScreen = MakeScreen( ScreenX, ScreenY, TRUE );

SetZBufferCmpType( DX_CMP_NEVER ) ;// Z値の比較モードをセットする( 2Dと3D描画に影響 )
SetWriteZBufferFlag( FALSE ) ;	// Zバッファに書き込みを行うか、フラグをセットする( 2Dと3D描画に影響 )
SetUseZBufferFlag( FALSE ) ;	// Zバッファを有効にするか、フラグをセットする( 2Dと3D描画に影響 )

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

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#6

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

これから出かけるので後ほど検証します。
出来れば、検証用のそのまま動くソースコードがあると有りがたいです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 15年前

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#7

投稿記事 by 史上最悪のデスペナ » 14年前

何故かなかなかログインできなかったので返信することが出来ませんでした。
ログインしないで返信しようとするとフォームが送信できませんし・・・・orz

遅くなりましたがこちら(
MMORPG~チャット編~.zip
(28.21 MiB) ダウンロード数: 203 回
)です。
よろしくお願いします

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

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#8

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

すいません、明日になるかも。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 15年前

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#9

投稿記事 by 史上最悪のデスペナ » 14年前

そういえば何処が問題の部分か書くの忘れてました

画面.cppのSubScreen()にMakeScreenがあります。
チャット.cppの46行目StringSend()内、87行目StringAdd()内
に問題部分です。

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

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#10

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

原因が分かりました。
SetDrawScreenをするとカメラ情報がキャンセルされるようです。
なので、カメラを再設定して下さい。

検証コード。このぐらい短い検証コードにしてもらうと問題点の検証が楽なので次回からお願いします。

コード:

#include "DxLib.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定

	int MapHandle = MV1LoadModel("model\\map\\ground00.mqo");
	MV1SetPosition( MapHandle, VGet( 0.0f, 0.0f, 0.0f ) );

	int SizeX, SizeY;
	int BackGraph = LoadGraph( "model\\pic\\Back.png" );
	GetGraphSize( BackGraph, &SizeX, &SizeY );
	int ChatScreen = MakeScreen( SizeX, SizeY, TRUE);	//透明抜き用のスクリーン作成

	//ライト設定
	ChangeLightTypeDir( VGet(0.0f, -1.0f, 0.0f ) );

	//	カメラ設定
	SetupCamera_Perspective( 60.0*PHI_F/180.0f );
	SetCameraNearFar( 0.1f, 100.0f );
	SetCameraPositionAndTarget_UpVecY( VGet(30.0f, 1.5f, -60.0f),VGet(0.0f,0.0f,0.0f) );
	
	// while( 裏画面を表画面に反映, メッセージ処理, 画面クリア )
	while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
		
		SetDrawScreen( ChatScreen );
		SetDrawBlendMode( DX_BLENDMODE_ALPHA, 127 );
		DrawGraph(0,0,BackGraph,TRUE);
		SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 255 );
		DrawFormatString( 0,0, GetColor(255,0,0),"文字書きテスト" );
		SetDrawScreen( DX_SCREEN_BACK );
		
	//	カメラ設定
	SetupCamera_Perspective( 60.0*PHI_F/180.0f );
	SetCameraNearFar( 0.1f, 100.0f );
	SetCameraPositionAndTarget_UpVecY( VGet(30.0f, 1.5f, -60.0f),VGet(0.0f,0.0f,0.0f) );
	
		MV1DrawModel( MapHandle );
		DrawGraph(0,0,ChatScreen,TRUE );
	}

	DxLib_End(); // DXライブラリ終了処理
	return 0;
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 15年前

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#11

投稿記事 by 史上最悪のデスペナ » 14年前

softya(ソフト屋) さんが書きました:原因が分かりました。
SetDrawScreenをするとカメラ情報がキャンセルされるようです。
なので、カメラを再設定して下さい。
ありがとうございます。凄いですね。どうやってそんなのを発見するんでしょう?
この現象を本家のほうに報告したほうがいいと思いますか?
softya(ソフト屋) さんが書きました:検証コード。このぐらい短い検証コードにしてもらうと問題点の検証が楽なので次回からお願いします。
あれでも結構削ったのですが、どこまで削ればいいか目安みたいなのはありますか?
今回、関係あるのは3D関連とMakeScreen関係、SetDrawScreen関係だと思ったのでその前後も含めたのですが・・・・・・

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

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#12

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

史上最悪のデスペナ さんが書きました:あれでも結構削ったのですが、どこまで削ればいいか目安みたいなのはありますか?
今回、関係あるのは3D関連とMakeScreen関係、SetDrawScreen関係だと思ったのでその前後も含めたのですが・・・・・・
本当に必要最低限の物にする事です。
この場合は、SetDrawScreenだ原因だと思ったのでモデルを表示してSetDrawScreen()だけを試すコードを作りました。
関数や変数の対応はご本人には分かるでしょうが他に人には分かりませんので追いかけるのが非常に困難です。
まぁ、「ゲームプログラミングの館」や本家の「DXライブラリ サンプルプログラム」程度のコードが望ましいです。

短いコードを作るとバグの状況が整理されますので、長いコードで色々いじっているよりも問題点を発見しやすくなると言うメリットがあります。

SetDrawScreen
史上最悪のデスペナ さんが書きました: softya(ソフト屋) さんが書きました:原因が分かりました。
SetDrawScreenをするとカメラ情報がキャンセルされるようです。
なので、カメラを再設定して下さい。
ありがとうございます。凄いですね。どうやってそんなのを発見するんでしょう?
この現象を本家のほうに報告したほうがいいと思いますか?
あちらの掲示板の過去ログを見てもそういう話は出てきませんので、レアケースとも言えます。
バグではなく仕様と言われる可能性も高いですが、本当にカメラがリセットされるのか確認のため報告するのは良いことだと思うのでお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 15年前

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#13

投稿記事 by 史上最悪のデスペナ » 14年前

softya(ソフト屋) さんが書きました:関数や変数の対応はご本人には分かるでしょうが他に人には分かりませんので追いかけるのが非常に困難です。
まぁ、「ゲームプログラミングの館」や本家の「DXライブラリ サンプルプログラム」程度のコードが望ましいです。
人のコードって読みにくいですよね^^;。細切れになったサンプルコードなら読めますが、ゲームのコード渡されても私は読めません・・・・
以後気をつけます。
softya(ソフト屋) さんが書きました:あちらの掲示板の過去ログを見てもそういう話は出てきませんので、レアケースとも言えます。
バグではなく仕様と言われる可能性も高いですが、本当にカメラがリセットされるのか確認のため報告するのは良いことだと思うのでお願いします。
私のような使い方をする人がそもそもいるのでしょうか^^;一応報告してきます。

ありがとうございました。

史上最悪のデスペナ
記事: 521
登録日時: 15年前

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#14

投稿記事 by 史上最悪のデスペナ » 14年前

本家サイトにて報告したところ、以下のような回答が管理人様より得られましたので報告させていただきます。


SetDrawScreen を使用するとカメラの設定がリセットされるのは仕様となります
( SetDrawArea の設定もリセットされます )

お手数をお掛けしてしまったみたいで申し訳ありません
SetDrawScreen の解説に注意書きとして設定がリセットされる旨を追記しました

本文そのままコピペさせていただきました。

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

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#15

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

了解です。やはり、仕様でしたか。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: DXLibにおける3DとSetDrawScreen()の共存方法

#16

投稿記事 by ISLe » 14年前

テクスチャを頻繁に切り替えると描画が遅くなるように、描画先を頻繁に切り替えると遅くなる気がします。
オフスクリーン描画とバックバッファ描画をきっちり分割する癖が付いてると気付かないのかもしれません。

お手軽に使えるはずのDXライブラリが、複雑なこともできるようになって、いろいろな制限が表に出てきているようです。

閉鎖

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