Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | pmbaty | 1 | # Rendering pipeline |
| 2 | |||
| 3 | The original game renders both 2d and 3d elements to the same memory buffer, called `gBack_screen`. |
||
| 4 | |||
| 5 | Another variable, `gRender_screen`, points into that memory buffer and is where the 3d scene is drawn on top of any existing 2d pixels. |
||
| 6 | |||
| 7 | Rendering is done in a (standard for the time) 8 bit paletted mode. |
||
| 8 | |||
| 9 | ``` |
||
| 10 | +-----------------------------------------+ |
||
| 11 | |gBack_screen | |
||
| 12 | | +------------------------+ | |
||
| 13 | | | gRender_screen | | |
||
| 14 | | | | | |
||
| 15 | | | | | |
||
| 16 | | | | | |
||
| 17 | | | | | |
||
| 18 | | +------------------------+ | |
||
| 19 | | | |
||
| 20 | +-----------------------------------------+ |
||
| 21 | ``` |
||
| 22 | |||
| 23 | The `RenderAFrame` function does the following: |
||
| 24 | |||
| 25 | 1. Render 2d background content (horizon, map, etc) to `gBack_screen` |
||
| 26 | 2. Start 3d scene rendering |
||
| 27 | 3. Render 3d environment to `gRender_screen` |
||
| 28 | 4. End 3d scene rendering |
||
| 29 | 5. Render 2d foreground content into `gBack_screen` (HUD, messages, etc) |
||
| 30 | 6. Swap buffers |
||
| 31 | |||
| 32 | If the rearview mirror is rendered, steps 3-4 are repeated, this time rendering into `gRearview_screen` |
||
| 33 | |||
| 34 | ## Palette manipulation |
||
| 35 | |||
| 36 | The game palette is updated frequently: |
||
| 37 | 1. Fade screen to black |
||
| 38 | 2. Fade screen back up to normal brightness |
||
| 39 | 3. Different palettes for the menu interface and for game play |
||
| 40 | 4. The "On drugs" powerup |
||
| 41 | |||
| 42 | Palette animations run in a tight loop, assuming they are writing to the system color palette, so do not re-render the 3d scene etc. We handle this by hooking the palette functions and reusing the last-rendered scene from our framebuffer. |
||
| 43 | |||
| 44 | ## OpenGL implementation |
||
| 45 | |||
| 46 | ### Start 3d rendering hook |
||
| 47 | - Capture the current `gBack_screen` and convert it to a 32 bit OpenGL texture, and render it as a full-screen quad. |
||
| 48 | - Configure OpenGL framebuffer to do render-to-texture |
||
| 49 | - Clear `gBack_screen` |
||
| 50 | |||
| 51 | ### Render model hook |
||
| 52 | - Render the model as an OpenGL VBO, convert referenced materials to OpenGL textures. |
||
| 53 | |||
| 54 | ### End 3d rendering hook |
||
| 55 | Render the framebuffer from above as a full-screen quad. |
||
| 56 | |||
| 57 | ### Swap buffers hook |
||
| 58 | - Again capture `gBack_screen` to pick up HUD elements rendered after the 3d scene, convert it to 32 bit, and render it as a full-screen quad. |
||
| 59 | - Generate a palette-manipulation image which is blended over the top of everything as a full-screen quad to handle palette animations. |