Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
/*
Copyright (c) 2016 DIVIDE-Studio
Copyright (c) 2009 Ionut Cava

This file is part of DIVIDE Framework.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software
and associated documentation files (the "Software"), to deal in the Software
without restriction,
including without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software
is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

*/

#ifndef _RENDERING_COMPONENT_H_
#define _RENDERING_COMPONENT_H_

#include "SGNComponent.h"
#include "Core/Math/Headers/MathMatrices.h"
#include "Platform/Video/Headers/GFXDevice.h"
#include "Rendering/Headers/EnvironmentProbe.h"

namespace Divide {

class Sky;
class Material;
class GFXDevice;
class RenderBin;
class WaterPlane;
class ImpostorBox;
class ShaderProgram;
class SceneGraphNode;
class ParticleEmitter;

TYPEDEF_SMART_POINTERS_FOR_CLASS(Material);

namespace Attorney {
    class RenderingCompRenderPass;
    class RenderingCompGFXDevice;
    class RenderingCompRenderBin;
    class RenderingCompSceneNode;
};

struct RenderCbkParams {
    explicit RenderCbkParams(GFXDevice& context,
                             const SceneGraphNode& sgn,
                             const SceneRenderState& sceneRenderState,
                             const RenderTargetID& renderTarget,
                             U32 passIndex)
        : _context(context),
          _sgn(sgn),
          _sceneRenderState(sceneRenderState),
          _renderTarget(renderTarget),
         _passIndex(passIndex)
    {
    }

    GFXDevice& _context;
    const SceneGraphNode& _sgn;
    const SceneRenderState& _sceneRenderState;
    const RenderTargetID& _renderTarget;
    U32 _passIndex;
};

typedef DELEGATE_CBK_PARAM<RenderCbkParams&> RenderCallback;

class RenderingComponent : public SGNComponent {
    friend class Attorney::RenderingCompRenderPass;
    friend class Attorney::RenderingCompGFXDevice;
    friend class Attorney::RenderingCompRenderBin;
    friend class Attorney::RenderingCompSceneNode;

   public:
    bool onRender(RenderStage currentStage) override;
    void update(const U64 deltaTime) override;

    void setActive(const bool state) override;
    void postLoad() override;

    void renderGeometry(const bool state);
    void renderWireframe(const bool state);
    void renderBoundingBox(const bool state);
    void renderBoundingSphere(const bool state);
    void renderSkeleton(const bool state);

    inline bool renderGeometry() const { return _renderGeometry; }
    inline bool renderWireframe() const { return _renderWireframe; }
    inline bool renderBoundingBox() const { return _renderBoundingBox; }
    inline bool renderBoundingSphere() const { return _renderBoundingSphere; }
    inline bool renderSkeleton() const { return _renderSkeleton; }

    inline U32 renderMask() const {
        U32 mask = 0;
        if (renderGeometry()) {
            SetBit(mask, to_const_uint(GenericDrawCommand::RenderOptions::RENDER_GEOMETRY));
        }
        if (renderWireframe()) {
            SetBit(mask, to_const_uint(GenericDrawCommand::RenderOptions::RENDER_WIREFRAME));
        }
        if (renderBoundingBox()) {
            SetBit(mask, to_const_uint(GenericDrawCommand::RenderOptions::RENDER_BOUNDS_AABB));
        }
        if (renderBoundingSphere()) {
            SetBit(mask, to_const_uint(GenericDrawCommand::RenderOptions::RENDER_BOUNDS_SPHERE));
        }
        return mask;
    }

    void castsShadows(const bool state);
    void receivesShadows(const bool state);

    bool castsShadows() const;
    bool receivesShadows() const;
    
    inline U32 drawOrder() const { return _drawOrder; }

    inline U32 commandIndex() const { return _commandIndex; }

    inline U32 commandOffset() const { return _commandOffset; }

    ShaderProgram_ptr getDrawShader(RenderStage renderStage = RenderStage::DISPLAY);

    size_t getDrawStateHash(RenderStage renderStage);

