4. Module Descriptions

4.1. Shader Stage

The vertex shader and geometry shader are configured in the shader stage by functions defined in the nn::gd::ShaderStage class.

The following figure provides an overview of the settings made in the shader stage.

Figure 4-1. Overview of the Shader Stage

ShaderStage Class Shader Program SetShaderPipeline() ShaderPipeline Object Vertex Shader Geometry Shader Uniform Settings CreateShaderPipeline() Shader Object Shader Program (Vertex Shader) CreateShader() Shader Program (Geometry Shader) Shader Binary File CreateShaderBinary() ShaderBinary Object

Applications load vertex shaders and geometry shaders as precompiled shader binary files. A shader binary file can contain one or more vertex shader and geometry shader programs.

To access a particular shader in a shader binary file, pass the loaded shader binary file to the nn::gd::ShaderStage::CreateShaderBinary() function and then use the ShaderBinary object that is generated.

Code 4-1. Creating a ShaderBinary Object
static nnResult nn::gd::ShaderStage::CreateShaderBinary(
        const void* shaderBytecode, u32 bytecodeLength,
        nn::gd::ShaderBinary** shaderBinary); 

Specify the starting address of the buffer storing the loaded shader binary code in the shaderBytecode parameter, and specify the size of the code (in bytes) in the bytecodeLength parameter.

Use the pointer that you receive from shaderBinary to access the ShaderBinary object that you have created.

Use the nn::gd::ShaderStage::CreateShader() function to create a Shader object for accessing the shader program contained within the ShaderBinary object. A Shader object represents the code for a single shader (either a vertex shader or a geometry shader).

Code 4-2. Creating a Shader Object
static nnResult nn::gd::ShaderStage::CreateShader(
        nn::gd::ShaderBinary* shaderBinary, u32 shaderBinaryIndex,
        nn::gd::Shader** shader); 

If the ShaderBinary object specified in the shaderBinary parameter has multiple shader programs, specify the shader program index in the shaderBinaryIndex parameter to create a Shader object.

The function sets a pointer in the shader parameter to the created Shader object.

Call the nn::gd::ShaderStage::CreateShaderPipeline() function with one or two Shader objects to create a ShaderPipeline object that you can use to apply the shader programs to the pipeline.

Code 4-3. Creating a ShaderPipeline Object and Applying Shader Programs to the Pipeline
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); 

Use the vertexShader parameter to specify the Shader object to use as the vertex shader. Use the geometryShader parameter to specify the Shader object to use as the geometry shader, or NULL if a geometry shader is not required.

Use the unmanagedRegister parameter to specify a range of registers for which the library will not automatically generate commands. For more information about this setting, see 4.1.2. Commands Automatically Generated by the Library to Set Registers.

Warning:

The GD library does not check whether the vertex shader outputs the proper vertex attributes to the geometry shader. To ensure that the vertex attributes output by the vertex shader match the vertex attributes used as input to the geometry shader, create a ShaderPipeline object with the correct combination of Shader objects.

The following sample code first creates a ShaderPipeline object that only uses a vertex shader, and then applies that object to the pipeline.

Code 4-4. Configuring the Shader Stage
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. Configuring Registers for Shader Settings

A ShaderPipeline object maintains values configured for floating-point constant registers and other registers that are used for shader settings. The GD library allows you to use shader stage functions to change register values for shader settings. These functions update variables that are temporarily saved as the international state of the ShaderPipeline object, and are not output to the 3D command buffer until a render command request.

The following table shows which functions to use to set values in different types of registers.

Table 4-1. Register Types and Functions Called
Type of Register Function
Floating-point constant register nn::gd::ShaderStage::SetShaderPipelineConstantFloat
Boolean register nn::gd::ShaderStage::SetShaderPipelineConstantBoolean
Integer register nn::gd::ShaderStage::SetShaderPipelineConstantInteger
Code 4-5. Functions Used to Configure Values to Registers for Shader Settings
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); 

Get a UniformLocation object using the nn::gd::ShaderStage::GetShaderUniformLocation() function, and then use the object to specify which register value to change. Use the name parameter to specify the name of the uniform setting when getting the object. The IsValid() function of the UniformLocation object returns a value of 1 when the correct uniform setting has been obtained.

4.1.2. Commands Automatically Generated by the Library to Set Registers

Commands to set registers are normally generated automatically when a different ShaderPipeline object (from the one currently being applied) is applied to the pipeline. However, performance may be improved in some cases by generating commands that write directly to the registers, rather than having commands generated automatically.

The nn::gd::ShaderStage::SetFloatConstantBuffer() function takes this into account and allows you to change register settings independently.

Code 4-6. Changing Register Settings Independently
static nnResult nn::gd::ShaderStage::SetFloatConstantBuffer(
        nn::gd::ShaderStage::ShaderType shaderType,
        u32 firstRegisterIndex, u32 registerCount, f32* constantBufferSrc); 

This function can only change the value of unmanaged floating-point constant registers, which are not set by automatically generated commands. The range of unmanaged registers is specified by the ShaderPipelineUnmanagedRegisters object given as the unmanagedRegister argument when a ShaderPipeline object is created.

The ShaderPipelineUnmanagedRegisters class comprises an array of the UnmanagedRegistersInterval objects and the number of elements in that array. The UnmanagedRegistersInterval class comprises the shader type (m_ShaderType), the number of the first unmanaged register (m_FirstUnmanagedRegister), and the number of unmanaged registers (m_RegisterCount).

Code 4-7. Classes Used to Specify Unmanaged Registers
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;
}; 

The following sample code shows how to create a ShaderPipeline object that includes unmanaged registers.

Code 4-8. Creating a ShaderPipeline Object Including Unmanaged Registers
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); 

The following code is an example of writing directly to unmanaged registers.

Code 4-9. Writing to Unmanaged Registers
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); 

If a ShaderPipeline object has already been applied to the pipeline and you apply a new one that was generated from different ShaderBinary objects, all of the data in the ShaderBinary objects is output to the 3D command buffer during rendering. Because of the associated processing load, we recommend using unmanaged registers instead to minimize the number of 3D commands that are output.

4.2. Vertex Input Stage

The vertex input stage handles settings related to vertex data (vertex attributes) input to the pipeline. The nn::gd::VertexInputStage class defines functions that configure these settings.

The following diagram provides an overview of the settings made in the vertex input stage.

Figure 4-2. Overview of the Vertex Input Stage

VertexInputStage Class 12 Vertex Buffer Slots Vertex Index Buffer(s) Primitive Type State Object (Input Layout) SetVertexBuffers() SetIndexBuffer() SetPrimitiveTopology() SetInputLayout() VertexBufferResource Object Offset IndexFormat PrimitiveTopology InputLayout Object Shader Object InputElementDescription Class CreateInputLayout()

4.2.1. Registering Vertex Buffers

Vertex buffers are registered in the vertex input stage's 12 slots. By specifying an array of VertexBufferResource objects and an array of starting offsets to vertex data, you can register vertex buffers in multiple consecutive slots by making a single call to the nn::gd::VertexInputStage::SetVertexBuffers() function.

Code 4-10. Registering Vertex Buffers
static nnResult nn::gd::VertexInputStage::SetVertexBuffers(
        u32 startSlot, u32 numBuffers,
        nn::gd::VertexBufferResource** vertexBuffers, u32* offsets); 

Use the startSlot parameter to specify the first slot number (0–11) for registering a vertex buffer. Use the numBuffers parameter to specify the number of elements in the array of VertexBufferResource objects given to vertexBuffers. Use the offsets parameter to specify the starting offset for the vertex data array. You must register vertex buffers with the same number of vertex data elements defined by the InputLayout object (described in 4.2.4. Input Layout).

4.2.2. Using Vertex Indices

When you use vertex indices to render primitives, create a VertexBufferResource object by specifying an array of vertex indices as resource data, and then call the nn::gd::VertexInputStage::SetIndexBuffer() function to register that object to the vertex input stage.

Code 4-11. Registering Vertex Indices
static nnResult nn::gd::VertexInputStage::SetIndexBuffer(
        nn::gd::VertexBufferResource* indexBuffer,
        nn::gd::VertexInputStage::IndexFormat format, u32 offset); 

The VertexBufferResource object specified for the indexBuffer parameter is registered to the vertex input stage. When you register VertexBufferResource objects interleaved with vertex and other data, specify the starting offset (in bytes) of the vertex indices in the offset parameter.

You can specify one of the following vertex index formats for the format parameter.

