1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6
7namespace bs
8{
9 /** @addtogroup Renderer-Internal
10 * @{
11 */
12
13 /** A set of available locations at which the renderer can call RendererExtension's render() method. */
14 enum class RenderLocation
15 {
16 /**
17 * Rendering happens before any scene objects are rendered and before the render target for scene objects is
18 * bound (e.g. GBuffer).
19 */
20 Prepare,
21
22 /**
23 * Rendering happens before any scene objects are rendered. The renderer guarantees the render targets used for
24 * rendering scene objects will be bound (e.g. GBuffer).
25 */
26 PreBasePass,
27
28 /**
29 * Rendering happens after all scene objects are rendered. The renderer guarantees the render targets used for
30 * rendering scene objects will be bound (e.g. GBuffer).
31 */
32 PostBasePass,
33
34 /**
35 * Rendering happens after all scene objects have been rendered and their final information has been written to
36 * the final scene color buffer, without any post-processing. The renderer guarantees the final scene color render
37 * target will be bound.
38 */
39 PostLightPass,
40
41 /**
42 * Rendering happens after all scene objects have been rendered and their final information has been written to
43 * the final scene color buffer, with post-processing. The renderer guarantees the final scene color render target
44 * will be bound.
45 */
46 Overlay
47 };
48
49 /**
50 * Interface that can be implemented in order to provide custom rendering code to the renderer.
51 * See Renderer::addPlugin().
52 *
53 * @note Core thread.
54 */
55 class BS_CORE_EXPORT RendererExtension
56 {
57 public:
58 /**
59 * Creates a brand new instance of a specific implementation of a renderer extension. Queues initialization of the
60 * object on the core thread and registers it with the renderer. Destruction will be queued on the core thread when
61 * the object goes out of scope.
62 *
63 * @note Sim thread.
64 */
65 template<class T>
66 static SPtr<T> create(const Any& data)
67 {
68 T* ext = new (bs_alloc<T>()) T();
69 _initializer(ext, data);
70
71 return SPtr<T>(ext, &RendererExtension::_deleter);
72 }
73
74 /** Called when the renderer extension is first initialized. */
75 virtual void initialize(const Any& data) {}
76
77 /** Called just before the renderer extension is destroyed. */
78 virtual void destroy() {}
79
80 /** Returns true if the render() method should be called for the provided camera. */
81 virtual bool check(const ct::Camera& camera) = 0;
82
83 /**
84 * Called at the point at which rendering should be performed for the provided camera. Relevant render targets
85 * are guaranteed to be already bound to the render API, depending on the RenderLocation. Note that actual structure
86 * of the render targets depends on the active renderer.
87 */
88 virtual void render(const ct::Camera& camera) = 0;
89
90 /**
91 * Determines when will the render() method execute, compared to other plugins using the same RenderLocation.
92 * Higher number means the extension will execute before extensions with lower numbers. Priorities only matter for
93 * extensions that share the same RenderLocation.
94 */
95 UINT32 getPriority() const { return mPriority; }
96
97 /**
98 * Returns a location that determines at which point in rendering should the system call the render() method. See
99 * RenderLocation.
100 */
101 RenderLocation getLocation() const { return mLocation; }
102
103 protected:
104 RendererExtension(RenderLocation location, UINT32 priority)
105 :mLocation(location), mPriority(priority)
106 { }
107
108 virtual ~RendererExtension() = default;
109 private:
110 /** Initializer that triggers when a renderer extension is first constructed. */
111 static void _initializer(RendererExtension* obj, const Any& data);
112
113 /** Deleter that triggers when a renderer extension object goes out of scope. */
114 static void _deleter(RendererExtension* obj);
115
116 RenderLocation mLocation;
117 UINT32 mPriority;
118 };
119
120 /** @} */
121}