Hardware/GX/Transform Unit
The transform unit (XF) is a component of the Wii's GX subsystem. It is responsible for transforming the incoming vertices to screen coordinates.
Writing to XF registers
Writing to XF registers is done by writing values to the FIFO, as shown below:
To write to one XF register:
- write 0x10 (8-bit)
- write 0x0000 (16-bit)
- write the address of the register (16-bit)
- write the value to write to the register (32-bit)
To write to multiple XF registers:
- write 0x10 (8-bit)
- write (n-1) (16-bit)
- write the address of the first register (16-bit)
- write the values to write to each register (32-bit each)
Where n is the number of registers to write.
XF registers
XF viewport registers
These registers define the viewport coordinates.
GX_XF_VIEWPORT_X0 (0x101A) | |
310 | |
Access | R/W |
- This register defines the X0 coordinate of the viewport.
GX_XF_VIEWPORT_Y0 (0x101B) | |
310 | |
Access | R/W |
- This register defines the Y0 coordinate of the viewport.
GX_XF_VIEWPORT_Z (0x101C) | |
310 | |
Access | R/W |
- This register defines the depth (far plane - near plane) of the viewport.
GX_XF_VIEWPORT_X1 (0x101D) | |
310 | |
Access | R/W |
- This register defines the X1 coordinate of the viewport.
GX_XF_VIEWPORT_Y1 (0x101E) | |
310 | |
Access | R/W |
- This register defines the Y1 coordinate of the viewport.
GX_XF_VIEWPORT_FP (0x101F) | |
310 | |
Access | R/W |
- This register defines the far plane of the viewport.
The viewport coordinates can be calculated as shown below:
- GX_XF_VIEWPORT_X0 = viewport_width / 2
- GX_XF_VIEWPORT_Y0 = (-viewport_height) / 2
- GX_XF_VIEWPORT_X1 = (viewport_x + (viewport_width / 2)) + 342
- GX_XF_VIEWPORT_Y1 = (viewport_y + (viewport_height / 2)) + 342
- GX_XF_VIEWPORT_FP = viewport_farplane * 16777215
- GX_XF_VIEWPORT_Z = (viewport_farplane - viewport_nearplane) * 16777215
Note: These formulas are taken from the libogc function GX_SetViewportJitter().
GX_XF_VIEWPORT_FP and GX_XF_VIEWPORT_Z are 24-bit fixed-point values ranging between 0 and 16777215. These numbers respectively represent 0.0 and 1.0 in floating-point.
All the other viewport registers are 32-bit floating-point values.
XF projection registers
These registers define the projection matrix. Actually, there are 7 registers, so they don't really define a matrix, but rather parts of it.
GX_XF_PROJ_0 (0x1020) | |
310 | |
Access | R/W |
GX_XF_PROJ_1 (0x1021) | |
310 | |
Access | R/W |
GX_XF_PROJ_2 (0x1022) | |
310 | |
Access | R/W |
GX_XF_PROJ_3 (0x1023) | |
310 | |
Access | R/W |
GX_XF_PROJ_4 (0x1024) | |
310 | |
Access | R/W |
GX_XF_PROJ_5 (0x1025) | |
310 | |
Access | R/W |
- These registers define 6 projection values.
GX_XF_PROJ_MODE (0x1026) | |
310 | |
Access | R/W |
- This register defines how the projection values will be translated.
Depending on GX_XF_PROJ_MODE, you must assign different parts of your 4x4 projection matrix to the projection values:
- GX_XF_PROJ_MODE = 0 (perspective):
- GX_XF_PROJ_0 = matrix[0][0]
- GX_XF_PROJ_1 = matrix[0][2]
- GX_XF_PROJ_2 = matrix[1][1]
- GX_XF_PROJ_3 = matrix[1][2]
- GX_XF_PROJ_4 = matrix[2][2]
- GX_XF_PROJ_5 = matrix[2][3]
- GX_XF_PROJ_MODE = 1 (orthographic):
- GX_XF_PROJ_0 = matrix[0][0]
- GX_XF_PROJ_1 = matrix[0][3]
- GX_XF_PROJ_2 = matrix[1][1]
- GX_XF_PROJ_3 = matrix[1][3]
- GX_XF_PROJ_4 = matrix[2][2]
- GX_XF_PROJ_5 = matrix[2][3]
Note: these assignments are taken from the libogc function GX_LoadProjectionMtx().