Table 4-2. Specifying the Vertex Index Format
Definition Description
INDEX_FORMAT_UBYTE Vertex indices are treated as an unsigned byte array.
INDEX_FORMAT_USHORT Vertex indices are treated as an unsigned short array.

4.2.3. Types of Primitives

Use the nn::gd::VertexInputStage::SetPrimitiveTopology() function to set the type of primitives to render.

Code 4-12. Setting the Type of Primitives to Render
static nnResult nn::gd::VertexInputStage::SetPrimitiveTopology(
        nn::gd::VertexInputStage::PrimitiveTopology primitiveTopology); 

Specify one of the following types of primitives for the primitiveTopology parameter.

Table 4-3. Types of Primitives
Definition Description
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 Geometry shader (GL_GEOMETRY_PRIMITIVE_DMP)

4.2.4. Input Layout

An input layout (InputLayout object) defines how input variables are connected between a vertex shader and vertex buffer. A vertex buffer comprises either a simple scalar value or several interleaved scalar values. Call the nn::gd::VertexInputStage::CreateInputLayout() function to create an InputLayout object. This function's parameters include an array of descriptor (InputElementDescription) objects for the input elements (vertex data) and a Shader object that was created in the shader stage.

Code 4-13. Creating, Releasing, and Applying an Input Layout to the Pipeline
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); 

Specify an array of descriptor (InputElementDescription) objects with information on the input elements in inputElementDescs, and pass the number of descriptor objects in the array to numElements. For more information about descriptor class settings, see 4.2.4.1. Descriptor Class for InputLayout Objects.

Specify the amount of vertex data used by a single vertex as an array in strides for each slot number. If all of the input elements are interleaved in a single vertex buffer, this array only has a single element that represents the total size of the input elements. If the input elements are not interleaved, this array has multiple elements for the size of each input element.

Use vertexShader to specify the Shader object for the vertex shader.

You can use the nn::gd::VertexInputStage::SetInputLayout() function to apply a created InputLayout object to the pipeline.

Use the nn::gd::VertexInputStage::ReleaseInputLayout() function to release an InputLayout object that is no longer needed. This also deallocates memory regions that were allocated internally when the CombinerState object was created.

In the following sample code, an input layout is created from a descriptor class that describes a single vertex buffer with three interleaved input elements. The layout is then applied to the pipeline (vertex input stage).

Code 4-14. Creating an Input Layout
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. Descriptor Class for InputLayout Objects

This section introduces the members of the descriptor class (InputElementDescription) for InputLayout objects and provides setting-related cautions and information.

Code 4-15. Definition of the InputElementDescription Class
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;
}; 
Slot Number (m_StreamSlot)

The slot number (0–11) used by an input element. To use the same slot number for more than one input element, the vertex buffers registered to that slot number must be interleaved. Slot numbers must be registered consecutively in ascending order, starting at 0.

Input Variable Name (m_SemanticName)

The name of an input variable defined by the vertex shader.

Input Element Data Format (m_Format)

The data format of an input element. Specify one of the values from the following table.

Table 4-4. Input Element Data Formats
Definition Description
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)
Input Element Size (m_Count)

The size of (number of components in) an input element. It can be a value between 1 and 4. Note that this is not the size of the input element in bytes.

Input Element Offset (m_AlignedByteOffset)

The offset (in bytes) to the starting input element. By specifying InputElementDescription::Append, the offset can be calculated automatically, thus simplifying descriptor class settings.

4.3. Texture Stage

The texture stage creates texture objects and handles texture unit-related settings. The nn::gd::TextureStage class defines functions that configure these settings.

The following diagram provides an overview of the settings made in the texture stage.

Figure 4-3. Overview of the Texture Stage

TextureStage Class Texture Unit 0 Texture Unit 1 Texture Unit 2 Texture Unit 3 Shadow Settings Projection Texture Settings Texture Resources State Object (Sampler Settings) Texture Coordinates Bias Value GD_TRUE GD_FALSE TextureCube Object TextureCubeDescription Class Texture2DResource Object Texture2D Object Textture2DDescription Class SamplerState Object SamplerStateDescription Class TextureCoordinateSourceUnit2 TextureCoordinateSourceUnit3 SetShadowZBias() SetPerspectiveShadow() SetTexture2DProjectionForUnit0() SetTextureUnit0() SetTexture() SetSamplerState() SetTextureCoordinateSourceForUnit2() SetTextureCoordinateSourceForUnit3Procedural() CreateTextureCube() CreateTexture2D() CreateSamplerState()

4.3.1. 2D Textures

2D textures are handled by Texture2D objects in the GD library. A Texture2D object is created from a single Texture2DResource object and a descriptor class (Texture2DDescription). If the Texture2DResource object has mipmap data, you can use descriptor class settings to specify which levels of mipmap data to use when you create a Texture2D object. For more information about the descriptor class settings, see 4.3.1.1. Descriptor Class for Texture2D Objects.

You can create and release a Texture2D object using the following functions.

Code 4-16. Creating and Releasing a Texture2D Object
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); 

Only management information is released when a Texture2D object is released. Texture2DResource objects are not released.

The following sample code creates a Texture2DResource object and uses it to create a Texture2D object.

Code 4-17. Creating a Texture2D Object
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. Descriptor Class for Texture2D Objects

This section introduces the member variables of the descriptor class (Texture2DDescription) for Texture2D objects and provides setting-related cautions and information.

Code 4-18. Definition of the Texture2DDescription Class
class nn::gd::Texture2DDescription
{
    s32 m_MinMipLevelIndex;
    s32 m_MaxMipLevelIndex;
}; 
Index of the Smallest Mipmap Level (m_MinMipLevelIndex)

This is the mipmap level of the Texture2DResource object used as the smallest mipmap level of a Texture2D object. If you set a value of -1, the largest mipmap level of the Texture2DResource object is used.

Index of the Largest Mipmap Level (m_MaxMipLevelIndex)

This is the mipmap level of the Texture2DResource object used as the largest mipmap level of a Texture2D object. If you set a value of -1, the largest mipmap level of the Texture2DResource object is used.

4.3.1.2. Getting Detailed Information About a Texture2D Object

You can use the nn::gd::TextureStage::GetTexture2DProperties() function to get detailed information (using the Texture2DProperties class).

Code 4-19. Getting Detailed Information on a Texture2D Object
static nnResult nn::gd::TextureStage::GetTexture2DProperties(
        const nn::gd::Texture2D* texture2D,
        nn::gd::Texture2DProperties* properties); 

Although the width, height, mipmap levels, and starting address of resource data may change with the mipmap levels specified when an object was created, they are generally the same as the detailed information for the Texture2DResource object.

Code 4-20. Definition of the Texture2DProperties Class
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. Cube Map Textures

Cube map textures are handled by TextureCube objects in the GD library. A TextureCube object is created using six Texture2DResource objects. As with Texture2D objects, you can specify which mipmap levels to use. Each face (Texture2DResource object) of the cube map texture must have the same format, mipmap levels, resolution (which depends on the mipmap level), and memory placement.

You can create and release a TextureCube object using the following functions.

Code 4-21. Creating and Releasing a TextureCube Object
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); 

Specify an array of six Texture2DResource objects, one for each face of the cube map texture, in the tex2DResources parameter. These textures are used for the +X, -X, +Y, -Y, +Z, and -Z faces, respectively, from the beginning of the array. Cube map texture faces are specified in the same order as the elements in descriptor class arrays.

Only management information is released when a TextureCube object is released. Texture2DResource objects are not released.

4.3.2.1. Descriptor Class for TextureCube Objects

This section introduces the members of the descriptor class (TextureCubeDescription) for TextureCube objects and provides setting-related cautions and information.

Code 4-22. Definition of the TextureCubeDescription Class
class nn::gd::TextureCubeDescription
{
    s32 m_MinMipLevelIndex[6];
    s32 m_MaxMipLevelIndex[6];
    TextureCubeDescription();
    TextureCubeDescription(int minMipLevelIndex, int maxMipLevelIndex);
}; 

This class differs from Texture2DDescription in that it specifies mipmap levels for six faces and has a constructor to simplify the process of doing so.

Index of the Smallest Mipmap Level (m_MinMipLevelIndex)

This is the mipmap level of the Texture2DResource object used as the smallest mipmap level of a TextureCube object. If you set a value of -1, the largest mipmap level of the Texture2DResource object is used.

The values in the array correspond to the Texture2DResource objects for the +X, -X, +Y, -Y, +Z, and -Z faces, in that order.

