2012年5月22日火曜日

tutorial 01: Basicの和訳


  要約

summary

 In this first tutorial, we will go through the elements necessary to create a minimal Direct3D 11 application. Every Direct3D 11 application must have these elements to function properly. The elements include setting up a window and a device object, and then displaying a color on the window.

この最初のチュートリアルでは、最小のダイレクト3D 11アプリケーションを作成するために必要な要素を見ていきます。あらゆるダイレクト3D 11のアプリケーションは、きちんと機能するために、これらの要素( ウインドウとデバイスオブジェクトの構築など )を備えていなければなりません。完成したプログラムはウインドウに色を表示するものです。
(訳注:初回ながら小難しいというか、初回だからこそ細かい設定が多いです。

  Direct3D 11 デバイス の構築

Setting up The Direct3D11 Device

The first steps of creating the window and message loop are identical in Direct3D 9, Direct3D 10, and Direct3D 11. See Direct3D 10 Tutorial 00: Win32 Basics for an introduction to this process.

ウィンドウとメッセージループを作るという最初のステップはDirect3D9、10、そして11で共通です。この部分のイントロダクションとしては
Direct3D10 Tutorial 00: Win32 Basicsを見て下さい。
(訳注:必要に応じてWin32APIプログラミングの部分とかもどうぞ)

Now that we have a window that is displaying, we can continue to set up a Direct3D 11 device. Setup is necessary if we are going to render any 3D scene.

 このステップを経てウインドウを手に入れたらDirect3D11デバイスのセットアップを続ける事が出来ます。どの様な3Dシーンを描画する場合でもこれが必要です。

The first thing to do is to create three objects: a device, an immediate context, and a swap chain. The immediate context is a new object in Direct3D 11.

最初にやるのは3つのオブジェクトを作ることです。:
デバイス(device)
イミディエイトコンテキスト(immediate context)
スワップチェーン(swap chain)の3つです。
イミディエイトコンテキストはDirect3D11の新しいオブジェクトです。

In Direct3D 10, the device object was used to perform both rendering and resource creation. In Direct3D 11, the immediate context is used by the application to perform rendering onto a buffer, and the device contains methods to create resources.

Direct3D10では、デバイスオブジェクトはレンダリングとリソース作成の両方を行いました。これに対しDirect3D11では イミディエイトコンテキストがアプリケーションによるバッファへのレンダリングに使われ、デバイスがリソース作成のメソッドを担当します。
( 訳注:リソースについてのMSDNの記事はD3D10 , D3D11等があります。

The swap chain is responsible for taking the buffer to which the device renders, and displaying the content on the actual monitor screen.
スワップチェーンはデバイスが描画したバッファを受け取り、そしてそれを実際のモニタ画面上に表示する役割があります。

The swap chain contains two or more buffers, mainly the front and the back.

スワップチェーンは2つかそれ以上のバッファを持ちます。主にフロントバッファとバックバッファです。

These are textures to which the device renders in order to display on the monitor.

これらはデバイスがモニター上に表示するために描画したテクスチャーです。

The front buffer is what is being presented currently to the user. This buffer is read-only and cannot be modified.
The back buffer is the render target to which the device will draw.

フロントバッファは現在ユーザーに提示されている絵です。このバッファは読み取り専用であり、加工する事は出来ません。バックバッファはデバイスがこれから書き込むための描画対象です。

Once it finishes the drawing operation, the swap chain will present the backbuffer by swapping the two buffers. The back buffer becomes the front buffer, and vice versa.

描画命令が完了したらスワップチェーンはこの2つのバッファを交換する事によってバックバッファを表示します。反対にバックバッファはフロントバッファになります。

To create the swap chain, we fill out a DXGI_SWAPCHAIN_DESC structure that describes the swap chain we are about to create. A few fields are worth mentioning.

スワップチェーンを作るためにDXGI_SWAPCHAIN_DESC構造体のフィールド(メンバ変数)を埋めて、どの様なスワップチェーンを作るか設定しましょう。この構造体の2,3のフィールドは言及する価値があります。

BackBufferUsage is a flag that tells the application how the back buffer will be used. In this case, we want to render to the back buffer, so we'll set BackBufferUsage to DXGI_USAGE_RENDER_TARGET_OUTPUT.


BackBufferUsageはアプリケーションにバックバッファがどう使われるかを教えます。今回、我々はバックバッファを描画対象として使いたいのでDXGI_USAGE_RENDER_TARGET_OUTPUTをセットします。

The OutputWindow field represents the window that the swap chain will use to present images on the screen.

OutputWindowフィールドはスワップチェーンが画面描画のためのイメージを送るウインドウを表します。

SampleDesc is used to enable multi-sampling. Since this tutorial does not use multi-sampling, SampleDesc's Count is set to 1 and Quality to 0 to have multi-sampling disabled.

SampleDescはマルチサンプリングを有効にするのに使われます。このチュートリアルはマルチサンプリングを使用しないのでCount =1, Quality = 0をセットしてマルチサンプリングを無効にします。

Once the description has been filled out, we can call the D3D11CreateDeviceAndSwapChain function to create both the device and the swap chain for us.

設定用の構造体を満たしたら、デバイスとスワップチェーンを作成するためにD3D11CreateDeviceAndSwapChain関数を呼ぶことが出来ます。

The following is the code to create a device and a swap chain:

以下はデバイスとスワップチェーンを作るためのコードです。
(訳注:あとデバイスコンテキストも作られます。)

DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory( &sd, sizeof(sd) );
sd.BufferCount = 1;
sd.BufferDesc.Width = 640;
sd.BufferDesc.Height = 480;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = g_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;

if( FAILED( D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, NULL, &g_pImmediateContext ) ) )
{
return FALSE;
}

The next thing we need to do is to create a render target view.

次にしないといけないのはレンダーターゲットビューの作成です。

A render target view is a type of resource view in Direct3D 11.

レンダーターゲットビューはDirect3D11のリソースビューの一種です。


(訳注:ちなみにリソースは描画関係のデータの事です。これにビューが付いたリソースビューは「描画用データの使い方の見通し」みたいなニュアンスだと思います。これらはどちらも型(COMインターフェース)の種類です。つまりID3D11ResourceやID3D11Viewという型があります。実際にはそれぞれに数種類存在する派生型を利用します。具体的な使い方と共に学べば済むので、今の段階で深く考える必要はないかも知れませんが。)

A resource view allows a resource to be bound to the graphics pipeline at a specific stage.

リソースビューはリソースを グラフィックパイプラインの特定のステージに結びつける事を可能にします。

Think of resource views as typecast in C.

リソースビューをC言語における型の様な物だと考えて下さい。

A chunk of raw memory in C can be cast to any data type.

C言語では、生のメモリの大きな塊を、どの様なデータ型にも型変換(キャスト)できます。

We can cast that chunk of memory to an array of integers, an array of floats, a structure, an array of structures, and so on.

我々はこのメモリの塊を整数(integer)の配列にもfloatの配列にも、構造体にも構造体の配列、あるいはその他にも変換できます。

The raw memory itself is not very useful to us if we don't know its type.

生のメモリそのものは使い手が型を知らないとあまり有用ではありません。

Direct3D 11 resource views act in a similar way.

 Direct3D11のリソースビューもこれと似た使い道をします。

For instance, a 2D texture, analogous to the raw memory chunk, is the raw underlying resource.

例えば2Dテクスチャは生のメモリに類似する生の状態のリソースです。

Once we have that resource we can create different resource views to bind that texture to different stages in the graphics pipeline with different formats: as a render target to which to render, as a depth stencil buffer that will receive depth information, or as a texture resource.

一旦そのリソースを持てば、グラフィックパイプラインの別のステージに結びつける別のフォーマットのリソースビューを作る事が出来ます(レンダーターゲットとして、深度値を受け取るdepth stencil buffer として、あるいはテクスチャリソースとして)。

Where C typecasts allow a memory chunk to be used in a different manner, so do Direct3D 11 resource views.

Cの型変換はメモリの塊を別のマナーで使われるのを許しましたが、Direct3D11のリソースビューも同様です。

We need to create a render target view because we would like to bind the back buffer of our swap chain as a render target.

ここで我々はスワップチェーンのバックバッファを描画対象にしたいので、レンダーターゲットビューを作る必要があります。

This enables Direct3D 11 to render onto it.

これによってDirect3D11は、そこに描画が出来るようになります。

We first call GetBuffer() to get the back buffer object.

我々は最初にバックバッファ オブジェクトを取得するためにGetBuffer()を呼びます。

Optionally, we can fill in a D3D11_RENDERTARGETVIEW_DESC structure that describes the render target view to be created.

任意ですが、3D11_RENDERTARGETVIEW_DESC構造体を埋めることで作られるレンダーターゲットビューの設定を行う事が出来ます。

This description is normally the second parameter to CreateRenderTargetView.

この構造体は通常、CreateRenderTargetView()の第二引数となります。

However, for these tutorials, the default render target view will suffice.

しかしながら、一連のチュートリアルではデフォルトのレンダーターゲットビューで事足ります。

The default render target view can be obtained by passing NULL as the second parameter.

デフォルトのレンダーターゲットビューはこの2番めの引数をNULLにすれば得られます。

Once we have created the render target view, we can call OMSetRenderTargets() on the immediate context to bind it to the pipeline.

一旦レンダーターゲットビューを作ればイミディエイトコンテキストからOMSetRenderTargets()を呼んでパイプラインに結びつける事が出来ます。
(訳注:ちなみにOMSetRenderTargets()という関数の名前の頭に付いているOMはパイプライン出力結合ステージ(OutPutMerger Stage)の事を指しています。)

This ensures the output that the pipeline renders gets written to the back buffer.

 これによってパイプラインが描画した出力がバックバッファに描かれる事が保証されます。

The code to create and set the render target view is as follows:

レンダーターゲットビューを作ってセットするコードは以下のようになります。

// レンダーターゲットビューの作成
ID3D11Texture2D *pBackBuffer;
if( FAILED( g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID*)&pBackBuffer ) ) )
return FALSE;
hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
pBackBuffer->Release();
if( FAILED( hr ) )
return FALSE;
g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );


The last thing we need to set up before Direct3D 11 can render is initialize the viewport.

 Direct3D11による描画のために必要な最後のセットアップは、viewportの初期化です。

The viewport maps clip space coordinates, where X and Y range from -1 to 1 and Z ranges from 0 to 1, to render target space, sometimes known as pixel space.

ビューポートはクリップ空間座標の-1から1の範囲のXとY、そして0から1の範囲のZをレンダーターゲット空間へマッピングします。
(訳注:クリップ空間とはチュートリアル4で説明されるプロジェクション空間の事です。)

In Direct3D 9, if the application does not set up a viewport, a default viewport is set up to be the same size as the render target.

Direct3D9ではアプリケーションでビューポートをセットアップしなくてもデフォルトビューポートがレンダーターゲットと同サイズになるようにセットアップされました。

In Direct3D 11, no viewport is set by default. Therefore, we must do so before we can see anything on the screen.

Direct3D11ではデフォルトでセットされるビューポートは存在しません。そういう訳で我々はスクリーンで何かを見る前にそれをやらなくてはなりません。

Since we would like to use the entire render target for the output, we set the top left point to (0, 0) and width and height to be identical to the render target's size.

我々は出力にレンダーターゲットの全体を使いたいので、左上の点を(0,0)に、そして幅(width)と高さ(height)をレンダーターゲットと同一にします。

