Line data Source code
1 : /* Copyright (C) 2023 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef INCLUDED_PATCHRDATA
19 : #define INCLUDED_PATCHRDATA
20 :
21 : #include "graphics/Patch.h"
22 : #include "graphics/RenderableObject.h"
23 : #include "maths/Vector2D.h"
24 : #include "maths/Vector3D.h"
25 : #include "renderer/backend/IDeviceCommandContext.h"
26 : #include "renderer/backend/IShaderProgram.h"
27 : #include "renderer/VertexBufferManager.h"
28 :
29 : #include <vector>
30 :
31 : class CPatch;
32 : class CShaderDefines;
33 : class CSimulation2;
34 : class CTerrainTextureEntry;
35 : class CTextRenderer;
36 : class ShadowMap;
37 :
38 : //////////////////////////////////////////////////////////////////////////////////////////////////
39 : // CPatchRData: class encapsulating logic for rendering terrain patches; holds per
40 : // patch data, plus some supporting static functions for batching, etc
41 0 : class CPatchRData : public CRenderData
42 : {
43 : public:
44 : CPatchRData(CPatch* patch, CSimulation2* simulation);
45 : ~CPatchRData();
46 :
47 : static Renderer::Backend::IVertexInputLayout* GetBaseVertexInputLayout();
48 : static Renderer::Backend::IVertexInputLayout* GetBlendVertexInputLayout();
49 : static Renderer::Backend::IVertexInputLayout* GetStreamVertexInputLayout(
50 : const bool bindPositionAsTexCoord);
51 : static Renderer::Backend::IVertexInputLayout* GetSideVertexInputLayout();
52 :
53 : static Renderer::Backend::IVertexInputLayout* GetWaterSurfaceVertexInputLayout(
54 : const bool bindWaterData);
55 : static Renderer::Backend::IVertexInputLayout* GetWaterShoreVertexInputLayout();
56 :
57 : void Update(CSimulation2* simulation);
58 : void RenderOutline();
59 : void RenderPriorities(CTextRenderer& textRenderer);
60 :
61 : void RenderWaterSurface(
62 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
63 : Renderer::Backend::IVertexInputLayout* vertexInputLayout);
64 : void RenderWaterShore(
65 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
66 : Renderer::Backend::IVertexInputLayout* vertexInputLayout);
67 :
68 : CPatch* GetPatch() { return m_Patch; }
69 :
70 0 : const CBoundingBoxAligned& GetWaterBounds() const { return m_WaterBounds; }
71 :
72 : static void RenderBases(
73 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
74 : Renderer::Backend::IVertexInputLayout* vertexInputLayout,
75 : const std::vector<CPatchRData*>& patches, const CShaderDefines& context, ShadowMap* shadow);
76 : static void RenderBlends(
77 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
78 : Renderer::Backend::IVertexInputLayout* vertexInputLayout,
79 : const std::vector<CPatchRData*>& patches, const CShaderDefines& context, ShadowMap* shadow);
80 : static void RenderStreams(
81 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
82 : Renderer::Backend::IVertexInputLayout* vertexInputLayout,
83 : const std::vector<CPatchRData*>& patches);
84 : static void RenderSides(
85 : Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
86 : Renderer::Backend::IVertexInputLayout* vertexInputLayout,
87 : const std::vector<CPatchRData*>& patches);
88 :
89 : static void PrepareShader(ShadowMap* shadow);
90 :
91 : private:
92 : friend struct SBlendStackItem;
93 :
94 : struct SSplat
95 : {
96 0 : SSplat() : m_Texture(0), m_IndexCount(0) {}
97 :
98 : // texture to apply during splat
99 : CTerrainTextureEntry* m_Texture;
100 : // offset into the index array for this patch where splat starts
101 : size_t m_IndexStart;
102 : // number of indices used by splat
103 : size_t m_IndexCount;
104 : };
105 :
106 0 : struct SBaseVertex
107 : {
108 : // vertex position
109 : CVector3D m_Position;
110 : CVector3D m_Normal;
111 : // pad to a power of two
112 : u8 m_Padding[8];
113 : };
114 : cassert(sizeof(SBaseVertex) == 32);
115 :
116 0 : struct SSideVertex
117 : {
118 : // vertex position
119 : CVector3D m_Position;
120 : // pad to a power of two
121 : u8 m_Padding[4];
122 : };
123 : cassert(sizeof(SSideVertex) == 16);
124 :
125 0 : struct SBlendVertex
126 : {
127 : // vertex position
128 : CVector3D m_Position;
129 : // vertex uvs for alpha texture
130 : float m_AlphaUVs[2];
131 : CVector3D m_Normal;
132 : };
133 : cassert(sizeof(SBlendVertex) == 32);
134 :
135 : // Mixed Fancy/Simple water vertex description data structure
136 0 : struct SWaterVertex
137 : {
138 : // vertex position
139 : CVector3D m_Position;
140 : CVector2D m_WaterData;
141 : // pad to a power of two
142 : u8 m_Padding[12];
143 : };
144 : cassert(sizeof(SWaterVertex) == 32);
145 :
146 : // build this renderdata object
147 : void Build();
148 :
149 : void AddBlend(std::vector<SBlendVertex>& blendVertices, std::vector<u16>& blendIndices,
150 : u16 i, u16 j, u8 shape, CTerrainTextureEntry* texture);
151 :
152 : void BuildBlends();
153 : void BuildIndices();
154 : void BuildVertices();
155 : void BuildSides();
156 :
157 : void BuildSide(std::vector<SSideVertex>& vertices, CPatchSideFlags side);
158 :
159 : // owner patch
160 : CPatch* m_Patch;
161 :
162 : // vertex buffer handle for side vertices
163 : CVertexBufferManager::Handle m_VBSides;
164 :
165 : // vertex buffer handle for base vertices
166 : CVertexBufferManager::Handle m_VBBase;
167 :
168 : // vertex buffer handle for base vertex indices
169 : CVertexBufferManager::Handle m_VBBaseIndices;
170 :
171 : // vertex buffer handle for blend vertices
172 : CVertexBufferManager::Handle m_VBBlends;
173 :
174 : // vertex buffer handle for blend vertex indices
175 : CVertexBufferManager::Handle m_VBBlendIndices;
176 :
177 : // list of base splats to apply to this patch
178 : std::vector<SSplat> m_Splats;
179 :
180 : // splats used in blend pass
181 : std::vector<SSplat> m_BlendSplats;
182 :
183 : // boundary of water in this patch
184 : CBoundingBoxAligned m_WaterBounds;
185 :
186 : // Water vertex buffer
187 : CVertexBufferManager::Handle m_VBWater;
188 : CVertexBufferManager::Handle m_VBWaterShore;
189 :
190 : // Water indices buffer
191 : CVertexBufferManager::Handle m_VBWaterIndices;
192 : CVertexBufferManager::Handle m_VBWaterIndicesShore;
193 :
194 : CSimulation2* m_Simulation;
195 :
196 : // Build water vertices and indices (vertex buffer and data vector)
197 : void BuildWater();
198 :
199 : // parameter allowing a varying number of triangles per patch for LOD
200 : // MUST be an exact divisor of PATCH_SIZE
201 : // compiled const for the moment until/if dynamic water LOD is offered
202 : // savings would be mostly beneficial for GPU or simple water
203 : static const ssize_t water_cell_size = 1;
204 : };
205 :
206 : #endif // INCLUDED_PATCHRDATA
|