    void getMaterialColourMatrix(mat4<F32>& matOut) const;

    void getRenderingProperties(vec4<F32>& propertiesOut, F32& reflectionIndex, F32& refractionIndex) const;

    inline const Material_ptr& getMaterialInstance() const { return _materialInstance; }

    void registerShaderBuffer(ShaderBufferLocation slot,
                              vec2<U32> bindRange,
                              ShaderBuffer& shaderBuffer);

    void unregisterShaderBuffer(ShaderBufferLocation slot);

    void rebuildMaterial();

    void registerTextureDependency(const TextureData& additionalTexture);
    void removeTextureDependency(const TextureData& additionalTexture);

    inline void setReflectionCallback(RenderCallback cbk) { _reflectionCallback = cbk; }
    inline void setRefractionCallback(RenderCallback cbk) { _refractionCallback = cbk; }

    void drawDebugAxis();

   protected:
    friend class SceneGraphNode;
    explicit RenderingComponent(GFXDevice& context,
                                Material_ptr materialInstance,
                                SceneGraphNode& parentSGN);
    ~RenderingComponent();

   protected:
    bool canDraw(RenderStage renderStage);
    void updateLoDLevel(const Camera& camera, RenderStage renderStage);

    /// Called after the parent node was rendered
    void postRender(const SceneRenderState& sceneRenderState,
                    RenderStage renderStage,
                    RenderSubPassCmds& subPassesInOut);

    void prepareDrawPackage(const SceneRenderState& sceneRenderState, RenderStage renderStage);

    RenderPackage& getDrawPackage(const SceneRenderState& sceneRenderState, RenderStage renderStage);

    RenderPackage& getDrawPackage(RenderStage renderStage);


    inline void drawOrder(U32 index) { _drawOrder = index; }

    inline void commandIndex(U32 index) { _commandIndex = index; }

    inline void commandOffset(U32 offset) { _commandOffset = offset; }

    // This returns false if the node is not reflective, otherwise it generates a new reflection cube map
    // and saves it in the appropriate material slot
    bool updateReflection(U32 reflectionIndex, 
                          const vec3<F32>& camPos,
                          const vec2<F32>& zPlanes,
                          const SceneRenderState& renderState);
    bool updateRefraction(U32 refractionIndex,
                          const vec3<F32>& camPos,
                          const vec2<F32>& zPlanes,
                          const SceneRenderState& renderState);
    bool clearReflection();
    bool clearRefraction();

    void updateEnvProbeList(const EnvironmentProbeList& probes);

   protected:
    GFXDevice& _context;
    Material_ptr _materialInstance;
    std::array<ShaderProgram_ptr, to_const_uint(RenderStage::COUNT)> _customShaders;

    /// LOD level is updated at every visibility check
    U8  _lodLevel;  ///<Relative to camera distance
    U32 _drawOrder;
    U32 _commandIndex;
    U32 _commandOffset;
    bool _preDrawPass;
    bool _castsShadows;
    bool _receiveShadows;
    bool _renderGeometry;
    bool _renderWireframe;
    bool _renderBoundingBox;
    bool _renderBoundingSphere;
    bool _renderSkeleton;
    TextureDataContainer _textureDependencies;
    std::array<RenderPackage, to_const_uint(RenderStage::COUNT)> _renderData;
    
    IMPrimitive* _boundingBoxPrimitive[2];
    IMPrimitive* _boundingSpherePrimitive;
    IMPrimitive* _skeletonPrimitive;

    RenderCallback _reflectionCallback;
    RenderCallback _refractionCallback;

    EnvironmentProbeList _envProbes;
    vectorImpl<Line> _axisLines;
    IMPrimitive* _axisGizmo;
};

namespace Attorney {
class RenderingCompRenderPass {
    private:
        static bool updateReflection(RenderingComponent& renderable,
                                     U32 reflectionIndex,
                                     const vec3<F32>& camPos,
                                     const vec2<F32>& zPlanes,
                                     const SceneRenderState& renderState)
        {
            return renderable.updateReflection(reflectionIndex, camPos, zPlanes, renderState);
        }

