DirectXプログラミング講座 〜Vol7. 3Dポリゴンの表示〜

ここでは3D空間に平面四角形を描画する方法を解説します。


CRectPolygonクラス

CRectPolygonはCImage2Dの3D版ともいえるクラスです。扱い方も似通っており、簡単に3D空間に四角形オブジェクトを作り出すことができます。


'3D四角形オブジェクトを構成する4つの頂点座標を設定する
CRectPolygon::SetVertices(
    pVertices As *D3DVECTOR   '頂点座標(4要素のD3DVECTOR構造体配列)
)

'四角形オブジェクトの色を設定する
CRectPolygon::SetColor(
    dwColor As D3DCOLOR   '四角形オブジェクトの色(D3DCOLOR_XRGB、D3DCOLOR_RGBAマクロ関数を利用する)
)

'四角形オブジェクトにテクスチャを貼り付けます
CRectPolygon::SetTexture(
    pFileName As BytePtr,           'テクスチャ画像を指すファイルパス
    TransparentColor As D3DCOLOR    '透明色(D3DCOLOR_XRGBマクロ関数で指定。透明処理をしないときは0)
)

'四角形オブジェクトを3D空間に描画します(RenderProc関数の中から呼び出す必要があります)
CRectPolygon::Draw(
    VectorPosition As *D3DVECTOR,   '位置
    VectorDirection As *D3DVECTOR   '方向
)

'3D座標または3Dベクトルの表現
Type D3DVECTOR
    x As Single
    y As Single
    z As Single
End Type

3Dには必要!カメラの存在

3D空間の描画には、対象物の状態と共に、どの位置からどの方向を向いて見ているかという視点に関する情報が必要になります。そこで登場するのがカメラです。ABDXでは、以下の2つの関数を使ってカメラ及び視野の設定を行います。


'カメラの位置、方向を設定する
dx_SetCamera(
    pVectorEye As *D3DVECTOR,   'カメラの位置
    pVectorAt As *D3DVECTOR,    '注視対象の位置
    pVectorUp As *D3DVECTOR     'カレントワールドの上方。一般的な値は[0, 1, 0]
)

'視野情報を設定する
dx_SetProjection(
    angle As Single,      '視野角。一般的な値は ( 60 * D3DX_PI / 180 ) 
    aspect As Single,     'アスペクト比(ビュー空間の高さを幅で除算した値)。一般的な値は1
    nearclip As Single,   '近いビュー平面のZ値
    backclip As Single    '遠いビュー平面のZ値
)

サンプルプログラムの作成方法


↑実行イメージ

サンプルプロジェクトをダウンロード

プロジェクト名を "test3d" にセットして、DirectXアプリケーションのプロジェクトを新たに作成します。ここから、test3d.abpに対してコーディングをしていきます。

●test3d.abpの先頭部分のコーディング

CRectPolygonオブジェクトポインタの定義を行います。今回は2つの四角形オブジェクトを扱うため、pModel1、pModel2を定義します。

#include "test3d.idx"


Dim ScreenX=640 As Long    'ディスプレイの幅  (ピクセル単位)
Dim ScreenY=480 As Long    'ディスプレイの高さ(ピクセル単位)

' TODO: この位置にグローバル変数を定義してください。
Dim pModel1 As *CRectPolygon
Dim pModel2 As *CRectPolygon

●InitProc関数のコーディング

CRectPolygonオブジェクトの生成を行います。CRectPolygon::SetVertices関数で四角形オブジェクトの頂点座標を設定します。2Dのときと異なり、頂点座標のXYZ要素はスケールを基準にしています。CRectPolygon::SetTexture関数でテクスチャをセットします。これらの処理をpModel1、pModel2に対して行ったら、カリングモード(四角形の裏側を描画しない機能)をオフに、ライト機能をオフにします。ライト機能をオフにすることで、四角形オブジェクトは自発光型になり、照明や質感の設定を省くことができます。

