4. 各モジュールの説明

4.1. シェーダステージ

シェーダステージでは頂点シェーダおよびジオメトリシェーダに関する設定を行います。これらの設定を行う関数は nn::gd::ShaderStage クラスに定義されています。

以下の図はシェーダステージで行われる設定の概要を示したものです。

図 4-1. シェーダステージの概要

ShaderStageクラス シェーダプログラム SetShaderPipeline() ShaderPipelineオブジェクト 頂点シェーダ ジオメトリシェーダ ユニフォーム設定 CreateShaderPipeline() Shaderオブジェクト シェーダプログラム(頂点シェーダ) CreateShader() シェーダプログラム(ジオメトリシェーダ) シェーダバイナリファイル CreateShaderBinary() ShaderBinaryオブジェクト

頂点シェーダおよびジオメトリシェーダは、事前にコンパイルされたシェーダバイナリファイルとしてアプリケーションに読み込まれます。シェーダバイナリファイルには、1 つ以上の頂点シェーダやジオメトリシェーダのシェーダプログラムを含むことができます。

シェーダバイナリファイルの中に記述されている特定のシェーダを参照するためには、読み込んだシェーダバイナリファイルを nn::gd::ShaderStage::CreateShaderBinary() に渡して作成された ShaderBinary オブジェクトを使用します。

コード 4-1. ShaderBinary オブジェクトの作成
static nnResult nn::gd::ShaderStage::CreateShaderBinary(
        const void* shaderBytecode, u32 bytecodeLength,
        nn::gd::ShaderBinary** shaderBinary);

shaderBytecode bytecodeLength には、読み込んだシェーダバイナリのコードが格納されているバッファの先頭アドレスとコードのバイトサイズを指定します。

今後、作成された ShaderBinary オブジェクトへのアクセスには shaderBinary で受け取ったポインタを介して行います。

ShaderBinary オブジェクトに含まれているシェーダプログラムにアクセスするための Shader オブジェクトは nn::gd::ShaderStage::CreateShader() で作成します。Shader オブジェクトは 1 つのシェーダコード(頂点シェーダ、ジオメトリシェーダのいずれか)を表します。

コード 4-2. Shader オブジェクトの作成
static nnResult nn::gd::ShaderStage::CreateShader(
        nn::gd::ShaderBinary* shaderBinary, u32 shaderBinaryIndex,
        nn::gd::Shader** shader);

shaderBinary に指定されている ShaderBinary オブジェクトに複数のシェーダプログラムが含まれている場合は、シェーダプログラムのインデックスを shaderBinaryIndex に指定して Shader オブジェクトを作成してください。

今後、作成された Shader オブジェクトへのアクセスには shader で受け取ったポインタを介して行います。

シェーダプログラムをパイプラインに反映するために使用する ShaderPipeline オブジェクトは、1 つまたは 2 つの Shader オブジェクトを用いて、nn::gd::ShaderStage::CreateShaderPipeline() で作成されます。

コード 4-3. ShaderPipeline オブジェクトの作成とパイプラインへの反映
static nnResult nn::gd::ShaderStage::CreateShaderPipeline(
        nn::gd::Shader* vertexShader, nn::gd::Shader* geometryShader,
        nn::gd::ShaderPipeline** shaderPipeline,
        nn::gd::ShaderPipelineUnmanagedRegisters* unmanagedRegister = NULL);
static nnResult nn::gd::ShaderStage::SetShaderPipeline(
        nn::gd::ShaderPipeline* shaderPipeline);

vertexShader には、頂点シェーダとして使用する Shader オブジェクトを指定します。geometryShader には、ジオメトリシェーダとして使用する Shader オブジェクトを指定しますが、ジオメトリシェーダが不要である場合は NULL を渡してください。

unmanagedRegister には、レジスタ設定のコマンドをライブラリが自動生成しないようにするレジスタの範囲を指定します。この設定については「4.1.2. ライブラリによるレジスタへの設定コマンドの自動生成」で説明します。

注意:

GD ライブラリでは、頂点シェーダからジオメトリシェーダへと出力される頂点属性が正しいかどうかをチェックしません。頂点シェーダから出力される頂点属性とジオメトリシェーダの入力に使用する頂点属性が一致するように、正しい組み合わせの Shader オブジェクトで ShaderPipeline オブジェクトを作成してください。

以下のコード例では、頂点シェーダのみを使用する ShaderPipeline オブジェクトを生成してパイプラインに反映しています。

コード 4-4. シェーダステージで行われる設定のコード例
nn::gd::ShaderBinary* shaderBinary = 0;
nn::gd::ShaderPipeline* shaderPipeline = 0;
nn::gd::Shader* vertexShader = 0;
nn::gd::ShaderStage::CreateShaderBinary(
        shaderBinaryFileBuffer, bufferSize, &shaderBinary);
nn::gd::ShaderStage::CreateShader(shaderBinary, 0, &vertexShader);
nn::gd::ShaderStage::CreateShaderPipeline(vertexShader, NULL, &shaderPipeline);
nn::gd::ShaderStage::SetShaderPipeline(shaderPipeline);

4.1.1. シェーダ設定レジスタへの設定

浮動小数点定数レジスタなどのシェーダ設定レジスタへ設定される値は ShaderPipeline オブジェクトが保持しています。GD ライブラリでは、シェーダ設定レジスタへの設定値をシェーダステージの関数で変更することができます。関数で更新された変数は一旦内部状態としてオブジェクトに保存され、描画コマンドが要求されるまで 3D コマンドバッファに出力されません。

レジスタの種類によって、値の設定に使用する関数は以下のように異なります。

表 4-1. レジスタの種類と呼び出す関数
レジスタの種類 関数
浮動小数点定数レジスタ nn::gd::ShaderStage::SetShaderPipelineConstantFloat()
ブールレジスタ nn::gd::ShaderStage::SetShaderPipelineConstantBoolean()
整数レジスタ nn::gd::ShaderStage::SetShaderPipelineConstantInteger()
コード 4-5. シェーダ設定レジスタへの値の設定に使用する関数
static nnResult nn::gd::ShaderStage::SetShaderPipelineConstantFloat(
        nn::gd::ShaderPipeline* shaderPipeline,
        nn::gd::UniformLocation uniformLocation, f32* v);
static nnResult nn::gd::ShaderStage::SetShaderPipelineConstantBoolean(
        nn::gd::ShaderPipeline* shaderPipeline,
        nn::gd::UniformLocation uniformLocation, u16 v, u32 count);
static nnResult nn::gd::ShaderStage::SetShaderPipelineConstantInteger(
        nn::gd::ShaderPipeline* shaderPipeline,
        nn::gd::UniformLocation uniformLocation, u8* v);
static nn::gd::UniformLocation nn::gd::ShaderStage::GetShaderUniformLocation(
        nn::gd::ShaderPipeline* shaderPipeline, const char* name);

設定値を変更するレジスタの指定には nn::gd::ShaderStage::GetShaderUniformLocation() で取得した UniformLocation クラスを使用します。取得する際の name にはユニフォーム設定の名前を指定してください。正しいユニフォーム設定が取得できている場合、UniformLocation クラスの IsValid() は 1 を返します。

4.1.2. ライブラリによるレジスタへの設定コマンドの自動生成

通常、現在反映されているものとは別の ShaderPipeline オブジェクトをパイプラインに反映させたときには、レジスタへの設定コマンドが自動的に生成されます。しかし、場合によっては自動的に設定コマンドを生成せずに、直接レジスタに値を書き込むコマンドを生成することでパフォーマンスが向上するケースがあります。

そのようなケースを考慮して、nn::gd::ShaderStage::SetFloatConstantBuffer() で独自にレジスタの設定値を変更することができます。

コード 4-6. 独自にレジスタの設定値を変更する関数
static nnResult nn::gd::ShaderStage::SetFloatConstantBuffer(
        nn::gd::ShaderStage::ShaderType shaderType,
        u32 firstRegisterIndex, u32 registerCount, f32* constantBufferSrc);

この関数で設定値が変更できるのは、自動的に設定コマンドを生成しない(「unmanaged」な)浮動小数点定数レジスタに限られています。「unmanaged」なレジスタの範囲は ShaderPipeline オブジェクトの作成時の引数 unmanagedRegister に渡す ShaderPipelineUnmanagedRegisters クラスで指定します。

ShaderPipelineUnmanagedRegisters クラスは UnmanagedRegistersInterval クラスの配列とその要素数で構成され、UnmanagedRegistersInterval クラスはシェーダの種類(m_ShaderType)と「unmanaged」なレジスタの最初の番号(m_FirstUnmanagedRegister)と個数(m_RegisterCount)で構成されています。

コード 4-7. 「unmanaged」なレジスタの指定で使用するクラス
class nn::gd::UnmanagedRegistersInterval
{
    nn::gd::ShaderStage::ShaderType m_ShaderType;
    u32 m_FirstUnmanagedRegister;
    u32 m_RegisterCount;
};
class nn::gd::ShaderPipelineUnmanagedRegisters
{
    nn::gd::UnmanagedRegistersInterval* m_ArrayUnmanagedRegistersInterval;
    u32 m_CountUnmanagedRegistersInterval;
};

以下のコード例は「unmanaged」なレジスタを含む ShaderPipeline クラスの作成例です。

コード 4-8. 「unmanaged」なレジスタを含む ShaderPipeline クラスの作成例
nn::gd::ShaderPipelineUnmanagedRegisters unmanagedRegs;
nn::gd::UnmanagedRegistersInterval arrayUnmanagedRegistersInterval[] =
{
    {nn::gd::ShaderStage::SHADER_TYPE_VERTEX, 0, 4},
    {nn::gd::ShaderStage::SHADER_TYPE_VERTEX, 4, 3},
    {nn::gd::ShaderStage::SHADER_TYPE_VERTEX, 8, 3}
};

unmanagedRegs.m_ArrayUnmanagedRegistersInterval =
        arrayUnmanagedRegistersInterval;
unmanagedRegs.m_CountUnmanagedRegistersInterval = 3;
nn::gd::ShaderStage::CreateShaderPipeline(
        s_vertexShader, NULL, &s_shaderPipeline, &unmanagedRegs);

「unmanaged」なレジスタには、以下のようなコードで直接書き込むことになります。

コード 4-9. 「unmanaged」なレジスタへの書き込み
nn::gd::UniformLocation s_shaderVariable_proj =
    nn::gd::ShaderStage::GetShaderUniformLocation(
        s_shaderPipeline, "uProjection");

nn::gd::ShaderStage::SetFloatConstantBuffer(
    nn::gd::ShaderStage::SHADER_TYPE_VERTEX,
        s_shaderVariable_proj.getRegister(), 4, data);

新たに反映された ShaderPipeline オブジェクトが、現在反映されていたものとは異なる ShaderBinary オブジェクトから作成されたものである場合、描画の際に ShaderBinary オブジェクトに含まれるすべてのデータが 3D コマンドバッファに出力されます。この処理には負荷がかかるため、「unmanaged」なレジスタを利用して、出力される 3D コマンドを最小限に止めるようにすることが推奨されます。

4.2. 頂点入力ステージ

頂点入力ステージではパイプラインへの頂点データ(頂点属性)の入力に関する設定を行います。これらの設定を行うための関数は nn::gd::VertexInputStage クラスに定義されています。

以下の図は頂点入力ステージで行われる設定の概要を示したものです。

図 4-2. 頂点入力ステージの概要

VertexInputStageクラス 頂点バッファのスロット(12個) 頂点インデックスバッファ プリミティブの種類 ステートオブジェクト(入力レイアウト) SetVertexBuffers() SetIndexBuffer() SetPrimitiveTopology() SetInputLayout() VertexBufferResourceオブジェクト オフセット IndexFormat PrimitiveTopology InputLayoutオブジェクト Shaderオブジェクト InputElementDescriptionクラス CreateInputLayout()

4.2.1. 頂点バッファの登録

頂点バッファは頂点入力ステージに 12 個あるスロットに登録します。nn::gd::VertexInputStage::SetVertexBuffers() では VertexBufferResource オブジェクトの配列と頂点データの開始オフセットの配列を指定しますので、一度の呼び出しで連続する複数のスロットに頂点バッファを登録することができます。

コード 4-10. 頂点バッファの登録
static nnResult nn::gd::VertexInputStage::SetVertexBuffers(
        u32 startSlot, u32 numBuffers,
        nn::gd::VertexBufferResource** vertexBuffers, u32* offsets);

startSlot には頂点バッファを登録する最初のスロット番号(0~11)を、numBuffers には vertexBuffers に指定された VertexBufferResource オブジェクト配列の要素数を、offsets には頂点データの開始オフセットの配列を指定します。登録される頂点バッファを構成する頂点データの要素は、「4.2.4. 入力レイアウト」で説明する InputLayout オブジェクトでの定義と一致している必要があります。

4.2.2. 頂点インデックスの使用

プリミティブの描画に頂点インデックスを使用する場合は、頂点インデックスの配列をリソースデータに指定して作成された VertexBufferResource オブジェクトを nn::gd::VertexInputStage::SetIndexBuffer() で頂点入力ステージに登録します。

コード 4-11. 頂点インデックスの登録
static nnResult nn::gd::VertexInputStage::SetIndexBuffer(
        nn::gd::VertexBufferResource* indexBuffer,
        nn::gd::VertexInputStage::IndexFormat format, u32 offset);

indexBuffer に指定されている VertexBufferResource オブジェクトが頂点入力ステージに登録されます。頂点データなどとインターリーブされている VertexBufferResource オブジェクトを登録する場合は、頂点インデックスの開始位置をバイト単位のオフセット値を offset に指定します。

