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 "graphics/abstract_renderer.hpp"
31 #include "graphics/gl_headers.hpp"
32 #include "graphics/wind.hpp"
33 #include "io/file_manager.hpp"
34 #include "utils/aligned_array.hpp"
35 #include "utils/no_copy.hpp"
36 #include "utils/ptr_vector.hpp"
37 #include "utils/vec3.hpp"
38 #include <memory>
39 #include <string>
40 #include <vector>
41 
42 #include <irrArray.h>
43 #include <dimension2d.h>
44 #include <position2d.h>
45 #include <matrix4.h>
46 #include <vector2d.h>
47 #include <IEventReceiver.h>
48 #include <SColor.h>
49 
50 namespace SP
51 {
52  class SPDynamicDrawCall;
53 }
54 
55 
56 namespace irr
57 {
58  namespace scene { class ISceneManager; class IMesh; class IAnimatedMeshSceneNode; class IAnimatedMesh;
59  class IMeshSceneNode; class IParticleSystemSceneNode; class ICameraSceneNode; class ILightSceneNode;
60  class CLensFlareSceneNode; }
61  namespace gui { class IGUIEnvironment; class IGUIFont; }
62  namespace video { struct IRenderTarget; class ITexture; class IVideoDriver;
63  class SMaterial; }
64  class IrrlichtDevice;
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 namespace GE { class GERenderInfo; }
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, RES_CHANGE_CANCEL,
122  RES_CHANGE_SAME, RES_CHANGE_YES_WARN, RES_CHANGE_SAME_FULL} 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  int m_screen_orientation;
149  std::vector<VideoMode> m_modes;
150 
151  void setupViewports();
152 
155 
160 
162  void applyResolutionSettings(bool recreate_device);
163  void createListOfVideoModes();
164 
165  bool m_request_screenshot;
166 
167  bool m_ssaoviz;
168  bool m_shadowviz;
169  bool m_lightviz;
170  bool m_boundingboxesviz;
171  bool m_recording;
172  bool m_render_nw_debug;
173 
175  irr::video::SColor m_clear_color;
176 
177 
178  unsigned m_last_light_bucket_distance;
179  unsigned m_skinning_joint;
180 
181  SP::SPDynamicDrawCall* m_sun_interposer;
182  core::vector3df m_sun_direction;
183  video::SColorf m_suncolor;
184 
185 
186  std::vector<LightNode *> m_lights;
187 
188  std::vector<BloomData> m_forcedbloom;
189 
190  std::vector<scene::ISceneNode *> m_background;
191 
192  float m_ssao_radius;
193  float m_ssao_k;
194  float m_ssao_sigma;
195  irr::ELOG_LEVEL m_logger_level;
196 #ifdef DEBUG
198  std::vector<irr::scene::IAnimatedMeshSceneNode*> m_debug_meshes;
199 #endif
200  // ------------------------------------------------------------------------
201  void updateDisplace(float dt);
202  // ------------------------------------------------------------------------
203  void resizeWindow();
204 public:
205  void doScreenShot();
206 public:
207  IrrDriver();
208  ~IrrDriver();
209  void initDevice();
210  void reset();
211  void setMaxTextureSize();
212  void unsetMaxTextureSize();
213  void getOpenGLData(std::string *vendor, std::string *renderer,
214  std::string *version);
215 
216  void increaseObjectCount();
217  core::array<video::IRenderTarget> &getMainSetup();
218  void updateConfigIfRelevant();
219  core::recti getSplitscreenWindow(int window_num);
220  void setAllMaterialFlags(scene::IMesh *mesh) const;
221  scene::IAnimatedMesh *getAnimatedMesh(const std::string &name);
222  scene::IMesh *getMesh(const std::string &name);
223  void displayFPS();
224  void displayStoryModeTimer();
225  bool OnEvent(const irr::SEvent &event);
226  void setAmbientLight(const video::SColorf &light,
227  bool force_SH_computation = true);
228  video::ITexture *getTexture(FileManager::AssetType type,
229  const std::string &filename);
230  video::ITexture *getTexture(const std::string &filename);
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<GE::GERenderInfo> 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 *addSkyBox(const std::vector<video::ITexture*> &texture_names,
256  const std::vector<video::ITexture*> &spherical_harmonics_textures);
257  void suppressSkyBox();
258  void removeNode(scene::ISceneNode *node);
259  void removeMeshFromCache(scene::IMesh *mesh);
260  void removeTexture(video::ITexture *t);
261  scene::IAnimatedMeshSceneNode
262  *addAnimatedMesh(scene::IAnimatedMesh *mesh,
263  const std::string& debug_name,
264  scene::ISceneNode* parent = NULL,
265  std::shared_ptr<GE::GERenderInfo> render_info = nullptr);
266  scene::ICameraSceneNode
267  *addCameraSceneNode();
268  Camera *addCamera(unsigned int index, AbstractKart *kart);
269  void removeCameraSceneNode(scene::ICameraSceneNode *camera);
270  void removeCamera(Camera *camera);
271  void update(float dt, bool loading=false);
273  void changeResolution(const int w, const int h, const bool fullscreen);
275  void cancelResChange();
276 
277  bool moveWindow(int x, int y);
278 
279  void showPointer();
280  void hidePointer();
281  void setLastLightBucketDistance(unsigned d) { m_last_light_bucket_distance = d; }
282  void setSkinningJoint(unsigned d) { m_skinning_joint = d; }
283  bool isPointerShown() const { return m_pointer_shown; }
284  core::position2di getMouseLocation();
285 
286  void printRenderStats();
287  void requestScreenshot();
288  class GPUTimer &getGPUTimer(unsigned);
289  const char* getGPUQueryPhaseName(unsigned);
290 
291 #ifndef SERVER_ONLY
292  std::unique_ptr<RenderTarget> createRenderTarget(const irr::core::dimension2du &dimension,
293  const std::string &name);
294 #endif
295  // ------------------------------------------------------------------------
297  const irr::video::SColor& getClearColor() const { return m_clear_color; }
298  // ------------------------------------------------------------------------
300  void setClearbackBufferColor(irr::video::SColor color)
301  {
302  m_clear_color = color;
303  } // setClearbackBufferColor
304 
305 
307  const std::vector<VideoMode>& getVideoModes() const { return m_modes; }
308  // ------------------------------------------------------------------------
310  const core::dimension2d<u32>& getFrameSize() const;
311  // ------------------------------------------------------------------------
313  IrrlichtDevice *getDevice() const { return m_device; }
314  // ------------------------------------------------------------------------
316  video::IVideoDriver *getVideoDriver() const { return m_video_driver; }
317  // ------------------------------------------------------------------------
319  scene::ISceneManager *getSceneManager() const { return m_scene_manager; }
320  // ------------------------------------------------------------------------
322  gui::IGUIEnvironment *getGUI() const { return m_gui_env; }
323  // ------------------------------------------------------------------------
326  unsigned int getRealTime();
327  // ------------------------------------------------------------------------
329  void giveBoost(unsigned int cam_index) { m_renderer->giveBoost(cam_index);}
330  // ------------------------------------------------------------------------
331  inline core::vector3df getWind() {return m_wind->getWind();}
332 
333  // -----------------------------------------------------------------------
335  inline const SHCoefficients* getSHCoefficients() {return m_renderer->getSHCoefficients();}
336  // -----------------------------------------------------------------------
337  const core::vector3df& getSunDirection() const { return m_sun_direction; };
338  // -----------------------------------------------------------------------
339  void setSunDirection(const core::vector3df &SunPos)
340  {
341  m_sun_direction = SunPos;
342  }
343  // -----------------------------------------------------------------------
344  video::SColorf getSunColor() const { return m_suncolor; }
345  // -----------------------------------------------------------------------
346  void setSunColor(const video::SColorf &col)
347  {
348  m_suncolor = col;
349  }
350  // ------------------------------------------------------------------------
351  GLuint getRenderTargetTexture(TypeRTT which);
352  GLuint getDepthStencilTexture();
353  // ------------------------------------------------------------------------
354  void resetDebugModes();
355  // ------------------------------------------------------------------------
356  void toggleSSAOViz() { m_ssaoviz = !m_ssaoviz; }
357  // ------------------------------------------------------------------------
358  bool getSSAOViz() { return m_ssaoviz; }
359  // ------------------------------------------------------------------------
360  void toggleShadowViz() { m_shadowviz = !m_shadowviz; }
361  // ------------------------------------------------------------------------
362  bool getShadowViz() { return m_shadowviz; }
363  // ------------------------------------------------------------------------
364  void toggleBoundingBoxesViz() { m_boundingboxesviz = !m_boundingboxesviz; }
365  // ------------------------------------------------------------------------
366  void toggleRenderNetworkDebug() { m_render_nw_debug = !m_render_nw_debug; }
367  // ------------------------------------------------------------------------
368  bool getRenderNetworkDebug() const { return m_render_nw_debug; }
369  // ------------------------------------------------------------------------
370  void renderNetworkDebug();
371  // ------------------------------------------------------------------------
372  bool getBoundingBoxesViz() { return m_boundingboxesviz; }
373  // ------------------------------------------------------------------------
374  int getSceneComplexity() { return m_scene_complexity; }
375  // ------------------------------------------------------------------------
376  void resetSceneComplexity() { m_scene_complexity = 0; }
377  // ------------------------------------------------------------------------
378  void addSceneComplexity(int complexity)
379  {
380  if (complexity > 1) m_scene_complexity += (complexity - 1);
381  }
382  // ------------------------------------------------------------------------
383  float getLODMultiplier() { return m_lod_multiplier; }
384  // ------------------------------------------------------------------------
385  void setLODMultiplier(float multiplier) { m_lod_multiplier = multiplier; }
386  // ------------------------------------------------------------------------
387  bool isRecording() const { return m_recording; }
388  // ------------------------------------------------------------------------
389  void setRecording(bool val);
390  // ------------------------------------------------------------------------
391  std::vector<LightNode *> getLights() { return m_lights; }
392  // ------------------------------------------------------------------------
393  void addGlowingNode(scene::ISceneNode *n, float r = 1.0f, float g = 1.0f,
394  float b = 1.0f)
395  {
396  m_renderer->addGlowingNode(n, r, g, b);
397  }
398  // ------------------------------------------------------------------------
399  void clearGlowingNodes() { m_renderer->clearGlowingNodes(); }
400  // ------------------------------------------------------------------------
401  void addForcedBloomNode(scene::ISceneNode *n, float power = 1)
402  {
403  BloomData dat;
404  dat.node = n;
405  dat.power = power;
406 
407  m_forcedbloom.push_back(dat);
408  }
409  // ------------------------------------------------------------------------
410  void clearForcedBloom() { m_forcedbloom.clear(); }
411  // ------------------------------------------------------------------------
412  const std::vector<BloomData> &getForcedBloom() const
413  {
414  return m_forcedbloom;
415  }
416  // ------------------------------------------------------------------------
417  void clearBackgroundNodes() { m_background.clear(); }
418  // ------------------------------------------------------------------------
419  void addBackgroundNode(scene::ISceneNode * const n)
420  {
421  m_background.push_back(n);
422  }
423  // ------------------------------------------------------------------------
424  scene::ISceneNode *addLight(const core::vector3df &pos, float energy,
425  float radius, float r, float g, float b,
426  bool sun_ = false,
427  scene::ISceneNode* parent = NULL);
428  // ------------------------------------------------------------------------
429  void clearLights();
430  // ------------------------------------------------------------------------
431  SP::SPDynamicDrawCall* getSunInterposer() { return m_sun_interposer; }
432  // ------------------------------------------------------------------------
433 
434  void cleanSunInterposer();
435  void createSunInterposer();
436  // ------------------------------------------------------------------------
437  void setViewMatrix(core::matrix4 matrix)
438  {
439  m_ViewMatrix = matrix; matrix.getInverse(m_InvViewMatrix);
440  }
441  // ------------------------------------------------------------------------
442  const core::matrix4 &getViewMatrix() const { return m_ViewMatrix; }
443  // ------------------------------------------------------------------------
444  const core::matrix4 &getInvViewMatrix() const { return m_InvViewMatrix; }
445  // ------------------------------------------------------------------------
446  void setProjMatrix(core::matrix4 matrix)
447  {
448  m_ProjMatrix = matrix; matrix.getInverse(m_InvProjMatrix);
449  }
450  // ------------------------------------------------------------------------
451  const core::matrix4 &getProjMatrix() const { return m_ProjMatrix; }
452  // ------------------------------------------------------------------------
453  const core::matrix4 &getInvProjMatrix() const { return m_InvProjMatrix; }
454  // ------------------------------------------------------------------------
455  void genProjViewMatrix()
456  {
457  m_ProjViewMatrix = m_ProjMatrix * m_ViewMatrix;
458  m_InvProjViewMatrix = m_ProjViewMatrix;
459  m_InvProjViewMatrix.makeInverse();
460  }
461  // ------------------------------------------------------------------------
462  const core::matrix4 &getProjViewMatrix() const { return m_ProjViewMatrix; }
463  // ------------------------------------------------------------------------
464  const core::matrix4 &getInvProjViewMatrix() const
465  {
466  return m_InvProjViewMatrix;
467  }
468  // ------------------------------------------------------------------------
469  const core::vector2df &getCurrentScreenSize() const
470  {
471  return m_renderer->getCurrentScreenSize();
472  }
473  // ------------------------------------------------------------------------
474  const core::dimension2du getActualScreenSize() const
475  {
476  return m_actual_screen_size;
477  }
478  // ------------------------------------------------------------------------
479  float getSSAORadius() const
480  {
481  return m_ssao_radius;
482  }
483 
484  // ------------------------------------------------------------------------
485  void setSSAORadius(float v)
486  {
487  m_ssao_radius = v;
488  }
489 
490  // ------------------------------------------------------------------------
491  float getSSAOK() const
492  {
493  return m_ssao_k;
494  }
495 
496  // ------------------------------------------------------------------------
497  void setSSAOK(float v)
498  {
499  m_ssao_k = v;
500  }
501 
502  // ------------------------------------------------------------------------
503  float getSSAOSigma() const
504  {
505  return m_ssao_sigma;
506  }
507 
508  // ------------------------------------------------------------------------
509  void setSSAOSigma(float v)
510  {
511  m_ssao_sigma = v;
512  }
513 #ifdef DEBUG
514  std::vector<scene::IAnimatedMeshSceneNode*> getDebugMeshes()
515  {
516  return m_debug_meshes;
517  }
519  void clearDebugMesh() { m_debug_meshes.clear(); }
520  // ------------------------------------------------------------------------
522  void addDebugMesh(scene::IAnimatedMeshSceneNode *node)
523  {
524  m_debug_meshes.push_back(node);
525  } // addDebugMesh
526 
527 #endif
528  void onLoadWorld();
529  void onUnloadWorld();
530 
531  void updateSplitAndLightcoordRangeFromComputeShaders(size_t width,
532  size_t height);
533 
534  void uploadLightingData();
535  void sameRestart() { m_resolution_changing = RES_CHANGE_SAME; }
538  void fullRestart() { m_resolution_changing = RES_CHANGE_SAME_FULL; }
539  // ------------------------------------------------------------------------
540  u32 getDefaultFramebuffer() const;
541  // ------------------------------------------------------------------------
542  void handleWindowResize();
543 }; // IrrDriver
544 
545 extern IrrDriver *irr_driver;
546 
547 #endif // HEADER_IRR_DRIVER_HPP
An abstract interface for the actual karts.
Definition: abstract_kart.hpp:62
Virtual base class for the renderer.
Definition: abstract_renderer.hpp:60
This is the base class for all cameras.
Definition: camera.hpp:49
AssetType
The various asset types (and directories) STK might request.
Definition: file_manager.hpp:63
Definition: frame_buffer.hpp:33
Definition: glwrap.hpp:56
A simple class to store video resolutions.
Definition: irr_driver.hpp:128
class that creates the irrLicht device and offers higher-level ways to manage the 3D scene
Definition: irr_driver.hpp:86
AbstractRenderer * m_renderer
Renderer.
Definition: irr_driver.hpp:99
int m_scene_complexity
Store if the scene is complex (based on polycount, etc)
Definition: irr_driver.hpp:157
Wind * m_wind
Wind.
Definition: irr_driver.hpp:102
const std::vector< VideoMode > & getVideoModes() const
Returns a list of all video modes supports by the graphics card.
Definition: irr_driver.hpp:307
core::array< video::IRenderTarget > m_mrt
The main MRT setup.
Definition: irr_driver.hpp:107
void setClearbackBufferColor(irr::video::SColor color)
Sets the color to use when clearing the back buffer.
Definition: irr_driver.hpp:300
irr::video::SColor m_clear_color
Background colour to reset a buffer.
Definition: irr_driver.hpp:175
void fullRestart()
Used when we don't want a changed resolution prompt but need to reinit things that sameRestart doesn'...
Definition: irr_driver.hpp:538
core::matrix4 m_ViewMatrix
Matrixes used in several places stored here to avoid recomputation.
Definition: irr_driver.hpp:110
gui::IGUIEnvironment * m_gui_env
Irrlicht gui environment.
Definition: irr_driver.hpp:93
const SHCoefficients * getSHCoefficients()
Returns a pointer to the spherical harmonics coefficients.
Definition: irr_driver.hpp:335
gui::IGUIEnvironment * getGUI() const
Returns the gui environment, used to add widgets to a screen.
Definition: irr_driver.hpp:322
const irr::video::SColor & getClearColor() const
Returns the color to clear the back buffer.
Definition: irr_driver.hpp:297
gui::IGUIFont * m_race_font
Irrlicht race font.
Definition: irr_driver.hpp:97
void giveBoost(unsigned int cam_index)
Use motion blur for a short time.
Definition: irr_driver.hpp:329
video::IVideoDriver * m_video_driver
Irrlicht video driver.
Definition: irr_driver.hpp:95
video::IVideoDriver * getVideoDriver() const
Returns the irrlicht video driver.
Definition: irr_driver.hpp:316
scene::ISceneManager * m_scene_manager
Irrlicht scene manager.
Definition: irr_driver.hpp:91
scene::ISceneManager * getSceneManager() const
Returns the irrlicht scene manager.
Definition: irr_driver.hpp:319
IrrlichtDevice * getDevice() const
Returns the irrlicht device.
Definition: irr_driver.hpp:313
float m_lod_multiplier
Used for auto-LoD adjustment in low-complexity scenes.
Definition: irr_driver.hpp:159
bool m_pointer_shown
Whether the mouse cursor is currently shown.
Definition: irr_driver.hpp:154
IrrlichtDevice * m_device
The irrlicht device.
Definition: irr_driver.hpp:89
Definition: light.hpp:44
Utility class, you can inherit from this class to disallow the assignment operator and copy construct...
Definition: no_copy.hpp:26
manages smoke particle effects
Definition: per_camera_node.hpp:46
Definition: render_target.hpp:42
Definition: sp_dynamic_draw_call.hpp:42
Definition: wind.hpp:26
Definition: irr_driver.hpp:138
Definition: spherical_harmonics.hpp:33