Skip to content

Commit 42f2aea

Browse files
committed
feat(ww3d2): add IRenderBackend abstract interface
1 parent b2daaa7 commit 42f2aea

2 files changed

Lines changed: 225 additions & 0 deletions

File tree

Core/Libraries/Source/WWVegas/WW3D2/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ set(WW3D2_SRC
9090
htree.h
9191
#htreemgr.cpp
9292
#htreemgr.h
93+
IRenderBackend.h
9394
intersec.cpp
9495
intersec.h
9596
intersec.inl
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
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

Comments
 (0)