次に、dx_SetCamera関数を使ってカメラの設定を行います。カメラの位置は[0,0,0]を基準に、手前(Z=-4)の少し上(Y=2)にでもしておきます。注視位置を[0,0,0]にセットし、カレントワールドの上方は一般的な値1を指定しておきます。

カメラ設定を終えたら、dx_SetProjection関数を使って視野の設定を行います。視野角及びアスペクト比には一般的な数値としてそれぞれ60*D3DX_PI/180、1を設定します。近いビュー平面のZ値にはなるべく小さな値を、遠いビュー平面のZ値にはなるべく大きな値をセットしておきます。ビュー平面とは、描画の対象となる範囲のことを言いいます。物体がビュー平面を超えた場合は、描画の対象にならなくなるので、注意が必要です。

Function InitProc()
    'DirectXを初期化
    If dx_Init(hMainWnd,ScreenX,ScreenY,FALSE)=0 Then
        InitProc=0
        Exit Function
    End If

    'マウスカーソルを非表示にする
    ShowCursor(FALSE)

    ' TODO: この位置にアプリケーションの初期化コードを記述してください。

    pModel1=New CRectPolygon
    Dim vertices1[3]=[
        [-1, 1, 0],
        [ 1, 1, 0],
        [-1,-1, 0],
        [ 1,-1, 0]
    ] As D3DVECTOR
    pModel1->SetVertices(vertices1)
    pModel1->SetTexture("texture1.jpg",0)

    pModel2=New CRectPolygon
    Dim vertices2[3]=[
        [-1, 0, 1],
        [ 1, 0, 1],
        [-1, 0,-1],
        [ 1, 0,-1]
    ] As D3DVECTOR
    pModel2->SetVertices(vertices2)
    pModel2->SetTexture("texture2.jpg",0)

    'カリングモードをセット(※四角形オブジェクトの背面の描画の対象にする)
    dx_SetCullMode(D3DCULL_NONE)

    'ライト機能をオフにする
    dx_SetLightOff()

    'カメラの位置及び方向をセット
    Dim VectorEye=[0,2,-4] As D3DVECTOR
    Dim VectorAt=[0,0,0] As D3DVECTOR
    Dim VectorUp=[0,1,0] As D3DVECTOR
    dx_SetCamera(VarPtr(VectorEye),VarPtr(VectorAt),VarPtr(VectorUp))

    '視野情報をセット
    dx_SetProjection(60*D3DX_PI/180,
        1,
        0.01,
        100)

    InitProc=1
End Function

●QuitProc関数のコーディング

pModel1、pModel2オブジェクトを解放します。

Sub QuitProc()
    ' TODO: この位置にアプリケーションの終了処理を記述してください。

    Delete pModel1
    Delete pModel2

    'DirectXの終了処理
    dx_Quit()
End Sub

●RenderProc関数のコーディング

CRectPolygon::Draw関数を使って四角形オブジェクトの描画を行います。今回は物体移動は行わないため、VectorPositionは[0,0,0]にセットしておきます。その代わり、物体をランダムな方向へ回転させるため、VectorDirectionに細工を施しておきます。GetTickCount関数はWindowsが起動してからの時間をミリ秒単位で返す機能を持ち、描画毎にVectorDirectionが示す方向が変化するようにします。

Sub RenderProc()
    ' TODO: この位置に描画に関するコードを記述してください。

    Dim VectorPosition=[0,0,0] As D3DVECTOR

    Dim VectorDirection As D3DVECTOR
    VectorDirection.x=GetTickCount()/700
    VectorDirection.y=GetTickCount()/800
    VectorDirection.z=GetTickCount()/900

    pModel1->Draw(VarPtr(VectorPosition),VarPtr(VectorDirection))
    pModel2->Draw(VarPtr(VectorPosition),VarPtr(VectorDirection))
End Sub

3Dとなると扱う対象物が増え、更にXYに加えてZ座標のことも考慮しなければなりませんでした。少し難しかったなと感じられた方は、いろいろといじくってみて、それぞれの数値がどんな意味を持つのかを理解しておきましょう。



講座インデックスへ戻る ©2005 Discoversoft