Pioneer
Renderer.h
Go to the documentation of this file.
1 // Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #ifndef _RENDERER_H
5 #define _RENDERER_H
6 
7 #include "Graphics.h"
8 #include "Light.h"
9 #include "Stats.h"
10 #include "Types.h"
11 #include "core/StringHash.h"
12 #include "graphics/BufferCommon.h"
13 #include "libs.h"
14 #include "matrix4x4.h"
15 #include <map>
16 #include <memory>
17 
18 namespace Graphics {
19 
20  /*
21  * Renderer base class. A Renderer draws points, lines, triangles.
22  * It is also used to create render states, materials and vertex/index buffers.
23  */
24 
25  class IndexBuffer;
26  class InstanceBuffer;
27  class Material;
28  class MaterialDescriptor;
29  class MeshObject;
30  class RenderState;
31  class RenderTarget;
32  class Texture;
33  class TextureDescriptor;
34  class UniformBuffer;
35  class VertexArray;
36  class VertexBuffer;
37 
38  struct VertexBufferDesc;
39  struct RenderStateDesc;
40  struct RenderTargetDesc;
41 
42  // Renderer base, functions return false if
43  // failed/unsupported
44  class Renderer {
45  private:
46  typedef std::pair<std::string, std::string> TextureCacheKey;
47  typedef std::map<TextureCacheKey, RefCountedPtr<Texture> *> TextureCacheMap;
48 
49  public:
50  using TextureCache = TextureCacheMap;
51 
52  Renderer(SDL_Window *win, int width, int height);
53  virtual ~Renderer();
54 
55  virtual const char *GetName() const = 0;
56  virtual RendererType GetRendererType() const = 0;
57 
58  virtual void WriteRendererInfo(std::ostream &out) const {}
59 
60  virtual void CheckRenderErrors(const char *func = nullptr, const int line = -1) const {}
61 
62  virtual bool SupportsInstancing() = 0;
63 
64  SDL_Window *GetSDLWindow() const { return m_window; }
65  float GetDisplayAspect() const { return static_cast<float>(m_width) / static_cast<float>(m_height); }
66  int GetWindowWidth() const { return m_width; }
67  int GetWindowHeight() const { return m_height; }
68  virtual int GetMaximumNumberAASamples() const = 0;
69 
70  //get supported minimum for z near and maximum for z far values
71  virtual bool GetNearFarRange(float &near_, float &far_) const = 0;
72 
73  virtual bool BeginFrame() = 0;
74  virtual bool EndFrame() = 0;
75  //traditionally gui happens between endframe and swapbuffers
76  virtual bool SwapBuffers() = 0;
77 
78  //set 0 to render to screen
79  virtual bool SetRenderTarget(RenderTarget *) = 0;
80 
81  // Set the scissor extents. This has no effect if not drawing with a renderstate using scissorTest.
82  // In particular, the scissor state will not affect clearing the screen.
83  virtual bool SetScissor(ViewportExtents scissor) = 0;
84 
85  //clear color and depth buffer
86  virtual bool ClearScreen() = 0;
87  //clear depth buffer
88  virtual bool ClearDepthBuffer() = 0;
89  virtual bool SetClearColor(const Color &c) = 0;
90 
91  virtual bool SetViewport(ViewportExtents vp) = 0;
92  virtual ViewportExtents GetViewport() const = 0;
93 
94  //set the model view matrix
95  virtual bool SetTransform(const matrix4x4f &m) = 0;
96  virtual matrix4x4f GetTransform() const = 0;
97 
98  //set projection matrix
99  virtual bool SetPerspectiveProjection(float fov, float aspect, float near_, float far_) = 0;
100  virtual bool SetOrthographicProjection(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) = 0;
101  virtual bool SetProjection(const matrix4x4f &m) = 0;
102  virtual matrix4x4f GetProjection() const = 0;
103 
104  virtual bool SetWireFrameMode(bool enabled) = 0;
105 
106  virtual bool SetLightIntensity(Uint32 numlights, const float *intensity) = 0;
107  virtual bool SetLights(Uint32 numlights, const Light *l) = 0;
108  const Light &GetLight(const Uint32 idx) const
109  {
110  assert(idx < 4);
111  return m_lights[idx];
112  }
113  virtual Uint32 GetNumLights() const { return 0; }
114  virtual bool SetAmbientColor(const Color &c) = 0;
115  const Color &GetAmbientColor() const { return m_ambient; }
116 
117  //drawing functions
118  // TODO: placeholder API; here until CommandLists are exposed
119  // and all code can safely deal with async drawing
120  virtual bool FlushCommandBuffers() = 0;
121 
122  // All drawing commands are assumed to defer execution of the command
123  // until the next commandlist flush. This is to batch GPU data updates
124  // and ensure state changes are minimal and internally consistent.
125  // If the calling code really needs all pending draw commands to be
126  // executed before making state changes, call FlushCommandBuffers to
127  // manually synchronize.
128 
129  // Upload and draw the contents of this VertexArray. Should be used for highly dynamic geometry that changes per-frame.
130  // The contents of the VertexArray will be cached internally by the renderer and uploaded in bulk.
131  virtual bool DrawBuffer(const VertexArray *v, Material *m) = 0;
132  // Draw a subregion from an existing vertex+index buffer. Should be used for drawing aggregated vertex streams
133  // generated by middleware (e.g. UI buffers) that are updated once or twice during the frame.
134  // vtxOffset, idxOffset specify the starting element, not the starting byte offset in the buffer
135  virtual bool DrawBufferDynamic(VertexBuffer *v, uint32_t vtxOffset, IndexBuffer *i, uint32_t idxOffset, uint32_t numElems, Material *m) = 0;
136  // Draw a single mesh object (vertex+index buffer) using the given material.
137  virtual bool DrawMesh(MeshObject *, Material *) = 0;
138  // Draw multiple instances of a mesh object using the given material.
140 
141  //creates a unique material based on the descriptor. It will not be deleted automatically.
142  virtual Material *CreateMaterial(const std::string &shader, const MaterialDescriptor &descriptor, const RenderStateDesc &stateDescriptor) = 0;
143  // Make a copy of the given material with a possibly new descriptor or render state.
144  virtual Material *CloneMaterial(const Material *mat, const MaterialDescriptor &descriptor, const RenderStateDesc &stateDescriptor) = 0;
145  virtual Texture *CreateTexture(const TextureDescriptor &descriptor) = 0;
146  virtual RenderTarget *CreateRenderTarget(const RenderTargetDesc &) = 0; //returns nullptr if unsupported
149  virtual InstanceBuffer *CreateInstanceBuffer(Uint32 size, BufferUsage) = 0;
150  virtual UniformBuffer *CreateUniformBuffer(Uint32 size, BufferUsage) = 0;
151 
152  // Create a new mesh object that wraps the given vertex and index buffers.
153  virtual MeshObject *CreateMeshObject(VertexBuffer *vertexBuffer, IndexBuffer *indexBuffer = nullptr) = 0;
154 
155  // Create a new mesh object and vertex buffer, and upload data from the given vertex array. Optionally associate the given index buffer.
156  // This is a convenience function to avoid boilerplate needed to set up a vertex buffer and mesh object from a vertex array.
157  // This function is not suitable for transient geometry; prefer DrawBuffer instead.
158  virtual MeshObject *CreateMeshObjectFromArray(const VertexArray *vertexArray, IndexBuffer *indexBuffer = nullptr, BufferUsage usage = BUFFER_USAGE_STATIC) = 0;
159 
160  // Return a reference to the render state desc that is used by the given material.
161  virtual const RenderStateDesc &GetMaterialRenderState(const Material *mat) = 0;
162 
163  Texture *GetCachedTexture(const std::string &type, const std::string &name);
164  void AddCachedTexture(const std::string &type, const std::string &name, Texture *texture);
165  void RemoveCachedTexture(const std::string &type, const std::string &name);
167 
168  const TextureCache &GetTextureCache() { return m_textureCache; }
169 
170  virtual bool ReloadShaders() = 0;
171 
172  // take a ticket representing the current renderer state. when the ticket
173  // is deleted, the renderer state is restored
174  // XXX state must die
175  class StateTicket {
176  public:
178  m_renderer(r)
179  {
180  m_renderer->PushState();
181  m_storedVP = m_renderer->GetViewport();
182  m_storedProj = m_renderer->GetProjection();
183  m_storedMV = m_renderer->GetTransform();
184  }
185 
186  virtual ~StateTicket()
187  {
188  m_renderer->PopState();
189  m_renderer->SetViewport(m_storedVP);
190  m_renderer->SetTransform(m_storedMV);
191  m_renderer->SetProjection(m_storedProj);
192  }
193 
194  StateTicket(const StateTicket &) = delete;
195  StateTicket &operator=(const StateTicket &) = delete;
196 
197  private:
198  Renderer *m_renderer;
199  matrix4x4f m_storedProj;
200  matrix4x4f m_storedMV;
201  ViewportExtents m_storedVP;
202  };
203 
204  // Temporarily save the current transform matrix to do non-destructive drawing.
205  class MatrixTicket {
206  public:
208  MatrixTicket(r, r->GetTransform())
209  {}
210 
211  MatrixTicket(Renderer *r, const matrix4x4f &newMat) :
212  m_renderer(r)
213  {
214  m_storedMat = m_renderer->GetTransform();
215  m_renderer->SetTransform(newMat);
216  }
217 
218  virtual ~MatrixTicket()
219  {
220  m_renderer->SetTransform(m_storedMat);
221  }
222 
223  MatrixTicket(const MatrixTicket &) = delete;
224  MatrixTicket &operator=(const MatrixTicket &) = delete;
225 
226  private:
227  Renderer *m_renderer;
228  matrix4x4f m_storedMat;
229  };
230 
231  virtual bool Screendump(ScreendumpState &sd) { return false; }
232  virtual bool FrameGrab(ScreendumpState &sd) { return false; }
233 
234  Stats &GetStats() { return m_stats; }
235 
236  // Returns a hashed name for referring to material constant slots and other constant-size string names
237  static constexpr size_t GetName(std::string_view s) { return hash_64_fnv1a(s.data(), s.size()); }
238 
239  protected:
240  int m_width;
241  int m_height;
245  SDL_Window *m_window;
246 
247  virtual void PushState() = 0;
248  virtual void PopState() = 0;
249 
250  private:
251  TextureCacheMap m_textureCache;
252  };
253 
254 } // namespace Graphics
255 
256 #endif
constexpr uint64_t hash_64_fnv1a(const char *const data, size_t len)
Definition: FNV1a.h:29
Definition: VertexBuffer.h:102
Definition: VertexBuffer.h:127
Definition: Light.h:14
Definition: Material.h:60
Definition: Material.h:148
Definition: VertexBuffer.h:156
Definition: RenderTarget.h:38
Definition: Renderer.h:205
virtual ~MatrixTicket()
Definition: Renderer.h:218
MatrixTicket(const MatrixTicket &)=delete
MatrixTicket & operator=(const MatrixTicket &)=delete
MatrixTicket(Renderer *r)
Definition: Renderer.h:207
MatrixTicket(Renderer *r, const matrix4x4f &newMat)
Definition: Renderer.h:211
Definition: Renderer.h:175
StateTicket & operator=(const StateTicket &)=delete
StateTicket(Renderer *r)
Definition: Renderer.h:177
StateTicket(const StateTicket &)=delete
virtual ~StateTicket()
Definition: Renderer.h:186
Definition: Renderer.h:44
Renderer(SDL_Window *win, int width, int height)
Definition: Renderer.cpp:10
virtual int GetMaximumNumberAASamples() const =0
virtual Material * CreateMaterial(const std::string &shader, const MaterialDescriptor &descriptor, const RenderStateDesc &stateDescriptor)=0
virtual bool DrawBufferDynamic(VertexBuffer *v, uint32_t vtxOffset, IndexBuffer *i, uint32_t idxOffset, uint32_t numElems, Material *m)=0
virtual bool SetClearColor(const Color &c)=0
virtual bool SetProjection(const matrix4x4f &m)=0
Light m_lights[4]
Definition: Renderer.h:243
virtual bool SetOrthographicProjection(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax)=0
virtual bool ReloadShaders()=0
virtual bool SetWireFrameMode(bool enabled)=0
virtual Material * CloneMaterial(const Material *mat, const MaterialDescriptor &descriptor, const RenderStateDesc &stateDescriptor)=0
virtual bool SetPerspectiveProjection(float fov, float aspect, float near_, float far_)=0
virtual IndexBuffer * CreateIndexBuffer(Uint32 size, BufferUsage, IndexBufferSize=INDEX_BUFFER_32BIT)=0
virtual const char * GetName() const =0
virtual void PushState()=0
virtual bool SetLightIntensity(Uint32 numlights, const float *intensity)=0
virtual bool SupportsInstancing()=0
virtual ViewportExtents GetViewport() const =0
virtual bool FrameGrab(ScreendumpState &sd)
Definition: Renderer.h:232
virtual bool SetLights(Uint32 numlights, const Light *l)=0
virtual bool SetScissor(ViewportExtents scissor)=0
const Light & GetLight(const Uint32 idx) const
Definition: Renderer.h:108
float GetDisplayAspect() const
Definition: Renderer.h:65
virtual InstanceBuffer * CreateInstanceBuffer(Uint32 size, BufferUsage)=0
Stats m_stats
Definition: Renderer.h:244
virtual UniformBuffer * CreateUniformBuffer(Uint32 size, BufferUsage)=0
virtual bool FlushCommandBuffers()=0
virtual RenderTarget * CreateRenderTarget(const RenderTargetDesc &)=0
const Color & GetAmbientColor() const
Definition: Renderer.h:115
static constexpr size_t GetName(std::string_view s)
Definition: Renderer.h:237
SDL_Window * GetSDLWindow() const
Definition: Renderer.h:64
virtual const RenderStateDesc & GetMaterialRenderState(const Material *mat)=0
Texture * GetCachedTexture(const std::string &type, const std::string &name)
Definition: Renderer.cpp:24
virtual bool SwapBuffers()=0
int GetWindowHeight() const
Definition: Renderer.h:67
void AddCachedTexture(const std::string &type, const std::string &name, Texture *texture)
Definition: Renderer.cpp:31
virtual bool Screendump(ScreendumpState &sd)
Definition: Renderer.h:231
virtual bool SetTransform(const matrix4x4f &m)=0
int m_width
Definition: Renderer.h:240
virtual bool DrawMesh(MeshObject *, Material *)=0
void RemoveCachedTexture(const std::string &type, const std::string &name)
Definition: Renderer.cpp:37
void RemoveAllCachedTextures()
Definition: Renderer.cpp:45
virtual void PopState()=0
Color m_ambient
Definition: Renderer.h:242
virtual Texture * CreateTexture(const TextureDescriptor &descriptor)=0
SDL_Window * m_window
Definition: Renderer.h:245
virtual bool BeginFrame()=0
virtual bool DrawMeshInstanced(MeshObject *, Material *, InstanceBuffer *)=0
virtual bool DrawBuffer(const VertexArray *v, Material *m)=0
virtual Uint32 GetNumLights() const
Definition: Renderer.h:113
TextureCacheMap TextureCache
Definition: Renderer.h:50
virtual void CheckRenderErrors(const char *func=nullptr, const int line=-1) const
Definition: Renderer.h:60
virtual MeshObject * CreateMeshObjectFromArray(const VertexArray *vertexArray, IndexBuffer *indexBuffer=nullptr, BufferUsage usage=BUFFER_USAGE_STATIC)=0
virtual void WriteRendererInfo(std::ostream &out) const
Definition: Renderer.h:58
virtual bool ClearDepthBuffer()=0
virtual MeshObject * CreateMeshObject(VertexBuffer *vertexBuffer, IndexBuffer *indexBuffer=nullptr)=0
virtual VertexBuffer * CreateVertexBuffer(const VertexBufferDesc &)=0
const TextureCache & GetTextureCache()
Definition: Renderer.h:168
virtual matrix4x4f GetTransform() const =0
virtual matrix4x4f GetProjection() const =0
virtual RendererType GetRendererType() const =0
virtual bool SetViewport(ViewportExtents vp)=0
int GetWindowWidth() const
Definition: Renderer.h:66
virtual bool SetAmbientColor(const Color &c)=0
virtual bool ClearScreen()=0
virtual ~Renderer()
Definition: Renderer.cpp:18
virtual bool EndFrame()=0
Stats & GetStats()
Definition: Renderer.h:234
virtual bool SetRenderTarget(RenderTarget *)=0
virtual bool GetNearFarRange(float &near_, float &far_) const =0
int m_height
Definition: Renderer.h:241
Definition: Stats.h:19
Definition: Texture.h:54
Definition: Texture.h:106
Definition: UniformBuffer.h:11
Definition: VertexArray.h:19
Definition: VertexBuffer.h:65
Definition: Background.h:14
RendererType
Definition: Graphics.h:18
IndexBufferSize
Definition: Types.h:76
@ INDEX_BUFFER_32BIT
Definition: Types.h:78
BufferUsage
Definition: Types.h:65
@ BUFFER_USAGE_STATIC
Definition: Types.h:66
Definition: Color.h:66
Definition: RenderState.h:10
Definition: RenderTarget.h:20
Definition: Graphics.h:134
Definition: VertexBuffer.h:43
Definition: Graphics.h:59