Index of the Largest Mipmap Level (m_MaxMipLevelIndex)

This is the mipmap level of the Texture2DResource object used as the largest mipmap level of a TextureCube object. If you set a value of -1, the largest mipmap level of the Texture2DResource object is used.

The values in the array correspond to the Texture2DResource objects for the +X, -X, +Y, -Y, +Z, and -Z faces, in that order.

4.3.2.2. Getting Detailed Information About a TextureCube Object

You can use the nn::gd::TextureStage::GetTextureCubeProperties() function to get detailed information (using the TextureCubeProperties class) about a TextureCube object.

Code 4-23. Getting Detailed Information About a TextureCube Object
static nnResult nn::gd::TextureStage::GetTextureCubeProperties(
        const nn::gd::TextureCube* TextureCube,
        nn::gd::TextureCubeProperties* properties); 

This class is the same as Texture2DProperties with the following exceptions: it maintains the starting address of six faces of resource data and accepts a cube map face in the faceIndex parameter, to get address information for mipmap data.

Code 4-24. Definition of the TextureCubeProperties Class
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. Texture Units

The GD library provides four logical texture units to match the 3DS hardware.

Table 4-5. Types of Textures That Can Be Set for Each Texture Unit
Definition Types of Textures That Can Be Set

TextureStage::TEXTURE_UNIT_0

(Texture unit 0)

2D textures (including gas and shadows)

Cube map textures (including shadows)

Projection textures

TextureStage::TEXTURE_UNIT_1

(Texture unit 1)

2D textures

TextureStage::TEXTURE_UNIT_2

(Texture unit 2)

2D textures

TextureStage::TEXTURE_UNIT_3_PROCEDURAL

(Texture unit 3)

Procedural textures
Note:

The procedural texture stage handles all TextureStage::TEXTURE_UNIT_3_PROCEDURAL settings except for texture coordinates.

2D textures

Use the nn::gd::TextureStage::SetTexture() function to set a 2D texture. You can set a 2D texture in three texture units: 0, 1, and 2.

Code 4-25. Setting a 2D Texture in a Texture Unit
static nnResult nn::gd::TextureStage::SetTexture(
        nn::gd::TextureStage::TextureUnitId textureUnitId,
        nn::gd::Texture2D& texture2D); 
Other (Non-Procedural) Textures

All other textures (except for procedural textures) can only be set in texture unit 0.

Code 4-26. Setting Other Textures
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); 

Use the nn::gd::TextureStage::SetTextureUnit0() function to set a cube map texture.

By calling the nn::gd::TextureStage::SetTexture2DProjectionForUnit0() function and passing GD_TRUE as an argument, you can treat the 2D texture set in texture unit 0 as a projection texture.

If you apply perspective projection to create texture coordinates when you access a shadow texture or shadow cube map texture, pass GD_TRUE as an argument to nn::gd::TextureStage::SetPerspectiveShadow. You can also use nn::gd::TextureStage::SetShadowZBias to set a bias value that will be subtracted from the distance to the light source when a shadow texture is generated.

4.3.3.1. Texture Coordinates

The following functions set the texture coordinates input to texture units 2 and 3.

Code 4-27. Setting Texture Coordinates
// 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); 

You can specify the following arguments to these functions.

Table 4-6. Texture Coordinates That Can Be Set for Texture Unit 2
Definition Input Texture Coordinates
UNIT2_TEXTURE_COORDINATE_FROM_UNIT_2 Texture coordinate 2 (default).
UNIT2_TEXTURE_COORDINATE_FROM_UNIT_1 Texture coordinate 1
Table 4-7. Texture Coordinates That Can Be Set for Texture Unit 3
Definition Input Texture Coordinates
UNIT3_PROCEDURAL_TEXTURE_COORDINATE_FROM_UNIT_0 Texture coordinate 0 (default).
UNIT3_PROCEDURAL_TEXTURE_COORDINATE_FROM_UNIT_1 Texture coordinate 1
UNIT3_PROCEDURAL_TEXTURE_COORDINATE_FROM_UNIT_2 Texture coordinate 2

4.3.4. Sampler Settings

To configure the texture sampling method (sampler settings), create a state (SamplerState) object and set it in a texture unit.

Code 4-28. Creating, Releasing, and Specifying Sampler Settings in a Texture Unit
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); 

Configure sampler settings in a descriptor class (SamplerStateDescription) in advance, specified in the desc parameter. For more information about descriptor class settings, see 4.3.4.1. Descriptor Class for SamplerState Objects.

You can use the nn::gd::TextureStage::SetSamplerState() function to set a created SamplerState object in a texture unit. You can configure sampler settings in three texture units: 0, 1, and 2.

Use the nn::gd::TextureStage::ReleaseSamplerState() function to release a SamplerState object that is no longer needed. This also deallocates memory regions that were allocated internally when the CombinerState object was created.

The following sample code creates a SamplerState object with the default settings, changes the minification and magnification filters, and then sets that object in texture unit 0.

Code 4-29. Sampler Settings
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. Descriptor Class for SamplerState Objects

This section introduces the members of the descriptor (SamplerStateDescription) class for SamplerState objects and provides setting-related cautions and information.

Code 4-30. Definition of the SamplerStateDescription Class
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();
}; 
Minification Filter (m_MinFilter)

This filter is applied during texture minification. You can set this value using the SetMinFilter() function.

Magnification Filter (m_MagFilter)

This filter is applied during texture magnification. You can set this value using the SetMagFilter() function.

Wrapping Mode in the S Direction (m_WrapS)

This wrapping mode is applied to repeating textures in the S direction. You can set this value using the SetWrapS() function.

Wrapping Mode in the T Direction (m_WrapT)

This wrapping mode is applied to repeating textures in the T direction. You can set this value using the SetWrapT() function.

Border Color (m_BorderColor)

This border color is used when TextureStage::SAMPLER_WRAP_CLAMP_TO_BORDER is specified as the wrapping mode. You can call the SetBorderColor() function to set each RGBA component to a value between 0 and 255 or between 0.0 and 1.0.

LOD Bias (m_LodBias)

This bias value is used to determine the level of detail (LOD). Because you must set this value using the same format as when setting a GPU register, do so by passing a value between -16.0 and 16.0 to the SetLoadBias() function.

The bias value is a 13-bit signed fixed-point decimal number with 8 fractional bits. To change member variables directly, use the Utils::Float32ToFix13Fraction8 utility function.

Minimum LOD (m_MinLod)

This is the smallest mipmap level used for LOD. If you use LOD, set the smallest mipmap level to a value of 0 or greater. (Specify 0 if you do not use LOD.) You can set this value using the SetMinLod() function.

Maximum LOD (m_MaxLod)

This is the largest mipmap level used for LOD. Specify a value of 0 when you do not use LOD and a value that is one less than the maximum number of mipmap levels in the texture when you do use LOD. You can set this value using the SetMaxLod() function.

Specify UINT_MAX or another large value when the same sampler settings are used by textures that have different numbers of mipmap levels. This value will be one less than the number of mipmap levels in the texture when it is rendered. It is determined from the default settings and source.

Default Settings (ToDefault)

You can call the ToDefault() function to change all members to their default values. This is also done in the constructor.

Table 4-8. Default Sampler Settings
Member Setting Value
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
Shadow Texture Settings (SetShadow)

You can call the SetShadow() function to change all members to their values for shadow textures.

Table 4-9. Sampler Settings for Shadow Textures
Member Setting Value
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
Warning:

Do not change the filter, wrapping mode, and LOD settings.

Shadow Cube Texture Settings (SetShadowCube)

You can call the SetShadowCube() function to change all members to their values for shadow cube map textures.

Table 4-10. Sampler Settings for Shadow Cube Map Textures
Member Setting Value
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
Warning:

Do not change the filter, wrapping mode, and LOD settings.

Gas Texture Settings (SetGas)

You can call the SetGas() function to change all members to their values for gas textures.

Table 4-11. Sampler Settings for Gas Textures
Member Setting Value
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
Warning:

Do not change the filter, wrapping mode, and LOD settings.

4.4. Procedural Texture Stage

The procedural texture stage handles settings related to procedural textures. The nn::gd::ProceduralTextureStage class defines functions that configure these settings.

The following figure gives an overview of the settings made in the procedural texture stage.

Figure 4-4. Overview of the Procedural Texture Stage