        static bool updateRefraction(RenderingComponent& renderable,
                                     U32 refractionIndex,
                                     const vec3<F32>& camPos,
                                     const vec2<F32>& zPlanes,
                                     const SceneRenderState& renderState)
        {
            return renderable.updateRefraction(refractionIndex, camPos, zPlanes, renderState);
        }

        static bool clearReflection(RenderingComponent& renderable)
        {
            return renderable.clearReflection();
        }

        static bool clearRefraction(RenderingComponent& renderable)
        {
            return renderable.clearRefraction();
        }

        static void updateEnvProbeList(RenderingComponent& renderable, const EnvironmentProbeList& probes) {
            renderable.updateEnvProbeList(probes);
        }

        friend class Divide::RenderPass;
};

class RenderingCompSceneNode {
    private:
        static RenderPackage& getDrawPackage(RenderingComponent& renderable, RenderStage renderStage) {
            return renderable.getDrawPackage(renderStage);
        }

        static void setCustomShader(RenderingComponent& renderable,
                                    RenderStage renderStage,
                                    const ShaderProgram_ptr& shaderProgram)  {
            renderable._customShaders[to_uint(renderStage)] = shaderProgram;
        }

        static void setCustomShader(RenderingComponent& renderable,
                                    const ShaderProgram_ptr& shaderProgram) {
            for (U32 i = 0; i < to_const_uint(RenderStage::COUNT); ++i) {
                renderable._customShaders[i] = shaderProgram;
            }
        }

    friend class Divide::Sky;
    friend class Divide::SubMesh;
    friend class Divide::WaterPlane;
    friend class Divide::ParticleEmitter;
};

class RenderingCompGFXDevice {
   private:
    static void prepareDrawPackage(RenderingComponent& renderable,
                                             const SceneRenderState& sceneRenderState,
                                             RenderStage renderStage) {
        renderable.prepareDrawPackage(sceneRenderState, renderStage);
    }

    static RenderPackage& getDrawPackage(RenderingComponent& renderable,
                                         const SceneRenderState& sceneRenderState,
                                         RenderStage renderStage,
                                         U32 cmdOffset,
                                         U32 cmdIndex) {
        renderable.commandIndex(cmdIndex);
        renderable.commandOffset(cmdOffset);
        return renderable.getDrawPackage(sceneRenderState, renderStage);
    }

    friend class Divide::GFXDevice;
};

class RenderingCompRenderBin {
   private:
    static const RenderPackage& getRenderData(RenderingComponent& renderable, RenderStage renderStage) {
        return renderable._renderData[to_uint(renderStage)];
    }

    static void postRender(RenderingComponent& renderable,
                           const SceneRenderState& sceneRenderState,
                           RenderStage renderStage,
                           RenderSubPassCmds& subPassesInOut) {
        renderable.postRender(sceneRenderState, renderStage, subPassesInOut);
    }

    static void drawOrder(RenderingComponent& renderable, U32 index) {
        renderable.drawOrder(index);
    }

    friend class Divide::RenderBin;
};

};  // namespace Attorney
};  // namespace Divide
#endif

Commits for Divide-Framework/trunk/Source Code/Graphs/Components/Headers/RenderingComponent.h

Diff revisions: vs.
Revision Author Commited Message
827 Diff Diff IonutCava picture IonutCava Sun 22 Jan, 2017 21:59:36 +0000

