The small3d framework
Renderer.hpp
Go to the documentation of this file.
1 
10 #pragma once
11 
12 #if defined(__ANDROID__)
13 #include <android/asset_manager.h>
14 #elif defined(SMALL3D_IOS)
15  // todo: Add ios includes if necessary
16 #else
17 #define GLFW_INCLUDE_VULKAN
18 #include <GLFW/glfw3.h>
19 #endif
20 
21 #include "Logger.hpp"
22 #include "Image.hpp"
23 #include "Model.hpp"
24 #include "SceneObject.hpp"
25 
26 #include <unordered_map>
27 #include <vector>
28 
29 #define GLM_FORCE_RADIANS
30 #include <glm/glm.hpp>
31 #include <ft2build.h>
32 #include FT_FREETYPE_H
33 
34 namespace small3d
35 {
40  struct VulkanImage {
41  VkImageView imageView = VK_NULL_HANDLE;
42  VkImage image = VK_NULL_HANDLE;
43  VkDeviceMemory imageMemory = VK_NULL_HANDLE;
44  VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
45  VkDescriptorSet orthoDescriptorSet = VK_NULL_HANDLE;
46  };
47 
52  struct UboOrientation {
53  glm::mat4x4 xRotationMatrix;
54  glm::mat4x4 yRotationMatrix;
55  glm::mat4x4 zRotationMatrix;
56  glm::vec3 offset;
57  float padding[13];
58  };
59 
64  struct UboColour {
65  glm::vec4 colour;
66  float padding[4];
67  };
68 
73  class Renderer
74  {
75 
76  private:
77 
78 #if !defined(__ANDROID__) && !defined(SMALL3D_IOS)
79  GLFWwindow* window;
80 #endif
81 
82  std::string windowTitle = "";
83 
84  static int realScreenWidth, realScreenHeight;
85 
86  std::string shadersPath = "";
87 
88  uint32_t maxObjectsPerPass;
89 
90  uint32_t perspectivePipelineIndex = 100;
91  uint32_t orthographicPipelineIndex = 100;
92 
93  uint32_t currentSwapchainImageIndex = 0;
94 
95  std::vector<VkBuffer> renderOrientationBuffersDynamic;
96  std::vector<VkDeviceMemory> renderOrientationBuffersDynamicMemory;
97 
98  std::vector<VkBuffer> cameraOrientationBuffers;
99  std::vector<VkDeviceMemory> cameraOrientationBufferMemories;
100 
101  std::vector<VkBuffer> worldDetailsBuffers;
102  std::vector<VkDeviceMemory> worldDetailsBufferMemories;
103 
104  std::vector<VkBuffer> lightIntensityBuffers;
105  std::vector<VkDeviceMemory> lightIntensityBufferMemories;
106 
107  std::vector<VkBuffer> colourBuffersDynamic;
108  std::vector<VkDeviceMemory> colourBuffersDynamicMemory;
109 
110  VkSampler textureSampler;
111 
112  std::vector<VkImageView> boundTextureViews;
113 
114  std::allocator<char> alloc;
115 
116  float frustumScale = 0.0f;
117  float zNear = 0.0f;
118  float zFar = 0.0f;
119  float zOffsetFromCamera = 0.0f;
120 
121  std::unordered_map<std::string, VulkanImage> textures;
122 
123  FT_Library library = 0;
124  std::vector<float> textMemory;
125  std::unordered_map<std::string, FT_Face> fontFaces;
126 
127 #ifdef __ANDROID__
128  std::vector<AAsset*> fontAssets;
129 #endif
130 
131  static std::vector<Model> nextModelsToDraw;
132 
133  static VkVertexInputBindingDescription bd[3];
134  static VkVertexInputAttributeDescription ad[3];
135 
136  static VkDescriptorSetLayout descriptorSetLayout;
137  static VkDescriptorSet descriptorSet;
138  static VkDescriptorSetLayout textureDescriptorSetLayout;
139  static VkDescriptorSetLayout perspectiveLayouts[2];
140 
141  static VkVertexInputBindingDescription orthobd[2];
142  static VkVertexInputAttributeDescription orthoad[2];
143 
144  static VkDescriptorSetLayout orthoDescriptorSetLayout;
145  static VkDescriptorSet orthoDescriptorSet;
146  static VkDescriptorSetLayout textureOrthoDescriptorSetLayout;
147  static VkDescriptorSetLayout orthographicLayouts[2];
148 
149  size_t dynamicOrientationAlignment = 0;
150  UboOrientation* uboOrientationDynamic = nullptr;
151  uint32_t orientationMemIndex = 0;
152  size_t uboOrientationDynamicSize = 0;
153 
154  size_t dynamicColourAlignment = 0;
155  UboColour* uboColourDynamic = nullptr;
156  uint32_t colourMemIndex = 0;
157  size_t uboColourDynamicSize = 0;
158 
159 
160 #if !defined(__ANDROID__) && !defined(SMALL3D_IOS)
161  static void framebufferSizeCallback(GLFWwindow* window, int width,
162  int height);
163 #endif
164 
165  static int setInputStateCallback(VkPipelineVertexInputStateCreateInfo*
166  inputStateCreateInfo);
167  static int setPipelineLayoutCallback(VkPipelineLayoutCreateInfo*
168  pipelineLayoutCreateInfo);
169 
170  int bindBuffers(VkCommandBuffer commandBuffer, const Model& model);
171  void recordDrawCommand(VkCommandBuffer commandBuffer,
172  VkPipelineLayout pipelineLayout, const Model& model,
173  uint32_t swapchainImageIndex);
174 
175  static int setOrthoInputStateCallback(VkPipelineVertexInputStateCreateInfo*
176  inputStateCreateInfo);
177  static int setOrthoPipelineLayoutCallback(VkPipelineLayoutCreateInfo*
178  pipelineLayoutCreateInfo);
179 
180  int bindOrthoBuffers(VkCommandBuffer commandBuffer,
181  const Model& model);
182  void recordOrthoDrawCommand(VkCommandBuffer commandBuffer,
183  VkPipelineLayout pipelineLayout, const Model& model,
184  uint32_t swapchainImageIndex);
185 
186  void initVulkan();
187 
188  VkDescriptorPool descriptorPool;
189  bool descriptorPoolCreated = false;
190  void createDescriptorPool();
191 
192  VkDescriptorPool orthoDescriptorPool;
193  bool orthoDescriptorPoolCreated = false;
194  void createOrthoDescriptorPool();
195 
196  VkCommandBuffer nextCommandBuffer;
197 
198  std::vector<Model> garbageModels;
199 
200  void allocateDescriptorSets();
201  void updateDescriptorSets();
202 
203  void allocateOrthoDescriptorSets();
204  void updateOrthoDescriptorSets();
205 
206  void setColourBuffer(glm::vec4 colour, uint32_t memIndex);
207 
208  void positionNextObject(const glm::vec3 offset,
209  const glm::vec3 rotation,
210  uint32_t memIndex);
211  void positionCamera();
212  VulkanImage getTextureHandle(const std::string name) const;
213  VulkanImage generateTexture(const std::string name,
214  const float* data,
215  const unsigned long width,
216  const unsigned long height,
217  const bool replace);
218 
219  void init(const int width, const int height,
220  const std::string shadersPath);
221  void initWindow(int& width, int& height);
222 
223  void setPerspectiveAndLight();
224 
225  // On Android and iOS, it is useful to be able to destroy and recreate the
226  // renderer, so it is not provided only as a singleton for that platform.
227  // By the way, do NOT create a renderer using getInstance and then
228  // try to delete it in code. That will make an app crash. Either
229  // create it with getInstance and assume it is a singleton which
230  // will be destroyed automatically when the program terminates,
231  // or instantiate it with "new" if you would like to delete it
232  // later.
233 #if defined(__ANDROID__) || defined(SMALL3D_IOS)
234  public:
235  Renderer(const std::string &windowTitle = "",
236  const int width = 0,
237  const int height = 0,
238  const float frustumScale = 1.0f,
239  const float zNear = 1.0f,
240  const float zFar = 24.0f,
241  const float zOffsetFromCamera = -1.0f,
242  const std::string &shadersPath =
243 #ifndef SMALL3D_IOS
244  "resources/shaders/",
245 #else
246  "resources1/shaders/",
247 #endif
248  const uint32_t maxObjectsPerPass = 20);
249 #else
250  Renderer(const std::string &windowTitle, const int width,
251  const int height, const float frustumScale, const float zNear,
252  const float zFar, const float zOffsetFromCamera,
253  const std::string &shadersPath, const uint32_t maxObjectsPerPass);
254 
255 
256 #endif
257 
258  Renderer();
259 
260 #if !defined(__ANDROID__) && !defined(SMALL3D_IOS)
261  public:
262 #endif
263 
267  glm::vec3 lightDirection;
268 
272  glm::vec3 cameraPosition;
273 
277  glm::vec3 cameraRotation;
278 
283  int getScreenWidth();
284 
289  int getScreenHeight();
290 
294  float lightIntensity = 1.0f;
295 
332  static Renderer& getInstance(const std::string &windowTitle = "",
333  const int width = 0,
334  const int height = 0,
335  const float frustumScale = 1.0f,
336  const float zNear = 1.0f,
337  const float zFar = 24.0f,
338  const float zOffsetFromCamera = -1.0f,
339  const std::string &shadersPath =
340  "resources/shaders/",
341  const uint32_t maxObjectsPerPass = 20);
342 
346  ~Renderer();
347 
348 #if !defined(__ANDROID__) && !defined(SMALL3D_IOS)
349 
352  GLFWwindow* getWindow() const;
353 #endif
354 
360  void generateTexture(const std::string &name, const Image &image);
361 
373  void generateTexture(const std::string &name, const std::string &text,
374  const glm::vec3 &colour,
375  const int fontSize = 48,
376  const std::string &fontPath =
377 #ifndef SMALL3D_IOS
378  "resources/fonts/CrusoeText/CrusoeText-Regular.ttf",
379 #else
380  "resources1/fonts/CrusoeText/CrusoeText-Regular.ttf",
381 #endif
382  const bool replace = true);
383 
389  void deleteTexture(const std::string &name);
390 
398  void createRectangle(Model& rect,
399  const glm::vec3& topLeft,
400  const glm::vec3& bottomRight);
401 
417  void render(Model& model, const glm::vec3 &offset, const glm::vec3 &rotation,
418  const glm::vec4 &colour, const std::string &textureName = "",
419  const bool perspective = true);
420 
429  void render(Model& model, const glm::vec3 &offset, const glm::vec3 &rotation,
430  const std::string &textureName);
431 
439  void render(Model& model, const std::string& textureName,
440  const bool perspective = true);
441 
448  void render(Model& model, const glm::vec4& colour,
449  const bool perspective = true);
450 
451 
457  void render(SceneObject &sceneObject, const glm::vec4 &colour);
458 
465  void render(SceneObject &sceneObject, const std::string &textureName);
466 
472  void clearBuffers(Model& model) const;
473 
479  void clearBuffers(SceneObject& sceneObject) const;
480 
487  void clearScreen() const;
488 
497  void clearScreen(const glm::vec4 &colour);
498 
502  void swapBuffers();
503 
504  Renderer(Renderer const&) = delete;
505  void operator=(Renderer const&) = delete;
506  Renderer(Renderer&&) = delete;
507  void operator=(Renderer&&) = delete;
508 
509  };
510 }
void deleteTexture(const std::string &name)
Deletes the texture indicated by the given name.
Definition: Renderer.cpp:1502
A 3D model, loaded from a Wavefront file.
Definition: Model.hpp:25
void clearScreen() const
This function does not do anything in this edition (Vulkan) of small3d, since the screen is automatic...
Definition: Renderer.cpp:1808
int getScreenHeight()
Get the real screen height.
Definition: Renderer.cpp:1251
Header of the Image class.
void clearBuffers(Model &model) const
Clear a Model from the GPU buffers (the object itself remains intact).
Definition: Renderer.cpp:1792
Header of the SceneObject class.
void swapBuffers()
Swap the buffers.
Definition: Renderer.cpp:1827
An image, loaded from a png file, which can be used for generating textures.
Definition: Image.hpp:29
glm::vec3 cameraPosition
The camera position in world space.
Definition: Renderer.hpp:272
glm::vec3 lightDirection
Vector, indicating the direction of the light in the scene.
Definition: Renderer.hpp:267
An object that appears on the 3D scene. It is made up of one or more models (the latter for animation...
Definition: SceneObject.hpp:35
void render(Model &model, const glm::vec3 &offset, const glm::vec3 &rotation, const glm::vec4 &colour, const std::string &textureName="", const bool perspective=true)
Render a Model.
Definition: Renderer.cpp:1548
~Renderer()
Destructor.
Definition: Renderer.cpp:1269
The renderer (Vulkan)
Definition: Renderer.hpp:73
void createRectangle(Model &rect, const glm::vec3 &topLeft, const glm::vec3 &bottomRight)
Populates a Model object with a rectangle stretching between the given coordinates.
Definition: Renderer.cpp:1516
glm::vec3 cameraRotation
The camera rotation (around the x, y and z axes)
Definition: Renderer.hpp:277
Header of the Model class.
Header of the Logger class.
static Renderer & getInstance(const std::string &windowTitle="", const int width=0, const int height=0, const float frustumScale=1.0f, const float zNear=1.0f, const float zFar=24.0f, const float zOffsetFromCamera=-1.0f, const std::string &shadersPath="resources/shaders/", const uint32_t maxObjectsPerPass=20)
Get the instance of the Renderer (the Renderer is a singleton).
Definition: Renderer.cpp:1255
GLFWwindow * getWindow() const
Get the GLFW window object, associated with the Renderer.
Definition: Renderer.cpp:1379
int getScreenWidth()
Get the real screen width.
Definition: Renderer.cpp:1247
float lightIntensity
The light intensity (set to -1.0f if no lighting is to be used).
Definition: Renderer.hpp:294