ProceduralTextureStage Class RGB Mapping G Function Alpha Mapping Independent Alpha Mode Texture Parameters Clamp Method Shift Method Minification Filter Method LOD Bias Noise Enable Parameters Lookup Tables F Function (RGB) F Function (Alpha) Noise Modulation Function Color Lookup Lookup Offset Lookup Table Width SetRgbMap() SetAlphaSeparate() SetAlphaMap() SetClampUV() SetShiftUV() SetMinFilter() SetTexBias() SetNoiseEnable() SetNoiseUV() UploadLookUpTableRgbMap UploadLookUpTableAlphaMap UploadLookUpTableNoiseMap UploadLookUpTableColorMap SetTexOffset() SetTexWidth() UvMap GD_TRUE GD_FALSE Clamp Shift MinFilter LOD Bias Value Noise Parameters Color Lookup Table Offset Value Color Lookup Table Width

4.4.1. Setting Procedural Texture Parameters

Functions have been provided for setting each of the procedural texture parameters.

Code 4-31. Functions for Setting Procedural Texture Parameters
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);
}; 

The following table shows which parameters are set by each function. For more information about how to specify arguments and what effect these parameters have, see the CTR-SDK API Reference and other documentation.

Table 4-12. Parameters Set by Functions in the Procedural Texture Stage
Function Parameters
SetRgbMap The G function for RGB mapping. Default value: UV_MAP_U
SetAlphaSeparate Whether to enable independent alpha mode. Default value: GD_FALSE
SetAlphaMap The G function for alpha mapping. Default value: UV_MAP_U
SetClampUV The clamp mode. Default value: CLAMP_TO_ZERO
SetShiftUV The shift mode. Default value: SHIFT_NONE
SetMinFilter The minification filter mode. Default value: MIN_FILTER_LINEAR
SetTexBias The LOD bias. Default value: 0.5
SetNoiseEnable Whether to enable noise. Default value: GD_FALSE
SetNoiseUV Noise parameters. Default values: F=0.0, P=0.0, and A=0.0 for both U and V
SetTexWidth Color lookup table width. Default value: 0
SetTexOffset Color lookup table offset. Default value: 0
Note:

The SetTexBias and SetNoiseUV() functions convert the values passed as arguments into the format used when setting GPU registers.

4.4.2. Loading Lookup Tables Used by the Procedural Texture Stage

There are two ways to load F functions (for RGB mapping and alpha mapping), noise modulation data, color lookup tables, and other lookup tables used by procedural textures: The first is to use functions (with the Float suffix) that take arrays of floating-point numbers. The second is to use functions (with the Native suffix) that take arrays of data to be written unchanged to the GPU registers. Because these are immediate functions, data is written to the 3D command buffer when they are run.

Code 4-32. Functions for Loading Lookup Tables Used by the Procedural Texture Stage
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);
}; 

You can use index and lutSize values to partially overwrite a lookup table. However, an error occurs if the total exceeds the maximum number of elements in the following table.

To load a lookup table with arrays of floating-point numbers, you must provide one array for the data (the Map parameter) and one for the deltas (the MapDelta parameter). However, you need eight arrays to load a color lookup table: two for each of the color's four components.

If you load any lookup table (except for a color lookup table) with an array that has been converted into native format, you only need to provide one array because both the data and the delta have been combined into a single element.

The following table shows the format of and maximum number of elements in the arrays used by each function to load a lookup table.

Table 4-13. Functions for Loading Lookup Tables Used by the Procedural Texture Stage
Function Lookup Table Format Maximum Number of Elements
UploadLookUpTableRgbMapFloat RGB mapping Floating-point numbers 128
UploadLookUpTableRgbMapNative RGB mapping Native 128
UploadLookUpTableAlphaMapFloat Alpha mapping Floating-point numbers 128
UploadLookUpTableAlphaMapNative Alpha mapping Native 128
UploadLookUpTableNoiseMapFloat Noise modulation table Floating-point numbers 128
UploadLookUpTableNoiseMapNative Noise modulation table Native 128
UploadLookUpTableColorMapFloat Color lookup table Floating-point numbers 256
UploadLookUpTableColorMapNative Color lookup table Native 256

4.4.2.1. Helper Functions for Loading Lookup Tables

Helper functions have been provided for converting arrays of floating-point numbers into native format. Functions that load lookup tables from arrays of floating-point numbers internally convert the arrays into native format. This is expensive and not suited for runtime use. We recommend that you use some other strategy, such as providing data that has already been converted into native format or using the helper functions to convert the data when the lookup table is loaded for the first time.

Code 4-33. Helper Functions for Loading Lookup Tables
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);
}; 

For all lookup tables except for color lookup tables, a single array of data (destination) is generated by combining the data and deltas. The original data is converted into 12-bit unsigned fixed-point numbers with 12 fractional bits in bits [11:0] of the generated data. The original deltas are converted into 12-bit signed fixed-point numbers with 11 fractional bits (and negative numbers expressed in two's complement) in bits [23:12] of the generated data.

For color lookup tables, a combination of data and deltas for each RGBA component (a total of eight arrays) is converted into a combination of a single color and delta value (the destRef and destDelta parameters). Although they are converted through different methods, every color and delta value that is generated has eight bits each for the alpha, blue, green, and red components, arranged respectively from the most- to the least-significant bit. Color values are converted from 8-bit signed fixed-point numbers with 7 fractional bits, between 0.0 and 1.0, into unsigned 8-bit integers between 0 and 255. Delta values between -1.0 and 1.0 are converted into 8-bit signed (two’s complement) fixed-point numbers with 7 fractional bits.

Note:

For more information about how these values are converted, see the 3DS Programming Manual: Advanced Graphics.

The GD library provides utility functions for these conversions.

4.5. Lighting Stage

The lighting stage configures the global lighting environment and individual lights. The nn::gd::LightingStage class defines functions that configure these settings. Applications do not need to enable or disable the lighting environment. The library manages lighting settings. The lighting environment is only enabled when lighting results are required by combiner settings.

The following diagram provides an overview of the settings made in the lighting stage. (This does not include individual lights).

Figure 4-5. Overview of the Lighting Stage (Except for Individual Lights)

LightingStage Class Global Settings Ambient Light Specular Clamping Fresnel Factor Shadows Texture Unit to Use Shadow Attenuation (Primary) Shadow Attenuation (Secondary) Shadow Attenuation (Alpha Component) Inversion Bump Mapping Bump Mode Lookup Tables Layer Configuration D0/D1/SP/FR/RB/RG/RR Type of Input Value Taking Absolute Input Values Output Scaling Enabling D0 Enabling D1 Enabling Reflection (RR/RG/RB) SetGlobalColorAmbient() SetClampHighlight() SetFresnelSelector() SetShadowSelectorTexture() SetShadowPrimary() SetShadowSecondary() SetShadowAlpha() SetInvertShadow() SetBumpMode() SetBumpSelectorTexture() SetLayerConfiguration() UploadLookUpTable SetLookUpTableInputValue() SetLookUpTableAbsInput() SetLookUpTableOutputScaling() EnableLookUpTableD0() EnableLookUpTableD1() EnableLookUpTableReflection() Color Value GD_TRUE GD_FALSE TextureStage::TextureUnitId BumpMode LayerConfiguration LookUpTableInputValue LookUpTableOutputScaleValue

4.5.1. Configuring the Global Lighting Environment

Functions have been provided for setting each of the global lighting environment parameters.

Code 4-34. Functions for Setting Global Lighting Parameters
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);
}; 

The following table shows which parameters are set by each function. For more information about how to specify arguments and what effect these parameters have, see the CTR-SDK API Reference and other documentation.

Table 4-14. Parameters Configured by Functions in the Lighting Stage
Function Parameters
SetGlobalColorAmbient The light source color of global ambient light. Default value: (10, 10, 10)
SetClampHightlight Specular light clamping. Default value: GD_TRUE
SetFresnelSelector Fresnel factor. Default value: FRESNEL_SELECTOR_TYPE_NO_FRESNEL
SetShadowSelectorTexture The texture unit used by shadows. Default value: TEXTURE_UNIT_0
SetShadowPrimary Effect of shadows on the primary color. Default value: GD_FALSE
SetShadowSecondary Effect of shadows on the secondary color. Default value: GD_FALSE
SetShadowAlpha Effect of shadows on the alpha component. Default value: GD_FALSE
SetInvertShadow Shadow term inversion. Default value: GD_FALSE
SetBumpMode Bump-map perturbation mode and whether to regenerate the third component of normal vectors. Default values: BUMPMODE_NOT_USED, GD_FALSE
SetBumpSelectorTexture The texture unit used for bump mapping. Default value: TEXTURE_UNIT_0
Note:

