libdragon
Enumerations | Functions

RDP Command queue: mode setting. More...

Go to the source code of this file.

Enumerations

enum  rdpq_filter_t { FILTER_POINT = SOM_SAMPLE_POINT >> SOM_SAMPLE_SHIFT , FILTER_BILINEAR = SOM_SAMPLE_BILINEAR >> SOM_SAMPLE_SHIFT , FILTER_MEDIAN = SOM_SAMPLE_MEDIAN >> SOM_SAMPLE_SHIFT }
 Texture filtering types. More...
 
enum  rdpq_dither_t {
  DITHER_SQUARE_SQUARE = (SOM_RGBDITHER_SQUARE | SOM_ALPHADITHER_SAME) >> SOM_ALPHADITHER_SHIFT , DITHER_SQUARE_INVSQUARE = (SOM_RGBDITHER_SQUARE | SOM_ALPHADITHER_INVERT) >> SOM_ALPHADITHER_SHIFT , DITHER_SQUARE_NOISE = (SOM_RGBDITHER_SQUARE | SOM_ALPHADITHER_NOISE) >> SOM_ALPHADITHER_SHIFT , DITHER_SQUARE_NONE = (SOM_RGBDITHER_SQUARE | SOM_ALPHADITHER_NONE) >> SOM_ALPHADITHER_SHIFT ,
  DITHER_BAYER_BAYER = (SOM_RGBDITHER_BAYER | SOM_ALPHADITHER_SAME) >> SOM_ALPHADITHER_SHIFT , DITHER_BAYER_INVBAYER = (SOM_RGBDITHER_BAYER | SOM_ALPHADITHER_INVERT) >> SOM_ALPHADITHER_SHIFT , DITHER_BAYER_NOISE = (SOM_RGBDITHER_BAYER | SOM_ALPHADITHER_NOISE) >> SOM_ALPHADITHER_SHIFT , DITHER_BAYER_NONE = (SOM_RGBDITHER_BAYER | SOM_ALPHADITHER_NONE) >> SOM_ALPHADITHER_SHIFT ,
  DITHER_NOISE_SQUARE = (SOM_RGBDITHER_NOISE | SOM_ALPHADITHER_SAME) >> SOM_ALPHADITHER_SHIFT , DITHER_NOISE_INVSQUARE = (SOM_RGBDITHER_NOISE | SOM_ALPHADITHER_INVERT) >> SOM_ALPHADITHER_SHIFT , DITHER_NOISE_NOISE = (SOM_RGBDITHER_NOISE | SOM_ALPHADITHER_NOISE) >> SOM_ALPHADITHER_SHIFT , DITHER_NOISE_NONE = (SOM_RGBDITHER_NOISE | SOM_ALPHADITHER_NONE) >> SOM_ALPHADITHER_SHIFT ,
  DITHER_NONE_BAYER = (SOM_RGBDITHER_NONE | SOM_ALPHADITHER_SAME) >> SOM_ALPHADITHER_SHIFT , DITHER_NONE_INVBAYER = (SOM_RGBDITHER_NONE | SOM_ALPHADITHER_INVERT) >> SOM_ALPHADITHER_SHIFT , DITHER_NONE_NOISE = (SOM_RGBDITHER_NONE | SOM_ALPHADITHER_NOISE) >> SOM_ALPHADITHER_SHIFT , DITHER_NONE_NONE = (SOM_RGBDITHER_NONE | SOM_ALPHADITHER_NONE) >> SOM_ALPHADITHER_SHIFT
}
 Dithering configuration. More...
 
enum  rdpq_tlut_t { TLUT_NONE = 0 , TLUT_RGBA16 = 2 , TLUT_IA16 = 3 }
 Types of palettes supported by RDP. More...
 
enum  rdpq_mipmap_t {
  MIPMAP_NONE = 0 , MIPMAP_NEAREST = SOM_TEXTURE_LOD >> 32 , MIPMAP_INTERPOLATE = (SOM_TEXTURE_LOD | SOMX_LOD_INTERPOLATE) >> 32 , MIPMAP_INTERPOLATE_SHARPEN = (SOM_TEXTURE_LOD | SOMX_LOD_INTERPOLATE | SOM_TEXTURE_SHARPEN) >> 32 ,
  MIPMAP_INTERPOLATE_DETAIL = (SOM_TEXTURE_LOD | SOMX_LOD_INTERPOLATE | SOM_TEXTURE_DETAIL) >> 32
}
 Types of mipmap supported by RDP. More...
 
enum  rdpq_antialias_t { AA_NONE = 0 , AA_STANDARD = 1 , AA_REDUCED = 2 }
 Types of antialiasing supported by RDP. More...
 

