DrawScene.cpp
#include "StdAfx.h"
#include "DrawScene.h"
using namespace Core;
using namespace Microsoft;
using namespace System;
using namespace System::Diagnostics;
// DirectXのライブラリによる const/volatile 修飾子の使用の警告を抑制する
#pragma warning( disable : 4400 )
/// [ Constructor ]
DrawScene::DrawScene( Microsoft::DirectX::Direct3D::Device^ device ) :
m_device( device )
{
// 座標軸を生成する
CreateAxisOfCoordinates();
// 床を生成する
CreateFloor();
}
/// [ Finalizer ]
DrawScene::!DrawScene()
{
delete m_axisOfCoordinates;
delete m_floor;
}
/// 座標軸を生成する
void DrawScene::CreateAxisOfCoordinates()
{
// 頂点バッファを生成する
m_axisOfCoordinates = gcnew DirectX::Direct3D::VertexBuffer(
DirectX::Direct3D::CustomVertex::PositionColored::typeid, // 頂点データを定義した構造体
6, // 頂点数
m_device, // デバイス
DirectX::Direct3D::Usage::Dynamic | // 使用法
DirectX::Direct3D::Usage::WriteOnly,
DirectX::Direct3D::CustomVertex::PositionColored::Format, // 頂点フォーマット
DirectX::Direct3D::Pool::Default
);
// 頂点の生成イベントに登録する
m_axisOfCoordinates->Created += gcnew System::EventHandler( this, &DrawScene::SetAxisOfCoordinates );
// ... そのイベントを呼び出して 設定させる
SetAxisOfCoordinates( m_axisOfCoordinates, nullptr );
}
/// 座標軸を設定する
void DrawScene::SetAxisOfCoordinates( System::Object^ sender, System::EventArgs^ )
{
// 引数から目的とする型を取得する
DirectX::Direct3D::VertexBuffer^ vertexBuffer = safe_cast< DirectX::Direct3D::VertexBuffer^ >( sender );
// 頂点を格納する配列を生成する
array< DirectX::Direct3D::CustomVertex::PositionColored >^ vertices
= gcnew array< DirectX::Direct3D::CustomVertex::PositionColored >( 6 );
const float Length = 1.2f; // 長さ
// ... 頂点の位置を設定する
vertices[ 0 ].Position = DirectX::Vector3( 0.0f, 0.0f, 0.0f );
vertices[ 1 ].Position = DirectX::Vector3( Length, 0.0f, 0.0f );
vertices[ 2 ].Position = DirectX::Vector3( 0.0f, 0.0f, 0.0f );
vertices[ 3 ].Position = DirectX::Vector3( 0.0f, Length, 0.0f );
vertices[ 4 ].Position = DirectX::Vector3( 0.0f, 0.0f, 0.0f );
vertices[ 5 ].Position = DirectX::Vector3( 0.0f, 0.0f, Length );
// ... 頂点の色を設定する
int red = Drawing::Color::Red.ToArgb();
int green = Drawing::Color::Green.ToArgb();
int blue = Drawing::Color::Blue.ToArgb();
vertices[ 0 ].Color = red;
vertices[ 1 ].Color = red;
vertices[ 2 ].Color = green;
vertices[ 3 ].Color = green;
vertices[ 4 ].Color = blue;
vertices[ 5 ].Color = blue;
// 頂点データの範囲をロックして、頂点バッファ メモリへのリファレンスを取得する
vertexBuffer->SetData( vertices, 0, DirectX::Direct3D::LockFlags::None );
// [ Reference ]「Managed DirectX9」Tom Miller(Sams) P40
}
/// 床を生成する
void DrawScene::CreateFloor()
{
// 頂点数を求める( 幅 / 間隔 + 1 ) x 縦横2辺 x 両端2点
const int NumberOfVertices = ( safe_cast< int >( WidthOfFloor / DistanceOfFloorMesh ) + 1 ) * 2 * 2;
// 頂点バッファを生成する
m_floor = gcnew DirectX::Direct3D::VertexBuffer(
DirectX::Direct3D::CustomVertex::PositionColored::typeid, // 頂点データを定義した構造体
NumberOfVertices, // 頂点数
m_device, // デバイス
DirectX::Direct3D::Usage::Dynamic | // 使用法
DirectX::Direct3D::Usage::WriteOnly,
DirectX::Direct3D::CustomVertex::PositionColored::Format, // 頂点フォーマット
DirectX::Direct3D::Pool::Default
);
// 頂点の生成イベントに登録する
m_floor->Created += gcnew System::EventHandler( this, &DrawScene::SetFloor );
// ... そのイベントを呼び出して 設定させる
SetFloor( m_floor, nullptr );
}
/// 床を設定する
void DrawScene::SetFloor( System::Object^ sender, System::EventArgs^ )
{
// 引数から目的とする型を取得する
DirectX::Direct3D::VertexBuffer^ vertexBuffer = safe_cast< DirectX::Direct3D::VertexBuffer^ >( sender );
const int NumberOfSide = safe_cast< int >( WidthOfFloor / DistanceOfFloorMesh ) + 1; // 辺の数
const int NumberOfVertices = NumberOfSide * 2 * 2; // 頂点数
// 頂点を格納する配列を生成する
array< DirectX::Direct3D::CustomVertex::PositionColored >^ vertices
= gcnew array< DirectX::Direct3D::CustomVertex::PositionColored >( NumberOfVertices );
int index = 0;
for( int x = 0; x < NumberOfSide; x++ )
{
float offset = WidthOfFloor / 2.0f;
float y = x * DistanceOfFloorMesh - offset;
// X軸方向の線分を設定する
vertices[ index++ ].Position = DirectX::Vector3( -offset, y, 0.0f );
if( x == safe_cast< int >( WidthOfFloor / DistanceOfFloorMesh ) / 2 )
{
// 中央ならば座標軸と重なるので、原点までしか描画しない
offset = 0.0f;
}
vertices[ index++ ].Position = DirectX::Vector3( +offset, y, 0.0f );
}
for( int y = 0; y < NumberOfSide; y++ )
{
float offset = WidthOfFloor / 2.0f;
float x = y * DistanceOfFloorMesh - offset;
// Y軸方向の線分を設定する
vertices[ index++ ].Position = DirectX::Vector3( x, -offset, 0.0f );
if( y == safe_cast< int >( WidthOfFloor / DistanceOfFloorMesh ) / 2 )
{
// 中央ならば座標軸と重なるので、原点までしか描画しない
offset = 0.0f;
}
vertices[ index++ ].Position = DirectX::Vector3( x, +offset, 0.0f );
}
for (int i = 0; i < NumberOfVertices; i++)
{
// 頂点の色を設定する
vertices[ i ].Color = Drawing::Color::Gray.ToArgb();
}
// 頂点データの範囲をロックして、頂点バッファ メモリへのリファレンスを取得する
vertexBuffer->SetData( vertices, 0, DirectX::Direct3D::LockFlags::None );
// [ Reference ]「Managed DirectX9」Tom Miller(Sams) P40
}
/// 描画する
void DrawScene::Render()
{
// 変換行列を初期化する
m_device->Transform->World = DirectX::Matrix::Identity;
// 床のプリミティブ数を求める
const int NumberOfFloorPrimitive = ( safe_cast< int >( WidthOfFloor / DistanceOfFloorMesh ) + 1 ) * 2;
// ... 床を描画する
RenderLine( m_floor, NumberOfFloorPrimitive );
// 座標軸を描画する
RenderLine( m_axisOfCoordinates, 3 );
}
/// ラインを描画する
void DrawScene::RenderLine( Microsoft::DirectX::Direct3D::VertexBuffer^ data, int primitiveCount )
{
// ライトを無効にする
m_device->RenderState->Lighting = false;
// 頂点バッファを デバイスのデータ ストリームにバインドする
m_device->SetStreamSource( 0, data, 0 );
m_device->VertexFormat = DirectX::Direct3D::CustomVertex::PositionColored::Format; // 頂点フォーマット
// ... レンダリングする
m_device->DrawPrimitives(
DirectX::Direct3D::PrimitiveType::LineList,
0, // 頂点の読み出し開始位置
primitiveCount // プリミティブの数
);
}