SuperTuxKart
irr_driver.hpp
1 //
2 // SuperTuxKart - a fun racing game with go-kart
3 // Copyright (C) 2009-2015 Joerg Henrichs
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 3
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 #ifndef HEADER_IRR_DRIVER_HPP
20 #define HEADER_IRR_DRIVER_HPP
21 
30 #include <IVideoDriver.h>
31 #include <vector2d.h>
32 #include <dimension2d.h>
33 #include <SColor.h>
34 #include "IrrlichtDevice.h"
35 #include "ISkinnedMesh.h"
36 #include "graphics/abstract_renderer.hpp"
37 #include "graphics/gl_headers.hpp"
38 #include "graphics/wind.hpp"
39 #include "io/file_manager.hpp"
40 #include "utils/aligned_array.hpp"
41 #include "utils/no_copy.hpp"
42 #include "utils/ptr_vector.hpp"
43 #include "utils/vec3.hpp"
44 #include <memory>
45 #include <string>
46 #include <vector>
47 
48 #ifdef ANDROID
49 #include "main_android.hpp"
50 #endif
51 
52 
53 namespace SP
54 {
55  class SPDynamicDrawCall;
56 }
57 
58 
59 namespace irr
60 {
61  namespace scene { class ISceneManager; class IMesh; class IAnimatedMeshSceneNode; class IAnimatedMesh;
62  class IMeshSceneNode; class IParticleSystemSceneNode; class ICameraSceneNode; class ILightSceneNode;
63  class CLensFlareSceneNode; }
64  namespace gui { class IGUIEnvironment; class IGUIFont; }
65 }
66 using namespace irr;
67 
68 enum TypeRTT : unsigned int;
69 class AbstractKart;
70 class AbstractRenderer;
71 class Camera;
72 class FrameBuffer;
73 class LightNode;
74 class PerCameraNode;
75 class RenderInfo;
76 class RenderTarget;
77 
78 struct SHCoefficients;
79 
85 class IrrDriver : public IEventReceiver, public NoCopy
86 {
87 private:
89  IrrlichtDevice *m_device;
91  scene::ISceneManager *m_scene_manager;
93  gui::IGUIEnvironment *m_gui_env;
95  video::IVideoDriver *m_video_driver;
97  gui::IGUIFont *m_race_font;
100 
103 
104  core::dimension2du m_actual_screen_size;
105 
107  core::array<video::IRenderTarget> m_mrt;
108 
110  core::matrix4 m_ViewMatrix, m_InvViewMatrix, m_ProjMatrix, m_InvProjMatrix, m_ProjViewMatrix, m_InvProjViewMatrix;
111 
112 
113 private:
121  enum {RES_CHANGE_NONE, RES_CHANGE_YES,
122  RES_CHANGE_SAME, RES_CHANGE_YES_WARN} m_resolution_changing;
123 
124 
125 public:
127  class VideoMode
128  {
129  private:
130  int m_width;
131  int m_height;
132  public:
133  VideoMode(int w, int h) {m_width=w; m_height=h; }
134  int getWidth() const {return m_width; }
135  int getHeight() const {return m_height; }
136  }; // VideoMode
137 
138  struct BloomData {
139  scene::ISceneNode * node;
140  float power;
141  };
142 
143  video::SColorf getAmbientLight() const;
144 
145 
146 
147 private:
148  std::vector<VideoMode> m_modes;
149 
150  void setupViewports();
151 
154 
157 
159  void applyResolutionSettings(bool recreate_device);
160  void createListOfVideoModes();
161 
162  bool m_request_screenshot;
163 
164  bool m_ssaoviz;
165  bool m_shadowviz;
166  bool m_lightviz;
167  bool m_boundingboxesviz;
168  bool m_recording;
169  bool m_render_nw_debug;
170 
172  irr::video::SColor m_clear_color;
173 
174 
175  unsigned m_last_light_bucket_distance;
176  unsigned m_skinning_joint;
177 
178  SP::SPDynamicDrawCall* m_sun_interposer;
179  core::vector3df m_sun_direction;
180  video::SColorf m_suncolor;
181 
182 
183  std::vector<LightNode *> m_lights;
184 
185  std::vector<BloomData> m_forcedbloom;
186 
187  std::vector<scene::ISceneNode *> m_background;
188 
189  float m_ssao_radius;
190  float m_ssao_k;
191  float m_ssao_sigma;
192 
193 #ifdef DEBUG
194 
195  std::vector<irr::scene::IAnimatedMeshSceneNode*> m_debug_meshes;
196 #endif
197 
198 public:
199  void doScreenShot();
200 public:
201  IrrDriver();
202  ~IrrDriver();
203  void initDevice();
204  void reset();
205  void setMaxTextureSize();
206  void unsetMaxTextureSize();
207  void getOpenGLData(std::string *vendor, std::string *renderer,
208  std::string *version);
209 
210  void increaseObjectCount();
211  core::array<video::IRenderTarget> &getMainSetup();
212  void updateConfigIfRelevant();
213  core::recti getSplitscreenWindow(int WindowNum);
214  void setAllMaterialFlags(scene::IMesh *mesh) const;
215  scene::IAnimatedMesh *getAnimatedMesh(const std::string &name);
216  scene::IMesh *getMesh(const std::string &name);
217  void displayFPS();
218  void displayStoryModeTimer();
219  bool OnEvent(const irr::SEvent &event);
220  void setAmbientLight(const video::SColorf &light,
221  bool force_SH_computation = true);
222  video::ITexture *getTexture(FileManager::AssetType type,
223  const std::string &filename,
224  bool is_premul=false,
225  bool is_prediv=false,
226  bool complain_if_not_found=true);
227  video::ITexture *getTexture(const std::string &filename,
228  bool is_premul=false,
229  bool is_prediv=false,
230  bool complain_if_not_found=true);
231  void grabAllTextures(const scene::IMesh *mesh);
232  void dropAllTextures(const scene::IMesh *mesh);
233  scene::IMesh *createQuadMesh(const video::SMaterial *material=NULL,
234  bool create_one_quad=false);
235  scene::IMesh *createTexturedQuadMesh(const video::SMaterial *material,
236  const double w, const double h);
237  scene::ISceneNode *addWaterNode(scene::IMesh *mesh, scene::IMesh **welded,
238  float wave_height,
239  float wave_speed, float wave_length);
240  scene::IMeshSceneNode*addOctTree(scene::IMesh *mesh);
241  scene::ISceneNode* addSphere(float radius,
242  const video::SColor &color=video::SColor(128, 255, 255, 255));
243  scene::ISceneNode* addMesh(scene::IMesh *mesh,
244  const std::string& debug_name,
245  scene::ISceneNode *parent = NULL,
246  std::shared_ptr<RenderInfo> render_info = nullptr);
247  PerCameraNode *addPerCameraNode(scene::ISceneNode* node,
248  scene::ICameraSceneNode* cam,
249  scene::ISceneNode *parent = NULL);
250  scene::ISceneNode *addBillboard(const core::dimension2d< f32 > size,
251  const std::string& tex_name,
252  scene::ISceneNode* parent=NULL);
253  scene::IParticleSystemSceneNode
254  *addParticleNode(bool default_emitter=true);
255  scene::ISceneNode *addSkyDome(video::ITexture *texture, int hori_res,
256  int vert_res, float texture_percent,
257  float sphere_percent);
258  scene::ISceneNode *addSkyBox(const std::vector<video::ITexture*> &texture_names,
259  const std::vector<video::ITexture*> &spherical_harmonics_textures);
260  void suppressSkyBox();
261  void removeNode(scene::ISceneNode *node);
262  void removeMeshFromCache(scene::IMesh *mesh);
263  void removeTexture(video::ITexture *t);
264  scene::IAnimatedMeshSceneNode
265  *addAnimatedMesh(scene::IAnimatedMesh *mesh,
266  const std::string& debug_name,
267  scene::ISceneNode* parent = NULL,
268  std::shared_ptr<RenderInfo> render_info = nullptr);
269  scene::ICameraSceneNode
270  *addCameraSceneNode();
271  Camera *addCamera(unsigned int index, AbstractKart *kart);
272  void removeCameraSceneNode(scene::ICameraSceneNode *camera);
273  void removeCamera(Camera *camera);
274  void update(float dt, bool loading=false);
276  void changeResolution(const int w, const int h, const bool fullscreen);
278  void cancelResChange();
279 
280  bool moveWindow(int x, int y);
281 
282  void showPointer();
283  void hidePointer();
284  void setLastLightBucketDistance(unsigned d) { m_last_light_bucket_distance = d; }
285  void setSkinningJoint(unsigned d) { m_skinning_joint = d; }
286  bool isPointerShown() const { return m_pointer_shown; }
287  core::position2di getMouseLocation();
288 
289  void printRenderStats();
290  void requestScreenshot();
291  class GPUTimer &getGPUTimer(unsigned);
292  const char* getGPUQueryPhaseName(unsigned);
293 
294 #ifndef SERVER_ONLY
295  std::unique_ptr<RenderTarget> createRenderTarget(const irr::core::dimension2du &dimension,
296  const std::string &name);
297 #endif
298  // ------------------------------------------------------------------------
300  const irr::video::SColor& getClearColor() const { return m_clear_color; }
301  // ------------------------------------------------------------------------
303  void setClearbackBufferColor(irr::video::SColor color)
304  {
305  m_clear_color = color;
306  } // setClearbackBufferColor
307 
308 
310  const std::vector<VideoMode>& getVideoModes() const { return m_modes; }
311  // ------------------------------------------------------------------------
313  const core::dimension2d<u32>& getFrameSize() const
314  { return m_video_driver->getCurrentRenderTargetSize(); }
315  // ------------------------------------------------------------------------
317  IrrlichtDevice *getDevice() const { return m_device; }
318  // ------------------------------------------------------------------------
320  video::IVideoDriver *getVideoDriver() const { return m_video_driver; }
321  // ------------------------------------------------------------------------
323  scene::ISceneManager *getSceneManager() const { return m_scene_manager; }
324  // ------------------------------------------------------------------------
326  gui::IGUIEnvironment *getGUI() const { return m_gui_env; }
327  // ------------------------------------------------------------------------
330  unsigned int getRealTime() {return m_device->getTimer()->getRealTime(); }
331  // ------------------------------------------------------------------------
333  void giveBoost(unsigned int cam_index) { m_renderer->giveBoost(cam_index);}
334  // ------------------------------------------------------------------------
335  inline core::vector3df getWind() {return m_wind->getWind();}
336 
337  // -----------------------------------------------------------------------
339  inline const SHCoefficients* getSHCoefficients() {return m_renderer->getSHCoefficients();}
340  // -----------------------------------------------------------------------
341  const core::vector3df& getSunDirection() const { return m_sun_direction; };
342  // -----------------------------------------------------------------------
343  void setSunDirection(const core::vector3df &SunPos)
344  {
345  m_sun_direction = SunPos;
346  }
347  // -----------------------------------------------------------------------
348  video::SColorf getSunColor() const { return m_suncolor; }
349  // -----------------------------------------------------------------------
350  void setSunColor(const video::SColorf &col)
351  {
352  m_suncolor = col;
353  }
354  // ------------------------------------------------------------------------
355  GLuint getRenderTargetTexture(TypeRTT which);
356  GLuint getDepthStencilTexture();
357  // ------------------------------------------------------------------------
358  void resetDebugModes();
359  // ------------------------------------------------------------------------
360  void toggleSSAOViz() { m_ssaoviz = !m_ssaoviz; }
361  // ------------------------------------------------------------------------
362  bool getSSAOViz() { return m_ssaoviz; }
363  // ------------------------------------------------------------------------
364  void toggleShadowViz() { m_shadowviz = !m_shadowviz; }
365  // ------------------------------------------------------------------------
366  bool getShadowViz() { return m_shadowviz; }
367  // ------------------------------------------------------------------------
368  void toggleBoundingBoxesViz() { m_boundingboxesviz = !m_boundingboxesviz; }
369  // ------------------------------------------------------------------------
370  void toggleRenderNetworkDebug() { m_render_nw_debug = !m_render_nw_debug; }
371  // ------------------------------------------------------------------------
372  bool getRenderNetworkDebug() const { return m_render_nw_debug; }
373  // ------------------------------------------------------------------------
374  void renderNetworkDebug();
375  // ------------------------------------------------------------------------
376  bool getBoundingBoxesViz() { return m_boundingboxesviz; }
377  // ------------------------------------------------------------------------
378  int getSceneComplexity() { return m_scene_complexity; }
379  void resetSceneComplexity() { m_scene_complexity = 0; }
380  void addSceneComplexity(int complexity)
381  {
382  if (complexity > 1) m_scene_complexity += (complexity - 1);
383  }
384  // ------------------------------------------------------------------------
385  bool isRecording() const { return m_recording; }
386  // ------------------------------------------------------------------------
387  void setRecording(bool val);
388  // ------------------------------------------------------------------------
389  std::vector<LightNode *> getLights() { return m_lights; }
390  // ------------------------------------------------------------------------
391  void addGlowingNode(scene::ISceneNode *n, float r = 1.0f, float g = 1.0f,
392  float b = 1.0f)
393  {
394  m_renderer->addGlowingNode(n, r, g, b);
395  }
396  // ------------------------------------------------------------------------
397  void clearGlowingNodes() { m_renderer->clearGlowingNodes(); }
398  // ------------------------------------------------------------------------
399  void addForcedBloomNode(scene::ISceneNode *n, float power = 1)
400  {
401  BloomData dat;
402  dat.node = n;
403  dat.power = power;
404 
405  m_forcedbloom.push_back(dat);
406  }
407  // ------------------------------------------------------------------------
408  void clearForcedBloom() { m_forcedbloom.clear(); }
409  // ------------------------------------------------------------------------
410  const std::vector<BloomData> &getForcedBloom() const
411  {
412  return m_forcedbloom;
413  }
414  // ------------------------------------------------------------------------
415  void clearBackgroundNodes() { m_background.clear(); }
416  // ------------------------------------------------------------------------
417  void addBackgroundNode(scene::ISceneNode * const n)
418  {
419  m_background.push_back(n);
420  }
421  // ------------------------------------------------------------------------
422  scene::ISceneNode *addLight(const core::vector3df &pos, float energy,
423  float radius, float r, float g, float b,
424  bool sun = false,
425  scene::ISceneNode* parent = NULL);
426  // ------------------------------------------------------------------------
427  void clearLights();
428  // ------------------------------------------------------------------------
429  SP::SPDynamicDrawCall* getSunInterposer() { return m_sun_interposer; }
430  // ------------------------------------------------------------------------
431 
432  void cleanSunInterposer();
433  void createSunInterposer();
434  // ------------------------------------------------------------------------
435  void setViewMatrix(core::matrix4 matrix)
436  {
437  m_ViewMatrix = matrix; matrix.getInverse(m_InvViewMatrix);
438  }
439  // ------------------------------------------------------------------------
440  const core::matrix4 &getViewMatrix() const { return m_ViewMatrix; }
441  // ------------------------------------------------------------------------
442  const core::matrix4 &getInvViewMatrix() const { return m_InvViewMatrix; }
443  // ------------------------------------------------------------------------
444  void setProjMatrix(core::matrix4 matrix)
445  {
446  m_ProjMatrix = matrix; matrix.getInverse(m_InvProjMatrix);
447  }
448  // ------------------------------------------------------------------------
449  const core::matrix4 &getProjMatrix() const { return m_ProjMatrix; }
450  // ------------------------------------------------------------------------
451  const core::matrix4 &getInvProjMatrix() const { return m_InvProjMatrix; }
452  // ------------------------------------------------------------------------
453  void genProjViewMatrix()
454  {
455  m_ProjViewMatrix = m_ProjMatrix * m_ViewMatrix;
456  m_InvProjViewMatrix = m_ProjViewMatrix;
457  m_InvProjViewMatrix.makeInverse();
458  }
459  // ------------------------------------------------------------------------
460  const core::matrix4 &getProjViewMatrix() const { return m_ProjViewMatrix; }
461  // ------------------------------------------------------------------------
462  const core::matrix4 &getInvProjViewMatrix() const
463  {
464  return m_InvProjViewMatrix;
465  }
466  // ------------------------------------------------------------------------
467  const core::vector2df &getCurrentScreenSize() const
468  {
469  return m_renderer->getCurrentScreenSize();
470  }
471  // ------------------------------------------------------------------------
472  const core::dimension2du getActualScreenSize() const
473  {
474  return m_actual_screen_size;
475  }
476  // ------------------------------------------------------------------------
477  float getSSAORadius() const
478  {
479  return m_ssao_radius;
480  }
481 
482  // ------------------------------------------------------------------------
483  void setSSAORadius(float v)
484  {
485  m_ssao_radius = v;
486  }
487 
488  // ------------------------------------------------------------------------
489  float getSSAOK() const
490  {
491  return m_ssao_k;
492  }
493 
494  // ------------------------------------------------------------------------
495  void setSSAOK(float v)
496  {
497  m_ssao_k = v;
498  }
499 
500  // ------------------------------------------------------------------------
501  float getSSAOSigma() const
502  {
503  return m_ssao_sigma;
504  }
505 
506  // ------------------------------------------------------------------------
507  void setSSAOSigma(float v)
508  {
509  m_ssao_sigma = v;
510  }
511 #ifdef DEBUG
512  std::vector<scene::IAnimatedMeshSceneNode*> getDebugMeshes()
513  {
514  return m_debug_meshes;
515  }
517  void clearDebugMesh() { m_debug_meshes.clear(); }
518  // ------------------------------------------------------------------------
520  void addDebugMesh(scene::IAnimatedMeshSceneNode *node)
521  {
522  m_debug_meshes.push_back(node);
523  } // addDebugMesh
524 
525 #endif
526  void onLoadWorld();
527  void onUnloadWorld();
528 
529  void updateSplitAndLightcoordRangeFromComputeShaders(size_t width,
530  size_t height);
531 
532  void uploadLightingData();
533  void sameRestart() { m_resolution_changing = RES_CHANGE_SAME; }
534  // ------------------------------------------------------------------------
535  u32 getDefaultFramebuffer() const
536  { return m_video_driver->getDefaultFramebuffer(); }
537 }; // IrrDriver
538 
539 extern IrrDriver *irr_driver;
540 
541 #endif // HEADER_IRR_DRIVER_HPP
Definition: wind.hpp:25
Wind * m_wind
Wind.
Definition: irr_driver.hpp:102
void giveBoost(unsigned int cam_index)
Use motion blur for a short time.
Definition: irr_driver.hpp:333
const SHCoefficients * getSHCoefficients()
Returns a pointer to the spherical harmonics coefficients.
Definition: irr_driver.hpp:339
Definition: frame_buffer.hpp:32
A simple class to store video resolutions.
Definition: irr_driver.hpp:127
Definition: light.hpp:36
Definition: glwrap.hpp:52
Definition: irr_driver.hpp:138
scene::ISceneManager * m_scene_manager
Irrlicht scene manager.
Definition: irr_driver.hpp:91
Definition: spherical_harmonics.hpp:32
gui::IGUIFont * m_race_font
Irrlicht race font.
Definition: irr_driver.hpp:97
gui::IGUIEnvironment * m_gui_env
Irrlicht gui environment.
Definition: irr_driver.hpp:93
video::IVideoDriver * getVideoDriver() const
Returns the irrlicht video driver.
Definition: irr_driver.hpp:320
Virtual base class for the renderer.
Definition: abstract_renderer.hpp:44
AssetType
The various asset types (and directories) STK might request.
Definition: file_manager.hpp:61
const std::vector< VideoMode > & getVideoModes() const
Returns a list of all video modes supports by the graphics card.
Definition: irr_driver.hpp:310
const core::dimension2d< u32 > & getFrameSize() const
Returns the frame size.
Definition: irr_driver.hpp:313
Utility class, you can inherit from this class to disallow the assignment operator and copy construct...
Definition: no_copy.hpp:25
void setClearbackBufferColor(irr::video::SColor color)
Sets the color to use when clearing the back buffer.
Definition: irr_driver.hpp:303
unsigned int getRealTime()
Returns the current real time, which might not be 0 at start of the application.
Definition: irr_driver.hpp:330
class that creates the irrLicht device and offers higher-level ways to manage the 3D scene
Definition: irr_driver.hpp:85
video::IVideoDriver * m_video_driver
Irrlicht video driver.
Definition: irr_driver.hpp:95
IrrlichtDevice * m_device
The irrlicht device.
Definition: irr_driver.hpp:89
scene::ISceneManager * getSceneManager() const
Returns the irrlicht scene manager.
Definition: irr_driver.hpp:323
Definition: render_target.hpp:28
int m_scene_complexity
Store if the scene is complex (based on polycount, etc)
Definition: irr_driver.hpp:156
Definition: sp_dynamic_draw_call.hpp:41
manages smoke particle effects
Definition: per_camera_node.hpp:45
AbstractRenderer * m_renderer
Renderer.
Definition: irr_driver.hpp:99
core::matrix4 m_ViewMatrix
Matrixes used in several places stored here to avoid recomputation.
Definition: irr_driver.hpp:110
irr::video::SColor m_clear_color
Background colour to reset a buffer.
Definition: irr_driver.hpp:172
IrrlichtDevice * getDevice() const
Returns the irrlicht device.
Definition: irr_driver.hpp:317
Definition: render_info.hpp:27
core::array< video::IRenderTarget > m_mrt
The main MRT setup.
Definition: irr_driver.hpp:107
This is the base class for all cameras.
Definition: camera.hpp:48
An abstract interface for the actual karts.
Definition: abstract_kart.hpp:61
const irr::video::SColor & getClearColor() const
Returns the color to clear the back buffer.
Definition: irr_driver.hpp:300
gui::IGUIEnvironment * getGUI() const
Returns the gui environment, used to add widgets to a screen.
Definition: irr_driver.hpp:326
bool m_pointer_shown
Whether the mouse cursor is currently shown.
Definition: irr_driver.hpp:153