format には、頂点インデックスのフォーマットを以下から選択して指定します。

表 4-2. 頂点インデックスのフォーマット指定
定義 説明
INDEX_FORMAT_UBYTE 頂点インデックスを unsigned byte の配列として扱います。
INDEX_FORMAT_USHORT 頂点インデックスを unsigned short の配列として扱います。

4.2.3. プリミティブの種類

描画するプリミティブの種類は nn::gd::VertexInputStage::SetPrimitiveTopology() で設定します。

コード 4-12. 描画するプリミティブの種類の設定
static nnResult nn::gd::VertexInputStage::SetPrimitiveTopology(
        nn::gd::VertexInputStage::PrimitiveTopology primitiveTopology);

primitiveTopology には、プリミティブの種類を以下から選択して指定します。

表 4-3. プリミティブの種類
定義 説明
PRIMITIVE_TOPOLOGY_TRIANGLELIST Triangles(GL_TRIANGLES
PRIMITIVE_TOPOLOGY_TRIANGLESTRIP Triangle Strip(GL_TRIANGLE_STRIP
PRIMITIVE_TOPOLOGY_TRIANGLEFAN Triangle Fan(GL_TRIANGLE_FAN
PRIMITIVE_TOPOLOGY_GEOMETRY ジオメトリシェーダ(GL_GEOMETRY_PRIMITIVE_DMP

4.2.4. 入力レイアウト

入力レイアウト(InputLayout オブジェクト)には、頂点バッファと頂点シェーダの間での入力変数の接続方法を定義します。頂点バッファは単純なスカラ値またはインターリーブされたいくつかのスカラ値の配列によって構成されています。InputLayout オブジェクトは、入力要素(頂点データ)のデスクリプタクラス(InputElementDescription)の配列とシェーダステージで作成した Shader オブジェクトを引数に持つ、nn::gd::VertexInputStage::CreateInputLayout() の呼び出しで作成します。

コード 4-13. 入力レイアウトの作成、解放、パイプラインへの設定
static nnResult nn::gd::VertexInputStage::CreateInputLayout(
        nn::gd::InputElementDescription* inputElementDescs, u32 numElements,
        u32* strides, nn::gd::Shader* vertexShader,
        nn::gd::InputLayout** inputLayout);
static nnResult nn::gd::VertexInputStage::ReleaseInputLayout(
        nn::gd::InputLayout* inputLayout);
static nnResult nn::gd::VertexInputStage::SetInputLayout(
        nn::gd::InputLayout* inputLayout);

入力要素の情報は inputElementDescs に指定するデスクリプタクラス(InputElementDescription)の配列にあらかじめ設定し、numElements には配列に含まれているデスクリプタクラスの数を渡します。デスクリプタクラスに設定する情報の詳細は「4.2.4.1. InputLayout オブジェクトのデスクリプタクラス」を参照してください。

strides には、1 頂点あたりに使用する頂点データのサイズをスロット番号ごとの配列で指定します。すべての入力要素が 1 つの頂点バッファにインターリーブされているならば、その入力要素の合計サイズで 1 つの要素だけを持つ配列となります。インターリーブされていなければ、それぞれの入力要素のサイズで複数の要素を持つ配列となります。

vertexShader には、頂点シェーダの Shader オブジェクトを指定します。

作成された InputLayout オブジェクトは nn::gd::VertexInputStage::SetInputLayout() でパイプラインに反映することができます。

不要になった InputLayout オブジェクトは nn::gd::VertexInputStage::ReleaseInputLayout() で解放してください。このとき、オブジェクトが作成されたときに内部で確保されたメモリ領域も解放されます。

以下のコード例は、3 つの入力要素がインターリーブされた 1 つの頂点バッファを記述するデスクリプタクラスから作成された入力レイアウトをパイプライン(頂点入力ステージ)に設定するものです。

コード 4-14. 入力レイアウトの作成例
nn::gd::InputLayout* inputLayout = 0;
nn::gd::InputElementDescription descs[] =
{
    { 0, "aPosition",
        nn::gd::VertexInputStage::STREAM_TYPE_FLOAT, 3, 0 },
    { 0, "aColor",
        nn::gd::VertexInputStage::STREAM_TYPE_FLOAT, 4, sizeof(float) * 3 },
    { 0, "aNormal",
        nn::gd::VertexInputStage::STREAM_TYPE_FLOAT, 3, sizeof(float) * 7 },
};
u32 strides[] = { sizeof(float) * 10 };
nn::gd::VertexInputStage::CreateInputLayout(
        descs, 3, strides, vertexShader, &inputLayout);

nn::gd::VertexInputStage::SetInputLayout(inputLayout);

4.2.4.1. InputLayout オブジェクトのデスクリプタクラス

InputLayout オブジェクトのデスクリプタクラス(InputElementDescription)のメンバを紹介し、設定に際しての注意点などを説明します。

コード 4-15. InputElementDescription クラスの定義
class nn::gd::InputElementDescription
{
    u32 m_StreamSlot;
    const char* m_SemanticName;
    nn::gd::VertexInputStage::ShaderStreamFormatType m_Format;
    u32 m_Count;
    u32 m_AlignedByteOffset;

    static const u32 Append = 0x00080000;
};
スロット番号(m_StreamSlot)

入力要素が使用するスロット番号(0~11)です。複数の入力要素が同じスロット番号を使用する場合、そのスロット番号に登録される頂点バッファはインターリーブされていなければなりません。また、スロット番号は 0 から昇順に、連番で登録されていなければなりません。

入力変数の名前(m_SemanticName)

頂点シェーダで定義されている入力変数の名前です。

入力要素のデータフォーマット(m_Format)

入力要素のデータフォーマットです。以下から選択して設定します。

表 4-4. 入力要素のデータフォーマット
定義 説明
VertexInputStage::STREAM_TYPE_BYTE byte(GL_BYTE
VertexInputStage::STREAM_TYPE_UNSIGNED_BYTE unsigned byte(GL_UNSIGNED_BYTE
VertexInputStage::STREAM_TYPE_SHORT short(GL_SHORT
VertexInputStage::STREAM_TYPE_FLOAT float(GL_FLOAT
入力要素のサイズ(m_Count)

入力要素のサイズ(コンポーネント数)です。設定可能な値の範囲は 1 ~ 4 です。入力要素のバイトサイズではないことに注意してください。

入力要素のオフセット(m_AlignedByteOffset)

入力要素の先頭までのオフセット(バイト単位)です。InputElementDescription::Append を指定した場合はオフセットが自動的に計算され、デスクリプタクラスの設定を簡便化することができます。

4.3. テクスチャステージ

テクスチャステージでは、テクスチャオブジェクトの作成やテクスチャユニットに関する設定を行います。これらの設定を行うための関数は nn::gd::TextureStage クラスに定義されています。

以下の図はテクスチャステージで行われる設定の概要を示したものです。

図 4-3. テクスチャステージの概要

TextureStageクラス テクスチャユニット0 テクスチャユニット1 テクスチャユニット2 テクスチャユニット3 シャドウの設定 プロジェクションテクスチャ設定 テクスチャリソース ステートオブジェクト(サンプラー設定) テクスチャ座標 バイアス値 GD_TRUE GD_FALSE TextureCubeオブジェクト TextureCubeDescriptionクラス Texture2DResourceオブジェクト Texture2Dオブジェクト Textture2DDescriptionクラス SamplerStateオブジェクト SamplerStateDescriptionクラス TextureCoordinateSourceUnit2 TextureCoordinateSourceUnit3 SetShadowZBias() SetPerspectiveShadow() SetTexture2DProjectionForUnit0() SetTextureUnit0() SetTexture() SetSamplerState() SetTextureCoordinateSourceForUnit2() SetTextureCoordinateSourceForUnit3Procedural() CreateTextureCube() CreateTexture2D() CreateSamplerState()

4.3.1. 2 次元テクスチャ

GD ライブラリでは Texture2D オブジェクトで 2 次元テクスチャを扱います。Texture2D オブジェクトは 1 つの Texture2DResource オブジェクトとデスクリプタクラス(Texture2DDescription)から作成されます。なお、デスクリプタクラスの設定によって、Texture2DResource オブジェクトがミップマップデータを含んでいる場合に、Texture2D オブジェクトの作成にどのレベルのミップマップデータを使用するかを指定することができます。デスクリプタクラスに設定する情報の詳細は「4.3.1.1. Texture2D オブジェクトのデスクリプタクラス」を参照してください。

Texture2D オブジェクトの作成と解放は以下の関数で行うことができます。

コード 4-16. Texture2D オブジェクトの作成と解放
static nnResult nn::gd::TextureStage::CreateTexture2D(
        const nn::gd::Texture2DResource* tex2DResource,
        nn::gd::Texture2DDescription* desc,
        nn::gd::Texture2D** texture2D);
static nnResult nn::gd::TextureStage::ReleaseTexture2D(
        nn::gd::Texture2D* texture2D);

Texture2D オブジェクトの解放時には管理情報のみが解放されます。Texture2DResource オブジェクトは解放されません。

以下は Texture2DResource オブジェクトを作成し、そこから Texture2D オブジェクトを作成するコードの例です。

コード 4-17. Texture2D オブジェクト作成のコード例
nn::gd::Texture2DResource* texture2DResource = 0;
nn::gd::Texture2DResourceDescription Text2DResDesc =
    {256, 256, 1, nn::gd::Resource::NATIVE_FORMAT_RGB_888,
    nn::gd::Memory::LAYOUT_BLOCK_8, nn::gd::Memory::FCRAM};
nn::gd::Resource::CreateTexture2DResource(
        &Text2DResDesc, data, GD_FALSE, &texture2DResource);
nn::gd::Texture2D* texture2D = 0;
nn::gd::Texture2DDescription tex2DDesc = {0, 0};
nn::gd::TextureStage::CreateTexture2D(
        texture2DResource, &tex2DDesc, &texture2D);

4.3.1.1. Texture2D オブジェクトのデスクリプタクラス

Texture2D オブジェクトのデスクリプタクラス(Texture2DDescription)のメンバを紹介し、設定に際しての注意点などを説明します。

コード 4-18. Texture2DDescription クラスの定義
class nn::gd::Texture2DDescription
{
    s32 m_MinMipLevelIndex;
    s32 m_MaxMipLevelIndex;
};
最小ミップマップレベルのインデックス(m_MinMipLevelIndex)

Texture2D オブジェクトの最小ミップマップレベルに使用する Texture2DResource オブジェクトのミップマップレベルです。-1 を設定した場合は Texture2DResource オブジェクトの最大のミップマップレベルが使用されます。

最大ミップマップレベルのインデックス(m_MaxMipLevelIndex)

Texture2D オブジェクトの最大ミップマップレベルに使用する Texture2DResource オブジェクトのミップマップレベルです。-1 を設定した場合は Texture2DResource オブジェクトの最大のミップマップレベルが使用されます。

4.3.1.2. Texture2D オブジェクトの詳細情報の取得

詳細情報(Texture2DProperties クラス)を nn::gd::TextureStage::GetTexture2DProperties() で取得することができます。

コード 4-19. Texture2D オブジェクトの詳細情報の取得
static nnResult nn::gd::TextureStage::GetTexture2DProperties(
        const nn::gd::Texture2D* texture2D,
        nn::gd::Texture2DProperties* properties);

オブジェクトの作成時に指定したミップマップレベルによって、幅や高さ、ミップマップレベル、リソースデータの先頭アドレスが変化することはありますが、基本的に Texture2DResource オブジェクトの詳細情報と同じです。

コード 4-20. Texture2DProperties クラスの定義
class nn::gd::Texture2DProperties
{
    u32 m_Width;
    u32 m_Height;
    u32 m_CountMipLevels;
    u32 m_PixelSize;
    nn::gd::Resource::NativeFormat m_Format;
    nn::gd::Memory::MemoryLayout m_MemLayout;
    nn::gd::Memory::MemoryLocation m_MemLocation;
    u8* m_MemAddr;
    nn::gd::MipmapResourceInfo GetMipmapAddress(u32 mipmapLevel);
};

4.3.2. キューブマップテクスチャ

GD ライブラリでは TextureCube オブジェクトでキューブマップテクスチャを扱います。TextureCube オブジェクトは 6 つの Texture2DResource オブジェクトを用いて作成されます。Texture2D オブジェクトと同様に、どのミップマップレベルを使用するかを指定することができます。すべての面の Texture2DResource オブジェクトは同じフォーマット、同じ解像度(ミップマップによる)、同じミップマップレベル、同じメモリ配置場所を満たしている必要があります。

TextureCube オブジェクトの作成と解放は以下の関数で行うことができます。

コード 4-21. TextureCube オブジェクトの作成と解放
static nnResult nn::gd::TextureStage::CreateTextureCube(
        nn::gd::Texture2DResource** tex2DResources,
        nn::gd::TextureCubeDescription* desc,
        nn::gd::TextureCube** textureCube);
static nnResult nn::gd::TextureStage::ReleaseTextureCube(
        nn::gd::TextureCube* textureCube);

tex2DResources には、6 面分の Texture2DResource オブジェクトの配列を指定します。配列の先頭から、+X、-X、+Y、-Y、+Z、-Z 面のテクスチャに使用されます。デスクリプタクラスでの配列の順序やキューブマップテクスチャの面を指定する際も同じです。

TextureCube オブジェクトの解放時には管理情報のみが解放されます。Texture2DResource オブジェクトは解放されません。

4.3.2.1. TextureCube オブジェクトのデスクリプタクラス

TextureCube オブジェクトのデスクリプタクラス(TextureCubeDescription)のメンバを紹介し、設定に際しての注意点などを説明します。

コード 4-22. TextureCubeDescription クラスの定義
class nn::gd::TextureCubeDescription
{
    s32 m_MinMipLevelIndex[6];
    s32 m_MaxMipLevelIndex[6];
    TextureCubeDescription();
    TextureCubeDescription(int minMipLevelIndex, int maxMipLevelIndex);
};

6 面分のミップマップレベルを指定することや、それを簡便化するためのコンストラクタが用意されている点が Texture2DDescription クラスとは異なります。

最小ミップマップレベルのインデックス(m_MinMipLevelIndex)

TextureCube オブジェクトの最小ミップマップレベルに使用する Texture2DResource オブジェクトのミップマップレベルです。-1 を設定した場合は Texture2DResource オブジェクトの最大のミップマップレベルが使用されます。

配列の先頭から、+X、-X、+Y、-Y、+Z、-Z 面の Texture2DResource オブジェクトに対応しています。

最大ミップマップレベルのインデックス(m_MaxMipLevelIndex)

TextureCube オブジェクトの最大ミップマップレベルに使用する Texture2DResource オブジェクトのミップマップレベルです。-1 を設定した場合は Texture2DResource オブジェクトの最大のミップマップレベルが使用されます。

配列の先頭から、+X、-X、+Y、-Y、+Z、-Z 面の Texture2DResource オブジェクトに対応しています。

4.3.2.2. TextureCube オブジェクトの詳細情報の取得

TextureCube オブジェクトの詳細情報(TextureCubeProperties クラス)を nn::gd::TextureStage::GetTextureCubeProperties() で取得することができます。

コード 4-23. TextureCube オブジェクトの詳細情報の取得
static nnResult nn::gd::TextureStage::GetTextureCubeProperties(
        const nn::gd::TextureCube* TextureCube,
        nn::gd::TextureCubeProperties* properties);

6 面分のリソースデータの先頭アドレスが保持されていることや、ミップマップデータのアドレス情報の取得で faceIndex にキューブマップ面を指定すること以外は Texture2DProperties クラスと同じです。

コード 4-24. TextureCubeProperties クラスの定義
class nn::gd::TextureCubeProperties
{
    u32 m_Width;
    u32 m_Height;
    u32 m_CountMipLevels;
    u32 m_PixelSize;
    nn::gd::Resource::NativeFormat m_Format;
    nn::gd::Memory::MemoryLayout m_MemLayout;
    nn::gd::Memory::MemoryLocation m_MemLocation;
    u8* m_MemAddr[6];

    nn::gd::MipmapResourceInfo GetMipmapAddress(u32 faceIndex, u32 mipmapLevel);
};

4.3.3. テクスチャユニット

GD ライブラリでは、3DS のハードウェア構成に合わせて 4 つの論理的なテクスチャユニットを提供しています。

表 4-5. テクスチャユニットと設定可能なテクスチャの種類
定義 設定可能なテクスチャの種類

TextureStage::TEXTURE_UNIT_0

(テクスチャユニット 0)

2 次元テクスチャ(ガス、シャドウ含む)

キューブマップテクスチャ(シャドウ含む)

プロジェクションテクスチャ

TextureStage::TEXTURE_UNIT_1

(テクスチャユニット 1)

2 次元テクスチャ

TextureStage::TEXTURE_UNIT_2

(テクスチャユニット 2)

2 次元テクスチャ

TextureStage::TEXTURE_UNIT_3_PROCEDURAL

(テクスチャユニット 3)

プロシージャルテクスチャ
補足:

テクスチャ座標以外の TextureStage::TEXTURE_UNIT_3_PROCEDURAL への設定は、プロシージャルテクスチャステージで行います。

2 次元テクスチャ

2 次元テクスチャの設定は nn::gd::TextureStage::SetTexture() で行います。設定対象となるテクスチャユニットはテクスチャユニット 0/1/2 の 3 つです。

コード 4-25. テクスチャユニットへの 2 次元テクスチャの設定
static nnResult nn::gd::TextureStage::SetTexture(
        nn::gd::TextureStage::TextureUnitId textureUnitId,
        nn::gd::Texture2D& texture2D);
そのほかのテクスチャ(プロシージャルテクスチャを除く)

そのほかのテクスチャ(プロシージャルテクスチャを除く)はテクスチャユニット 0 にのみ設定することができます。

コード 4-26. そのほかのテクスチャの設定
static nnResult nn::gd::TextureStage::SetTextureUnit0(
        nn::gd::TextureCube& textureCube);
static void nn::gd::TextureStage::SetTexture2DProjectionForUnit0(gdBool value);
static void nn::gd::TextureStage::SetPerspectiveShadow(gdBool v);
static void nn::gd::TextureStage::SetShadowZBias(f32 zBias);

キューブマップテクスチャの設定は nn::gd::TextureStage::SetTextureUnit0() で行います。

nn::gd::TextureStage::SetTexture2DProjectionForUnit0() の引数に GD_TRUE を渡して呼び出すことで、テクスチャユニット 0 に設定された 2 次元テクスチャをプロジェクションテクスチャとして扱うことができます。

シャドウテクスチャまたはシャドウキューブマップテクスチャを参照する際のテクスチャ座標の生成に透視投影を適用する場合は、 nn::gd::TextureStage::SetPerspectiveShadow() の引数に GD_TRUE を渡して呼び出してください。また、nn::gd::TextureStage::SetShadowZBias() では、シャドウテクスチャの生成時に光源までの距離から減算されるバイアス値を設定することができます。

4.3.3.1. テクスチャ座標

テクスチャユニット 2/3 に入力されるテクスチャ座標の設定は以下の関数で行われます。

コード 4-27. テクスチャ座標の設定
// For TextureUnit2
static void nn::gd::TextureStage::SetTextureCoordinateSourceForUnit2(
        nn::gd::TextureStage::TextureCoordinateSourceUnit2 u);
// For TextureUnit3
static void nn::gd::TextureStage::SetTextureCoordinateSourceForUnit3Procedural(
        nn::gd::TextureStage::TextureCoordinateSourceUnit3Procedural u);

それぞれの関数には、以下の引数が指定可能です。

表 4-6. テクスチャユニット 2 に設定可能なテクスチャ座標
定義 入力されるテクスチャ座標
UNIT2_TEXTURE_COORDINATE_FROM_UNIT_2 テクスチャ座標 2(デフォルト)
UNIT2_TEXTURE_COORDINATE_FROM_UNIT_1 テクスチャ座標 1
表 4-7. テクスチャユニット 3 に設定可能なテクスチャ座標
定義 入力されるテクスチャ座標
UNIT3_PROCEDURAL_TEXTURE_COORDINATE_FROM_UNIT_0 テクスチャ座標 0(デフォルト)
UNIT3_PROCEDURAL_TEXTURE_COORDINATE_FROM_UNIT_1 テクスチャ座標 1
UNIT3_PROCEDURAL_TEXTURE_COORDINATE_FROM_UNIT_2 テクスチャ座標 2

4.3.4. サンプラー設定

テクスチャのサンプリング方法の設定(サンプラー設定)はステートオブジェクト(SamplerState オブジェクト)を作成し、それをテクスチャユニットに設定することで行われます。

コード 4-28. サンプラー設定の作成、解放、テクスチャユニットへの設定
static nnResult nn::gd::TextureStage::CreateSamplerState(
        const nn::gd::SamplerStateDescription* desc,
        nn::gd::SamplerState** sampler);
static nnResult nn::gd::TextureStage::ReleaseSamplerState(
        nn::gd::SamplerState* sampler);
static nnResult nn::gd::TextureStage::SetSamplerState(
        nn::gd::TextureStage::TextureUnitId textureUnitId,
        nn::gd::SamplerState* sampler);

サンプラー設定の情報は desc に指定するデスクリプタクラス(SamplerStateDescription)にあらかじめ設定します。デスクリプタクラスに設定する情報の詳細は「4.3.4.1. SamplerState オブジェクトのデスクリプタクラス」を参照してください。

作成された SamplerState オブジェクトは nn::gd::TextureStage::SetSamplerState() でテクスチャユニットに設定することができます。サンプラー設定が可能なテクスチャユニットは、テクスチャユニット 0/1/2 の 3 つです。

不要になった SamplerState オブジェクトは nn::gd::TextureStage::ReleaseSamplerState() で解放してください。このとき、オブジェクトが作成されたときに内部で確保されたメモリ領域も解放されます。

以下のコード例では、デフォルトの設定から縮小時と拡大時のフィルタを変更した SamplerState オブジェクトを作成し、テクスチャユニット 0 への設定を行っています。

コード 4-29. サンプラー設定のコード例
nn::gd::SamplerState* sampler = 0;
nn::gd::SamplerStateDescription samplerdesc;
samplerdesc.ToDefault();
samplerdesc.m_MinFilter = nn::gd::TextureStage::SAMPLER_MIN_FILTER_LINEAR;
samplerdesc.m_MagFilter = nn::gd::TextureStage::SAMPLER_MAG_FILTER_LINEAR;
nn::gd::TextureStage::CreateSamplerState(&samplerdesc, &sampler);
nn::gd::TextureStage::SetSamplerState(
        nn::gd::TextureStage::TEXTURE_UNIT_0, sampler);

4.3.4.1. SamplerState オブジェクトのデスクリプタクラス

SamplerState オブジェクトのデスクリプタクラス(SamplerStateDescription クラス)のメンバを紹介し、設定に際しての注意点などを説明します。

コード 4-30. SamplerStateDescription クラスの定義
class nn::gd::SamplerStateDescription
{
    nn::gd::TextureStage::SamplerMinFilter m_MinFilter;
    nn::gd::TextureStage::SamplerMagFilter m_MagFilter;
    nn::gd::TextureStage::SamplerWrapMode m_WrapS;
    nn::gd::TextureStage::SamplerWrapMode m_WrapT;
    u8 m_BorderColor[4];
    u32 m_LodBias;
    u32 m_MinLod;
    u32 m_MaxLod;

    void SetMinFilter(nn::gd::TextureStage::SamplerMinFilter filter);
    void SetMagFilter(nn::gd::TextureStage::SamplerMagFilter filter);
    void SetWrapS(nn::gd::TextureStage::SamplerWrapMode wrap);
    void SetWrapT(nn::gd::TextureStage::SamplerWrapMode wrap);
    void SetBorderColor(u8 colorR, u8 colorG, u8 colorB, u8 colorA);
    void SetBorderColor(f32 colorR, f32 colorG, f32 colorB, f32 colorA);
    void SetLodBias(f32 biasValue);
    void SetMinLod(u32 lodValue);
    void SetMaxLod(u32 lodValue);

    SamplerStateDescription();
    void ToDefault();
    void SetShadow();
    void SetShadowCube();
    void SetGas();
};
縮小時のフィルタ(m_MinFilter)

テクスチャが縮小表示される際に適用されるフィルタです。SetMinFilter() で設定することができます。

拡大時のフィルタ(m_MagFilter)

テクスチャが拡大表示される際に適用されるフィルタです。SetMagFilter() で設定することができます。

S 方向のラッピングモード(m_WrapS)

S 方向へのテクスチャの繰り返しで適用されるラッピングモードです。SetWrapS() で設定することができます。

T 方向のラッピングモード(m_WrapT)

T 方向へのテクスチャの繰り返しで適用されるラッピングモードです。SetWrapT() で設定することができます。

ボーダーカラー(m_BorderColor)

ラッピングモードに TextureStage::SAMPLER_WRAP_CLAMP_TO_BORDER を指定したときに使用されるボーダーカラーです。SetBorderColor() で RGBA の各成分を 0~255 または 0.0~1.0 の範囲で設定することができます。

LOD のバイアス値(m_LodBias)

LOD を決定する際に使用されるバイアス値です。GPU のレジスタに設定する際のフォーマットで値を設定しなければなりませんので、-16.0 ~ 16.0 の範囲の値を SetLodBias() に渡して設定してください。

バイアス値のフォーマットは小数部 8 ビットの符号つき 13 ビット固定小数点数です。直接メンバ変数を変更する場合は、ユーティリティ関数の Utils::Float32ToFix13Fraction8() を利用してください。

LOD の最小レベル(m_MinLod)

LOD で使用する最小のミップマップレベルです。LOD を使用する場合は最小のミップマップレベルを 0 以上(使用しない場合は 0)で設定してください。SetMinLod() で設定することができます。

LOD の最大レベル(m_MaxLod)

LOD で使用する最大のミップマップレベルです。LOD を使用しない場合は 0 を、使用する場合は(テクスチャの持つ最大のミップマップレベル – 1)を設定してください。SetMaxLod() で設定することができます。

異なるミップマップレベル数を持つテクスチャで同じサンプラー設定を使用する場合は UINT_MAX などの大きな値を設定してください。描画時に(テクスチャの持つミップマップレベル数 - 1)が設定されます。デフォルトの設定やソースから判断しています。

デフォルトの設定(ToDefault())

ToDefault() で、すべてのメンバをデフォルトの値に変更することができます。この設定はコンストラクタでも行われています。

表 4-8. デフォルトのサンプラー設定
メンバ 設定値
m_MinFilter TextureStage::SAMPLER_MIN_FILTER_NEAREST
m_MagFilter TextureStage::SAMPLER_MAG_FILTER_NEAREST
m_WrapS TextureStage::SAMPLER_WRAP_REPEAT
m_WrapT TextureStage::SAMPLER_WRAP_REPEAT
m_BorderColor (0, 0, 0, 0)
m_LodBias 0.0
m_MinLod 0
m_MaxLod 0xFFFFFFFF
シャドウテクスチャ用の設定(SetShadow())

SetShadow() で、すべてのメンバをシャドウテクスチャ用の値に変更することができます。

表 4-9. シャドウテクスチャ用のサンプラー設定
メンバ 設定値
m_MinFilter TextureStage::SAMPLER_MIN_FILTER_LINEAR
m_MagFilter TextureStage::SAMPLER_MAG_FILTER_LINEAR
m_WrapS TextureStage::SAMPLER_WRAP_CLAMP_TO_BORDER
m_WrapT TextureStage::SAMPLER_WRAP_CLAMP_TO_BORDER
m_BorderColor (0, 0, 0, 0)
m_LodBias 0.0
m_MinLod 0
m_MaxLod 0xFFFFFFFF
注意:

フィルタ、ラッピングモード、LOD の設定を変更しないでください。

シャドウキューブテクスチャ用の設定(SetShadowCube())

SetShadowCube() で、すべてのメンバをシャドウキューブマップテクスチャ用の値に変更することができます。

表 4-10. シャドウキューブマップテクスチャ用のサンプラー設定
メンバ 設定値
m_MinFilter TextureStage::SAMPLER_MIN_FILTER_LINEAR
m_MagFilter TextureStage::SAMPLER_MIN_FILTER_LINEAR
m_WrapS TextureStage::SAMPLER_WRAP_CLAMP_TO_EDGE
m_WrapT TextureStage::SAMPLER_WRAP_CLAMP_TO_EDGE
m_BorderColor (0, 0, 0, 0)
m_LodBias 0.0
m_MinLod 0
m_MaxLod 0xFFFFFFFF
注意:

フィルタ、ラッピングモード、LOD の設定を変更しないでください。

ガステクスチャ用の設定(SetGas())

SetGas() で、すべてのメンバをガステクスチャ用の値に変更することができます。

表 4-11. ガステクスチャ用のサンプラー設定
メンバ 設定値
m_MinFilter TextureStage::SAMPLER_MIN_FILTER_NEAREST
m_MagFilter TextureStage::SAMPLER_MAG_FILTER_NEAREST
m_WrapS TextureStage::SAMPLER_WRAP_CLAMP_TO_EDGE
m_WrapT TextureStage::SAMPLER_WRAP_CLAMP_TO_EDGE
m_BorderColor (0, 0, 0, 0)
m_LodBias 0.0
m_MinLod 0
m_MaxLod 0xFFFFFFFF
注意:

フィルタ、ラッピングモード、LOD の設定を変更しないでください。

4.4. プロシージャルテクスチャステージ

プロシージャルテクスチャステージでは、プロシージャルテクスチャに関する設定を行います。これらの設定を行うための関数は nn::gd::ProceduralTextureStage クラスに定義されています。

以下の図はプロシージャルテクスチャステージで行われる設定の概要を示したものです。

図 4-4. プロシージャルテクスチャステージの概要

ProceduralTextureStageクラス RGBマッピング G関数 アルファマッピング アルファ独立モード テクスチャパラメータ クランプ方法 シフト方法 MINフィルタ方式 LODバイアス ノイズ 有効化 パラメータ 参照テーブル F関数(RGB) F関数(アルファ) ノイズ変調関数 カラー参照 参照のオフセット 参照テーブルの幅 SetRgbMap() SetAlphaSeparate() SetAlphaMap() SetClampUV() SetShiftUV() SetMinFilter() SetTexBias() SetNoiseEnable() SetNoiseUV() UploadLookUpTableRgbMap UploadLookUpTableAlphaMap UploadLookUpTableNoiseMap UploadLookUpTableColorMap SetTexOffset() SetTexWidth() UvMap GD_TRUE GD_FALSE Clamp Shift MinFilter LODバイアス値 ノイズのパラメータ カラー参照テーブルのオフセット値 カラー参照テーブルの幅

4.4.1. プロシージャルテクスチャのパラメータ設定

プロシージャルテクスチャの各パラメータに対する設定を行う関数が用意されています。

コード 4-31. プロシージャルテクスチャのパラメータ設定関数
class nn::gd::ProceduralTextureStage
{
    static void SetRgbMap(UvMap rgbMap);
    static void SetAlphaSeparate(gdBool alphaSeparate);
    static void SetAlphaMap(UvMap alphaMap);
    static void SetClampUV(Clamp u, Clamp v);
    static void SetShiftUV(Shift u, Shift v);
    static void SetMinFilter(MinFilter minFilter);
    static void SetTexBias(f32 texBias);
    static void SetNoiseEnable(gdBool noiseEnable);
    static void SetNoiseUV(f32 noiseU[3], f32 noiseV[3]);
    static void SetTexWidth(u8 texWidth);
    static void SetTexOffset(u8 texOffset);
};

下表に、それぞれの関数で設定が行われるパラメータを示します。引数の指定方法やパラメータの影響については関数リファレンスなどを参照してください。

表 4-12. プロシージャルテクスチャステージの関数で設定が行われるパラメータ
関数 パラメータ
SetRgbMap() RGB マッピングの G 関数(デフォルト:UV_MAP_U
SetAlphaSeparate() アルファ独立モードの有効化(デフォルト:GD_FALSE
SetAlphaMap() アルファマッピングの G 関数(デフォルト:UV_MAP_U
SetClampUV() クランプモード(デフォルト:CLAMP_TO_ZERO
SetShiftUV() シフトモード(デフォルト:SHIFT_NONE
SetMinFilter() 縮小時のフィルタモード(デフォルト:MIN_FILTER_LINEAR
SetTexBias() LOD バイアス(デフォルト:0.5)
SetNoiseEnable() ノイズの有効化(デフォルト:GD_FALSE
SetNoiseUV() ノイズのパラメータ(デフォルト:U, V ともに F=0.0, P=0.0, A=0.0)
SetTexWidth() カラー参照テーブルの幅(デフォルト:0)
SetTexOffset() カラー参照テーブルのオフセット(デフォルト:0)
補足:

SetTexBias()SetNoiseUV() では、引数で渡された値を関数内で GPU のレジスタに設定する際のフォーマットに変換しています。

4.4.2. プロシージャルテクスチャステージで使用する参照テーブルのロード

F 関数(RGB マッピング、アルファマッピング)やノイズ変調データ、カラー参照テーブルといった、プロシージャルテクスチャで使用する参照テーブルをロードする関数には、浮動小数点数の配列で指定するもの(~Float())と、GPU のレジスタにそのまま書き込むデータの配列で指定するもの(~Native())が用意されています。なお、参照テーブルのロード関数はイミディエート関数ですので、実行時に 3D コマンドバッファにデータが書き込まれます。

コード 4-32. プロシージャルテクスチャステージで使用する参照テーブルのロード関数
class nn::gd::ProceduralTextureStage
{
    static nnResult UploadLookUpTableRgbMapFloat(
            u32 index, f32* Map, f32* MapDelta, u32 lutSize);
    static nnResult UploadLookUpTableRgbMapNative(
            u32 index, u32* Map, u32 lutSize);
    static nnResult UploadLookUpTableAlphaMapFloat(
            u32 index, f32* Map, f32* MapDelta, u32 lutSize);
    static nnResult UploadLookUpTableAlphaMapNative(
            u32 index, u32* Map, u32 lutSize);
    static nnResult UploadLookUpTableNoiseMapFloat(
            u32 index, f32* Map, f32* MapDelta, u32 lutSize);
    static nnResult UploadLookUpTableNoiseMapNative(
            u32 index, u32* Map, u32 lutSize);
    static nnResult UploadLookUpTableColorMapFloat(
            u32 index, f32** Map, f32** MapDelta, u32 lutSize);
    static nnResult UploadLookUpTableColorMapNative(
            u32 index, u32* Map, u32* MapDelta, u32 lutSize);
};

index lutSize の指定によって、参照テーブルを部分的に書き換えることができます。ただし、その合計が下表で示されている要素の最大値を超えるような指定ではエラーが発生します。

浮動小数点数の配列で参照テーブルをロードする場合、データ(Map)と差分値(MapDelta)の 2 つの配列を用意する必要があります。ただし、カラー参照テーブルをロードする場合は 4 つのカラー成分それぞれで用意するため、8 つの配列が必要です。

ネイティブフォーマットに変換された配列で参照テーブルをロードする場合、カラー参照テーブル以外はデータと差分値が 1 つの要素にまとめられているため、用意する配列は 1 つだけです。

下表は、ロードする参照テーブル、配列のフォーマット、配列の要素の最大値を関数ごとに示したものです。

表 4-13. プロシージャルテクスチャステージで使用する参照テーブルのロード関数の一覧
関数 参照テーブル フォーマット 要素数の最大値
UploadLookUpTableRgbMapFloat() RGB マッピング 浮動小数点数 128
UploadLookUpTableRgbMapNative() RGB マッピング ネイティブ 128
UploadLookUpTableAlphaMapFloat() アルファマッピング 浮動小数点数 128
UploadLookUpTableAlphaMapNative() アルファマッピング ネイティブ 128
UploadLookUpTableNoiseMapFloat() ノイズ変調テーブル 浮動小数点数 128
UploadLookUpTableNoiseMapNative() ノイズ変調テーブル ネイティブ 128
UploadLookUpTableColorMapFloat() カラー参照テーブル 浮動小数点数 256
UploadLookUpTableColorMapNative() カラー参照テーブル ネイティブ 256

4.4.2.1. 参照テーブルのロードのヘルパー関数

浮動小数点数の配列をネイティブフォーマットに変換するヘルパー関数が用意されています。浮動小数点数の配列から参照テーブルをロードする関数は、内部でネイティブへのフォーマット変換が行われるために負荷が高く、ランタイムでの実行には向いていません。そのため、あらかじめネイティブフォーマットに変換されたデータを用意するか、初回ロード時にヘルパー関数でフォーマット変換を行っておくなどの実装を推奨します。

コード 4-33. 参照テーブルのロードのヘルパー関数
class nn::gd::ProceduralTextureStage::Helper
{
    static nnResult ConvertLookUpTableDataFloatToNative(
            f32* valueData, f32* deltaData, u32 lutSize, u32* destination);
    static nnResult ConvertColorLookUpTableDataFloatToNative(
            f32** refArray, f32** deltaArray, u32 lutSize,
            u32* destRef, u32* destDelta);
};

カラー参照テーブル以外は、データと差分値の組み合わせから 1 つのデータ(destination)が生成されます。生成されるデータは、ビット [23 : 12] が差分値を小数部 11 ビットの符号つき 12 ビット固定小数点数(負の値は 2 の補数表現)に変換した値、ビット [11 : 0] がデータを小数部 12 ビットの符号なし 12 ビット固定小数点数に変換した値です。

カラー参照テーブルは、RGBA 各成分のデータと差分値の組み合わせ(合計 8 つの配列)から 1 つのカラー値と差分値の組み合わせ(destRefdestDelta)が生成されます。生成されるカラー値、差分値ともに、各成分を変換した値がアルファ成分、青成分、緑成分、赤成分の順に上位ビットから 8 ビットずつ配置されていますが、値の変換方法が異なります。カラー値は 0.0 ~ 1.0 の範囲を 0 ~ 255 にマップしたときの符号なし 8 ビット整数に、差分値は -1.0 ~ 1.0 の範囲を小数部 7 ビットの符号つき 8 ビット固定小数点数(負の値は 2 の補数表現)に、それぞれ変換しています。

補足:

変換方法の詳細は「3DS プログラミングマニュアル - グラフィックス応用編」を参照してください。

また、GD ライブラリには変換のためのユーティリティ関数が用意されています。

4.5. ライティングステージ

ライティングステージでは、グローバルライティング環境の設定と個別のライト設定を行います。これらの設定を行う関数は nn::gd::LightingStage クラスに定義されています。なお、ライティング環境の有効/無効をアプリケーションで設定する必要はありません。ライティングの設定はライブラリで管理されており、コンバイナ設定でライティングの結果が必要な場合にだけライティング環境が有効となるように実装されています。

以下の図はライティングステージで行われる設定の概要(個別のライトを除く)を示したものです。

図 4-5. ライティングステージの概要(個別のライトを除く)

LightingStageクラス グローバル設定 環境光 鏡面光のクランプ フレネルファクタ シャドウ 使用するテクスチャユニット シャドウ減衰(プライマリ) シャドウ減衰(セカンダリ) シャドウ減衰(アルファ成分) 反転 バンプマッピング バンプモード 参照テーブル レイヤコンフィグレーション D0/D1/SP/FR/RB/RG/RR 入力値の種類 入力値の絶対値化 出力値のスケール D0の有効化 D1の有効化 反射(RR/RG/RB)の有効化 SetGlobalColorAmbient() SetClampHighlight() SetFresnelSelector() SetShadowSelectorTexture() SetShadowPrimary() SetShadowSecondary() SetShadowAlpha() SetInvertShadow() SetBumpMode() SetBumpSelectorTexture() SetLayerConfiguration() UploadLookUpTable SetLookUpTableInputValue() SetLookUpTableAbsInput() SetLookUpTableOutputScaling() EnableLookUpTableD0() EnableLookUpTableD1() EnableLookUpTableReflection() カラー値 GD_TRUE GD_FALSE TextureStage::TextureUnitId BumpMode LayerConfiguration LookUpTableInputValue LookUpTableOutputScaleValue

4.5.1. グローバルライティング環境の設定

グローバルライティング環境の各パラメータに対する設定を行う関数が用意されています。

コード 4-34. グローバルライティング環境のパラメータ設定関数
class nn::gd::LightingStage
{
    static void SetGlobalColorAmbient(u8 R, u8 G, u8 B);
    static void SetClampHightlight(gdBool value);
    static void SetFresnelSelector(FresnelSelectorType fresnelSelectorType);

    static void SetShadowSelectorTexture(
        nn::gd::TextureStage::TextureUnitId textureUnit);
    static void SetShadowPrimary(gdBool value);
    static void SetShadowSecondary(gdBool value);
    static void SetShadowAlpha(gdBool value);
    static void SetInvertShadow(gdBool value);

    static void SetBumpMode(BumpMode bumpMode, gdBool bumpRenorm);
    static void SetBumpSelectorTexture(
        nn::gd::TextureStage::TextureUnitId textureUnit);
};

下表に、それぞれの関数で設定が行われるパラメータを示します。引数の指定方法やパラメータの影響については関数リファレンスなどを参照してください。

表 4-14. ライティングステージの関数で設定が行われるパラメータ
関数 パラメータ
SetGlobalColorAmbient() グローバル環境光の光源色(デフォルト:(10, 10, 10))
SetClampHightlight() 鏡面光のクランプ(デフォルト:GD_TRUE
SetFresnelSelector() フレネルファクタ(デフォルト:FRESNEL_SELECTOR_TYPE_NO_FRESNEL
SetShadowSelectorTexture() シャドウで使用するテクスチャユニット(デフォルト:TEXTURE_UNIT_0
SetShadowPrimary() プライマリカラーへのシャドウの影響(デフォルト:GD_FALSE
SetShadowSecondary() セカンダリカラーへのシャドウの影響(デフォルト:GD_FALSE
SetShadowAlpha() アルファ成分へのシャドウの影響(デフォルト:GD_FALSE
SetInvertShadow() シャドウ項の反転(デフォルト:GD_FALSE
SetBumpMode() バンプマッピングの摂動モードと法線の第 3 成分の再生成(デフォルト:BUMPMODE_NOT_USED, GD_FALSE
SetBumpSelectorTexture() バンプマッピングで使用するテクスチャユニット(デフォルト:TEXTURE_UNIT_0
補足:

SetGlobalColorAmbient() はイミディエート関数です。

4.5.2. レイヤコンフィグレーションと参照テーブルの設定

ライティングで使用される参照テーブルを決定するレイヤコンフィグレーション、参照テーブルへの入力値、参照テーブルからの出力値のスケーリング、ディストリビューションファクタ、反射を設定する関数が用意されています。

コード 4-35. 参照テーブルに関係するパラメータの設定関数
class nn::gd::LightingStage
{
    static void SetLayerConfiguration(LayerConfiguration layerConfiguration);
    static void SetLookUpTableInputValue(
        LookUpTableId lutId, LookUpTableInputValue lutInputValue);
    static void SetLookUpTableAbsInput(LookUpTableId lutId, gdBool value);
    static void SetLookUpTableOutputScaling(
        LookUpTableId lutId, LookUpTableOutputScaleValue outputScalingValue);
    static void EnableLookUpTableD0(gdBool value);
    static void EnableLookUpTableD1(gdBool value);
    static void EnableLookUpTableReflection(gdBool value);
};

下表に、それぞれの関数で設定が行われるパラメータを示します。引数の指定方法やパラメータの影響については関数リファレンスなどを参照してください。

表 4-15. ライティングステージの関数で設定が行われる参照テーブルに関するパラメータ
関数 パラメータ
SetLayerConfiguration() レイヤコンフィグレーション(デフォルト:LAYER_CONFIGURATION_0
SetLookUpTableInputValue() 参照テーブルへの入力値(デフォルト:参照テーブルすべて INPUT_VALUE_NH
SetLookUpTableAbsInput() 参照テーブルへの入力値の絶対値化(デフォルト:参照テーブルすべて GD_FALSE
SetLookUpTableOutputScaling() 参照テーブルからの出力値のスケーリング(デフォルト:参照テーブルすべて OUTPUT_SCALE_VALUE_1
EnableLookUpTableD0() ディストリビューションファクタ 0 への参照テーブルの適用(デフォルト:GD_FALSE
EnableLookUpTableD1() ディストリビューションファクタ 1 への参照テーブルの適用(デフォルト:GD_FALSE
EnableLookUpTableReflection() 反射への参照テーブルの適用(デフォルト:GD_FALSE

4.5.3. ライティングステージで使用する参照テーブルのロード

ライティングで使用する参照テーブルをロードする関数には、浮動小数点数の配列で指定するもの(UploadLookUpTableFloat())と、GPU のレジスタにそのまま書き込むデータの配列で指定するもの(UploadLookUpTableNative())が用意されています。なお、参照テーブルのロード関数はイミディエート関数ですので、実行時に 3D コマンドバッファにデータが書き込まれます。

コード 4-36. ライティングステージで使用する参照テーブルのロード関数
class nn::gd::LightingStage
{
    static nnResult UploadLookUpTableFloat(
        LookUpTableUploadId lutID, u32 lutStartIndex,
        const f32* valueData, const f32* deltaData, u32 dataCount);
    static nnResult UploadLookUpTableNative(
        LookUpTableUploadId lutID, u32 lutStartIndex,
        const u32* data, u32 dataCount);

    class Helper
    {
        static nnResult ConvertLookUpTableDataFloatToNative(
            const f32* valueData, const f32* deltaData, u32 dataCount,
            u32* __restrict destination);
    };
};

ライティングで使用する参照テーブルの要素数は 256 固定です。lutStartIndexdataCount の指定によって、参照テーブルを部分的に書き換えることができますが、その合計が 256 を超えるような指定ではエラーが発生します。

なお、参照テーブルへの入力値が絶対値化されるかどうかによって、参照テーブルの構成が異なります。絶対値化しない(入力値の範囲が -1.0~1.0)場合は、参照テーブルの 128 番目と 129 番目の要素に対応する入力値が不連続になる(0.9922 から -1.0 にジャンプする)ことに注意してください。

浮動小数点数の配列で参照テーブルをロードする場合、データ(valueData)と差分値(deltaData)の 2 つの配列を用意する必要があります。

ネイティブフォーマットに変換された配列で参照テーブルをロードする場合、参照テーブルにロードするデータはデータと差分値が 1 つの要素にまとめられているため、用意する配列は 1 つだけです。

浮動小数点数の配列をネイティブフォーマットに変換するヘルパー関数が用意されています。ヘルパー関数では、データと差分値の組み合わせから 1 つのデータ(destination)を生成します。生成されるデータは、ビット [23 : 12] が差分値を小数部 11 ビットの符号つき 12 ビット固定小数点数(小数部は絶対値)に変換した値、ビット [11 : 0] がデータを小数部 12 ビットの符号なし 12 ビット固定小数点数に変換した値です。

補足:

変換方法の詳細は「3DS プログラミングマニュアル - グラフィックス応用編」を参照してください。

また、GD ライブラリには変換のためのユーティリティ関数が用意されています。

4.5.4. ライト

3DS のハードウェアは 8 個のライトによるライティングに対応しています。GD ライブラリでは、個々のライトを nn::gd::Light クラスの個別のインスタンスとして表現し、nn::gd::LightingStage クラスに内包するようにして 8 個分の Light オブジェクトがライブラリの初期化時に作成されます。そのため、アプリケーションで Light オブジェクトを作成する必要はなく、nn::gd::LightingStage::light[0].EnableLight(GD_TRUE) のように、ライティングステージに定義されたメンバとしてアクセスします。

以下の図は Light オブジェクトで行われる設定の概要を示したものです。

図 4-6. Light オブジェクトの概要

Lightクラス 設定 ライトの有効化 ライトの種類 両面ライティング シャドウ減衰 ジオメトリファクタ0の有効化 ジオメトリファクタ1の有効化 光源色 環境光 拡散光 鏡面光0 鏡面光1 位置/方向 光源の位置 光源の方向 スポットライト/距離減衰 SP/DA スポットライト(SP)の有効化 スポットライトの方向 距離減衰(DA)の有効化 距離減衰のスケール、バイアス EnableLight() SetLightType() EnableToSideDiffuse() EnableShadowed() EnableGeomFactor0() EnableGeomFactor1() SetColorAmbient() SetColorDiffuse() SetColorSpecular0() SetColorSpecular1() SetPosition() SetDirection() UploadLookUpTable EnableSpotLight() SetSpotDirection() EnableDistanceAttenuation() SetDistanceAttenuationScaleBias() GD_TRUE GD_FALSE SourceType カラー値 座標値 方向ベクトル 参照テーブル スケール、バイアス

4.5.4.1. ライトの設定

ライトの各パラメータに対する設定を行う関数が用意されています。

コード 4-37. ライトのパラメータ設定関数
class nn::gd::Light
{
    void EnableLight(gdBool value);
    void SetLightType(SourceType sourceType);
    void EnableTwoSideDiffuse(gdBool value);
    void EnableShadowed(gdBool value);
    void EnableGeomFactor0(gdBool value);
    void EnableGeomFactor1(gdBool value);

    void SetColorAmbient(u8 R, u8 G, u8 B);
    void SetColorDiffuse(u8 R, u8 G, u8 B);
    void SetColorSpecular0(u8 R, u8 G, u8 B);
    void SetColorSpecular1(u8 R, u8 G, u8 B);

    void SetPosition(f32 X, f32 Y, f32 Z);
    void SetDirection(f32 X, f32 Y, f32 Z);

    void EnableSpotLight(gdBool value);
    void SetSpotDirection(f32 X, f32 Y, f32 Z);
    void EnableDistanceAttenuation(gdBool value);
    void SetDistanceAttenuationScaleBias(
        f32 attenuationScale, f32 attenuationBias);
    nnResult UploadLookUpTableFloat(
        LightLookUpTableUploadId lightLutID, u32 lutStartIndex,
        const f32* valueData, const f32* deltaData, u32 dataCount);
    nnResult UploadLookUpTableNative(
        LightLookUpTableUploadId lightLutID, u32 lutStartIndex,
        const u32* data, u32 dataCount);
};

下表に、それぞれの関数で設定が行われるパラメータを示します。引数の指定方法やパラメータの影響については関数リファレンスなどを参照してください。

表 4-16. Light オブジェクトの関数で設定が行われるパラメータ
関数 パラメータ
EnableLight() ライトの有効化(デフォルト:GD_FALSE
SetLightType() 光源の種類(デフォルト:SOURCE_TYPE_POINT(点光源))
EnableTwoSideDiffuse() 両面ライティングの有効化(デフォルト:GD_FALSE
EnableShadowed() シャドウ減衰の有効化(デフォルト:GD_FALSE
EnableGeomFactor0() ジオメトリファクタ 0 の有効化(デフォルト:GD_FALSE
EnableGeomFactor1() ジオメトリファクタ 1 の有効化(デフォルト:GD_FALSE
SetColorAmbient() 環境光の色(デフォルト:(0, 0, 0))
SetColorDiffuse() 拡散光の色(デフォルト:(255, 255, 255))
SetColorSpecular0() 鏡面光 0 の色(デフォルト:(255, 255, 255))
SetColorSpecular1() 鏡面光 1 の色(デフォルト:(255, 255, 255))
SetPosition() 点光源の位置(デフォルト:(0.0, 0.0, 0.0))
SetDirection() 平行光源の方向(デフォルト設定なし)
EnableSpotLight() スポットライトの有効化(デフォルト:GD_FALSE
SetSpotDirection() スポットライトの方向(デフォルト:(0.0, 0.0, 0.0))
EnableDistanceAttenuation() 距離減衰の有効化(デフォルト:GD_FALSE
SetDistanceAttenuationScaleBias()

距離減衰のスケールとバイアス(デフォルト:0.0, 0.0)

開始距離と終了距離から設定値を求めるユーティリティ関数(Utils::ConvertStartEndToScaleBias())が用意されています。

参照テーブルの指定を除いて、参照テーブルのロード方法はライティングステージでの参照テーブルのロード方法と同じです。なお、距離減衰(DA)で使用する参照テーブルは入力値の範囲が 0.0~1.0 であることを想定して作成されていなければなりません。

補足:

ライトの設定を行う関数は、EnableLight()EnableShadowed()EnableSpotLight()EnableDistanceAttenuation() を除いて、すべてイミディエート関数です。

4.6. ラスタライザステージ

ラスタライザステージでは、フラグメントパイプラインに出力されるピクセルのラスタライズ処理の設定を行います。これらの設定を行う関数は nn::gd::RasterizerStage クラスに定義されています。

以下の図はラスタライザステージで行われる設定の概要を示したものです。

図 4-7. ラスタライザステージの概要

RasterizerStageクラス カリング カリングモード ビューポート クリッピング 有効化 クリッピング面 シザーテスト シザーボックス アーリーデプステスト 設定 バッファのクリア SetCulling() SetViewport() EnableClippingPlane() SetClippingPlane() EnableScissor() SetScissor() SetEarlyDepthTest() ClearEarlyDepth() Culling Viewportクラス GD_TRUE GD_FALSE クリッピング面のパラメータ EarlyDepthFunction クリアに使用するデプス値

4.6.1. カリングの設定

カリングの設定は nn::gd::RasterizerStage::SetCulling() で行います。

コード 4-38. カリングの設定関数
static void nn::gd::RasterizerStage::SetCulling(
        nn::gd::RasterizerStage::Culling culling);

culling にカリングの方法を指定します。デフォルトでは時計回り(CULLING_CLOCKWISE)が指定されています。

4.6.2. ビューポートの設定

ビューポートの設定は nn::gd::RasterizerStage::SetViewport() で行います。

コード 4-39. ビューポートの設定関数
class nn::gd::Viewport
{
    u32 m_X;
    u32 m_Y;
    u32 m_Width;
    u32 m_Height;

    Viewport();
    Viewport(u32 x, u32 y, u32 width, u32 height);
    void Set(u32 x, u32 y, u32 width, u32 height);
};

static void nn::gd::RasterizerStage::SetViewport(
        nn::gd::Viewport& viewport);

ビューポートの領域は nn::gd::Viewport クラスで定義します。ビューポートの方向は LCD の配置方向と異なることに注意してください。デフォルトでは Viewport(0, 0, 240, 320) が設定されています。

4.6.3. クリッピングの設定

クリッピングの設定は以下の関数で行います。

コード 4-40. クリッピングの設定関数
static void nn::gd::RasterizerStage::EnableClippingPlane(gdBool value);
static void nn::gd::RasterizerStage::SetClippingPlane(
        f32 param1, f32 param2, f32 param3, f32 param4);

デフォルトではクリッピングは無効(GD_FALSE)で、パラメータはすべて 0 に設定されています。

4.6.4. シザーテストの設定

シザーテストの設定は以下の関数で行います。

コード 4-41. シザーテストの設定関数
static void nn::gd::RasterizerStage::EnableScissor(gdBool value);
static void nn::gd::RasterizerStage::SetScissor(
        nn::gd::Viewport& area);

デフォルトではシザーテストは無効(GD_FALSE)で、シザーボックスには Viewport(0, 0, 0, 0) が設定されています。

4.6.5. アーリーデプステストの設定

アーリーデプステストの設定は以下の関数で行います。

コード 4-42. アーリーデプステストの設定関数
static void nn::gd::RasterizerStage::SetEarlyDepthTest(
        gdBool enable, nn::gd::RasterizerStage::EarlyDepthFunction func);
static void nn::gd::RasterizerStage::ClearEarlyDepth(f32 depthClearValue);

デフォルトではアーリーデプステストは無効(GD_FALSE, EARLYDEPTH_FUNCTION_LESS)で、クリアに使用するデプス値には 1.0 が設定されています。

アーリーデプステストを使用する場合は、ブロックモードがブロック 32 モードに設定されていなければなりません。詳しくは「3DS プログラミングマニュアル - グラフィックス応用編」の「ブロックモードの設定」を参照してください。

4.7. コンバイナステージ

コンバイナステージでは、(テクスチャ)コンバイナとコンバイナバッファの設定を行います。これらの設定を行う関数は nn::gd::CombinerStage クラスに定義されています。

以下の図はコンバイナステージで行われる設定の概要を示したものです。

図 4-8. コンバイナステージの概要

CombinerStageクラス 定数カラー(ユニット0~5) ステートオブジェクト(コンバイナ設定) SetTextureCombinerUnitConstantColor() SetTextureCombinerState() CreateTextureCombinerState() カラー値 CombinerStateオブジェクト CombinerDescriptionクラス

4.7.1. コンバイナ設定

コンバイナステージでは、すべてのコンバイナとコンバイナバッファの設定をひとまとめにしたステートオブジェクト(CombinerState オブジェクト)を作成し、CombinerState オブジェクトを切り替えることで定数カラー以外のコンバイナに関する設定を一括で変更することができます。

CombinerState オブジェクトはオペランドなどの設定が定義されたデスクリプタクラス(CombinerDescription)から作成します。

コード 4-43. コンバイナ設定の作成、解放、パイプラインへの設定
static nnResult nn::gd::CombinerStage::CreateTextureCombinerState(
        const nn::gd::CombinerDescription* description,
        nn::gd::CombinerState** textureCombinerState);
static nnResult nn::gd::CombinerStage::ReleaseTextureCombinerState(
        nn::gd::CombinerState* textureCombinerState);
static nnResult nn::gd::CombinerStage::SetTextureCombinerState(
        nn::gd::CombinerState* textureCombinerState);

コンバイナへの設定は description に指定するデスクリプタクラス(CombinerDescription)にあらかじめ設定します。デスクリプタクラスに設定する情報の詳細は後述します。

作成された CombinerState オブジェクトは nn::gd::CombinerStage::SetTextureCombinerState() でコンバイナステージに設定することができます。

不要になったステートオブジェクトは nn::gd::CombinerStage::ReleaseTextureCombinerState() で解放してください。このとき、オブジェクトが作成されたときに内部で確保されたメモリ領域も解放されます。

コンバイナへの設定のうち、定数カラーの設定だけは以下の関数で行います。デフォルトの定数カラーは不定値ですので、コンバイナ設定で定数カラーを使用する場合は必ず設定を行ってください。

コード 4-44. 定数カラーの設定
static nnResult nn::gd::CombinerStage::SetTextureCombinerUnitConstantColor(
        nn::gd::CombinerStage::UnitId unit,
        u8 colorR, u8 colorG, u8 colorB, u8 colorA);

この関数はイミディエート関数ですので、実行と同時にコマンドバッファへの 3D コマンドの蓄積を行います。

4.7.1.1. CombinerState オブジェクトのデスクリプタクラス

CombinerState オブジェクトのデスクリプタクラス(CombinerDescription クラス)のメンバを紹介し、設定に際しての注意点などを説明します。

CombinerDescription クラスは 6 つのコンバイナユニットの設定を内包しています。必ずしもすべてのユニットに対して設定を行うことがないため、ユニットを指定してメンバ変数への設定を行うメンバ関数を呼び出すように設計されています。

コード 4-45. CombinerDescription クラスの定義
class nn::gd::CombinerDescription
{
    struct BufferInput
    {
        nn::gd::CombinerStage::BufferInput m_Rgb1; 
        nn::gd::CombinerStage::BufferInput m_Rgb2;
        nn::gd::CombinerStage::BufferInput m_Rgb3;
        nn::gd::CombinerStage::BufferInput m_Rgb4;
        nn::gd::CombinerStage::BufferInput m_Alpha1;
        nn::gd::CombinerStage::BufferInput m_Alpha2;
        nn::gd::CombinerStage::BufferInput m_Alpha3;
        nn::gd::CombinerStage::BufferInput m_Alpha4;
    };
    struct BufferInput m_BufferInput;

    void SetSourceRGB(
            nn::gd::CombinerStage::UnitId unit,
            nn::gd::CombinerStage::Source sourceRGB1,
            nn::gd::CombinerStage::Source sourceRGB2,
            nn::gd::CombinerStage::Source sourceRGB3);
    void SetOperandRGB(
            nn::gd::CombinerStage::UnitId unit,
            nn::gd::CombinerStage::OperandRgb opRGB1,
            nn::gd::CombinerStage::OperandRgb opRGB2,
            nn::gd::CombinerStage::OperandRgb opRGB3);
    void SetSourceAlpha(
            nn::gd::CombinerStage::UnitId unit,
            nn::gd::CombinerStage::Source sourceA1,
            nn::gd::CombinerStage::Source sourceA2,
            nn::gd::CombinerStage::Source sourceA3);
    void SetOperandAlpha(
            nn::gd::CombinerStage::UnitId unit,
            nn::gd::CombinerStage::OperandAlpha opA1,
            nn::gd::CombinerStage::OperandAlpha opA2,
            nn::gd::CombinerStage::OperandAlpha opA3);
    void SetCombineRGB(
            nn::gd::CombinerStage::UnitId unit,
            nn::gd::CombinerStage::CombineRgb combineRgb);
    void SetCombineAlpha(
            nn::gd::CombinerStage::UnitId unit,
            nn::gd::CombinerStage::CombineAlpha combineAlpha);
    void SetScaleRGB(
            nn::gd::CombinerStage::UnitId unit,
            nn::gd::CombinerStage::Scale scaleRgb);
    void SetScaleAlpha(
            nn::gd::CombinerStage::UnitId unit,
            nn::gd::CombinerStage::Scale scaleAlpha);
    void SetBufferColor(u8 colorR, u8 colorG, u8 colorB, u8 colorA);
    void SetCombinerInUse(nn::gd::CombinerStage::UnitId unit, gdBool mode);

    CombinerDescription();
    void ToDefault();
};
入力ソースの設定(SetSourceRGB()、SetSourceAlpha())

指定されたコンバイナユニットの入力ソース 0~2 を設定します。

オペランドの設定(SetOperandRGB()、SetOperandAlpha())

指定されたコンバイナユニットのオペランド 0~2 を設定します。

コンバイナ関数の設定(SetCombineRGB()、SetCombineAlpha())

指定されたコンバイナユニットのコンバイナ関数を設定します。

スケーリング値の設定(SetScaleRGB()、SetScaleAlpha())

指定されたコンバイナユニットのスケーリング値を設定します。

コンバイナバッファ 0 の定数カラーの設定(SetBufferColor())

コンバイナバッファ 0 の定数カラーを設定します。

コンバイナバッファの入力ソース(m_BufferInput)

コンバイナバッファ 1~4 の入力ソースを設定します。設定用の関数は用意されていません。

コンバイナユニットの使用設定(SetCombinerInUse())

指定されたコンバイナユニットの設定内容を有効(GD_TRUE)または無効(GD_FALSE)に設定します。設定内容を有効にしなければ、そのユニットの設定はデフォルトの設定になります。

デフォルトの設定(ToDefault())

ToDefault() で、すべてのメンバをデフォルトの値に変更することができます。この設定はコンストラクタでも行われています。

表 4-17. デフォルトのコンバイナ設定
メンバ デフォルトの設定内容

SetSourceRGB()

SetSourceAlpha()

SOURCE_CONSTANT(ユニット 0 のすべての入力ソース)

SOURCE_PREVIOUS(ユニット 1~5 のすべての入力ソース)

SetOperandRGB() OPERAND_RGB_SRC_COLOR(すべてのオペランド)
SetOperandAlpha() OPERAND_ALPHA_SRC_ALPHA(すべてのオペランド)
SetCombineRGB() COMBINE_RGB_REPLACE(すべてのユニット)
SetCombineAlpha() COMBINE_ALPHA_REPLACE(すべてのユニット)

SetScaleRGB()

SetScaleAlpha()

SCALE_1(すべてのユニット)
SetBufferColor() (0, 0, 0, 0)
m_BufferInput INPUT_PREVIOUS_BUFFER(すべての入力)
SetCombinerInUse() GD_FALSE(すべてのユニット)

4.8. フォグステージ

フォグステージでは、フォグとガスの描画に関連するすべての設定を行います。これらの設定を行うための関数は nn::gd::FogStage クラスに定義されています。

以下の図はフォグステージで行われる設定の概要を示したものです。

図 4-9. フォグステージの概要

FogStageクラス モード設定 フォグモード フォグ フォグカラー 入力値の反転 フォグ参照テーブル ガス シェーディング密度情報 密度の減衰 密度の最大値 密度の自動更新 平面シェーディング強度の設定 視線シェーディング強度の設定 デプス方向の減衰 参照テーブルの入力値 シェーディング参照テーブル SetGasFogMode() SetFogColor() setFogZFlip() UploadFogLookUpTable SetGasShadingDensity() SetGasAttenuation() SetGasAccumulationMax() SetGasAutoAccumulation() SetGasLightXY() SetGasLightZ() SetGasDeltaZ() SetGasLightColorLutInput() UploadGasLookUpTable Mode カラー値 GD_TRUE GD_FALSE 参照テーブル GasShadingDensitySource 係数 最大値 最小値 減衰 方向 GasColorLookUpTableInput

4.8.1. フォグモード

GPU のフォグ機能のモード切り替えは nn::gd::FogStage::SetGasFogMode() で行います。

コード 4-46. フォグモードの切り替え
static void nn::gd::FogStage::SetGasFogMode(nn::gd::FogStage::Mode mode);

mode に指定する値は以下のものから選択します。

表 4-18. フォグモードの指定
定義 説明
FogStage::MODE_NONE フォグ機能を使用しません。(デフォルト)
FogStage::MODE_FOG フォグ機能を通常のフォグモードで使用します。
FogStage::MODE_GAS フォグ機能をガスモードで使用します。

4.8.2. フォグの設定

フォグの各パラメータに対する設定を行う関数が用意されています。

コード 4-47. フォグのパラメータ設定関数
class nn::gd::FogStage
{
    static void SetFogColor(u8 R, u8 G, u8 B);
    static void SetFogZFlip(gdBool zFlip);
};

下表に、それぞれの関数で設定が行われるパラメータを示します。引数の指定方法やパラメータの影響については関数リファレンスなどを参照してください。

表 4-19. フォグステージの関数で設定が行われるフォグのパラメータ
関数 パラメータ
SetFogColor() フォグカラー(デフォルト:(0, 0, 0))
SetFogZFlip() 入力デプス値の反転(デフォルト:GD_FALSE
補足:

参照テーブルのロード方法については「4.8.4. フォグステージで使用する参照テーブルのロード」を参照してください。

4.8.3. ガスの設定

ガスの各パラメータに対する設定を行う関数が用意されています。

コード 4-48. ガスのパラメータ設定関数
class nn::gd::FogStage
{
    static void SetGasShadingDensity(
        GasShadingDensitySource shadingDensitySrc);
    static void SetGasAttenuation(f32 attenuation);
    static void SetGasAccumulationMax(f32 maxAccumulation);
    static void SetGasAutoAccumulation(gdBool enableAutoAccumulation);
    static void SetGasLightXY(
        u8 lightMinimum, u8 lightMaximum, u8 lightAttenuation);
    static void SetGasLightZ(
        u8 scattMinimum, u8 scattMaximum, u8 scattAttenuation, u8 lz);
    static void SetGasDeltaZ(f32 deltaZ);
    static void SetGasLightColorLutInput(
        GasColorLookUpTableInput colorLutInput);
};

下表に、それぞれの関数で設定が行われるパラメータを示します。引数の指定方法やパラメータの影響については関数リファレンスなどを参照してください。

表 4-20. フォグステージの関数で設定が行われるガスのパラメータ
関数 パラメータ
SetGasShadingDensity() シェーディングで使用する密度情報(デフォルト:GAS_SHADING_DENSITY_SOURCE_PLAIN
SetGasAttenuation() シェーディングのアルファ値の計算で使用する密度減衰の係数(デフォルト:1.0)
SetGasAccumulationMax() 密度情報の最大値の逆数(デフォルト:1.0)
SetGasAutoAccumulation() 密度情報の最大値の逆数を自動的に計算するかどうか(デフォルト:GD_FALSE
SetGasLightXY() 平面シェーディングの制御に使用する最小強度、最大強度、密度の減衰(デフォルト:(0, 0, 0))
SetGasLightZ() 視線シェーディングの制御に使用する最小強度、最大強度、密度の減衰、視線方向の影響(デフォルト:(0, 0, 0, 0))
SetGasDeltaZ() デプス方向の減衰係数(デフォルト:10.0)
SetGasLightColorLutInput() シェーディング参照テーブルへの入力値(デフォルト:GAS_COLOR_INPUT_LIGHT_FACTOR
補足:

参照テーブルのロード方法については「4.8.4. フォグステージで使用する参照テーブルのロード」を参照してください。

4.8.4. フォグステージで使用する参照テーブルのロード

フォグステージで使用するフォグ係数の参照テーブルとシェーディング参照テーブルをロードする関数には、浮動小数点数の配列で指定するもの(~Float())と、GPU のレジスタにそのまま書き込むデータの配列で指定するもの(~Native())が用意されています。なお、参照テーブルのロード関数はイミディエート関数ですので、実行時に 3D コマンドバッファにデータが書き込まれます。

コード 4-49. フォグステージで使用する参照テーブルのロード関数
class nn::gd::FogStage
{
    static nnResult UploadFogLookUpTableNative(
        u32 lutStartIndex, u32* data, u32 countData);
    static nnResult UploadFogLookUpTableFloat(
        u32 lutStartIndex, const f32* dataValue, const f32* dataDelta,
        u32 countData);
    static nnResult UploadGasLookUpTableNative(
        u32 lutStartIndex, u32* data, u32 countData);
    static nnResult UploadGasLookUpTableFloat(
        u32 lutStartIndex, f32* dataValue, f32* dataDelta, u32 countData);
};

lutStartindex countData の指定によって、参照テーブルを部分的に書き換えることができます。ただし、その合計が下表で示されている要素の最大値を超えるような指定ではエラーが発生します。

浮動小数点数の配列で参照テーブルをロードする場合、データ(dataValue)と差分値(dataDelta)の 2 つの配列を用意する必要があります。ただし、シェーディング参照テーブルは 3 要素(カラー成分を RGB の順番で格納)から 1 つのデータが生成されるため、要素数が(countData * 3)の配列を指定しなければならないことに注意してください。

ネイティブフォーマットに変換された配列で参照テーブルをロードする場合、データと差分値が 1 つの要素にまとめられているため、用意する配列は 1 つだけです。ただし、シェーディング参照テーブルのロードで用意する配列の要素数の最大値が、ネイティブの配列と浮動小数点数の配列とで異なることに注意してください。

下表は、ロードする参照テーブル、配列のフォーマット、配列の要素の最大値を関数ごとに示したものです。

表 4-21. フォグステージで使用する参照テーブルのロード関数の一覧
関数 参照テーブル フォーマット 要素数の最大値
UploadFogLookUpTableFloat() フォグ係数 浮動小数点数 128
UploadFogLookUpTableNative() フォグ係数 ネイティブ 128
UploadGasLookUpTableFloat() シェーディング 浮動小数点数 8
UploadGasLookUpTableNative() シェーディング ネイティブ 16

4.8.4.1. 参照テーブルのロードのヘルパー関数

浮動小数点数の配列をネイティブフォーマットに変換するヘルパー関数が用意されています。浮動小数点数の配列から参照テーブルをロードする関数は、内部でネイティブへのフォーマット変換が行われるために負荷が高く、ランタイムでの実行には向いていません。そのため、あらかじめネイティブフォーマットに変換されたデータを用意するか、初回ロード時にヘルパー関数でフォーマット変換を行っておくなどの実装を推奨します。

コード 4-50. 参照テーブルのロードのヘルパー関数
class nn::gd::FogStage::Helper
{
    static nnResult ConvertFogLookUpTableDataFloatToNative(
        const f32* dataValue, const f32* dataDelta, u32 countData,
        u32 *__restrict dest);
    static nnResult ConvertGasLookUpTableDataFloatToNative(
        const f32* dataValue, const f32* dataDelta, u32 countData,
        u32 *__restrict dest);
};

フォグステージで用意されているヘルパー関数は、いずれもデータと差分値の組み合わせから 1 つのデータ(dest)を生成します。

フォグ係数の参照テーブル用に生成されるデータは、ビット [23 : 13] がデータを小数部 11 ビットの符号なし 11 ビット固定小数点数に変換した値、ビット [12 : 0] が差分値を小数部 11 ビットの符号つき 13 ビット固定小数点数(負の値は 2 の補数表現)に変換した値です。

シェーディング参照テーブル用に生成されるデータは特殊です。特に変換元の配列の 3 要素(R、G、B の順)から 1 つのデータを生成することと、変換後の配列では 1 つのデータの中にデータと差分値が変換されるのではなく、配列の前半 8 つと後半 8 つそれぞれにデータと差分値が変換されることに注意してください。

前半の 8 つは差分値から生成されます。生成されるデータは、RGB 各成分の差分値を符号つき 8 ビット整数に変換したものを、ビット [23 : 16] に B 成分、ビット [15 : 8] に G 成分、ビット [7 : 0] に R 成分をパッキングしたものです。

後半の 8 つはデータから生成されます。生成されるデータは、RGB 各成分のデータを小数部 0 ビットの符号なし 8 ビット固定小数点数に変換したものを、ビット [23 : 16] に B 成分、ビット [15 : 8] に G 成分、ビット [7 : 0] に R 成分をパッキングしたものです。

補足:

変換方法の詳細は「3DS プログラミングマニュアル - グラフィックス応用編」を参照してください。

また、GD ライブラリには変換のためのユーティリティ関数が用意されています。

4.9. アウトプットステージ

アウトプットステージでは、ブレンディングやデプステスト、ステンシルテスト、ターゲットバッファの設定など、ピクセル出力に関するすべての設定を行います。これらの設定を行う関数は nn::gd::OutputStage クラスに定義されています。

以下の図はアウトプットステージで行われる設定の概要を示したものです。

図 4-10. アウトプットステージの概要

OutputStageクラス フレームバッファ レンダーターゲット デプスステンシルターゲット 書き込みマスク フラグメント オペレーションモード デプスバッファのモード ソフトシャドウの設定 デプステスト、ステンシルテスト ステートオブジェクト(デプスステンシルテスト設定) アルファテスト アルファテストの設定 論理演算、ブレンディング ステートオブジェクト(ブレンディング設定) 定数カラー SetRenderTarget() SetDepthStencilTarget() SetColorWriteMask() SetFragOpMode() SetDepthRangeMode() SetPenumbraScaleBias() SetDepthStencilState() SetAlphaTest() SetBlendState() SetBlendColor() RenderTagetオブジェクト DepthStencilTargetオブジェクト ColorWriteMask FragmentOperationMode DepthBufferType スケール、バイアス DepthStencilStateオブジェクト 比較方法、参照値 BlendStateオブジェクト カラー値

4.9.1. フラグメントオペレーションモード

フラグメントオペレーションモードの切り替えは nn::gd::OutputStage::SetFragOpMode() で行います。

コード 4-51. フラグメントオペレーションモードの設定関数
static void nn::gd::OutputStage::SetFragOpMode(
        nn::gd::OutputStage::FragmentOperationMode fragOpMode);

fragOpMode に指定する値は以下のものから選択します。

表 4-22. フラグメントオペレーションモード
定義 説明
FRAGMENT_OPERATION_MODE_FRAGMENT_COLOR 標準のフラグメント処理(デフォルト)
FRAGMENT_OPERATION_MODE_GAS_ACCUMULATION シャドウ累積パス用のフラグメント処理
FRAGMENT_OPERATION_MODE_SHADOW_MAP ガスの密度情報描画用のフラグメント処理

4.9.2. フレームバッファ

GD ライブラリでは RenderTarget オブジェクトと DepthStencilTarget オブジェクトでフレームバッファ(カラーバッファとデプスステンシルバッファ)を扱います。どちらのオブジェクトも 1 つの Texture2DResource オブジェクトとそれぞれのデスクリプタクラス(RenderTargetDescriptionDepthStencilTargetDescription)から作成されます。なお、デスクリプタクラスの設定によって、Texture2DResource オブジェクトがミップマップデータを含んでいる場合に、オブジェクトの作成にどのレベルのミップマップデータを使用するかを指定することができます。

フレームバッファオブジェクト(RenderTarget オブジェクトおよび DepthStencilTarget オブジェクト)の作成と解放、パイプラインへの設定は以下の関数で行うことができます。

コード 4-52. フレームバッファオブジェクトの作成、解放、パイプラインへの設定
static nnResult nn::gd::OutputStage::CreateRenderTarget(
        const nn::gd::Texture2DResource* texture2DResource,
        const nn::gd::RenderTargetDescription* desc,
        nn::gd::RenderTarget** renderTarget);
static nnResult nn::gd::OutputStage::ReleaseRenderTarget(
        nn::gd::RenderTarget* renderTarget);
static nnResult nn::gd::OutputStage::SetRenderTarget(
        const nn::gd::RenderTarget* renderTarget);

static nnResult nn::gd::OutputStage::CreateDepthStencilTarget(
        const nn::gd::Texture2DResource* texture2DResource,
        const nn::gd::DepthStencilTargetDescription* desc,
        nn::gd::DepthStencilTarget** depthStencil);
static nnResult nn::gd::OutputStage::ReleaseDepthStencilTarget(
        nn::gd::DepthStencilTarget* depthStencil);
static nnResult nn::gd::OutputStage::SetDepthStencilTarget(
        const nn::gd::DepthStencilTarget* depthStencil);

関数名が~RenderTarget() のものはカラーバッファに対して、~DepthStencilTarget() のものはデプス(ステンシル)バッファに対して処理を行う関数です。

フレームバッファの設定は desc に指定するそれぞれのデスクリプタクラス(RenderTargetDescription または DepthStencilTargetDescription)にあらかじめ設定します。デスクリプタクラスに設定する情報の詳細は「4.9.2.1. フレームバッファオブジェクトのデスクリプタクラス」を参照してください。

フレームバッファに使用することのできる Texture2DResource オブジェクトのピクセルフォーマットは制限されています。詳しくは「3.1.1. Texture2DResource オブジェクトの作成」を参照してください。

作成されたフレームバッファオブジェクトは nn::gd::OutputStage::Set() でフレームバッファに設定することができます。

不要になったフレームバッファオブジェクトは nn::gd::OutputStage::Release() で解放してください。このとき、フレームバッファオブジェクトの管理情報のみが解放されます。Texture2DResource オブジェクトは解放されません。

4.9.2.1. フレームバッファオブジェクトのデスクリプタクラス

フレームバッファオブジェクト(RenderTarget オブジェクトと DepthStencilTarget オブジェクト)のデスクリプタクラス(RenderTargetDescription クラスと DepthStencilTargetDescription クラス)のメンバを紹介し、設定に際しての注意点などを説明します。

コード 4-53. フレームバッファオブジェクトのデスクリプタクラスの定義
class nn::gd::RenderTargetDescription
{
    u32 m_MipLevelIndex;
};
class nn::gd::DepthStencilTargetDescription
{
    u32 m_MipLevelIndex;
}; 
ミップマップレベルのインデックス(m_MipLevelIndex)

フレームバッファオブジェクトの作成に使用する Texture2DResource オブジェクトのミップマップレベルです。

4.9.2.2. フレームバッファオブジェクトの詳細情報の取得

詳細情報(TargetProperties クラス)には、作成時に指定された Texture2DResource オブジェクトの内容を元にしたフレームバッファに関する情報が格納されています。

詳細情報の取得で使用する関数は RenderTarget オブジェクトと DepthStencilTarget オブジェクトで異なりますが、取得するのは同じ TargetProperties クラスです。

コード 4-54. フレームバッファオブジェクトの詳細情報の取得
static nnResult nn::gd::OutputStage::GetRenderTargetProperties(
        const nn::gd::RenderTarget* renderTarget,
        nn::gd::TargetProperties* properties);
static nnResult nn::gd::OutputStage::GetDepthStencilTargetProperties(
        const nn::gd::DepthStencilTarget* depthStencil,
        nn::gd::TargetProperties* properties);

オブジェクトの作成時に指定したミップマップレベルによって、幅や高さ、ミップマップレベル、リソースデータの先頭アドレスが変化することはありますが、基本的に Texture2DResource オブジェクトの詳細情報と同じです。

コード 4-55. TargetProperties クラスの定義
class nn::gd::TargetProperties
{
    u32 m_Width;
    u32 m_Height;
    u32 m_PixelSize;
    nn::gd::Resource::NativeFormat m_Format;
    nn::gd::Memory::MemoryLayout m_MemLayout;
    nn::gd::Memory::MemoryLocation m_MemLocation;
    u8* m_MemAddr;
};

4.9.2.3. フレームバッファのクリア

指定した値でカラーバッファとデプス(ステンシル)バッファをクリアすることができます。

コード 4-56. フレームバッファのクリア
static nnResult nn::gd::Memory::ClearTargets(
        const nn::gd::RenderTarget* renderTarget,
        const nn::gd::DepthStencilTarget* depthStencilTarget,
        const u8 ColorRGBA[4], float depth, u8 stencil);

この関数内で nngxAddMemoryFillCommand() を呼び出していますので、実際の処理はコマンドリストの実行時に行われます。

4.9.2.4. カラーマスク

nn::gd::OutputStage::SetColorWriteMask() でカラーマスクの設定を変更し、カラーバッファへの書き込みを制御することができます。

コード 4-57. カラーマスクの設定関数
 static void nn::gd::OutputStage::SetColorWriteMask(u32 mask);

mask には、以下のフラグの論理和を指定します。

表 4-23. カラーマスクのフラグ
定義 説明
COLOR_WRITE_MASK_ENABLE_RED 赤成分の書き込みを有効に設定
COLOR_WRITE_MASK_ENABLE_GREEN 緑成分の書き込みを有効に設定
COLOR_WRITE_MASK_ENABLE_BLUE 青成分の書き込みを有効に設定
COLOR_WRITE_MASK_ENABLE_ALPHA アルファ成分の書き込みを有効に設定
COLOR_WRITE_MASK_ENABLE_ALL すべての成分の書き込みを有効に設定(デフォルト)

4.9.3. デプステスト、ステンシルテスト

デプステストとステンシルテストの設定はステートオブジェクト(DepthStencilState オブジェクト)を作成し、アウトプットステージに設定する DepthStencilState オブジェクトを切り替えることでデプステストとステンシルテストに関する設定を一括で変更することができます。

DepthStencilState オブジェクトの作成と解放、パイプラインへの設定は以下の関数で行うことができます。

コード 4-58. DepthStencilState オブジェクトの作成、解放、パイプラインへの設定
static nnResult nn::gd::OutputStage::CreateDepthStencilState(
        const nn::gd::DepthStencilStateDescription* desc,
        nn::gd::DepthStencilState** DepthStencilState);
static nnResult nn::gd::OutputStage::ReleaseDepthStencilState(
        nn::gd::DepthStencilState* DepthStencilState);
static nnResult nn::gd::OutputStage::SetDepthStencilState(
        const nn::gd::DepthStencilState* state, u8 stencilRef);

デプスとステンシルのテストの設定は desc に指定するデスクリプタクラス(DepthStencilStateDescription)にあらかじめ設定します。デスクリプタクラスに設定する情報の詳細は「4.9.3.1. DepthStencilState オブジェクトのデスクリプタクラス」を参照してください。

作成されたステートオブジェクトは nn::gd::OutputStage::SetDepthStencilState() でパイプラインに設定することができます。stencilRef には、ステンシルテストで使用する参照値を指定します。

不要になったステートオブジェクトは nn::gd::OutputStage::ReleaseDepthStencilState() で解放してください。このとき、ステートオブジェクトとして作成されたときに内部で確保されたメモリ領域も解放されます。

4.9.3.1. DepthStencilState オブジェクトのデスクリプタクラス

DepthStencilState オブジェクトのデスクリプタクラス(DepthStencilStateDescription クラス)のメンバを紹介し、設定に際しての注意点などを説明します。

コード 4-59. DepthStencilStateDescription クラスの定義
class nn::gd::DepthStencilStateDescription
{
    gdBool                                  m_DepthEnable;
    gdBool                                  m_StencilEnable;
    u8                                      m_StencilWriteMask;
    u8                                      m_StencilReadMask;
    nn::gd::OutputStage::DepthWriteMask     m_DepthMask;
    nn::gd::OutputStage::DepthFunction      m_DepthFunc;
    nn::gd::OutputStage::StencilFunction    m_StencilFunc;
    nn::gd::OutputStage::StencilOperation   m_StencilFail;
    nn::gd::OutputStage::StencilOperation   m_StencilZFail;
    nn::gd::OutputStage::StencilOperation   m_StencilZPass;

    DepthStencilStateDescription();
    void ToDefault();
};
デプステストの有効化(m_DepthEnable)

デプステストを有効にする場合は GD_TRUE を設定します。

デプステストのライトマスク(m_DepthMask)

デプステストのライトマスクを設定します。

デプステストの比較関数(m_DepthFunc)

デプステストの比較関数を設定します。

ステンシルテストの有効化(m_StencilEnable)

ステンシルテストを有効にする場合は GD_TRUE を設定します。

ステンシルテストのライトマスク(m_StencilWriteMask)

ステンシルテストのライトマスクを設定します。

ステンシルテストのリードマスク(m_StencilReadMask)

ステンシルテストのリードマスクを設定します。

ステンシルテストの比較関数(m_StencilFunc)

ステンシルテストの比較関数を設定します。

ステンシルテストの失敗時の処理(m_StencilFail)

ステンシルテストの失敗時の処理を設定します。

ステンシルテストの成功時の処理(m_StencilZFail)

ステンシルテストに成功したが、デプステストに失敗したときの処理を設定します。

ステンシルテストとデプステストの成功時の処理(m_StencilZPass)

ステンシルテストとデプステストの両方が成功したときの処理を設定します。

デフォルトの設定(ToDefault())

ToDefault() で、すべてのメンバをデフォルトの値に変更することができます。この設定はコンストラクタでも行われています。

表 4-24. DepthStencilStateDescription クラスのデフォルト設定
メンバ デフォルトの設定内容
m_DepthEnable GD_FALSE
m_DepthMask DEPTH_WRITE_MASK_ALL
m_DepthFunc DEPTH_FUNCTION_LESS
m_StencilEnable GD_FALSE

m_StencilWriteMask

m_StencilReadMask

0xFF
m_StencilFunc STENCIL_FUNCTION_NEVER

m_StencilFail

m_StencilZFail

m_StencilZPass

STENCIL_OPERATION_KEEP

4.9.4. アルファテスト

アルファテストの設定は nn::gd::OutputStage::SetAlphaTest() で行います。

コード 4-60. アルファテストの設定
static void nn::gd::OutputStage::SetAlphaTest(
        gdBool enable, nn::gd::OutputStage::AlphaFunction func, u8 alphaRef);

アルファテストを有効にする場合は enableGD_TRUEfunc に比較関数、alphaRef に参照値を指定してください。デフォルトの設定は、引数の順に GD_FALSEALPHA_FUNCTION_NEVER0 です。

4.9.5. 論理演算、ブレンディング

論理演算とブレンディングの設定はステートオブジェクト(BlendState オブジェクト)を作成し、アウトプットステージに設定する BlendState オブジェクトを切り替えることで論理演算とブレンディングに関する設定を一括で変更することができます。

BlendState オブジェクトの作成と解放、パイプラインへの設定は以下の関数で行うことができます。

コード 4-61. BlendState オブジェクトの作成、解放、パイプラインへの設定
static nnResult nn::gd::OutputStage::CreateBlendState(
        const nn::gd::BlendStateDescription* desc,
        nn::gd::BlendState** blendState);
static nnResult nn::gd::OutputStage::ReleaseBlendState(
        nn::gd::BlendState* blendState);
static nnResult nn::gd::OutputStage::SetBlendState(
        const nn::gd::BlendState* blendState);

論理演算とブレンディングの設定は desc に指定するデスクリプタクラス(BlendStateDescription)にあらかじめ設定します。デスクリプタクラスに設定する情報の詳細は後述します。

作成された BlendState オブジェクトは nn::gd::OutputStage::SetBlendState() でパイプラインに設定することができます。

不要になったステートオブジェクトは nn::gd::OutputStage::ReleaseBlendState() で解放してください。このとき、ステートオブジェクトとして作成されたときに内部で確保されたメモリ領域も解放されます。

ブレンディングの設定のうち、ブレンドカラーの設定だけは以下の関数で行います。デフォルトのブレンドカラーは(0, 0, 0, 0)です。

コード 4-62. ブレンドカラーの設定
 static void nn::gd::OutputStage::SetBlendColor(u8 R, u8 G, u8 B, u8 A);

4.9.5.1. BlendState オブジェクトのデスクリプタクラス

BlendState オブジェクトのデスクリプタクラス(BlendStateDescription クラス)のメンバを紹介し、設定に際しての注意点などを説明します。

コード 4-63. BlendStateDescription クラスの定義
class nn::gd::BlendStateDescription
{
    nn::gd::OutputStage::BlendType m_BlendType;
    nn::gd::OutputStage::LogicOperator m_LogicOp;
    nn::gd::OutputStage::BlendFunction m_SrcRgb;
    nn::gd::OutputStage::BlendFunction m_DstRgb;
    nn::gd::OutputStage::BlendFunction m_SrcAlpha;
    nn::gd::OutputStage::BlendFunction m_DstAlpha;
    nn::gd::OutputStage::BlendEquation m_EqRgb;
    nn::gd::OutputStage::BlendEquation m_EqAlpha;

    BlendStateDescription();
    void ToDefault();

    void SetBlendFunc(
        nn::gd::OutputStage::BlendFunction src,
        nn::gd::OutputStage::BlendFunction dst,
        nn::gd::OutputStage::BlendEquation eq);
    void SetBlendFunc(
        nn::gd::OutputStage::BlendFunction srcRgb,
        nn::gd::OutputStage::BlendFunction dstRgb,
        nn::gd::OutputStage::BlendFunction srcAlpha,
        nn::gd::OutputStage::BlendFunction dstAlpha,
        nn::gd::OutputStage::BlendEquation eqRgb,
        nn::gd::OutputStage::BlendEquation eqAlpha);

    void SetBlendMode_DefaultBlending();
    void SetBlendMode_NoBlend();

    void SetLogicOperatorMode(nn::gd::OutputStage::LogicOperator logicOp);
    void SetLogicOperatorMode_Default();
};
論理演算とブレンディングの選択(m_BlendType)

論理演算を使用する場合は BLEND_TYPE_LOGICOP、ブレンディングを使用する場合は BLEND_TYPE_BLENDING を設定します。

論理演算の演算方法(m_LogicOp)

論理演算使用時の演算方法です。SetLogicOperatorMode() で設定することができます。

SetLogicOperatorMode_Default() で設定した場合は LOGIC_OPERATOR_COPY が設定されます。

ブレンディングの重み係数(m_SrcRgb、m_DstRgb、m_SrcAlpha、m_DstAlpha)

ブレンディングの重み係数です。ソースとデスティネーションそれぞれに RGB 成分とアルファ成分の設定が存在します。

ブレンディングの計算式(m_EqRgb、m_EqAlpha)

ブレンディングの計算式です。RGB 成分とアルファ成分の設定が存在します。

ブレンディングの一括設定(SetBlendFunc()、SetBlendMode_NoBlend())

SetBlendFunc() はブレンディングの設定を一括して行います。RGB 成分とアルファ成分を同じまたは個別に設定することができます。

SetBlendMode_NoBlend() はブレンディングが行われない(ソースそのままを出力する)設定に変更します。

表 4-25. SetBlendMode_NoBlend() によるブレンディング設定の変更
メンバ 設定
m_SrcRgb、m_SrcAlpha BLEND_FUNCTION_ONE
m_DstRgb、m_DstAlpha BLEND_FUNCTION_ZERO
m_EqRgb、m_EqAlpha BLEND_EQUATION_ADD
デフォルトの設定(ToDefault())

ToDefault() で、すべてのメンバをデフォルトの値に変更することができます。この設定はコンストラクタでも行われています。

デフォルトの設定ではブレンディングを使用し、ブレンディングの設定は SetBlendMode_NoBlend() で行われる設定と同じです。

4.9.6. w バッファ、ポリゴンオフセット

w バッファとポリゴンオフセットの設定は nn::gd::OutputStage::SetDepthRangeMode() で行います。

コード 4-64. w バッファとポリゴンオフセットの設定
static void nn::gd::OutputStage::SetDepthRangeMode(
        nn::gd::OutputStage::DepthBufferType type,
        f32 depthRangeNear, f32 depthRangeFar, s32 offset);

type には、w バッファの機能を使用する場合は DEPTHBUFFER_LINEAR を指定し、w バッファの機能を使用せずに通常のデプス値の範囲を使用する場合は DEPTHBUFFER_RECIPROCAL_FUNCTION を指定します。

depthRangeNear depthRangeFar には、w バッファの機能を使用しない場合はデプスのニア値とファー値を指定します。w バッファの機能を使用する場合は depthRangeNear に 0、depthRangeFar にスケール値を指定します。

ポリゴンオフセット機能を使用する場合は、offset にポリゴンオフセットのオフセット値を指定します。

4.9.7. ソフトシャドウ

ソフトシャドウのスケールとバイアスの設定は nn::gd::OutputStage::SetPenumbraScaleBias() で行います。この関数はイミディエート関数ですので、実行と同時にコマンドバッファへの 3D コマンドの蓄積を行います。

コード 4-65. ソフトシャドウの設定
static void nn::gd::OutputStage::SetPenumbraScaleBias(f32 Scale, f32 Bias);