Functions

void rdpq_mode_push (void)
 Push the current render mode into the stack. More...
 
void rdpq_mode_pop (void)
 Pop the current render mode from the stack. More...
 
rdpq_tlut_t rdpq_tlut_from_format (tex_format_t format)
 Converts the specified texture format to the TLUT mode that is needed to draw a texture of this format.
 
void rdpq_mode_begin (void)
 Start a batch of RDP mode changes. More...
 
void rdpq_mode_end (void)
 Finish a batch of RDP mode changes. More...
 
Render modes

These functions set a new render mode from scratch. Every render state is reset to some value (or default), so no previous state is kept valid.

void rdpq_set_mode_standard (void)
 Reset render mode to standard. More...
 
void rdpq_set_mode_fill (color_t color)
 Reset render mode to FILL type. More...
 
void rdpq_set_mode_copy (bool transparency)
 Reset render mode to COPY type. More...
 
void rdpq_set_mode_yuv (bool bilinear)
 Reset render mode to YUV mode. More...
 

Render states

These functions allow to tweak individual render states. They should be called after one of the render mode reset functions to configure the render states.

#define RDPQ_BLENDER_MULTIPLY   RDPQ_BLENDER((IN_RGB, IN_ALPHA, MEMORY_RGB, INV_MUX_ALPHA))
 Blending mode: multiplicative alpha. More...
 
#define RDPQ_BLENDER_MULTIPLY_CONST   RDPQ_BLENDER((IN_RGB, FOG_ALPHA, MEMORY_RGB, INV_MUX_ALPHA))
 Blending mode: multiplicative alpha with a constant value. More...
 
#define RDPQ_BLENDER_ADDITIVE   RDPQ_BLENDER((IN_RGB, IN_ALPHA, MEMORY_RGB, ONE))
 Blending mode: additive alpha. You can pass this macro to rdpq_mode_blender. More...
 
#define RDPQ_FOG_STANDARD   RDPQ_BLENDER((IN_RGB, SHADE_ALPHA, FOG_RGB, INV_MUX_ALPHA))
 Fogging mode: standard. You can pass this macro to rdpq_mode_fog.
 
void rdpq_mode_antialias (rdpq_antialias_t mode)
 Activate antialiasing. More...
 
void rdpq_mode_combiner (rdpq_combiner_t comb)
 Configure the color combiner. More...
 
void rdpq_mode_blender (rdpq_blender_t blend)
 Configure the formula to use for blending. More...
 
void rdpq_mode_fog (rdpq_blender_t fog)
 Enable or disable fog. More...
 
void rdpq_mode_dithering (rdpq_dither_t dither)
 Change dithering mode. More...
 
void rdpq_mode_alphacompare (int threshold)
 Activate alpha compare feature. More...
 
void rdpq_mode_zbuf (bool compare, bool update)
 Activate z-buffer usage. More...
 
void rdpq_mode_zoverride (bool enable, float z, int16_t deltaz)
 Set a fixed override of Z value. More...
 
void rdpq_mode_tlut (rdpq_tlut_t tlut)
 Activate palette lookup during drawing. More...
 
void rdpq_mode_filter (rdpq_filter_t filt)
 Activate texture filtering. More...
 
void rdpq_mode_mipmap (rdpq_mipmap_t mode, int num_levels)
 Activate mip-mapping. More...
 
void rdpq_mode_persp (bool perspective)
 Activate perspective correction for textures. More...
 

Detailed Description

RDP Command queue: mode setting.

The mode API is a high level API to simplify mode setting with RDP. Configuring render modes is possibly the most complex task with RDP programming, as the RDP is full of hardware features that interact badly between them or are in general non-orthogonal. The mode API tries to hide much of the complexity between an API more similar to a modern graphic API like OpenGL.

In general, mode setting with RDP is performed via two commands SET_COMBINE_MODE and SET_OTHER_MODES. These two commands are available as "raw" commands in the basic rdpq API as rdpq_set_combiner_raw and rdpq_set_other_modes_raw. These two functions set the specified configurations into the RDP hardware registers, and do nothing else, so they can always be used to do manual RDP programming.

Instead, the mode API follows the following pattern:

The rdpq mode API currently offers the following render modes:

After setting the render mode, you can configure the render states. An important implementation effort has been made to try and make the render states orthogonal, so that each one can be toggled separately without inter-dependence (a task which is particularly complex on the RDP hardware). Not all render states are available in all modes, refer to the documentation of each render state for further information.