To do this, use the following code:

これをするには、以下のコードを使います。

D3D11_VIEWPORT vp;
vp.Width = (FLOAT)width;
vp.Height = (FLOAT)height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pImmediateContext->RSSetViewports( 1, &vp );

メッセジループの改善

Modifying the Message Loop

We have set up the window and Direct3D 11 device, and we are ready to render.

ウインドウとDirect3D11のセットアップが済んだので描画の準備が出来ています。

However, there is still a problem with our message loop: it uses
GetMessage() to get messages.

しかしながら、まだ我々のメッセージループに問題があります。:メッセージの取得にGetMessage()を使っています。

The problem with GetMessage() is that if there is no message in the queue for the application window, GetMessage() blocks and does not return until a message is available.

GetMessage()の問題点はアプリケーションウインドウのキューにメッセージがない間、制御を返さない事です。

Thus, instead of doing something like rendering, our application is waiting within GetMessage() when the message queue is empty.

だからメッセージが空の時、描画のような何らかの処理をする代わりにアプリケーションはGetMessage()で待機してしまいます。

We can solve this problem by using PeekMessage() instead of GetMessage().

この問題はGetMessage()の代わりにPeekMessage()を使用することで解決します。

PeekMessage() can retrieve a message like GetMessage() does, but when there is no message waiting, PeekMessage() returns immediately instead of blocking.

