Notes Regarding the Use of NintendoWare for CTR Together With DMPGL

Introduction
Drawing with DMPGL
Drawing Graphics
Drawing Layouts (Fonts)
Pseudo-code
Frame Buffer Operations
GL API Bug Workaround

Introduction

This document is a collection of notes regarding the use of NintendoWare for CTR (henceforth called NW4C) together with DMPGL.

To improve the performance of NW4C, from version 0.7.0 there are commands directly generated without using DMPGL for interpretation by the GPU. For this reason, you must follow set procedures when using NW4C and DMPGL.

If you need more information about using DMPGL together with directly generated commands, see the following documentation:

If you need more information about the direct generation of commands, see the following documentation, which is included in the CTR-SDK:

Frame Buffer Operations

Under NW4C, the command for setting the frame buffer is issued directly to the GPU without invoking glBindFramebuffer under the RenderContext::SetRenderTarget namespace. glBindFramebuffer must be called separately and explicitly, if the application is executing gl functions that impact the frame buffer, such as glClear and glDrawElements.
    glBindFramebuffer( GL_FRAMEBUFFER,  renderTarget->GetBufferObject()
    glClear(mask);

Drawing with DMPGL

States are updated when DMPGL is called after the drawing of NW4C graphics, layouts and fonts.

    Drawing graphics, layouts and fonts
    nngxUpdateState(NN_GX_STATE_ALL);
    Drawing with DMPGL

After DMPGL is called, the state is validated when drawing NW4C graphics, NW4C layouts or NW4C fonts.

    nngxValidateState(NN_GX_STATE_ALL, false);
    Drawing graphics, layouts and fonts
	

Drawing graphics

States are reset before drawing of graphics.

    RenderContext::ResetState();
    Drawing graphics
	

Drawing Layouts (Fonts)

Before drawing a layout (or font), be sure to first set all parameters not set for layouts (or fonts), such as polygon culling and depth testing.

For details on how to set parameters not set for layouts (or fonts), see the Reference Manual entry for the nw::lyt::Drawer class. Also, see the layout demo sample for specific examples of making settings.

    Culling polygon faces and depth test settings
    Draw layout (or font)
	

Pseudo-code

Pseudo-code for Drawing Layouts After Drawing Graphics

while (true)
{
    RenderContext::ResetState();
    Drawing graphics

    Culling polygon faces, depth test settings, and so on
    Drawing layouts
}

Pseudo-code for Drawing with DMPGL After Drawing Graphics

while (true)
{
    RenderContext::ResetState();
    Drawing graphics

    nngxUpdateState(NN_GX_STATE_ALL)
    Drawing with DMPGL
}

Pseudo-code for Drawing Graphics After Drawing Layouts

while (true)
{
    Culling polygon faces, depth test settings, and so on
    Drawing layouts

    RenderContext::ResetState();
    Drawing graphics
}

Pseudo-code for Drawing Graphics After Drawing Layouts

while (true)
{
    Culling polygon faces, depth test settings, and so on
    Drawing layouts

    nngxUpdateState(NN_GX_STATE_ALL);
    Drawing with DMPGL
}

Pseudo-code for Drawing Graphics After Drawing with DMPGL

while (true)
{
    nngxUpdateState(NN_GX_STATE_ALL);
    Drawing with DMPGL

    RenderContext::ResetState();
    Drawing graphics
}

Pseudo-code for Drawing Layouts After Drawing with DMPGL

while (true)
{
    nngxUpdateState(NN_GX_STATE_ALL);
    Drawing with DMPGL

    Culling polygon faces, depth test settings, and so on
    Drawing layouts
}

GL API But Workaround

Although current specifications call for a value of 1 to be set in registers 0x229[8] and 0x253[8] when using glDrawElements in GL_TRIANGLES mode, or a value of 0 in other cases, these values are not set internally by OpenGL by the nngxValidateState function.

If you are drawing using NW4C or gl using other than glDrawElements in GL_TRIANGLES mode, you need to explicity set registers before drawing using GL.

u32 cmd[] = {
  0x00000000, 0x00020253, 
  0x00000000, 0x00020229
}; 
nngxAdd3DCommand(cmd, sizeof(cmd), GL_TRUE);

CONFIDENTIAL