Note
From a hardware perspective, rdpq handles automatically the "RDP cycle type". That is, it transparently switches from "1-cycle mode" to "2-cycle mode" whenever it is necessary. If you come from a RDP low-level programming background, it might be confusing at first because everything "just works" without needing to adjust settings any time you need to change a render state.

Mode setting stack

The mode API also keeps a small (4 entry) stack of mode configurations. This allows client code to temporarily switch render mode and then get back to the previous mode, which helps modularizing the code.

To save the current render mode onto the stack, use rdpq_mode_push. To restore the previous render mode from the stack, use rdpq_mode_pop.

Notice the mode settings being part of this stack are those which are configured via the mode API functions itself (rdpq_set_mode_* and rdpq_mode_*). Anything that doesn't go through the mode API is not saved/restored. For instance, activating blending via rdpq_mode_blender is saved onto the stack, whilst changing the BLEND color register (via rdpq_set_blend_color) is not, and you can tell by the fact that the function called to configure it is not part of the mode API.

Macro Definition Documentation

◆ RDPQ_BLENDER_MULTIPLY

#define RDPQ_BLENDER_MULTIPLY   RDPQ_BLENDER((IN_RGB, IN_ALPHA, MEMORY_RGB, INV_MUX_ALPHA))

Blending mode: multiplicative alpha.

This is standard multiplicative blending between the color being drawn and the framebuffer color.

You can pass this macro to rdpq_mode_blender.

◆ RDPQ_BLENDER_MULTIPLY_CONST

#define RDPQ_BLENDER_MULTIPLY_CONST   RDPQ_BLENDER((IN_RGB, FOG_ALPHA, MEMORY_RGB, INV_MUX_ALPHA))

Blending mode: multiplicative alpha with a constant value.

This is similar to RDPQ_BLENDER_MULTIPLY, but instead of using the alpha value from the texture (or rather, the one coming out of the color combiner), it uses a constant value that must be programmed via rdpq_set_fog_color:

You can pass this macro to rdpq_mode_blender:

float alpha = 0.5f;
rdpq_set_fog_color(RGBA32(0, 0, 0, alpha * 255));
#define RGBA32(rx, gx, bx, ax)
Create a color_t from the R,G,B,A components in the RGBA32 range (0-255).
Definition: graphics.h:49
void rdpq_set_fog_color(color_t color)
Set the RDP FOG blender register.
Definition: rdpq.h:887
void rdpq_mode_blender(rdpq_blender_t blend)
Configure the formula to use for blending.
Definition: rdpq_mode.h:591
#define RDPQ_BLENDER_MULTIPLY_CONST
Blending mode: multiplicative alpha with a constant value.
Definition: rdpq_mode.h:519

Notice that the alpha value coming out of the combiner is ignored. This means that you can use this blender formula even for blending textures without alpha channel.

◆ RDPQ_BLENDER_ADDITIVE

#define RDPQ_BLENDER_ADDITIVE   RDPQ_BLENDER((IN_RGB, IN_ALPHA, MEMORY_RGB, ONE))

Blending mode: additive alpha. You can pass this macro to rdpq_mode_blender.

NOTE: additive blending is broken on RDP because it can overflow. Basically, if the result of the sum is larger than 1.5 (in scale 0..1), instead of being clamped to 1, it overflows back to 0, which makes the mode almost useless. It is defined it for completeness.

Enumeration Type Documentation

◆ rdpq_filter_t

Texture filtering types.

Enumerator
FILTER_POINT 

Point filtering (aka nearest)

FILTER_BILINEAR 

Bilinear filtering.

FILTER_MEDIAN 

Median filtering.

◆ rdpq_dither_t

Dithering configuration.

RDP can optionally perform dithering on RGB and Alpha channel of the texture. The dithering is performed by the blender unit, which is also in charge of adapting the pixel color depth to that of the framebuffer. Dithering is a good way to reduce the mach banding effect created by color depth reduction.

The blender in fact will reduce the RGB components of the pixel (coming from the color combiner) to 5-bit when the framebuffer is 16-bit. If the framebuffer is 32-bit, the blender formula will be calculated with 8-bit per channel, so no dithering is required.

On the other hand, the alpha channels (used as multiplicative factors in the blender formulas) will always be reduced to 5-bit depth, even if the framebuffer is 32-bit. If you see banding artifacts in transparency levels of blended polygons, you may want to activate dithering on the alpha channel.

It is important to notice that the VI can optionally run an "dither filter" on the final image, while sending it to the video output. This algorithm tries to recover color depth precision by averaging lower bits in neighborhood pixels, and reducing the small noise created by dithering. display_init currently activates it by default on all 16-bit display modes, if passed FILTERS_DEDITHER or FILTERS_RESAMPLE_ANTIALIAS_DEDITHER.