PeekMessage()はGetMessage()同様にメッセジーを回収します。しかしメッセージのために待機はしません。PeekMessage()は待機の替りにすぐに制御を戻します。

We can then take this time to do some rendering.

それで我々はこの時間を使って何かを描画できます。

The modified message loop, which uses PeekMessage(), looks like this:

PeekMessage()を使ったメッセージループの改善は以下のようになります。

MSG msg = {0};
while( WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render(); // Do some rendering
}
}

レンダリングコード

The Rendering Code

Rendering is done in the Render() function.

レンダリング(描画)はRender()関数によって成されます。

In this tutorial, we will render the simplest scene possible, which is to fill the screen with a single color.

このチュートリアルで我々は画面を一色で満たすという最も単純なレンダリングを行います。

In Direct3D 11, an easy way to fill the render target with a single color is to use the immediate context's ClearRenderTargetView() method.

Direct3D11でレンダーターゲット(描画対象)を一色で塗る簡単な方法はイミディエイトコンテキストのClearRenderTargetView()メソッドを使うことです。

First, we define an array of four floats that describe the color with which we would like to fill the screen.

それにはまず、4つのfloatの配列を定義します。これが画面を満たす色を表します。

Then, we pass it to ClearRenderTargetView(). In this example, we choose a shade of blue.

次にそれをCleareRenderTargetView()に通します。この例では暗い青を選びます。

Once we fill our back buffer, we call the swap chain's Present() method to complete the rendering.

バックバッファを満たしたらスワップチェーンのPresent()メソッドを読んでレンダリングを完成させます。

Present() is responsible for displaying the swap chain's back buffer content onto the screen so that the user can see it.

Present()はバックバッファの内容をユーザーが見えるように画面に表示する役割があります。

The Render() function looks like this:

Render()関数はこの様になるでしょう。

void Render()
{
//
// Clear the backbuffer
//
float ClearColor[4] = { 0.0f, 0.125f, 0.6f, 1.0f }; // RGBA
g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );

g_pSwapChain->Present( 0, 0 );
}
(訳注 g_pd3dDevice->ClearRenderTargetView()の部分はg_pImmediateContext-> の間違いだと思われます。(Direct3D10ではデバイスコンテキストではなくデバイスが描画していました。)

今回は何も描画しないで色だけ塗りました。Direct3Dには、一度描画した物を取り消すという操作はないので、例えばアニメーションを表現する時は今回の様に背景の再描画で今まで画面に描いたものを一旦塗りつぶす必要があります。そうしないと残像が発生します。)

0 件のコメント: