Line 1: |
Line 1: |
| The transform unit (XF) is a component of the Wii's GX subsystem. It is responsible for transforming the incoming vertices to screen coordinates. | | 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. |
| + | |
| + | |
| + | {{regsimple | GX_XF_VIEWPORT_X0 | addr=0x101A | bits=32 | access = R/W}} |
| + | * This register defines the X0 coordinate of the viewport. |
| + | |
| + | |
| + | {{regsimple | GX_XF_VIEWPORT_Y0 | addr=0x101B | bits=32 | access = R/W}} |
| + | * This register defines the Y0 coordinate of the viewport. |
| + | |
| + | |
| + | {{regsimple | GX_XF_VIEWPORT_Z | addr=0x101C | bits=32 | access = R/W}} |
| + | * This register defines the depth (far plane - near plane) of the viewport. |
| + | |
| + | |
| + | {{regsimple | GX_XF_VIEWPORT_X1 | addr=0x101D | bits=32 | access = R/W}} |
| + | * This register defines the X1 coordinate of the viewport. |
| + | |
| + | |
| + | {{regsimple | GX_XF_VIEWPORT_Y1 | addr=0x101E | bits=32 | access = R/W}} |
| + | * This register defines the Y1 coordinate of the viewport. |
| + | |
| + | |
| + | {{regsimple | GX_XF_VIEWPORT_FP | addr=0x101F | bits=32 | 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. |
| + | |
| + | |
| + | {{regsimple | GX_XF_PROJ_0 | addr=0x1020 | bits=32 | access = R/W}} |
| + | {{regsimple | GX_XF_PROJ_1 | addr=0x1021 | bits=32 | access = R/W}} |
| + | {{regsimple | GX_XF_PROJ_2 | addr=0x1022 | bits=32 | access = R/W}} |
| + | {{regsimple | GX_XF_PROJ_3 | addr=0x1023 | bits=32 | access = R/W}} |
| + | {{regsimple | GX_XF_PROJ_4 | addr=0x1024 | bits=32 | access = R/W}} |
| + | {{regsimple | GX_XF_PROJ_5 | addr=0x1025 | bits=32 | access = R/W}} |
| + | * These registers define 6 projection values. |
| + | |
| + | |
| + | {{regsimple | GX_XF_PROJ_MODE | addr=0x1026 | bits=32 | 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().'' |