If you are using an emulator, make sure it correctly emulates the VI dither filter to judge the quality of the final image. For instance, the RDP plugin parallel-RDP (based on Vulkan) emulates it very accurately, so emulators like Ares, dgb-n64 or simple64 will produce a picture closer to real hardware.

The supported dither algorithms are:

  • SQUARE (aka "magic square"). This is a custom dithering algorithm, designed to work best with the VI dither filter. When using it, the VI will reconstruct a virtually perfect 32-bit image even though the framebuffer is only 16-bit.
  • BAYER: standard Bayer dithering. This algorithm looks better than the magic square when the VI dither filter is disabled, or in some specific scenarios like large blended polygons. Make sure to test it as well.
  • INVSQUARE and INVBAYER: these are the same algorithms, but using an inverse (symmetrical) pattern. They can be selected for alpha channels to avoid making transparency phase with color dithering, which is sometimes awkward.
  • NOISE: random noise dithering. The dithering is performed by perturbing the lower bit of each pixel with random noise. This will create a specific visual effect as it changes from frame to frame even on still images; it is especially apparent when used on alpha channel as it can affect transparency. It is more commonly used as a graphic effect rather than an actual dithering.
  • NONE: disable dithering.

While the RDP hardware allows to configure different dither algorithms for RGB and Alpha channels, unfortunately not all combinations are available. This enumerator defines the available combinations. For instance, DITHER_BAYER_NOISE selects the Bayer dithering for the RGB channels, and the noise dithering for alpha channel.

Enumerator
DITHER_SQUARE_SQUARE 

Dithering: RGB=Square, Alpha=Square.

DITHER_SQUARE_INVSQUARE 

Dithering: RGB=Square, Alpha=InvSquare.

DITHER_SQUARE_NOISE 

Dithering: RGB=Square, Alpha=Noise.

DITHER_SQUARE_NONE 

Dithering: RGB=Square, Alpha=None.

DITHER_BAYER_BAYER 

Dithering: RGB=Bayer, Alpha=Bayer.

DITHER_BAYER_INVBAYER 

Dithering: RGB=Bayer, Alpha=InvBayer.

DITHER_BAYER_NOISE 

Dithering: RGB=Bayer, Alpha=Noise.

DITHER_BAYER_NONE 

Dithering: RGB=Bayer, Alpha=None.

DITHER_NOISE_SQUARE 

Dithering: RGB=Noise, Alpha=Square.

DITHER_NOISE_INVSQUARE 

Dithering: RGB=Noise, Alpha=InvSquare.

DITHER_NOISE_NOISE 

Dithering: RGB=Noise, Alpha=Noise.

DITHER_NOISE_NONE 

Dithering: RGB=Noise, Alpha=None.

DITHER_NONE_BAYER 

Dithering: RGB=None, Alpha=Bayer.

DITHER_NONE_INVBAYER 

Dithering: RGB=None, Alpha=InvBayer.

DITHER_NONE_NOISE 

Dithering: RGB=None, Alpha=Noise.

DITHER_NONE_NONE 

Dithering: RGB=None, Alpha=None.

◆ rdpq_tlut_t

Types of palettes supported by RDP.

Enumerator
TLUT_NONE 

No palette.

TLUT_RGBA16 

Palette made of FMT_RGBA16 colors.

TLUT_IA16 

Palette made of FMT_IA16 colors.

◆ rdpq_mipmap_t

Types of mipmap supported by RDP.

Enumerator
MIPMAP_NONE 

Mipmap disabled.

MIPMAP_NEAREST 

Choose the nearest mipmap level.

MIPMAP_INTERPOLATE 

Interpolate between the two nearest mipmap levels (also known as "trilinear")

MIPMAP_INTERPOLATE_SHARPEN 

Interpolate between the two nearest mipmap levels (also known as "trilinear") with sharpening enabled.

MIPMAP_INTERPOLATE_DETAIL 

Interpolate between the two nearest mipmap levels (also known as "trilinear") with detail texture enabled.

◆ rdpq_antialias_t

Types of antialiasing supported by RDP.

Enumerator
AA_NONE 

No antialiasing.

AA_STANDARD 

Standard antialiasing.

AA_REDUCED 

Reduced antialiasing.

Function Documentation

◆ rdpq_mode_push()

void rdpq_mode_push ( void  )

Push the current render mode into the stack.

This function allows to push the current render mode into an internal stack. It allows to temporarily modify the render mode, and later recover its value.

This is effective on all render mode changes that can be modified via rdpq_mode_* function. It does not affect other RDP configurations such as the various colors.

The stack has 4 slots (including the current one).

◆ rdpq_mode_pop()

void rdpq_mode_pop ( void  )

Pop the current render mode from the stack.

This function allows to pop a previously pushed render mode from the stack, setting it as current again.

◆ rdpq_set_mode_standard()

void rdpq_set_mode_standard ( void  )
inline

Reset render mode to standard.

This is the most basic and general mode reset function. It configures the RDP processor in a standard and very basic way:

  • Basic texturing (without shading)
  • No dithering, antialiasing, blending, etc.

You can further configure the mode by calling one of the many functions in the mode API (rdpq_mode_*).

◆ rdpq_set_mode_fill()

void rdpq_set_mode_fill ( color_t  color)
inline

Reset render mode to FILL type.

This function sets the render mode type to FILL, which is used to quickly fill portions of the screens with a solid color. The specified color is configured via rdpq_set_fill_color, and can be changed later.

Notice that in FILL mode most of the RDP features are disabled, so all other render modes settings (rdpq_mode_* functions) do not work.

Parameters
[in]colorThe fill color to use

◆ rdpq_set_mode_copy()

void rdpq_set_mode_copy ( bool  transparency)

Reset render mode to COPY type.

This function sets the render mode type to COPY, which is used to quickly blit bitmaps. In COPY mode, only texture rectangles (aka "sprites") can be drawn and no advanced render mode features are working (rdpq_mode_* functions).

The only available feature is transparency: pixels with alpha set to 0 can optionally be discarded during blit, so that the target buffer contents is not overwritten for those pixels. This is implemented using alpha compare.

The COPY mode is approximately 4 times faster at drawing than the standard mode, so make sure to enable it whenever it is possible.

Note
The COPY mode only works with 16-bpp framebuffers. It will trigger a hardware crash (!) on 32-bpp framebuffers, so avoid using it. The validator will warn you about this anyway.
Parameters
[in]transparencyIf true, pixels with alpha set to 0 are not drawn
See also
rdpq_set_mode_standard

◆ rdpq_set_mode_yuv()

void rdpq_set_mode_yuv ( bool  bilinear)

Reset render mode to YUV mode.

This is a helper function to configure a render mode for YUV conversion. In addition of setting the render mode, this function also configures a combiner (given that YUV conversion happens also at the combiner level), and set standard YUV parameters (for BT.601 TV Range).

After setting the YUV mode, you can load YUV textures to TMEM (using a surface with FMT_YUV16), and then draw them on the screen as part of triangles or rectangles.

Parameters
[in]bilinearIf true, YUV textures will also be filtered with bilinear interpolation (note: this will require 2-cycle mode so it will be twice as slow).

◆ rdpq_mode_antialias()

void rdpq_mode_antialias ( rdpq_antialias_t  mode)
inline

Activate antialiasing.

This function can be used to enable/disable antialias at the RDP level. There are two different kinds of antialias on N64:

  • Antialias on internal edges: this is fully performed by RDP.
  • Antialias on external edges: this is prepared by RDP but is actually performed as a post-processing filter by VI.

This function activates both kinds of antialias, but to display correctly the second type, make sure that you did pass FILTERS_RESAMPLE_ANTIALIAS or FILTERS_RESAMPLE_ANTIALIAS_DEDITHER to display_init.

On the other hand, if you want to make sure that no antialias is performed, disable antialias with rdpq_mode_antialias(false) (which is the default for rdpq_set_mode_standard), and that will make sure that the VI will not do anything to the image, even if display_init was called with FILTERS_RESAMPLE_ANTIALIAS or FILTERS_RESAMPLE_ANTIALIAS_DEDITHER.

Note
Antialiasing internally uses the blender unit. If you already configured a formula via rdpq_mode_blender, antialias will just rely on that one to correctly blend pixels with the framebuffer. It is thus important that a custom formula configured via rdpq_mode_blender does blend with the background somehow.
Parameters
modeAntialiasing mode to use (or AA_NONE to disable)

◆ rdpq_mode_combiner()

void rdpq_mode_combiner ( rdpq_combiner_t  comb)
inline

Configure the color combiner.

This function allows to configure the color combiner formula to be used. The color combiner is the internal RDP hardware unit that mixes inputs from textures, colors and other sources and produces a RGB/Alpha value, that is then sent to the blender unit. If the blender is disabled (eg: the polygon is solid), the value produced by the combiner is the one that will be written into the framebuffer.

