4.1. シェーダステージ
シェーダステージでは頂点シェーダおよびジオメトリシェーダに関する設定を行います。これらの設定を行う関数は nn::gd::ShaderStage
クラスに定義されています。
以下の図はシェーダステージで行われる設定の概要を示したものです。
頂点シェーダおよびジオメトリシェーダは、事前にコンパイルされたシェーダバイナリファイルとしてアプリケーションに読み込まれます。シェーダバイナリファイルには、1 つ以上の頂点シェーダやジオメトリシェーダのシェーダプログラムを含むことができます。
シェーダバイナリファイルの中に記述されている特定のシェーダを参照するためには、読み込んだシェーダバイナリファイルを nn::gd::ShaderStage::CreateShaderBinary()
に渡して作成された 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 つのシェーダコード(頂点シェーダ、ジオメトリシェーダのいずれか)を表します。
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()
で作成されます。
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
オブジェクトを生成してパイプラインに反映しています。
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 コマンドバッファに出力されません。
レジスタの種類によって、値の設定に使用する関数は以下のように異なります。
レジスタの種類 | 関数 |
---|---|
浮動小数点定数レジスタ |
nn::gd::ShaderStage::SetShaderPipelineConstantFloat()
|
ブールレジスタ |
nn::gd::ShaderStage::SetShaderPipelineConstantBoolean()
|
整数レジスタ |
nn::gd::ShaderStage::SetShaderPipelineConstantInteger()
|
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()
で独自にレジスタの設定値を変更することができます。
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
)で構成されています。
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
クラスの作成例です。
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」なレジスタには、以下のようなコードで直接書き込むことになります。
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.1. 頂点バッファの登録
頂点バッファは頂点入力ステージに 12 個あるスロットに登録します。nn::gd::VertexInputStage::SetVertexBuffers()
では VertexBufferResource
オブジェクトの配列と頂点データの開始オフセットの配列を指定しますので、一度の呼び出しで連続する複数のスロットに頂点バッファを登録することができます。
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()
で頂点入力ステージに登録します。
static nnResult nn::gd::VertexInputStage::SetIndexBuffer( nn::gd::VertexBufferResource* indexBuffer, nn::gd::VertexInputStage::IndexFormat format, u32 offset);
indexBuffer
に指定されている VertexBufferResource
オブジェクトが頂点入力ステージに登録されます。頂点データなどとインターリーブされている VertexBufferResource
オブジェクトを登録する場合は、頂点インデックスの開始位置をバイト単位のオフセット値を offset
に指定します。
format
には、頂点インデックスのフォーマットを以下から選択して指定します。
定義 | 説明 |
---|---|
INDEX_FORMAT_UBYTE
|
頂点インデックスを unsigned byte の配列として扱います。 |
INDEX_FORMAT_USHORT
|
頂点インデックスを unsigned short の配列として扱います。 |
4.2.3. プリミティブの種類
描画するプリミティブの種類は nn::gd::VertexInputStage::SetPrimitiveTopology()
で設定します。
static nnResult nn::gd::VertexInputStage::SetPrimitiveTopology( nn::gd::VertexInputStage::PrimitiveTopology primitiveTopology);
primitiveTopology
には、プリミティブの種類を以下から選択して指定します。
定義 | 説明 |
---|---|
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()
の呼び出しで作成します。
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 つの頂点バッファを記述するデスクリプタクラスから作成された入力レイアウトをパイプライン(頂点入力ステージ)に設定するものです。
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
)のメンバを紹介し、設定に際しての注意点などを説明します。
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)
入力要素のデータフォーマットです。以下から選択して設定します。
定義 | 説明 |
---|---|
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.1. 2 次元テクスチャ
GD ライブラリでは Texture2D
オブジェクトで 2 次元テクスチャを扱います。Texture2D
オブジェクトは 1 つの Texture2DResource
オブジェクトとデスクリプタクラス(Texture2DDescription
)から作成されます。なお、デスクリプタクラスの設定によって、Texture2DResource
オブジェクトがミップマップデータを含んでいる場合に、Texture2D
オブジェクトの作成にどのレベルのミップマップデータを使用するかを指定することができます。デスクリプタクラスに設定する情報の詳細は「4.3.1.1. Texture2D オブジェクトのデスクリプタクラス」を参照してください。
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
オブジェクトを作成するコードの例です。
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
)のメンバを紹介し、設定に際しての注意点などを説明します。
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()
で取得することができます。
static nnResult nn::gd::TextureStage::GetTexture2DProperties( const nn::gd::Texture2D* texture2D, nn::gd::Texture2DProperties* properties);
オブジェクトの作成時に指定したミップマップレベルによって、幅や高さ、ミップマップレベル、リソースデータの先頭アドレスが変化することはありますが、基本的に Texture2DResource
オブジェクトの詳細情報と同じです。
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
オブジェクトの作成と解放は以下の関数で行うことができます。
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
)のメンバを紹介し、設定に際しての注意点などを説明します。
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()
で取得することができます。
static nnResult nn::gd::TextureStage::GetTextureCubeProperties( const nn::gd::TextureCube* TextureCube, nn::gd::TextureCubeProperties* properties);
6 面分のリソースデータの先頭アドレスが保持されていることや、ミップマップデータのアドレス情報の取得で faceIndex
にキューブマップ面を指定すること以外は Texture2DProperties
クラスと同じです。
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 つの論理的なテクスチャユニットを提供しています。
定義 | 設定可能なテクスチャの種類 |
---|---|
(テクスチャユニット 0) |
2 次元テクスチャ(ガス、シャドウ含む) キューブマップテクスチャ(シャドウ含む) プロジェクションテクスチャ |
(テクスチャユニット 1) |
2 次元テクスチャ |
(テクスチャユニット 2) |
2 次元テクスチャ |
(テクスチャユニット 3) |
プロシージャルテクスチャ |
テクスチャ座標以外の TextureStage::TEXTURE_UNIT_3_PROCEDURAL
への設定は、プロシージャルテクスチャステージで行います。
2 次元テクスチャ
2 次元テクスチャの設定は nn::gd::TextureStage::SetTexture()
で行います。設定対象となるテクスチャユニットはテクスチャユニット 0/1/2 の 3 つです。
static nnResult nn::gd::TextureStage::SetTexture( nn::gd::TextureStage::TextureUnitId textureUnitId, nn::gd::Texture2D& texture2D);
そのほかのテクスチャ(プロシージャルテクスチャを除く)
そのほかのテクスチャ(プロシージャルテクスチャを除く)はテクスチャユニット 0 にのみ設定することができます。
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 に入力されるテクスチャ座標の設定は以下の関数で行われます。
// 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);
それぞれの関数には、以下の引数が指定可能です。
定義 | 入力されるテクスチャ座標 |
---|---|
UNIT2_TEXTURE_COORDINATE_FROM_UNIT_2
|
テクスチャ座標 2(デフォルト) |
UNIT2_TEXTURE_COORDINATE_FROM_UNIT_1
|
テクスチャ座標 1 |
定義 | 入力されるテクスチャ座標 |
---|---|
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
オブジェクト)を作成し、それをテクスチャユニットに設定することで行われます。
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 への設定を行っています。
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
クラス)のメンバを紹介し、設定に際しての注意点などを説明します。
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()
で、すべてのメンバをデフォルトの値に変更することができます。この設定はコンストラクタでも行われています。
メンバ | 設定値 |
---|---|
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()
で、すべてのメンバをシャドウテクスチャ用の値に変更することができます。
メンバ | 設定値 |
---|---|
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()
で、すべてのメンバをシャドウキューブマップテクスチャ用の値に変更することができます。
メンバ | 設定値 |
---|---|
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()
で、すべてのメンバをガステクスチャ用の値に変更することができます。
メンバ | 設定値 |
---|---|
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.1. プロシージャルテクスチャのパラメータ設定
プロシージャルテクスチャの各パラメータに対する設定を行う関数が用意されています。
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); };
下表に、それぞれの関数で設定が行われるパラメータを示します。引数の指定方法やパラメータの影響については関数リファレンスなどを参照してください。
関数 | パラメータ |
---|---|
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 コマンドバッファにデータが書き込まれます。
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 つだけです。
下表は、ロードする参照テーブル、配列のフォーマット、配列の要素の最大値を関数ごとに示したものです。
関数 | 参照テーブル | フォーマット | 要素数の最大値 |
---|---|---|---|
UploadLookUpTableRgbMapFloat()
|
RGB マッピング | 浮動小数点数 | 128 |
UploadLookUpTableRgbMapNative()
|
RGB マッピング | ネイティブ | 128 |
UploadLookUpTableAlphaMapFloat()
|
アルファマッピング | 浮動小数点数 | 128 |
UploadLookUpTableAlphaMapNative()
|
アルファマッピング | ネイティブ | 128 |
UploadLookUpTableNoiseMapFloat()
|
ノイズ変調テーブル | 浮動小数点数 | 128 |
UploadLookUpTableNoiseMapNative()
|
ノイズ変調テーブル | ネイティブ | 128 |
UploadLookUpTableColorMapFloat()
|
カラー参照テーブル | 浮動小数点数 | 256 |
UploadLookUpTableColorMapNative()
|
カラー参照テーブル | ネイティブ | 256 |
4.4.2.1. 参照テーブルのロードのヘルパー関数
浮動小数点数の配列をネイティブフォーマットに変換するヘルパー関数が用意されています。浮動小数点数の配列から参照テーブルをロードする関数は、内部でネイティブへのフォーマット変換が行われるために負荷が高く、ランタイムでの実行には向いていません。そのため、あらかじめネイティブフォーマットに変換されたデータを用意するか、初回ロード時にヘルパー関数でフォーマット変換を行っておくなどの実装を推奨します。
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 つのカラー値と差分値の組み合わせ(destRef
と destDelta
)が生成されます。生成されるカラー値、差分値ともに、各成分を変換した値がアルファ成分、青成分、緑成分、赤成分の順に上位ビットから 8 ビットずつ配置されていますが、値の変換方法が異なります。カラー値は 0.0 ~ 1.0 の範囲を 0 ~ 255 にマップしたときの符号なし 8 ビット整数に、差分値は -1.0 ~ 1.0 の範囲を小数部 7 ビットの符号つき 8 ビット固定小数点数(負の値は 2 の補数表現)に、それぞれ変換しています。
変換方法の詳細は「3DS プログラミングマニュアル - グラフィックス応用編」を参照してください。
また、GD ライブラリには変換のためのユーティリティ関数が用意されています。
4.5. ライティングステージ
ライティングステージでは、グローバルライティング環境の設定と個別のライト設定を行います。これらの設定を行う関数は nn::gd::LightingStage
クラスに定義されています。なお、ライティング環境の有効/無効をアプリケーションで設定する必要はありません。ライティングの設定はライブラリで管理されており、コンバイナ設定でライティングの結果が必要な場合にだけライティング環境が有効となるように実装されています。
以下の図はライティングステージで行われる設定の概要(個別のライトを除く)を示したものです。
4.5.1. グローバルライティング環境の設定
グローバルライティング環境の各パラメータに対する設定を行う関数が用意されています。
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); };
下表に、それぞれの関数で設定が行われるパラメータを示します。引数の指定方法やパラメータの影響については関数リファレンスなどを参照してください。
関数 | パラメータ |
---|---|
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. レイヤコンフィグレーションと参照テーブルの設定
ライティングで使用される参照テーブルを決定するレイヤコンフィグレーション、参照テーブルへの入力値、参照テーブルからの出力値のスケーリング、ディストリビューションファクタ、反射を設定する関数が用意されています。
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); };
下表に、それぞれの関数で設定が行われるパラメータを示します。引数の指定方法やパラメータの影響については関数リファレンスなどを参照してください。
関数 | パラメータ |
---|---|
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 コマンドバッファにデータが書き込まれます。
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 固定です。lutStartIndex
と dataCount
の指定によって、参照テーブルを部分的に書き換えることができますが、その合計が 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.5.4.1. ライトの設定
ライトの各パラメータに対する設定を行う関数が用意されています。
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); };
下表に、それぞれの関数で設定が行われるパラメータを示します。引数の指定方法やパラメータの影響については関数リファレンスなどを参照してください。
関数 | パラメータ |
---|---|
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) 開始距離と終了距離から設定値を求めるユーティリティ関数( |
参照テーブルの指定を除いて、参照テーブルのロード方法はライティングステージでの参照テーブルのロード方法と同じです。なお、距離減衰(DA)で使用する参照テーブルは入力値の範囲が 0.0~1.0 であることを想定して作成されていなければなりません。
ライトの設定を行う関数は、EnableLight()
、EnableShadowed()
、EnableSpotLight()
、EnableDistanceAttenuation()
を除いて、すべてイミディエート関数です。
4.6. ラスタライザステージ
ラスタライザステージでは、フラグメントパイプラインに出力されるピクセルのラスタライズ処理の設定を行います。これらの設定を行う関数は nn::gd::RasterizerStage
クラスに定義されています。
以下の図はラスタライザステージで行われる設定の概要を示したものです。
4.6.1. カリングの設定
カリングの設定は nn::gd::RasterizerStage::SetCulling()
で行います。
static void nn::gd::RasterizerStage::SetCulling( nn::gd::RasterizerStage::Culling culling);
culling
にカリングの方法を指定します。デフォルトでは時計回り(CULLING_CLOCKWISE
)が指定されています。
4.6.2. ビューポートの設定
ビューポートの設定は nn::gd::RasterizerStage::SetViewport()
で行います。
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. クリッピングの設定
クリッピングの設定は以下の関数で行います。
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. シザーテストの設定
シザーテストの設定は以下の関数で行います。
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. アーリーデプステストの設定
アーリーデプステストの設定は以下の関数で行います。
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.7.1. コンバイナ設定
コンバイナステージでは、すべてのコンバイナとコンバイナバッファの設定をひとまとめにしたステートオブジェクト(CombinerState
オブジェクト)を作成し、CombinerState
オブジェクトを切り替えることで定数カラー以外のコンバイナに関する設定を一括で変更することができます。
CombinerState
オブジェクトはオペランドなどの設定が定義されたデスクリプタクラス(CombinerDescription
)から作成します。
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()
で解放してください。このとき、オブジェクトが作成されたときに内部で確保されたメモリ領域も解放されます。
コンバイナへの設定のうち、定数カラーの設定だけは以下の関数で行います。デフォルトの定数カラーは不定値ですので、コンバイナ設定で定数カラーを使用する場合は必ず設定を行ってください。
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 つのコンバイナユニットの設定を内包しています。必ずしもすべてのユニットに対して設定を行うことがないため、ユニットを指定してメンバ変数への設定を行うメンバ関数を呼び出すように設計されています。
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()
で、すべてのメンバをデフォルトの値に変更することができます。この設定はコンストラクタでも行われています。
メンバ | デフォルトの設定内容 |
---|---|
|
|
SetOperandRGB()
|
OPERAND_RGB_SRC_COLOR (すべてのオペランド) |
SetOperandAlpha()
|
OPERAND_ALPHA_SRC_ALPHA (すべてのオペランド) |
SetCombineRGB()
|
COMBINE_RGB_REPLACE (すべてのユニット) |
SetCombineAlpha()
|
COMBINE_ALPHA_REPLACE (すべてのユニット) |
|
SCALE_1 (すべてのユニット) |
SetBufferColor()
|
(0, 0, 0, 0) |
m_BufferInput
|
INPUT_PREVIOUS_BUFFER (すべての入力) |
SetCombinerInUse()
|
GD_FALSE (すべてのユニット) |
4.8. フォグステージ
フォグステージでは、フォグとガスの描画に関連するすべての設定を行います。これらの設定を行うための関数は nn::gd::FogStage
クラスに定義されています。
以下の図はフォグステージで行われる設定の概要を示したものです。
4.8.1. フォグモード
GPU のフォグ機能のモード切り替えは nn::gd::FogStage::SetGasFogMode()
で行います。
static void nn::gd::FogStage::SetGasFogMode(nn::gd::FogStage::Mode mode);
mode
に指定する値は以下のものから選択します。
定義 | 説明 |
---|---|
FogStage::MODE_NONE
|
フォグ機能を使用しません。(デフォルト) |
FogStage::MODE_FOG
|
フォグ機能を通常のフォグモードで使用します。 |
FogStage::MODE_GAS
|
フォグ機能をガスモードで使用します。 |
4.8.2. フォグの設定
フォグの各パラメータに対する設定を行う関数が用意されています。
class nn::gd::FogStage { static void SetFogColor(u8 R, u8 G, u8 B); static void SetFogZFlip(gdBool zFlip); };
下表に、それぞれの関数で設定が行われるパラメータを示します。引数の指定方法やパラメータの影響については関数リファレンスなどを参照してください。
関数 | パラメータ |
---|---|
SetFogColor()
|
フォグカラー(デフォルト:(0, 0, 0)) |
SetFogZFlip()
|
入力デプス値の反転(デフォルト:GD_FALSE ) |
参照テーブルのロード方法については「4.8.4. フォグステージで使用する参照テーブルのロード」を参照してください。
4.8.3. ガスの設定
ガスの各パラメータに対する設定を行う関数が用意されています。
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); };
下表に、それぞれの関数で設定が行われるパラメータを示します。引数の指定方法やパラメータの影響については関数リファレンスなどを参照してください。
関数 | パラメータ |
---|---|
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 コマンドバッファにデータが書き込まれます。
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 つだけです。ただし、シェーディング参照テーブルのロードで用意する配列の要素数の最大値が、ネイティブの配列と浮動小数点数の配列とで異なることに注意してください。
下表は、ロードする参照テーブル、配列のフォーマット、配列の要素の最大値を関数ごとに示したものです。
関数 | 参照テーブル | フォーマット | 要素数の最大値 |
---|---|---|---|
UploadFogLookUpTableFloat()
|
フォグ係数 | 浮動小数点数 | 128 |
UploadFogLookUpTableNative()
|
フォグ係数 | ネイティブ | 128 |
UploadGasLookUpTableFloat()
|
シェーディング | 浮動小数点数 | 8 |
UploadGasLookUpTableNative()
|
シェーディング | ネイティブ | 16 |
4.8.4.1. 参照テーブルのロードのヘルパー関数
浮動小数点数の配列をネイティブフォーマットに変換するヘルパー関数が用意されています。浮動小数点数の配列から参照テーブルをロードする関数は、内部でネイティブへのフォーマット変換が行われるために負荷が高く、ランタイムでの実行には向いていません。そのため、あらかじめネイティブフォーマットに変換されたデータを用意するか、初回ロード時にヘルパー関数でフォーマット変換を行っておくなどの実装を推奨します。
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.9.1. フラグメントオペレーションモード
フラグメントオペレーションモードの切り替えは nn::gd::OutputStage::SetFragOpMode()
で行います。
static void nn::gd::OutputStage::SetFragOpMode( nn::gd::OutputStage::FragmentOperationMode fragOpMode);
fragOpMode
に指定する値は以下のものから選択します。
定義 | 説明 |
---|---|
FRAGMENT_OPERATION_MODE_FRAGMENT_COLOR
|
標準のフラグメント処理(デフォルト) |
FRAGMENT_OPERATION_MODE_GAS_ACCUMULATION
|
シャドウ累積パス用のフラグメント処理 |
FRAGMENT_OPERATION_MODE_SHADOW_MAP
|
ガスの密度情報描画用のフラグメント処理 |
4.9.2. フレームバッファ
GD ライブラリでは RenderTarget
オブジェクトと DepthStencilTarget
オブジェクトでフレームバッファ(カラーバッファとデプスステンシルバッファ)を扱います。どちらのオブジェクトも 1 つの Texture2DResource
オブジェクトとそれぞれのデスクリプタクラス(RenderTargetDescription
と DepthStencilTargetDescription
)から作成されます。なお、デスクリプタクラスの設定によって、Texture2DResource
オブジェクトがミップマップデータを含んでいる場合に、オブジェクトの作成にどのレベルのミップマップデータを使用するかを指定することができます。
フレームバッファオブジェクト(RenderTarget
オブジェクトおよび DepthStencilTarget
オブジェクト)の作成と解放、パイプラインへの設定は以下の関数で行うことができます。
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
クラス)のメンバを紹介し、設定に際しての注意点などを説明します。
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
クラスです。
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
オブジェクトの詳細情報と同じです。
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. フレームバッファのクリア
指定した値でカラーバッファとデプス(ステンシル)バッファをクリアすることができます。
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()
でカラーマスクの設定を変更し、カラーバッファへの書き込みを制御することができます。
static void nn::gd::OutputStage::SetColorWriteMask(u32 mask);
mask
には、以下のフラグの論理和を指定します。
定義 | 説明 |
---|---|
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
オブジェクトの作成と解放、パイプラインへの設定は以下の関数で行うことができます。
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
クラス)のメンバを紹介し、設定に際しての注意点などを説明します。
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()
で、すべてのメンバをデフォルトの値に変更することができます。この設定はコンストラクタでも行われています。
メンバ | デフォルトの設定内容 |
---|---|
m_DepthEnable
|
GD_FALSE
|
m_DepthMask
|
DEPTH_WRITE_MASK_ALL
|
m_DepthFunc
|
DEPTH_FUNCTION_LESS
|
m_StencilEnable
|
GD_FALSE
|
|
0xFF
|
m_StencilFunc
|
STENCIL_FUNCTION_NEVER
|
|
STENCIL_OPERATION_KEEP
|
4.9.4. アルファテスト
アルファテストの設定は nn::gd::OutputStage::SetAlphaTest()
で行います。
static void nn::gd::OutputStage::SetAlphaTest( gdBool enable, nn::gd::OutputStage::AlphaFunction func, u8 alphaRef);
アルファテストを有効にする場合は enable
に GD_TRUE
、func
に比較関数、alphaRef
に参照値を指定してください。デフォルトの設定は、引数の順に GD_FALSE
、ALPHA_FUNCTION_NEVER
、0
です。
4.9.5. 論理演算、ブレンディング
論理演算とブレンディングの設定はステートオブジェクト(BlendState
オブジェクト)を作成し、アウトプットステージに設定する BlendState
オブジェクトを切り替えることで論理演算とブレンディングに関する設定を一括で変更することができます。
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)です。
static void nn::gd::OutputStage::SetBlendColor(u8 R, u8 G, u8 B, u8 A);
4.9.5.1. BlendState オブジェクトのデスクリプタクラス
BlendState
オブジェクトのデスクリプタクラス(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()
はブレンディングが行われない(ソースそのままを出力する)設定に変更します。
メンバ | 設定 |
---|---|
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()
で行います。
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
にポリゴンオフセットのオフセット値を指定します。