|
| 1 | +/* |
| 2 | +** Command & Conquer Generals Zero Hour(tm) |
| 3 | +** Copyright 2025 Electronic Arts Inc. |
| 4 | +** |
| 5 | +** This program is free software: you can redistribute it and/or modify |
| 6 | +** it under the terms of the GNU General Public License as published by |
| 7 | +** the Free Software Foundation, either version 3 of the License, or |
| 8 | +** (at your option) any later version. |
| 9 | +** |
| 10 | +** This program is distributed in the hope that it will be useful, |
| 11 | +** but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | +** GNU General Public License for more details. |
| 14 | +** |
| 15 | +** You should have received a copy of the GNU General Public License |
| 16 | +** along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 | +*/ |
| 18 | + |
| 19 | +// TheSuperHackers @refactor bobtista 10/04/2026 Introduce IRenderBackend |
| 20 | +// abstract interface so WW3D2 rendering can be re-targeted to modern backends |
| 21 | +// (bgfx, Diligent, etc.) while the existing DX8 path stays functional as the |
| 22 | +// reference implementation. See Core/Libraries/Source/WWVegas/WW3D2/RENDER_BACKEND.md. |
| 23 | + |
| 24 | +#pragma once |
| 25 | + |
| 26 | +#include "ww3dformat.h" |
| 27 | + |
| 28 | +// ----------------------------------------------------------------------------- |
| 29 | +// Forward declarations |
| 30 | +// ----------------------------------------------------------------------------- |
| 31 | +// |
| 32 | +// Kept lightweight deliberately. IRenderBackend.h must be includable without |
| 33 | +// dragging in the full WW3D2 header graph, so callers only pay for the types |
| 34 | +// they actually use. |
| 35 | +// |
| 36 | +// All W3D classes passed through this interface are referenced by pointer or |
| 37 | +// reference; none of them need a full definition in this header. |
| 38 | + |
| 39 | +class ShaderClass; |
| 40 | +class VertexMaterialClass; |
| 41 | +class TextureBaseClass; |
| 42 | +class TextureClass; |
| 43 | +class ZTextureClass; |
| 44 | +class SurfaceClass; |
| 45 | +class VertexBufferClass; |
| 46 | +class IndexBufferClass; |
| 47 | +class DynamicVBAccessClass; |
| 48 | +class DynamicIBAccessClass; |
| 49 | +class LightClass; |
| 50 | +class LightEnvironmentClass; |
| 51 | +class Matrix4x4; |
| 52 | +class Matrix3D; |
| 53 | +class Vector3; |
| 54 | + |
| 55 | +// ----------------------------------------------------------------------------- |
| 56 | +// POD types owned by the interface |
| 57 | +// ----------------------------------------------------------------------------- |
| 58 | + |
| 59 | +enum TransformKind |
| 60 | +{ |
| 61 | + // Values chosen so they can be mapped directly to D3DTS_* inside the |
| 62 | + // DX8Backend without a branch. A modern backend ignores these indices |
| 63 | + // and uses whichever matrix storage is convenient for it. |
| 64 | + RB_TRANSFORM_VIEW = 2, // D3DTS_VIEW |
| 65 | + RB_TRANSFORM_PROJECTION = 3, // D3DTS_PROJECTION |
| 66 | + RB_TRANSFORM_WORLD = 256 // D3DTS_WORLD |
| 67 | +}; |
| 68 | + |
| 69 | +struct RenderBackendViewport |
| 70 | +{ |
| 71 | + unsigned int x; |
| 72 | + unsigned int y; |
| 73 | + unsigned int width; |
| 74 | + unsigned int height; |
| 75 | + float min_z; |
| 76 | + float max_z; |
| 77 | +}; |
| 78 | + |
| 79 | +// ----------------------------------------------------------------------------- |
| 80 | +// IRenderBackend — abstract W3D-facing rendering interface |
| 81 | +// ----------------------------------------------------------------------------- |
| 82 | +// |
| 83 | +// This interface exposes the *high-level* subset of DX8Wrapper's public API: |
| 84 | +// the calls that take and return W3D types (ShaderClass, TextureBaseClass, |
| 85 | +// Matrix4x4, etc.) and are backend-neutral by construction. The low-level |
| 86 | +// D3D8-specific entry points on DX8Wrapper (Set_DX8_Render_State, |
| 87 | +// _Create_DX8_Texture, _Get_D3D_Device8, etc.) are NOT exposed here and |
| 88 | +// remain reachable only through DX8Wrapper's static methods. Code that |
| 89 | +// needs them is DX8-only and must be migrated during later phases. |
| 90 | +// |
| 91 | +// **Method names intentionally match the existing DX8Wrapper names** so |
| 92 | +// that migrating callers is a mechanical `DX8Wrapper::X(...)` → |
| 93 | +// `g_renderBackend->X(...)` rewrite with minimal diff noise. |
| 94 | +// |
| 95 | +// **This header is included from VC6-compiled translation units** (the |
| 96 | +// DX8 reference path and the tools). Keep it C++98-compatible: |
| 97 | +// - No <memory>, no <string>, no <vector> or other STL in signatures |
| 98 | +// - No `override`, `= default`, `= delete`, `auto`, `constexpr` |
| 99 | +// - `nullptr` is OK (the project has a VC6 shim) |
| 100 | +// - POD structs for parameter bundles |
| 101 | +// - Forward-declare W3D types rather than including their headers |
| 102 | +// |
| 103 | +// Implementations (DX8Backend.cpp, future BgfxBackend.cpp, etc.) can use |
| 104 | +// whatever C++ features the project's main build allows. |
| 105 | + |
| 106 | +class IRenderBackend |
| 107 | +{ |
| 108 | +public: |
| 109 | + virtual ~IRenderBackend() {} |
| 110 | + |
| 111 | + // ------------------------------------------------------------------------- |
| 112 | + // Device state queries |
| 113 | + // ------------------------------------------------------------------------- |
| 114 | + |
| 115 | + virtual bool Is_Device_Lost() const = 0; |
| 116 | + virtual bool Has_Stencil() = 0; |
| 117 | + virtual WW3DFormat Get_Back_Buffer_Format() = 0; |
| 118 | + virtual SurfaceClass * Get_Back_Buffer(unsigned int num) = 0; |
| 119 | + virtual void Set_Gamma(float gamma, float bright, float contrast, bool calibrate, bool uselimit) = 0; |
| 120 | + |
| 121 | + // ------------------------------------------------------------------------- |
| 122 | + // Frame lifecycle |
| 123 | + // ------------------------------------------------------------------------- |
| 124 | + |
| 125 | + virtual void Begin_Scene() = 0; |
| 126 | + virtual void End_Scene(bool flip_frame) = 0; |
| 127 | + virtual void Flip_To_Primary() = 0; |
| 128 | + virtual void Clear(bool clear_color, bool clear_z_stencil, |
| 129 | + const Vector3 & color, |
| 130 | + float dest_alpha, float z, unsigned int stencil) = 0; |
| 131 | + virtual void Set_Viewport(const RenderBackendViewport & viewport) = 0; |
| 132 | + |
| 133 | + // ------------------------------------------------------------------------- |
| 134 | + // Vertex / index buffers |
| 135 | + // ------------------------------------------------------------------------- |
| 136 | + |
| 137 | + virtual void Set_Vertex_Buffer(const VertexBufferClass * vb, unsigned int stream) = 0; |
| 138 | + virtual void Set_Vertex_Buffer(const DynamicVBAccessClass & vba) = 0; |
| 139 | + virtual void Set_Index_Buffer(const IndexBufferClass * ib, unsigned short index_base_offset) = 0; |
| 140 | + virtual void Set_Index_Buffer(const DynamicIBAccessClass & iba, unsigned short index_base_offset) = 0; |
| 141 | + virtual void Set_Index_Buffer_Index_Offset(unsigned int offset) = 0; |
| 142 | + |
| 143 | + // ------------------------------------------------------------------------- |
| 144 | + // State: shaders, materials, textures |
| 145 | + // ------------------------------------------------------------------------- |
| 146 | + |
| 147 | + virtual void Set_Shader(const ShaderClass & shader) = 0; |
| 148 | + virtual void Get_Shader(ShaderClass & shader) = 0; |
| 149 | + virtual void Set_Material(const VertexMaterialClass * material) = 0; |
| 150 | + virtual void Set_Texture(unsigned int stage, TextureBaseClass * texture) = 0; |
| 151 | + |
| 152 | + virtual void Apply_Render_State_Changes() = 0; |
| 153 | + virtual void Apply_Default_State() = 0; |
| 154 | + virtual void Invalidate_Cached_Render_States() = 0; |
| 155 | + |
| 156 | + // ------------------------------------------------------------------------- |
| 157 | + // Transforms |
| 158 | + // ------------------------------------------------------------------------- |
| 159 | + |
| 160 | + virtual void Set_Transform(TransformKind transform, const Matrix4x4 & m) = 0; |
| 161 | + virtual void Set_Transform(TransformKind transform, const Matrix3D & m) = 0; |
| 162 | + virtual void Get_Transform(TransformKind transform, Matrix4x4 & m) = 0; |
| 163 | + virtual void Set_World_Identity() = 0; |
| 164 | + virtual void Set_View_Identity() = 0; |
| 165 | + virtual bool Is_World_Identity() = 0; |
| 166 | + virtual bool Is_View_Identity() = 0; |
| 167 | + virtual void Set_Projection_Transform_With_Z_Bias(const Matrix4x4 & matrix, |
| 168 | + float znear, float zfar) = 0; |
| 169 | + |
| 170 | + // ------------------------------------------------------------------------- |
| 171 | + // Lighting and fog |
| 172 | + // ------------------------------------------------------------------------- |
| 173 | + |
| 174 | + virtual void Set_Light(unsigned int index, const LightClass & light) = 0; |
| 175 | + virtual void Set_Ambient(const Vector3 & color) = 0; |
| 176 | + virtual const Vector3 & Get_Ambient() const = 0; |
| 177 | + virtual void Set_Fog(bool enable, const Vector3 & color, float start, float end) = 0; |
| 178 | + virtual bool Get_Fog_Enable() const = 0; |
| 179 | + virtual void Set_Light_Environment(LightEnvironmentClass * light_env) = 0; |
| 180 | + virtual LightEnvironmentClass * Get_Light_Environment() const = 0; |
| 181 | + |
| 182 | + // ------------------------------------------------------------------------- |
| 183 | + // Draw calls |
| 184 | + // ------------------------------------------------------------------------- |
| 185 | + |
| 186 | + virtual void Draw_Triangles(unsigned short start_index, |
| 187 | + unsigned short polygon_count, |
| 188 | + unsigned short min_vertex_index, |
| 189 | + unsigned short vertex_count) = 0; |
| 190 | + |
| 191 | + virtual void Draw_Triangles(unsigned int buffer_type, |
| 192 | + unsigned short start_index, |
| 193 | + unsigned short polygon_count, |
| 194 | + unsigned short min_vertex_index, |
| 195 | + unsigned short vertex_count) = 0; |
| 196 | + |
| 197 | + virtual void Draw_Strip(unsigned short start_index, |
| 198 | + unsigned short index_count, |
| 199 | + unsigned short min_vertex_index, |
| 200 | + unsigned short vertex_count) = 0; |
| 201 | + |
| 202 | + // ------------------------------------------------------------------------- |
| 203 | + // Programmable pipeline (GPU vertex / pixel shaders) |
| 204 | + // ------------------------------------------------------------------------- |
| 205 | + // |
| 206 | + // These correspond to DX8's programmable shader slots. Modern backends |
| 207 | + // will re-interpret the handles internally; the interface treats the |
| 208 | + // shader id as an opaque unsigned long. |
| 209 | + |
| 210 | + virtual void Set_Vertex_Shader(unsigned long vertex_shader) = 0; |
| 211 | + virtual void Set_Pixel_Shader(unsigned long pixel_shader) = 0; |
| 212 | + virtual void Set_Vertex_Shader_Constant(int reg, const void * data, int count) = 0; |
| 213 | + virtual void Set_Pixel_Shader_Constant(int reg, const void * data, int count) = 0; |
| 214 | + |
| 215 | + // ------------------------------------------------------------------------- |
| 216 | + // Render targets |
| 217 | + // ------------------------------------------------------------------------- |
| 218 | + |
| 219 | + virtual TextureClass * Create_Render_Target(int width, int height, WW3DFormat format) = 0; |
| 220 | + virtual void Set_Render_Target_With_Z(TextureClass * texture, ZTextureClass * ztexture) = 0; |
| 221 | + virtual bool Is_Render_To_Texture() = 0; |
| 222 | + virtual void Set_Shadow_Map(int idx, ZTextureClass * ztex) = 0; |
| 223 | + virtual ZTextureClass * Get_Shadow_Map(int idx) = 0; |
| 224 | +}; |
0 commit comments