For common use cases, rdpq offers ready-to-use macros that you can pass to rdpq_mode_combiner: RDPQ_COMBINER_FLAT, RDPQ_COMBINER_SHADE, RDPQ_COMBINER_TEX, RDPQ_COMBINER_TEX_FLAT, RDPQ_COMBINER_TEX_SHADE.

For example, to draw a texture rectangle modulated with a flat color:

// Reset to standard rendering mode.
// Configure the combiner
// Configure the flat color that will modulate the texture
rdpq_set_prim_color(RGBA32(192, 168, 74, 255));
// Upload a texture into TMEM (tile descriptor #4)
rdpq_tex_upload(TILE4, &texture, 0);
// Draw the rectangle
0, 0, 32, 16, // x0, y0, x1, y1
0, 0, 1.0, 1.0f // s, t, ds, dt
);
void rdpq_set_prim_color(color_t color)
Set the RDP PRIM combiner register (color only) (RDP command: SET_PRIM_COLOR)
Definition: rdpq.h:949
@ TILE4
Tile #4 (for code readability)
Definition: rdpq.h:254
#define RDPQ_COMBINER_TEX_FLAT
Draw with a texture modulated with a flat color. Configure the color via rdpq_set_prim_color.
Definition: rdpq_macros.h:490
void rdpq_mode_combiner(rdpq_combiner_t comb)
Configure the color combiner.
Definition: rdpq_mode.h:465
void rdpq_set_mode_standard(void)
Reset render mode to standard.
Definition: rdpq_mode.c:92
#define rdpq_texture_rectangle(tile, x0, y0, x1, y1, s, t)
Draw a textured rectangle (RDP command: TEXTURE_RECTANGLE)
Definition: rdpq_rect.h:293
int rdpq_tex_upload(rdpq_tile_t tile, const surface_t *tex, const rdpq_texparms_t *parms)
Load a texture into TMEM.
Definition: rdpq_tex.c:398

Alternatively, you can use your own combiner formulas, created with either RDPQ_COMBINER1 (one pass) or RDPQ_COMBINER2 (two passes). See the respective documentation for all the details on how to create a custom formula.

When using a custom formula, you must take into account that some render states also rely on the combiner to work. Specifically:

  • Mipmap (rdpq_mode_mipmap): when activating interpolated mipmapping (MIPMAP_INTERPOLATE, also known as "trilinear filterig"), a dedicated color combiner pass is needed, so if you set a custom formula, it has to be a one-pass formula. Otherwise, a RSP assertion will trigger.
  • Fog (rdpq_mode_fog): fogging is generally made by substituting the alpha component of the shade color with a depth value, which is then used in the blender formula (eg: RDPQ_FOG_STANDARD). The only interaction with the color combiner is that the SHADE alpha component should not be used as a modulation factor in the combiner, otherwise you get wrong results (if you then use the alpha for blending). rdpq automatically adjusts standard combiners using shade (RDPQ_COMBINER_SHADE and RDPQ_COMBINER_TEX_SHADE) when fog is enabled, but for custom combiners it is up to the user to take care of that.
Parameters
combThe combiner formula to configure
See also
RDPQ_COMBINER1
RDPQ_COMBINER2
Note
For programmers with previous RDP programming experience: this function makes sure that the current cycle type can work correctly with the specified combiner formula. Specifically, it switches automatically between 1-cycle and 2-cycle depending on the formula being set and the blender unit configuration, and also automatically adapts combiner formulas to the required cycle mode. See the documentation in rdpq.c for more information.

◆ rdpq_mode_blender()

void rdpq_mode_blender ( rdpq_blender_t  blend)
inline

Configure the formula to use for blending.

This function can be used to configure the formula used in the blender unit.

The standard blending formulas are:

It is possible to also create custom formulas. The blender unit allows for up to two passes. Use RDPQ_BLENDER to create a one-pass blending formula, or RDPQ_BLENDER2 to create a two-pass formula.

Please notice that two-pass formulas are not compatible with fogging (rdpq_mode_fog). Also notice that rdpq_mode assumes that any formula that you set here (either one-pass or two-passes) does blend with the background. If you want to use a formula that does not blend with the background, set it via rdpq_mode_fog, otherwise you might get incorrect results when using anti-alias (see rdpq_mode_antialias).

The following example shows how to draw a texture rectangle using a fixed blending value of 0.5 (ignoring the alpha channel of the texture):