SetGlobalColorAmbient is an immediate function.

4.5.2. Setting the Layer Configuration and Lookup Tables

Functions have been provided to set the following: the layer configuration (this determines which lookup tables are used for lighting), lookup table input values, scaling of lookup table output values, distribution factors, and reflections.

Code 4-35. Functions for Setting Lookup Table-Related Parameters
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);
}; 

The following table shows which parameters are set by each function. For more information about how to specify arguments and what effect these parameters have, see the CTR-SDK API Reference and other documentation.

Table 4-15. Lookup Table-Related Parameters Set by Functions in the Lighting Stage
Function Parameters
SetLayerConfiguration The layer configuration. Default value: LAYER_CONFIGURATION_0
SetLookUpTableInputValue Lookup table input value. Default value: INPUT_VALUE_NH for all lookup tables
SetLookUpTableAbsInput Whether to take the absolute value of lookup table input value. Default value: GD_FALSE for all lookup tables
SetLookUpTableOutputScaling How to scale lookup table output values. Default value: OUTPUT_SCALE_VALUE_1 for all lookup tables
EnableLookUpTableD0 Whether to apply lookup tables to distribution factor 0. Default value: GD_FALSE
EnableLookUpTableD1 Whether to apply lookup tables to distribution factor 1. Default value: GD_FALSE
EnableLookUpTableReflection Whether to apply lookup tables to reflections. Default value: GD_FALSE

4.5.3. Loading Lookup Tables Used by the Lighting Stage

There are two functions for loading lookup tables used by lighting: UploadLookUpTableFloat, which takes arrays of floating-point numbers, and UploadLookUpTableNative, which takes arrays of data to be written unchanged to the GPU registers. Because these are immediate functions, data is written to the 3D command buffer when they are run.

Code 4-36. Functions for Loading Lookup Tables Used by the Lighting Stage
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);
    };
}; 

Lighting uses lookup tables with 256 elements. You can use lutStartIndex and dataCount values to partially overwrite a lookup table, but an error will occur if the total exceeds 256.

A lookup table's structure differs depending upon whether its input values are converted into absolute values. Note that the input values corresponding to the 128th and 129th elements of a lookup table will be discontinuous (they will jump from 0.9922 to -1.0) if the lookup table input values are not converted into absolute values (if they are between -1.0 and 1.0).

To load a lookup table with arrays of floating-point numbers, you need to provide one array for the data (the valueData parameter) and one array for the deltas (the deltaData parameter).

If you load any lookup table with an array that has been converted into native format, you only need to provide one array because both the data and the delta have been combined into a single element.

Helper functions have been provided for converting arrays of floating-point numbers into native format. These helper functions generate a single array of data (the destination parameter) by combining the data and deltas. The original data is converted into 12-bit unsigned fixed-point numbers with 12 fractional bits. The original deltas are converted into 12-bit signed fixed-point numbers with 11 fractional bits (which are absolute values). These are stored in bits [11:0] and [23:12] of the generated data, respectively.

Note:

For more information about how these values are converted, see the 3DS Programming Manual: Advanced Graphics.

The GD library provides utility functions for these conversions.

4.5.4. Lights

The 3DS hardware supports lighting with 8 lights. The GD library represents individual lights as separate instances of the nn::gd::Light class. The nn::gd::LightingStage class contains eight Light objects that are created when the library is initialized. As a result, applications do not need to create Light objects. Access them using the members defined by the lighting stage. For example, you could call nn::gd::LightingStage::light[0].EnableLight(GD_TRUE).

The following diagram provides an overview of the settings handled by Light objects.

Figure 4-6. Overview of Light Objects

Light Class Settings Enabling Lights Light Type Two-Sided Lighting Shadow Attenuation Enabling Geometry Factor 0 Enabling Geometry Factor 1 Light Colors Ambient Light Diffuse Light Specular Light 0 Specular Light 1 Position/Direction Light Source Position Light Source Direction Spotlights/Distance Attenuation SP/DA Enabling Spotlights (SP) Spotlight Direction Enabling Distance Attenuation (DA) Distance Attenuation Scale, Bias EnableLight() SetLightType() EnableToSideDiffuse() EnableShadowed() EnableGeomFactor0() EnableGeomFactor1() SetColorAmbient() SetColorDiffuse() SetColorSpecular0() SetColorSpecular1() SetPosition() SetDirection() UploadLookUpTable EnableSpotLight() SetSpotDirection() EnableDistanceAttenuation() SetDistanceAttenuationScaleBias() GD_TRUE GD_FALSE SourceType Color Value Coordinates Direction Vector Lookup Table Scale, Bias

4.5.4.1. Light Settings

Functions have been provided for setting each of the light parameters.

Code 4-37. Functions for Setting Light Parameters
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);
}; 

The following table shows which parameters are set by each function. For more information about how to specify arguments and what effect these parameters have, see the CTR-SDK API Reference and other documentation.

Table 4-16. Parameters Set by Light Object Functions
Function Parameters
EnableLight Whether to enable light. Default value: GD_FALSE
SetLightType Type of light source. Default value: SOURCE_TYPE_POINT
EnableTwoSideDiffuse Whether to enable two-sided lighting. Default value: GD_FALSE
EnableShadowed Whether to enable shadow attenuation. Default value: GD_FALSE
EnableGeomFactor0 Whether to enable geometry factor 0. Default value: GD_FALSE
EnableGeomFactor1 Whether to enable geometry factor 1. Default value: GD_FALSE
SetColorAmbient Ambient light color. Default value: (0, 0, 0)
SetColorDiffuse Diffuse light color. Default value: (255, 255, 255)
SetColorSpecular0 Color of specular light 0. Default value: (255, 255, 255)
SetColorSpecular1 Color of specular light 1. Default value: (255, 255, 255)
SetPosition Point light source position. Default value: (0.0, 0.0, 0.0)
SetDirection Directional light orientation. No default value.
EnableSpotLight Whether to enable spotlights. Default value: GD_FALSE
SetSpotDirection Spotlight direction. Default value: (0.0, 0.0, 0.0)
EnableDistanceAttenuation Whether to enable distance attenuation. Default value: GD_FALSE
SetDistanceAttenuationScaleBias

Scale and bias for distance attenuation. Default values: 0.0, 0.0

A utility function (Utils::ConvertStartEndToScaleBias) has been provided to find the appropriate setting values from both a starting and ending distance.

Lookup tables are loaded in the same way as they are for the lighting stage, although they are specified differently. The lookup tables used by distance attenuation (DA) must be created to accept input values between 0.0 and 1.0.

Note:

Every function that configures lights is an immediate function, except for EnableLight, EnableShadowed, EnableSpotLight, and EnableDistanceAttenuation.

4.6. Rasterizer Stage

The rasterizer stage configures the process of rasterizing pixels that are output to the fragment pipeline. The nn::gd::RasterizerStage class defines functions that configure these settings.

The following diagram provides an overview of the settings made in the rasterizer stage.

Figure 4-7. Overview of the Rasterizer Stage

RasterizerStage Class Culling Culling Mode Viewport Clipping Enable Clipping Plane Scissor Test Scissor Box Early Depth Test Settings Clearing the Buffer SetCulling() SetViewport() EnableClippingPlane() SetClippingPlane() EnableScissor() SetScissor() SetEarlyDepthTest() ClearEarlyDepth() Culling Viewport Class GD_TRUE GD_FALSE Clipping Plane Parameters EarlyDepthFunction Depth Value Used for Clearing

4.6.1. Culling Settings

Use the nn::gd::RasterizerStage::SetCulling() function to configure culling.

Code 4-38. Function for Configuring Culling
static void nn::gd::RasterizerStage::SetCulling(
        nn::gd::RasterizerStage::Culling culling); 

Specify the culling method in the culling parameter. Clockwise culling (CULLING_CLOCKWISE) is specified by default.

4.6.2. Configuring the Viewport

Use the nn::gd::RasterizerStage::SetViewport() function to configure the viewport.

Code 4-39. Functions for Configuring the Viewport
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); 

The nn::gd::Viewport class defines the viewport region. Note that the viewport has a different orientation than the LCDs. Viewport(0, 0, 240, 320) is set by default.

4.6.3. Clipping Settings

Use the following functions to configure clipping.

Code 4-40. Functions for Configuring Clipping
static void nn::gd::RasterizerStage::EnableClippingPlane(gdBool value);
static void nn::gd::RasterizerStage::SetClippingPlane(
        f32 param1, f32 param2, f32 param3, f32 param4); 