[IonutCava]
- ShaderBuffers now decide heuristically if they get persistently mapped or not (depends on size. Current limit is 512Kb for subData calls.
- Separate visible node command generation into 2 steps: onRender and getDrawPackage. onRender allows the creation of parallel tasks that should finish by the time the second call, getDrawPackage reaches the same node
- Update ParticleEmitter to take into account multiple players and increase parallelism at the cost of memory consumption and complexity.
- Add a default bounding box for Players (add extents to SceneTransform nodes)
- All buffers (ShaderBuffer, d3dConstantBuffer, glUniformBuffer, glBufferImpl, glGenericBuffer, etc) use BufferParams for creation.
— Constructor and create calls have been merged together

804 Diff Diff IonutCava picture IonutCava Thu 01 Dec, 2016 17:20:59 +0000

[IonutCava]
- Singleton elimination update Part I: get it to compile
— The following classes are no longer Singletons: GFXDevice, GL_API, DX_API, SFXWrapper, FmodWrapper, SDLWrapper, ALWrapper, PXDevice, InputInterface, RenderPassManager, SceneManager and ResourceManager;
— Refactor system to a Context / Component based implementation (Pass relevant context to objects: e.g. GFXDevice object to Textures, GUI to GUIElements, etc)
— Make devices and managers components of the kernel
— Allow multiple Resource caches to co-exist. This may prove useful for later when a more fragmented memory model is need (per frame / per scene / global caches / etc)

  • next steps: part II – cleanup/refactor new code, part III – optimise code, part IV – remove remaining Singletons (e.g. Application, ParamHandler, FrameListenerManager, Recast, PostFX and DebugInterface)
800 Diff Diff IonutCava picture IonutCava Fri 25 Nov, 2016 17:04:02 +0000

[IonutCava]
- More profile-guided optimizations
- Added GLSL normal map blending methods from: http://blog.selfshadow.com/sandbox/normals.html
- Added more profile timers

784 Diff Diff IonutCava picture IonutCava Mon 17 Oct, 2016 16:20:49 +0000

[IonutCava]
- Removed the CameraManager and move most of its functionality into static members of the Camera class
- Removed Camera push/pop system in favour of a stateless ptr based system to better fit the RenderPass structure

778 Diff Diff IonutCava picture IonutCava Mon 10 Oct, 2016 15:18:32 +0000

[IonutCava]
- Rendering abstraction cleanup

777 Diff Diff IonutCava picture IonutCava Fri 07 Oct, 2016 16:14:48 +0000

[IonutCava]
- Continue to implement CommandBuffer / RenderPass / RenderSubPass system.
— Rendering artefacts are still present.

776 Diff Diff IonutCava picture IonutCava Thu 06 Oct, 2016 15:57:56 +0000

[IonutCava]
- Improve the CommandBuffer system to include the notion of a RenderPass /RenderSubPass with output render target info stored in them (not used yet)

773 Diff Diff IonutCava picture IonutCava Tue 04 Oct, 2016 15:53:18 +0000

[IonutCava]
- Split GenericDrawCommand gathering system into Init/Update to facilitate future threading support
- Fix drawCount() == 0 case in submitRenderCommand
- Make _cameraPool (more) threadsafe

762 Diff Diff IonutCava picture IonutCava Thu 11 Aug, 2016 16:18:35 +0000

[IonutCava]
- Removed a lot of high level GFX state and merged it back on a lower level:
— depth mask is now a framebuffer specific toggle controlled by the RenderPolicy
— rasterization is now a per-buffer draw switch toggled by a rendering flag in GenericDrawCommand
- Replaced old style GL texture binding code with DSA style glBindTextures and glBindSamplers even for single textures
— completely removed the concept of a active texture unit in the GL code
- Fixed some draw policy settings that were clearing the depth buffer in the PostFX passes
- More build type flag replacement of macros
- Render pass system bug fixing
- Add option to skip occlusion culling for certain nodes

760 IonutCava picture IonutCava Tue 09 Aug, 2016 16:30:12 +0000

[IonutCava]
- Complete rewrite of RenderPass system:
— Allow every rendering pass (reflection, environment, etc) to use the same rendering system: occlusion culling, light culling, etc
— Define render passes by a param based token similar to modern API systems (DX12/Vulkan)
— W.I.P.: Depth rendering slightly wrong; Environment Mapping ,reflection and refraction rendering currently disabled
- Add compile time variables for DEBUG/PROFILE/RELEASE builds to validate all code for every build