// Set standard mode
// Configure the formula:
// (IN_RGB * FOG_ALPHA) + (MEMORY_RGB * (1 - FOG_ALPHA))
//
// where FOG_ALPHA is the fixed alpha value coming from the FOG register.
// Notice that the FOG register is not necessarily about fogging... it is
// just one of the two registers that can be used in blending formulas.
rdpq_mode_blender(RDPQ_BLENDER(IN_RGB, FOG_ALPHA, MEMORY_RGB, INV_MUX_ALPHA));
// Configure the FOG_ALPHA value to 128 (= 0.5). The RGB components are
// not used.
// Load a texture into TMEM
rdpq_tex_upload(TILE0, texture, 0);
// Draw it
0, 0, 64, 64, // x0,y0 - x1,y1
0, 0, 1.0, 1.0 // s0,t0 - ds,dt
);
@ TILE0
Tile #0 (for code readability)
Definition: rdpq.h:250
#define RDPQ_BLENDER(bl)
Build a 1-pass blender formula.
Definition: rdpq_macros.h:826
Parameters
blendBlending formula created with RDPQ_BLENDER, or 0 to disable.
See also
rdpq_mode_fog
RDPQ_BLENDER
RDPQ_BLENDER_MULTIPLY
RDPQ_BLENDER_ADDITIVE

◆ rdpq_mode_fog()

void rdpq_mode_fog ( rdpq_blender_t  fog)
inline

Enable or disable fog.

This function enables fog on RDP. Fog on RDP is simulated in the following way:

  • The T&L pipeline must calculate a depth information for each vertex of the primitive and put it into the alpha channel of the per-vertex color. This is outside of the scope of rdpq, so rdpq assumes that this has already been done when rdpq_mode_fog is called.
  • The RDP blender unit is programmed to modulate a "fog color" with the polygon pixel, using SHADE_ALPHA as interpolation factor. Since SHADE_ALPHA contains a depth information, the farther the object, the stronger it will assume the fog color.

To enable fog, pass RDPQ_FOG_STANDARD to this function, and call rdpq_set_fog_color to configure the fog color. This is the standard fogging formula.

If you want, you can instead build a custom fogging formula using RDPQ_BLENDER. Notice that rdpq_mode assumes that the formula that you set with rdpq_mode_fog does not blend with the background; for that, use rdpq_mode_blender.

To disable fog, call rdpq_mode_fog passing 0.

Note
Fogging uses one pass of the blender unit (the first), so this can coexist with a blending formula (rdpq_mode_blender) as long as it's a single pass one (created via RDPQ_BLENDER). If a two-pass blending formula (RDPQ_BLENDER2) was set with rdpq_mode_blender, fogging cannot be used.
Parameters
fogFog formula created with RDPQ_BLENDER, or 0 to disable.
See also
RDPQ_FOG_STANDARD
rdpq_set_fog_color
RDPQ_BLENDER
rdpq_mode_blender

◆ rdpq_mode_dithering()

void rdpq_mode_dithering ( rdpq_dither_t  dither)
inline

Change dithering mode.

This function allows to change the dithering algorithm performed by RDP on RGB and alpha channels. Note that by default, rdpq_set_mode_standard disables any dithering.

See rdpq_dither_t for an explanation of how RDP applies dithering and how the different dithering algorithms work.

Parameters
ditherDithering to perform
See also
rdpq_dither_t

◆ rdpq_mode_alphacompare()

void rdpq_mode_alphacompare ( int  threshold)
inline

Activate alpha compare feature.

This function activates the alpha compare feature. It allows to do per-pixel rejection (masking) depending on the value of the alpha component of the pixel. The value output from the combiner is compared with a configured threshold and if the value is lower, the pixel is not written to the framebuffer.

Moreover, RDP also support a random noise alpha compare mode, where the threshold value is calculated as a random number for each pixel. This can be used for special graphic effects.

Note
Alpha compare becomes more limited if antialiasing is enabled (both full and reduced, see rdpq_mode_antialias). In that case, any threshold value not equal to 0 will internally be treated as if 255 was specified. This implies that noise-based alpha compare is not supported under this condition.
Parameters
thresholdThreshold value. All pixels whose alpha is less than this threshold will not be drawn. Use 0 to disable. Use a negative value for activating the noise-based alpha compare.

◆ rdpq_mode_zbuf()

void rdpq_mode_zbuf ( bool  compare,
bool  update 
)
inline

Activate z-buffer usage.

Activate usage of Z-buffer. The Z-buffer surface must be configured via rdpq_set_z_image.

It is possible to separately activate the depth comparison (reading from the Z-buffer) and the Z update (writing to the Z-buffer).

Parameters
compareTrue if per-pixel depth test must be performed
updateTrue if per-pixel depth write must be performed
See also
rdpq_set_z_image