By default, clipping is disabled (with GD_FALSE) and all parameters are set to 0.

4.6.4. Scissor Test Settings

Use the following functions to configure the scissor test.

Code 4-41. Functions for Configuring the Scissor Test
static void nn::gd::RasterizerStage::EnableScissor(gdBool value);
static void nn::gd::RasterizerStage::SetScissor(
        nn::gd::Viewport& area); 

By default, the scissor test is disabled (GD_FALSE) and Viewport(0, 0, 0, 0) is set as the scissor box.

4.6.5. Early Depth Test Settings

Use the following functions to configure the early depth test.

Code 4-42. Functions for Configuring the Early Depth Test
static void nn::gd::RasterizerStage::SetEarlyDepthTest(
        gdBool enable, nn::gd::RasterizerStage::EarlyDepthFunction func);
static void nn::gd::RasterizerStage::ClearEarlyDepth(f32 depthClearValue); 

By default, the early depth test is disabled (GD_FALSE and EARLYDEPTH_FUNCTION_LESS) and 1.0 is set as the depth value to use for clearing.

Block-32 mode must be set as the block mode when you use the early depth test. For more information, see Block Mode Settings in the 3DS Programming Manual: Advanced Graphics.

4.7. Combiner Stage

The combiner stage configures (texture) combiners and combiner buffers. The nn::gd::CombinerStage class defines functions that configure these settings.

The following diagram provides an overview of the settings made in the combiner stage.

Figure 4-8. Overview of the Combiner Stage

CombinerStage Class Constant Color (Units 0-5) State Object (Combiner Settings) SetTextureCombinerUnitConstantColor() SetTextureCombinerState() CreateTextureCombinerState() Color Value CombinerState Object CombinerDescription Class

4.7.1. Combiner Settings

The combiner stage creates a state (CombinerState) object that consolidates all combiner and combiner buffer settings. By switching this CombinerState object, you can change all combiner-related settings in one operation, except for the constant color.

CombinerState objects are created from a descriptor class (CombinerDescription) that defines operands and other settings.

Code 4-43. Creating, Releasing, and Applying Combiner Settings to the Pipeline
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); 

Combiner settings are configured in the descriptor object (CombinerDescription) specified by the description parameter in advance. For more information about the descriptor class settings, see 4.9.5.1. Descriptor Class for BlendState Objects.

You can use the nn::gd::CombinerStage::SetTextureCombinerState() function to set a created CombinerState object in the combiner stage.

Use the nn::gd::CombinerStage::ReleaseTextureCombinerStage() function to release a state object that is no longer needed. This also deallocates memory regions that were allocated internally when the CombinerState object was created.

Use the following function to set the constant color. You must set a constant color if it is used by combiner settings, because the constant color is undefined by default.

Code 4-44. Setting the Constant Color
static nnResult nn::gd::CombinerStage::SetTextureCombinerUnitConstantColor(
        nn::gd::CombinerStage::UnitId unit,
        u8 colorR, u8 colorG, u8 colorB, u8 colorA); 

Because this is an immediate function, 3D commands are accumulated in the command buffer when it is run.

4.7.1.1. Descriptor Class for CombinerState Objects

This section introduces the members of the descriptor (CombinerDescription) class for CombinerState objects and provides setting-related cautions and information.

The CombinerDescription class contains settings for six combiner units. Because you will not necessarily configure every unit, this class is designed with member functions that set member variables for a specified unit.

Code 4-45. Definition of the CombinerDescription Class
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();
}; 
Input Source Settings (SetSourceRGB, SetSourceAlpha)

These functions set input sources 0 to 2 for the specified combiner unit.

Operand Settings (SetOperandRGB, SetOperandAlpha)

These functions set operands 0 to 2 for the specified combiner unit.

Combiner Function Settings (SetCombineRGB, SetCombineAlpha)

These functions set the combiner function for the specified combiner unit.

Scaling Value Settings (SetScaleRGB, SetScaleAlpha)

These functions set the scaling values for the specified combiner unit.

Constant Color for Combiner Buffer 0 Setting (SetBufferColor)

This function sets the constant color for combiner buffer 0.

Combiner Buffer Input Source (m_BufferInput)

Sets the input source for combiner buffers 1 to 4. No setter functions are defined for it.

Configuring How Combiner Units Are Used (SetCombinerInUse)

This function either enables (GD_TRUE) or disables (GD_FALSE) the settings for the specified combiner unit. If you do not enable settings for a combiner unit, it uses its default settings.

Default Settings (ToDefault)

You can call the ToDefault() function to change all members to their default values. This is also done in the constructor.

Table 4-17. Default Combiner Settings
Member Default Settings

SetSourceRGB

SetSourceAlpha

SOURCE_CONSTANT (all input sources for unit 0)

SOURCE_PREVIOUS (all input sources for units 1 to 5)

SetOperandRGB OPERAND_RGB_SRC_COLOR (all operands)
SetOperandAlpha OPERAND_ALPHA_SRC_ALPHA (all operands)
SetCombineRGB COMBINE_RGB_REPLACE (all units)
SetCombineAlpha COMBINE_ALPHA_REPLACE (all units)

SetScaleRGB

SetScaleAlpha

SCALE_1 (all units)
SetBufferColor (0,0,0,0)
m_BufferInput INPUT_PREVIOUS_BUFFER (all inputs)
SetCombinerInUse GD_FALSE (all units)

4.8. Fog Stage

The fog stage handles all settings related to rendering fog and gas. The nn::gd::FogStage class defines functions that configure these settings.

The following diagram provides an overview of the settings made in the fog stage.

Figure 4-9. Overview of the Fog Stage

FogStage Class Mode Settings Fog Mode Fog Fog Color Invert Input Value Fog Lookup Table Gas Shading Density Information Density Attenuation Maximum Density Value Automatic Density Updates Planar Shading Strength View Shading Strength Attenuation in the Depth Direction Lookup Table Input Value Shading Lookup Table SetGasFogMode() SetFogColor() setFogZFlip() UploadFogLookUpTable SetGasShadingDensity() SetGasAttenuation() SetGasAccumulationMax() SetGasAutoAccumulation() SetGasLightXY() SetGasLightZ() SetGasDeltaZ() SetGasLightColorLutInput() UploadGasLookUpTable Mode Color Value GD_TRUE GD_FALSE Lookup Table GasShadingDensitySource Coefficient Maximum Value Minimum Value Attenuation Direction GasColorLookUpTableInput

4.8.1. Fog Mode

Use the nn::gd::FogStage::SetGasFogMode() function to switch the mode for GPU fog features.

Code 4-46. Switching the Fog Mode
static void nn::gd::FogStage::SetGasFogMode(nn::gd::FogStage::Mode mode); 

You can specify one of the following values in the mode parameter.

Table 4-18. Specifying the Fog Mode
Definition Description
FogStage::MODE_NONE Do not use fog features. (Default.)
FogStage::MODE_FOG Use fog features normally in fog mode.
FogStage::MODE_GAS Use fog features in gas mode.

4.8.2. Fog Settings

Functions have been provided for setting each of the fog parameters.

Code 4-47. Functions for Setting Fog Parameters
class nn::gd::FogStage
{
    static void SetFogColor(u8 R, u8 G, u8 B);
    static void SetFogZFlip(gdBool zFlip);
}; 

The following table shows which parameters are set by each function. For more information about how to specify arguments and what effect these parameters have, see the CTR-SDK API Reference and other documentation.

Table 4-19. Parameters Configured by Functions in the Fog Stage
Function Parameters
SetFogColor Fog color. Default value: (0, 0, 0)
SetFogZFlip Whether to invert input depth value. Default value: GD_FALSE
Note:

For more information about how to load lookup tables, see 4.8.4. Loading Lookup Tables Used by the Fog Stage.

4.8.3. Gas Settings

Functions have been provided for setting each of the gas parameters.

Code 4-48. Functions for Setting Gas Parameters
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);
}; 

The following table shows which parameters are set by each function. For more information about how to specify arguments and what effect these parameters have, see the CTR-SDK API Reference and other documentation.

