「C++/CLI/teapot」の編集履歴(バックアップ)一覧に戻る

C++/CLI/teapot - (2012/09/17 (月) 09:32:34) のソース

|開発環境|Microsoft Visual C++ 2010 Express (SP1)|
|実行環境|Microsoft Windows XP Home Edition (SP3)|
|プロジェクトの種類|空の CLR プロジェクト|
|プロジェクト名|teapot|

Microsoft DirectX SDK (June 2010)をインストール

参考
日経ソフトウェア 2004/9
[[Sample Brower でティーポットを描画>http://www.eonet.ne.jp/~maeda/cs/browerteapot.htm]]

----
**エラー
fatal error C1107: アセンブリ 'Microsoft.DirectX.dll' がみつかりませんでした:
/AI または LIBPATH 環境変数を使用してアセンブリ検索パスを指定してください。

***対処
プロジェクト構成プロパティ→C/C++→全般→#using 参照の解決
C:\WINDOWS\Microsoft[[.NET]]\DirectX for Managed Code\1.0.2902.0
あるいは#usingではなく参照の追加でdllファイルを直接指定する

----
**エラー
'System.IO.FileLoadException' のハンドルされていない例外が teapot.exe で発生しました。
追加情報: 混合モード アセンブリはバージョン 'v1.1.4322' のランタイムに対して作成されており、
追加の構成情報がないと 4.0 ランタイムでは読み込めません。

***対処
app.configを用意する
プロジェクト「追加→既存の項目」を選択する
app.configプロパティ
全般→項目の種類:カスタム ビルド ツール
カスタム ビルド ツール→全般
コマンド ライン:copy app.config "$(TargetPath).config"
出力ファイル:$(TargetPath).config

[[Visual C++ 2008でアプリケーション構成ファイル(app.config)を使う>http://step.skr.jp/blog/2008/12/visual-c-2008appconfig.html]]

----
**エラー
マネージ デバッグ アシスタント 'LoaderLock' では
'C:\projects\vc++\teapot\Debug\teapot.exe' に問題を検出しました。
追加情報: DLL 'C:\WINDOWS\assembly\GAC\Microsoft.DirectX.Direct3D\1.0.2902.0__
31bf3856ad364e35\Microsoft.DirectX.Direct3D.dll' は、
OS ローダー ロック内でマネージ実行を試行しています。
DllMain またはイメージ初期化関数内でマネージ コードを実行しないでください。
この動作は、アプリケーションをハングさせる原因になる可能性があります。

***対処
メニューから「ツール→設定→上級者用の設定」を選択する
メニューから「デバッグ→例外」を選択する
Managed Debugging Assistants→LoaderLockの「スローされるとき」のチェックを外す

[[.NET開発者のためのDirectX連携手法>http://www.atmarkit.co.jp/fdotnet/directxworld/directxworld03/directxworld03_02.html]]
[[「LoaderLock が検出されました。」の対処方法>http://www.crystal-creation.com/software/technical-information/library/managed-directx/troubleshooting/loaderlock.htm]]

----

teapot.cpp
#highlight(cpp){{
#using <System.dll>
#using <System.Windows.Forms.dll>
#using <System.Drawing.dll>
#using <Microsoft.DirectX.dll>
#using <Microsoft.DirectX.Direct3D.dll>
#using <Microsoft.DirectX.Direct3DX.dll>

using namespace System;
using namespace System::Windows::Forms;
using namespace Microsoft::DirectX;
using namespace Microsoft::DirectX::Direct3D;

//==============================================================================
public ref class Teapot : Form
{
private:
	Device^ device;		// Direct3Dデバイス
	Mesh^ teapot;		// メッシュ・オブジェクト
	PresentParameters^ presentParams;

public:
	Teapot(void)
	{
		ClientSize = Drawing::Size(400, 300);
		Text = "Managed Direct3D Sample - Simple Teapot";
	}

	bool InitializeGraphics(void)
	{
		try {
			// Direct3Dデバイスの作成に使う構造体を設定
			presentParams = gcnew PresentParameters();
			presentParams->Windowed = true;
			presentParams->SwapEffect = SwapEffect::Discard;
			presentParams->EnableAutoDepthStencil = true;
			presentParams->AutoDepthStencilFormat = DepthFormat::D16;

			// Direct3Dデバイスを作成
			device = gcnew Device(0, DeviceType::Hardware, this,
				CreateFlags::SoftwareVertexProcessing,
				presentParams);
			device->DeviceReset += gcnew EventHandler(this,
				&Teapot::OnResetDevice);
			OnResetDevice(device, nullptr);
		}
		catch (DirectXException^) {
			return false;
		}
		return true;
	}

	void OnResetDevice(Object^ sender, EventArgs^ e)
	{
		// メッシュ・オブジェクトを作成
		teapot = Mesh::Teapot(device);

		// Zバッファを有効にする
		device->RenderState->ZBufferEnable = true;

		// マテリアルを設定
		Material^ mtrl = gcnew Material();
		mtrl->Diffuse = Drawing::Color::White;
		mtrl->Ambient = Drawing::Color::White;
		device->Material = *mtrl;

		// 照明を設定
		device->Lights[0]->Type = LightType::Directional;
		device->Lights[0]->Direction = Vector3(1.0f, -1.0f, 1.0f);
		device->Lights[0]->Diffuse = Drawing::Color::White;
		device->Lights[0]->Ambient = Drawing::Color::FromArgb(50, 50, 50);
		device->Lights[0]->Enabled = true;
//		device->Lights[0]->Commit();	// 廃止→Enabledで十分
		device->RenderState->Lighting = true;

		// ビュー行列を設定
		device->Transform->View = Matrix::LookAtLH(
			Vector3(0.0f, 2.0f, -3.0f),
			Vector3(0.0f, 0.0f, 0.0f),
			Vector3(0.0f, 1.0f, 0.0f));

		// 射影行列を設定
		float fAspect = device->PresentationParameters->BackBufferWidth /
			(float)device->PresentationParameters->BackBufferHeight;
		device->Transform->Projection = Matrix::PerspectiveFovLH(
			(float)(Math::PI / 4.0f), fAspect, 1.0f, 100.0f);
	}

// private:
	void Render(void)
	{
		if (device == nullptr) return;

		device->Clear(ClearFlags::Target | ClearFlags::ZBuffer,
			Drawing::Color::Blue, 1.0f, 0);
		device->BeginScene();
		device->Transform->World = Matrix::RotationY(
			Environment::TickCount / 1000.0f);
		teapot->DrawSubset(0);
		device->EndScene();
		device->Present();
	}
};

//==============================================================================
int main()
{
	Teapot^ frm = gcnew Teapot();
	if (!frm->InitializeGraphics()) {
		MessageBox::Show("Direct3Dの初期化に失敗しました");
		return 1;
	}
	frm->Show();
	while (frm->Created)
	{
		frm->Render();
		Application::DoEvents();
	}
	return 0;
}
}}

app.config
#highlight(xml){{
<?xml version='1.0' encoding='utf-8'?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0"/>
  </startup>
</configuration>
}}