◆ rdpq_mode_zoverride()

void rdpq_mode_zoverride ( bool  enable,
float  z,
int16_t  deltaz 
)
inline

Set a fixed override of Z value.

This function activates a special mode in which RDP will use a fixed value of Z for the next drawn primitives. This works with both rectangles (rdpq_fill_rectangle and rdpq_texture_rectangle) and triangles (rdpq_triangle).

If a triangle is drawn with per-vertex Z while the Z-override is active, the per-vertex Z will be ignored.

Parameters
enableEnable/disable the Z-override mode
zZ value to use (range 0..1)
deltazDeltaZ value to use.
See also
rdpq_set_prim_depth_raw

◆ rdpq_mode_tlut()

void rdpq_mode_tlut ( rdpq_tlut_t  tlut)
inline

Activate palette lookup during drawing.

This function allows to enable / disable palette lookup during drawing. To draw using a texture with palette, it is necessary to first load the texture into TMEM (eg: via rdpq_tex_upload), then load the palette (eg: via rdpq_tex_upload_tlut), and finally activate the palette drawing mode via rdpq_mode_tlut.

Parameters
tlutPalette type, or 0 to disable.
See also
rdpq_tex_upload
rdpq_tex_upload_tlut
rdpq_tlut_t

◆ rdpq_mode_filter()

void rdpq_mode_filter ( rdpq_filter_t  filt)
inline

Activate texture filtering.

This function allows to configure the kind of texture filtering that will be used while sampling textures.

Available in render modes: standard, copy.

Parameters
filtTexture filtering type
See also
rdpq_filter_t

◆ rdpq_mode_mipmap()

void rdpq_mode_mipmap ( rdpq_mipmap_t  mode,
int  num_levels 
)
inline

Activate mip-mapping.

This function can be used to turn on mip-mapping.

TMEM must have been loaded with multiple level of details (LOds) of the texture (a task for which rdpq is currently missing a helper, so it has to be done manually). Also, multiple consecutive tile descriptors (one for each LOD) must have been configured.

If you call rdpq_triangle when mipmap is active via rdpq_mode_mipmap, pass 0 to the number of mipmaps in rdpq_trifmt_t, as the number of levels set here will win over it.

Parameters
modeMipmapping mode (use MIPMAP_NONE to disable)
num_levelsNumber of mipmap levels to use. Pass 0 when setting MIPMAP_NONE.

◆ rdpq_mode_persp()

void rdpq_mode_persp ( bool  perspective)
inline

Activate perspective correction for textures.

This function enables or disables the perspective correction for texturing. Perspective correction does not slow down rendering, and thus it is basically free.

To be able to use perspective correction, make sure to pass the Z and W values in the triangle vertices.

Parameters
perspectiveTrue to activate perspective correction, false to disable it.

◆ rdpq_mode_begin()

void rdpq_mode_begin ( void  )

Start a batch of RDP mode changes.

This function can be used as an optimization when changing render mode and/or multiple render states. It allows to batch the changes, so that RDP hardware registers are updated only once.

To use it, put a call to rdpq_mode_begin and rdpq_mode_end around the mode functions that you would like to batch. For instance:

rdpq_mode_blender(RDPQ_BLENDING_MULTIPLY);
void rdpq_mode_mipmap(rdpq_mipmap_t mode, int num_levels)
Activate mip-mapping.
Definition: rdpq_mode.h:802
void rdpq_mode_dithering(rdpq_dither_t dither)
Change dithering mode.
Definition: rdpq_mode.h:664
void rdpq_mode_begin(void)
Start a batch of RDP mode changes.
Definition: rdpq_mode.c:133
void rdpq_mode_end(void)
Finish a batch of RDP mode changes.
Definition: rdpq_mode.c:143
@ DITHER_SQUARE_SQUARE
Dithering: RGB=Square, Alpha=Square.
Definition: rdpq_mode.h:199
@ MIPMAP_INTERPOLATE
Interpolate between the two nearest mipmap levels (also known as "trilinear")
Definition: rdpq_mode.h:248

The only effect of using rdpq_mode_begin is more efficient RSP and RDP usage, there is no semantic change in the way RDP is programmed when rdpq_mode_end is called.

Note
The functions affected by rdpq_mode_begin / rdpq_mode_end are just those that are part of the mode API (that is, rdpq_set_mode_* and rdpq_mode_*). Any other function is not batched and will be issued immediately.

◆ rdpq_mode_end()

void rdpq_mode_end ( void  )

Finish a batch of RDP mode changes.

This function completes a batch of changes started with rdpq_mode_begin.

See also
rdpq_mode_begin