Table 4-20. Gas Parameters Configured by Functions in the Fog Stage
Function Parameters
SetGasShadingDensity Density information used for shading. Default value: GAS_SHADING_DENSITY_SOURCE_PLAIN
SetGasAttenuation Density attenuation coefficient to use when calculating alpha value for shading. Default value: 1.0
SetGasAccumulationMax The reciprocal of the maximum density information value. Default value: 1.0
SetGasAutoAccumulation Whether to automatically calculate the reciprocal of the maximum density information value. Default value: GD_FALSE
SetGasLightXY Factors used to control planar shading: the minimum intensity, maximum intensity, and density attenuation. Default value: (0,0,0)
SetGasLightZ Factors used to control view shading: the minimum intensity, maximum intensity, density attenuation, and effect in the view direction. Default value: (0,0,0,0)
SetGasDeltaZ Attenuation coefficient in the depth direction. Default value: 10.0
SetGasLightColorLutInput Input value to the shading lookup table. Default value: GAS_COLOR_INPUT_LIGHT_FACTOR
Note:

For more information about how to load lookup tables, see 4.8.4. Loading Lookup Tables Used by the Fog Stage.

4.8.4. Loading Lookup Tables Used by the Fog Stage

There are two ways to load the lookup tables used for coefficients and shading in the fog stage: The first is through functions (with the Float suffix) that accept arrays of floating-point numbers. The second is through functions (with the Native suffix) that accept arrays of data to be written unchanged to the GPU registers. Because these are immediate functions, data is written to the 3D command buffer when they are run.

Code 4-49. Functions for Loading Lookup Tables Used by the Fog Stage
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);
}; 

You can use lutStartindex and countData values to partially overwrite a lookup table. However, an error occurs if the total exceeds the maximum number of elements in the following table.

To load a lookup table using arrays of floating-point numbers, you must provide one array for the data (the dataValue parameter) and one for the deltas (the dataDelta parameter). However, note that because each element in the shading lookup table is generated from three elements in these source arrays (which store the color components in RGB order), dataValue and dataDelta must have three times the number of elements specified in countData.

If you load any lookup table using an array that has been converted into native format, you only need to provide one array because both the data and the delta have been combined into a single element. However, the native and floating-point arrays used to load the shading lookup table have different maximum sizes.

The following table shows the format of and maximum number of elements in the arrays used by each function to load a lookup table.

Table 4-21. Functions for Loading Lookup Tables Used by the Fog Stage
Function Lookup Table Format Maximum Number of Elements
UploadFogLookUpTableFloat Fog Coefficients Floating-point numbers 128
UploadFogLookUpTableNative Fog Coefficients Native 128
UploadGasLookUpTableFloat Shading Floating-point numbers 8
UploadGasLookUpTableNative Shading Native 16

4.8.4.1. Helper Functions for Loading Lookup Tables

Helper functions have been provided for converting arrays of floating-point numbers into native format. Functions that load lookup tables from arrays of floating-point numbers internally convert the arrays into native format. This is expensive and not suited for runtime use. We recommend that you use some other strategy, such as providing data that has already been converted into native format or using the helper functions to convert the data when the lookup table is loaded for the first time.

Code 4-50. Helper Functions for Loading Lookup Tables
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);
}; 

Both helper functions provided by the fog stage generate a single array (the dest parameter) from a data array and a delta array.

Each data element is converted into an 11-bit unsigned fixed-point number with 11 fractional bits. Each delta is converted into a 13-bit signed (two's complement) fixed-point number with 11 fractional bits. These are stored in bits [23:13] and [12:0], respectively, of the data generated for the fog coefficient lookup table.

Data is generated for the shading lookup table in a special format. Specifically, note that the three elements of the source array (in R/G/B order) are converted into a single data value. Conversely, each element of the array dest does not contain both data and delta values. Instead, the first eight elements of the array store delta values, and the second eight elements store data values.

The first eight elements are generated from the deltas. The deltas for the R, G, and B components are converted into 8-bit signed integers that are packed into bits [7:0], [15:8], and [23:16] respectively.

The last eight elements are generated from the data. The data for the R, G, and B components are converted into 8-bit unsigned fixed-point numbers (with no fractional bits) that are packed into bits [7:0], [15:8], and [23:16] respectively.

Note:

For more information about how these values are converted, see the 3DS Programming Manual: Advanced Graphics.

The GD library provides utility functions for these conversions.

4.9. Output Stage

The output stage configures blending, the depth test, the stencil test, the target buffer, and other settings related to pixel output. The nn::gd::OutputStage class defines functions that configure these settings.

The following diagram provides an overview of the settings made in the output stage.

Figure 4-10. Overview of the Output Stage

OutputStage Class Framebuffer Render Target Depth (Stencil) Target Write Mask Fragments Operation Mode Depth Buffer Mode Soft Shadow Settings Depth and Stencil Test State Object (Depth Stencil Test Settings) Alpha Test Alpha Test Settings Logical Operations and Blending State Object (Blending Settings) Constant Color SetRenderTarget() SetDepthStencilTarget() SetColorWriteMask() SetFragOpMode() SetDepthRangeMode() SetPenumbraScaleBias() SetDepthStencilState() SetAlphaTest() SetBlendState() SetBlendColor() RenderTaget Object DepthStencilTarget Object ColorWriteMask FragmentOperationMode DepthBufferType Scale, Bias DepthStencilState Object Comparison Method, Reference Value BlendState Object Color Value

4.9.1. Fragment Operation Mode

You can use the nn::gd::OutputStage::SetFragOpMode() function to switch the fragment operation mode.

Code 4-51. Function for Setting the Fragment Operation Mode
static void nn::gd::OutputStage::SetFragOpMode(
        nn::gd::OutputStage::FragmentOperationMode fragOpMode); 

You can specify one of the following values in the fragOpMode parameter.

Table 4-22. Fragment Operation Modes
Definition Description
FRAGMENT_OPERATION_MODE_FRAGMENT_COLOR Normal fragment processing (this is the default value).
FRAGMENT_OPERATION_MODE_GAS_ACCUMULATION Fragment processing for the shadow accumulation path.
FRAGMENT_OPERATION_MODE_SHADOW_MAP Fragment processing for rendering gas density information.

4.9.2. Framebuffers

The GD library uses RenderTarget and DepthStencilTarget objects to operate on the framebuffer (color and depth stencil buffer). Both objects are created from a single Texture2DResource object and a descriptor class (RenderTargetDescription or DepthStencilTargetDescription,). If the Texture2DResource object has mipmap data, you can use descriptor class settings to specify which levels of mipmap data to use when you create the object.

You can use the following functions to create, release, and apply a framebuffer object (a RenderTarget or DepthStencilTarget object) to the pipeline.

Code 4-52. Creating, Releasing, and Applying a Framebuffer Object to the Pipeline
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); 

Functions that have the RenderTarget suffix affect the color buffer. Functions that have the DepthStencilTarget suffix affect the depth (stencil) buffer.

Configure framebuffer settings in the corresponding descriptor object (RenderTargetDescription or DepthStencilTargetDescription) specified in the desc parameter. For more information about the descriptor class settings, see 4.9.2.1. Descriptor Class for Framebuffer Objects.

Only a limited number of pixel formats can be used by a Texture2DResource object in the framebuffer. For more information, see 3.1.1. Creating a Texture2DResource Object.

After you have created a framebuffer object, you can set it as the framebuffer with the nn::gd::OutputStage::Set*() functions.

Use the nn::gd::OutputStage::Release*() functions to release framebuffer objects that are no longer needed. Only management data is released when a framebuffer object is released. Texture2DResource objects are not released.

4.9.2.1. Descriptor Class for Framebuffer Objects

This section introduces the members of the descriptor classes (RenderTargetDescription and DepthStencilTargetDescription) for framebuffer classes (RenderTarget and DepthStencilTarget) and provides setting-related cautions and information.

Code 4-53. Descriptor Class Definitions for Framebuffer Objects
class nn::gd::RenderTargetDescription
{
    u32 m_MipLevelIndex;
};
class nn::gd::DepthStencilTargetDescription
{
    u32 m_MipLevelIndex;
};  
Mipmap Level Index (m_MipLevelIndex)

This is the mipmap level of the Texture2DResource object used to create a framebuffer object.

4.9.2.2. Getting Detailed Information About Framebuffer Objects

Detailed information (the TargetProperties class) includes framebuffer-related information that is based on the content of the Texture2DResource object specified when the framebuffer was created.

The RenderTarget and DepthStencilTarget objects use different functions to get detailed information, but they both do so using the TargetProperties class.

Code 4-54. Getting Detailed Information About Framebuffer Objects
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); 

Although the width, height, mipmap levels, and starting address of resource data may change with the mipmap levels specified when an object was created, they are generally the same as the detailed information for the Texture2DResource object.

Code 4-55. Definition of the TargetProperties Class
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. Clearing the Framebuffer

You can clear the color buffer and depth (stencil) buffer using a specified value.

Code 4-56. Clearing the Framebuffer
static nnResult nn::gd::Memory::ClearTargets(
        const nn::gd::RenderTarget* renderTarget,
        const nn::gd::DepthStencilTarget* depthStencilTarget,
        const u8 ColorRGBA[4], float depth, u8 stencil); 

The framebuffer is actually cleared when the command list is executed because this function internally calls the nngxAddMemoryFillCommand() function.

4.9.2.4. Color Mask

Using the nn::gd::OutputStage::SetColorWriteMask() function, you can change color mask settings and control what is written to the color buffer.

Code 4-57. Function for Setting the Color Mask
 static void nn::gd::OutputStage::SetColorWriteMask(u32 mask); 

Specify a bitwise OR of the following flags in the mask parameter.

Table 4-23. Color Mask Flags
Definition Description
COLOR_WRITE_MASK_ENABLE_RED Enables write operations for the red component.
COLOR_WRITE_MASK_ENABLE_GREEN Enables write operations for the green component.
COLOR_WRITE_MASK_ENABLE_BLUE Enables write operations for the blue component.
COLOR_WRITE_MASK_ENABLE_ALPHA Enables write operations for the alpha component.
COLOR_WRITE_MASK_ENABLE_ALL Enables write operations for all components. (This value is the default.)

4.9.3. Depth and Stencil Tests

By creating a state (DepthStencilState) object and then switching the DepthStencilState object that is configured in the output stage, you can change all settings related to the depth and stencil test in one operation.

You can create, release, and apply a DepthStencilState object to the pipeline using the following functions.

Code 4-58. Creating, Releasing, and Applying a DepthStencilState Object to the Pipeline
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); 

Configure the depth and stencil test in a descriptor class (DepthStencilStateDescription) passed in the desc parameter. For more information about the descriptor class settings, see 4.9.3.1. Descriptor Class for DepthStencilState Objects.

After you have created a state object, you can apply it to the pipeline using the nn::gd::OutputStage::SetDepthStencilState() function. Specify the reference value to use in the stencil test in the stencilRef parameter.

Use the nn::gd::OutputStage::ReleaseDepthStencilState() function to release a state object that is no longer needed. This also releases memory regions that were allocated internally when the BlendState object was created as a state object.

4.9.3.1. Descriptor Class for DepthStencilState Objects

This section introduces the members of the descriptor (DepthStencilStateDescription) class for DepthStencilState objects and provides setting-related cautions and information.

Code 4-59. Definition of the DepthStencilStateDescription Class
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();
}; 
Enabling the Depth Test (m_DepthEnable)

The depth test is enabled if this is GD_TRUE.

Write Mask for the Depth Test (m_DepthMask)

Sets the write mask for the depth test.

Comparison Function for the Depth Test (m_DepthFunc)

Sets the comparison function for the depth test.

Enabling the Stencil Test (m_StencilEnable)

The stencil test is enabled if this is GD_TRUE.

Write Mask for the Stencil Test (m_StencilWriteMask)

Sets the write mask for the stencil test.

Read Mask for the Stencil Test (m_StencilReadMask)

Sets the read mask for the stencil test.

Comparison Function for the Stencil Test (m_StencilFunc)

Sets the comparison function for the stencil test.

Operation When the Stencil Test Fails (m_StencilFail)

Sets the operation to run when the stencil test fails.

Operation When the Stencil Test Passes (m_StencilZFail)

Sets the operation to run when the stencil test passes, but the depth test fails.

Operation When Both the Depth and Stencil Test Pass (m_StencilZPass)

Sets the operation to run when both the depth and stencil tests pass.

Default Settings (ToDefault)

You can call the ToDefault() function to change all members to their default values. This is also done in the constructor.

Table 4-24. Default Settings for the DepthStencilStateDescription Class
Member Default Settings
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. Alpha Test

Use the nn::gd::OutputStage::SetAlphaTest() function to configure the alpha test.

Code 4-60. Configuring the Alpha Test
static void nn::gd::OutputStage::SetAlphaTest(
        gdBool enable, nn::gd::OutputStage::AlphaFunction func, u8 alphaRef); 

To enable the alpha test, specify GD_TRUE in the enable parameter, a comparison function in the func parameter, and a reference value in the alphaRef parameter. The default settings for these parameters are GD_FALSE, ALPHA_FUNCTION_NEVER, and 0, respectively.

4.9.5. Logical Operations and Blending

By creating a state (BlendState) object and then switching the BlendState object that is configured in the output stage, you can change all settings related to logical operations and blending in one operation.

You can create, release, and apply a BlendState object to the pipeline using the following functions.

Code 4-61. Creating, Releasing, and Applying a BlendState Object to the Pipeline
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); 

Configure logical operations and blending in a descriptor class (BlendStateDescription) that is specified in the desc parameter. For more information about the descriptor class settings, see 4.9.5.1. Descriptor Class for BlendState Objects.

You can use the nn::gd::OutputStage::SetBlendState() function to apply a created BlendState object to the pipeline.

Use the nn::gd::OutputStage::ReleaseBlendState() function to release a state object that is no longer needed. This also releases memory regions that were allocated internally when the BlendState object was created as a state object.

Use the following function to set the blend color. The default blend color is (0, 0, 0, 0).

Code 4-62. Setting the Blend Color
 static void nn::gd::OutputStage::SetBlendColor(u8 R, u8 G, u8 B, u8 A); 

4.9.5.1. Descriptor Class for BlendState Objects

This section introduces the members of the descriptor (BlendStateDescription) class for BlendState objects and provides setting-related cautions and information.

Code 4-63. Definition of the BlendStateDescription Class
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();
}; 
Choice Between Logical Operations and Blending (m_BlendType)

Set to BLEND_TYPE_LOGICOP when logical operations are used or BLEND_TYPE_BLENDING when blending is used.

Logical Operation (m_LogicOp)

Indicates which logical operation to use. You can set this value using the SetLogicOperatorMode() function.

Set to LOGIC_OPERATOR_COPY by the SetLogicOperatorMode_Default() function.

Blend Weight Coefficients (m_SrcRgb, m_DstRgb, m_SrcAlpha, m_DstAlpha)

These are the blend weight coefficients. There are settings for the RGB and alpha components in both the source and destination.

Blend Equations (m_EqRgb, m_EqAlpha)

These are the blend equations. There is a setting for both the RGB and alpha components.

Batch Blend Settings (SetBlendFunc, SetBlendMode_NoBlend)

The SetBlendFunc() function configures all blending operations at the same time. You can either configure the RGB and alpha components together or separately.

The SetBlendMode_NoBlend() function changes settings so that there is no blending (the source is output unchanged).

Table 4-25. Blend Settings Changed by SetBlendMode_NoBlend
Member Setting
m_SrcRgb, m_SrcAlpha BLEND_FUNCTION_ONE
m_DstRgb, m_DstAlpha BLEND_FUNCTION_ZERO
m_EqRgb, m_EqAlpha BLEND_EQUATION_ADD
Default Settings (ToDefault)

You can call the ToDefault() function to change all members to their default values. This is also done in the constructor.

Blending is used by default, and the settings are the same as those configured by the SetBlendMode_NoBlend() function.

4.9.6. W-Buffer and Polygon Offset

Use the nn::gd::OutputStage::SetDepthRangeMode() function to configure the w-buffer and polygon offset.

Code 4-64. Setting the W-Buffer and Polygon Offset
static void nn::gd::OutputStage::SetDepthRangeMode(
        nn::gd::OutputStage::DepthBufferType type,
        f32 depthRangeNear, f32 depthRangeFar, s32 offset); 

Specify DEPTHBUFFER_LINEAR in the type parameter to use the w-buffer feature or specify DEPTHBUFFER_RECIPROCAL_FUNCTION to use the normal range of depth values instead.

Specify the near and far depth values in the depthRangeNear and depthRangeFar parameters when you do not use the w-buffer. Specify 0 in depthRangeNear and a scale value in depthRangeFar when you do use the w-buffer.

When you use a polygon offset, specify the offset value in the offset parameter.

4.9.7. Soft Shadows

Use the nn::gd::OutputStage::SetPenumbraScaleBias() function to set the scale and bias for soft shadows. Because this is an immediate function, 3D commands are accumulated in the command buffer when it is run.

Code 4-65. Setting Soft Shadows
static void nn::gd::OutputStage::SetPenumbraScaleBias(f32 Scale, f32 Bias);  

CONFIDENTIAL