1 /*
2  * This file is part of the Colobot: Gold Edition source code
3  * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
4  * http://epsitec.ch; http://colobot.info; http://github.com/colobot
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see http://gnu.org/licenses
18  */
19 
20 /**
21  * \file graphics/engine/engine.h
22  * \brief Main graphics engine - CEngine class
23  */
24 
25 #pragma once
26 
27 #include "common/singleton.h"
28 
29 #include "graphics/core/color.h"
30 #include "graphics/core/material.h"
31 #include "graphics/core/texture.h"
32 #include "graphics/core/vertex.h"
33 
34 #include "math/intpoint.h"
35 #include "math/matrix.h"
36 #include "math/point.h"
37 #include "math/sphere.h"
38 #include "math/vector.h"
39 
40 
41 #include <string>
42 #include <vector>
43 #include <map>
44 #include <set>
45 #include <memory>
46 #include <unordered_map>
47 
48 
49 class CApplication;
50 class CSoundInterface;
51 class CImage;
52 class CSystemUtils;
53 struct SystemTimeStamp;
54 struct Event;
55 
56 
57 // Graphics module namespace
58 namespace Gfx
59 {
60 
61 
62 class CDevice;
63 class COldModelManager;
64 class CLightManager;
65 class CText;
66 class CParticle;
67 class CWater;
68 class CCloud;
69 class CLightning;
70 class CPlanet;
71 class CTerrain;
72 class CPyroManager;
73 class CModelMesh;
74 struct ModelShadowSpot;
75 struct ModelTriangle;
76 
77 
78 /**
79  * \enum EngineRenderState
80  * \brief Render state of graphics engine
81  *
82  * States are used for settings certain modes, for instance texturing and blending.
83  * The enum is a bitmask and some of the states can be OR'd together.
84  */
85 enum EngineRenderState
86 {
87     //! Normal opaque materials
88     ENG_RSTATE_NORMAL           = 0,
89     //! The transparent texture (black = no)
90     ENG_RSTATE_TTEXTURE_BLACK   = (1<<0),
91     //! The transparent texture (white = no)
92     ENG_RSTATE_TTEXTURE_WHITE   = (1<<1),
93     //! The transparent diffuse color
94     ENG_RSTATE_TDIFFUSE         = (1<<2),
95     //! Texture wrap
96     ENG_RSTATE_WRAP             = (1<<3),
97     //! Texture borders with solid color
98     ENG_RSTATE_CLAMP            = (1<<4),
99     //! Light texture (ambient max)
100     ENG_RSTATE_LIGHT            = (1<<5),
101     //! Double black texturing
102     ENG_RSTATE_DUAL_BLACK       = (1<<6),
103     //! Double white texturing
104     ENG_RSTATE_DUAL_WHITE       = (1<<7),
105     //! Part 1 (no change in. MOD!)
106     ENG_RSTATE_PART1            = (1<<8),
107     //! Part 2
108     ENG_RSTATE_PART2            = (1<<9),
109     //! Part 3
110     ENG_RSTATE_PART3            = (1<<10),
111     //! Part 4
112     ENG_RSTATE_PART4            = (1<<11),
113     //! Double-sided face
114     ENG_RSTATE_2FACE            = (1<<12),
115     //! Image using alpha channel
116     ENG_RSTATE_ALPHA            = (1<<13),
117     //! Always use 2nd floor texturing
118     ENG_RSTATE_SECOND           = (1<<14),
119     //! Causes the fog
120     ENG_RSTATE_FOG              = (1<<15),
121     //! The transparent color (black = no)
122     ENG_RSTATE_TCOLOR_BLACK     = (1<<16),
123     //! The transparent color (white = no)
124     ENG_RSTATE_TCOLOR_WHITE     = (1<<17),
125     //! Mode for rendering text
126     ENG_RSTATE_TEXT             = (1<<18),
127     //! Only opaque texture, no blending, etc.
128     ENG_RSTATE_OPAQUE_TEXTURE   = (1<<19),
129     //! Only opaque color, no texture, blending, etc.
130     ENG_RSTATE_OPAQUE_COLOR     = (1<<20),
131     //! Texture using alpha channel
132     ENG_RSTATE_TTEXTURE_ALPHA   = (1<<21),
133     //! Color with transparency
134     ENG_RSTATE_TCOLOR_ALPHA     = (1<<22)
135 };
136 
137 
138 /**
139  * \enum EngineTriangleType
140  * \brief Type of triangles drawn for engine objects
141  */
142 enum EngineTriangleType
143 {
144     //! Triangles
145     ENG_TRIANGLE_TYPE_TRIANGLES = 1,
146     //! Surfaces
147     ENG_TRIANGLE_TYPE_SURFACE   = 2
148 };
149 
150 /**
151  * \struct EngineTriangle
152  * \brief A triangle drawn by the graphics engine
153  */
154 struct EngineTriangle
155 {
156     //! Triangle vertices
157     VertexTex2     triangle[3];
158     //! Material
159     Material       material;
160     //! Render state
161     int            state = ENG_RSTATE_NORMAL;
162     //! 1st texture
163     std::string    tex1Name;
164     //! 2nd texture
165     std::string    tex2Name;
166 };
167 
168 /**
169   \enum EngineObjectType
170   \brief Class of graphics engine object */
171 enum EngineObjectType
172 {
173     //! Object doesn't exist
174     ENG_OBJTYPE_NULL        = 0,
175     //! Terrain
176     ENG_OBJTYPE_TERRAIN     = 1,
177     //! Fixed object
178     ENG_OBJTYPE_FIX         = 2,
179     //! Moving object
180     ENG_OBJTYPE_VEHICLE    = 3,
181     //! Part of a moving object
182     ENG_OBJTYPE_DESCENDANT  = 4,
183     //! Fixed object type quartz
184     ENG_OBJTYPE_QUARTZ      = 5,
185     //! Fixed object type metal
186     ENG_OBJTYPE_METAL       = 6
187 };
188 
189 
190 /**
191  * \struct EngineBaseObjDataTier
192  * \brief Tier 3 of object tree (data)
193  */
194 struct EngineBaseObjDataTier
195 {
196     EngineTriangleType      type;
197     Material                material;
198     int                     state;
199     std::vector<VertexTex2> vertices;
200     unsigned int            staticBufferId;
201     bool                    updateStaticBuffer;
202 
203     inline EngineBaseObjDataTier(EngineTriangleType type = ENG_TRIANGLE_TYPE_TRIANGLES,
204                                  const Material& material = Material(),
205                                  int state = ENG_RSTATE_NORMAL)
typeEngineBaseObjDataTier206      : type(type)
207      , material(material)
208      , state(state)
209      , staticBufferId(0)
210      , updateStaticBuffer(false)
211     {}
212 };
213 
214 /**
215  * \struct EngineBaseObjTexTier
216  * \brief Tier 2 of base object tree (textures)
217  */
218 struct EngineBaseObjTexTier
219 {
220     std::string                        tex1Name;
221     Texture                            tex1;
222     std::string                        tex2Name;
223     Texture                            tex2;
224     std::vector<EngineBaseObjDataTier>  next;
225 
226     inline EngineBaseObjTexTier(const std::string& tex1Name = "",
227                                 const std::string& tex2Name = "")
tex1NameEngineBaseObjTexTier228      : tex1Name(tex1Name)
229      , tex2Name(tex2Name)
230     {}
231 };
232 
233 /**
234  * \struct BaseEngineObject
235  * \brief Base (template) object - geometry for engine objects
236  *
237  * This is also the tier 1 of base object tree.
238  */
239 struct EngineBaseObject
240 {
241     //! If true, base object is valid in objects vector
242     bool used = false;
243     //! Number of triangles
244     int                    totalTriangles = 0;
245     //! Bounding box min (origin 0,0,0 always included)
246     Math::Vector           bboxMin;
247     //! bounding box max (origin 0,0,0 always included)
248     Math::Vector           bboxMax;
249     //! A bounding sphere that contains all the vertices in this EngineBaseObject
250     Math::Sphere           boundingSphere;
251     //! Next tier (Tex)
252     std::vector<EngineBaseObjTexTier> next;
253 
LoadDefaultEngineBaseObject254     inline void LoadDefault()
255     {
256         *this = EngineBaseObject();
257     }
258 };
259 
260 /**
261  * \struct EngineObject
262  * \brief Object drawn by the graphics engine
263  */
264 struct EngineObject
265 {
266     //! If true, object is valid in objects vector
267     bool                   used = false;
268     //! Rank of associated base engine object
269     int                    baseObjRank = -1;
270     //! If true, the object is drawn
271     bool                   visible = false;
272     //! If true, object is behind the 2D interface
273     bool                   drawWorld = false;
274     //! If true, the shape is before the 2D interface
275     bool                   drawFront = false;
276     //! Type of object
277     EngineObjectType       type = ENG_OBJTYPE_NULL;
278     //! Transformation matrix
279     Math::Matrix           transform;
280     //! Distance to object from eye point
281     float                  distance = 0.0f;
282     //! Rank of the associated shadow
283     int                    shadowRank = -1;
284     //! Transparency of the object [0, 1]
285     float                  transparency = 0.0f;
286 
287     //! Loads default values
LoadDefaultEngineObject288     inline void LoadDefault()
289     {
290         *this = EngineObject();
291     }
292 };
293 
294 /**
295  * \struct EngineShadowType
296  * \brief Type of shadow drawn by the graphics engine
297  */
298 enum EngineShadowType
299 {
300     //! Normal shadow
301     ENG_SHADOW_NORM = 0,
302     //! TODO: ?
303     ENG_SHADOW_WORM = 1
304 };
305 
306 /**
307  * \struct EngineShadow
308  * \brief Shadow drawn by the graphics engine
309  */
310 struct EngineShadow
311 {
312     //! If true, shadow is valid
313     bool                used = false;
314     //! If true, shadow is invisible (object being carried for example)
315     bool                hide = false;
316     //! Rank of the associated object
317     int                 objRank = -1;
318     //! Type of shadow
319     EngineShadowType type = ENG_SHADOW_NORM;
320     //! Position of the shadow
321     Math::Vector        pos;
322     //! Normal to the terrain
323     Math::Vector        normal;
324     //! Angle of the shadow
325     float               angle = 0.0f;
326     //! Radius of the shadow
327     float               radius = 0.0f;
328     //! Intensity of the shadow
329     float               intensity = 0.0f;
330     //! Height from the ground
331     float               height = 0.0f;
332 
LoadDefaultEngineShadow333     void LoadDefault()
334     {
335         *this = EngineShadow();
336     }
337 };
338 
339 /**
340  * \struct EngineGroundSpot
341  * \brief A spot (large shadow) drawn on the ground by the graphics engine
342  */
343 struct EngineGroundSpot
344 {
345     //! If true, ground spot is valid
346     bool            used = false;
347     //! Color of the shadow
348     Color      color;
349     //! Min altitude
350     float           min = 0.0f;
351     //! Max altitude
352     float           max = 0.0f;
353     //! Transition area
354     float           smooth = 0.0f;
355     //! Position for the shadow
356     Math::Vector    pos;
357     //! Radius of the shadow
358     float           radius = 0.0f;
359     //! Position of the shadow drawn
360     Math::Vector    drawPos;
361     //! Radius of the shadow drawn
362     float           drawRadius = 0.0f;
363 
LoadDefaultEngineGroundSpot364     void LoadDefault()
365     {
366         *this = EngineGroundSpot();
367     }
368 };
369 
370 /**
371  * \enum EngineGroundMarkPhase
372  * \brief Phase of life of an EngineGroundMark
373  */
374 enum EngineGroundMarkPhase
375 {
376     //! Null phase
377     ENG_GR_MARK_PHASE_NULL = 0,
378     //! Increase
379     ENG_GR_MARK_PHASE_INC = 1,
380     //! Fixed
381     ENG_GR_MARK_PHASE_FIX = 2,
382     //! Decrease
383     ENG_GR_MARK_PHASE_DEC = 3
384 };
385 
386 /**
387  * \struct EngineGroundMark
388  * \brief A mark on ground drawn by the graphics engine
389  */
390 struct EngineGroundMark
391 {
392     //! If true, draw mark
393     bool                        draw = false;
394     //! Phase of life
395     EngineGroundMarkPhase  phase = ENG_GR_MARK_PHASE_NULL;
396     //! Times for 3 life phases
397     float                       delay[3] = {};
398     //! Fixed time
399     float                       fix = 0.0f;
400     //! Position for marks
401     Math::Vector                pos;
402     //! Radius of marks
403     float                       radius = 0.0f;
404     //! Color intensity
405     float                       intensity = 0.0f;
406     //! Draw position for marks
407     Math::Vector                drawPos;
408     //! Radius for  marks
409     float                       drawRadius = 0.0f;
410     //! Draw intensity for marks
411     float                       drawIntensity = 0.0f;
412     //! X dimension of table
413     int                         dx = 0;
414     //! Y dimension of table
415     int                         dy = 0;
416     //! Pointer to the table
417     char*                       table = nullptr;
418 
LoadDefaultEngineGroundMark419     void LoadDefault()
420     {
421         *this = EngineGroundMark();
422     }
423 };
424 
425 /**
426  * \enum EngineTextureMapping
427  * \brief Type of texture mapping
428  */
429 enum EngineTextureMapping
430 {
431     ENG_TEX_MAPPING_X       = 1,
432     ENG_TEX_MAPPING_Y       = 2,
433     ENG_TEX_MAPPING_Z       = 3,
434     ENG_TEX_MAPPING_1X      = 4,
435     ENG_TEX_MAPPING_1Y      = 5,
436     ENG_TEX_MAPPING_1Z      = 6
437 };
438 
439 
440 /**
441  * \enum EngineMouseType
442  * \brief Type of mouse cursor displayed in-game
443  */
444 enum EngineMouseType
445 {
446     //! Normal cursor (arrow)
447     ENG_MOUSE_NORM      = 0,
448     //! Busy
449     ENG_MOUSE_WAIT      = 1,
450     //! Edit (I-beam)
451     ENG_MOUSE_EDIT      = 2,
452     //! Hand
453     ENG_MOUSE_HAND      = 3,
454     //! Small cross
455     ENG_MOUSE_CROSS     = 4,
456     //! TODO: ?
457     ENG_MOUSE_SHOW      = 5,
458     //! Crossed out sign
459     ENG_MOUSE_NO        = 6,
460     //! Resize
461     ENG_MOUSE_MOVE      = 7,
462     //! Resize horizontally
463     ENG_MOUSE_MOVEH     = 8,
464     //! Resize vertically
465     ENG_MOUSE_MOVEV     = 9,
466     //! Resize diagonally bottom-left to top-right
467     ENG_MOUSE_MOVED     = 10,
468     //! Resize diagonally top-left to bottom-right
469     ENG_MOUSE_MOVEI     = 11,
470     //! Scroll to the left
471     ENG_MOUSE_SCROLLL   = 12,
472     //! Scroll to the right
473     ENG_MOUSE_SCROLLR   = 13,
474     //! Scroll up
475     ENG_MOUSE_SCROLLU   = 14,
476     //! Scroll down
477     ENG_MOUSE_SCROLLD   = 15,
478     //! Larger crosshair
479     ENG_MOUSE_TARGET    = 16,
480 
481     //! Number of items in enum
482     ENG_MOUSE_COUNT
483 };
484 
485 
486 /**
487  * \class CEngine
488  * \brief The graphics engine
489  *
490  * This is the main class for graphics engine. It is responsible for drawing the 3D scene,
491  * setting various render states, and facilitating the drawing of 2D interface.
492  *
493  * It uses a lower-level CDevice object which is implementation-independent core engine.
494  *
495  * \section Scene 3D Scene
496  *
497  * The 3D scene is drawn with view coordinates set from camera position in 3D space and
498  * a perspective projection matrix. The world matrix depends on the object drawn.
499  * The coordinate system is left-handed: X axis is to the right, Y axis to the top and Z axis
500  * is into the screen (Z = 0 is the sceen surface).
501  *
502  * In general, the 3D scene is composed of the following things:
503  *  - sky background (gradient or texture image)
504  *  - planets orbiting in the sky (drawn by CPlanet)
505  *  - terrain - ground of the game level (part of engine objects)
506  *  - main scene objects - robots, buildings, etc. (engine objects)
507  *  - water/lava (drawn by CWater)
508  *  - cloud layer (drawn by CCloud)
509  *  - fire, lightning and particle effects (CPyro, CLightning and CParticle)
510  *  - foreground image overlaid onto the scene at the end - for example, aiming crosshairs
511  *  - 2D interface controls available in-game
512  *  - mouse cursor
513  *  - animated highlight box of the selected object(s)
514  *
515  * \section Interface 2D Interface
516  *
517  * The 2D interface is drawn in fixed XY coordinates, independent from window size.
518  * Lower-left corner of the screen is (0,0) and upper-right corner is (1,1).
519  * Matrices for world, view and projection are therefore fixed and never change.
520  *
521  * The class tracks the change of window coordinates and conversion functions
522  * between the window and interface coordinates are provided.
523  *
524  * Interface drawing is delegated to CInterface class and particular controls
525  * are instances of CControl class. The source code for these classes is in
526  * src/ui directory.
527  *
528  * \section Objects Engine Objects
529  *
530  * The 3D scene is composed of objects which are basically collections of triangles forming
531  * a surface or simply independent triangles in space.
532  *
533  * Objects are uniquely identified by object rank obtained at object creation. Creating an
534  * object equals to allocating space for EngineObject structure which holds object parameters.
535  *
536  * Object's geometric data is stored as a separate object -- base engine object. Each object
537  * must reference a valid base engine object or an empty base engine object (with rank = -1).
538  * This many-to-one association allows to share same geometric data (e.g. from same model)
539  * across objects.
540  *
541  * Base engine object data is stored in a 4-tier tree which splits the data describing triangles.
542  *
543  * The 4 tiers contain the following information:
544  *  - level 1 (EngineBaseObject) - geometric statistics
545  *  - level 2 (EngineBaseObjTexTier) - two textures (names and structs) applied to triangles,
546  *  - level 3 (EngineBaseObjDataTier) - type of object*, material, render state and the actual vertex data
547  *
548  *  *NOTE: type of object in this context means only the internal type in 3D engine. It is not related
549  *  to CObject types.
550  *
551  * Last tier containing vertex data contains also an ID of static buffer holding the data.
552  * The static buffer is created and updated with new data as needed.
553  *
554  * Such tiered structure complicates loops over all object data, but saves a lot of memory and
555  * optimizes the rendering process.
556  *
557  * \section Shadows Shadows
558  *
559  * Each engine object can be associated with a shadow (EngineShadow). Like objects, shadows are
560  * identified by their rank obtained upon creation.
561  *
562  * Shadows are drawn as circular spots on the ground, except for shadows for worms, which have
563  * special mode for them.
564  *
565  * \section RenderStates Render States
566  *
567  * Almost every primitive drawn on screen is drawn in state set through EngineRenderState enum.
568  * In some functions, custom modes are still set, using CDevice's SetRenderState. However, it
569  * will be subject to removal in the future. Generally, setting render states should be minimized
570  * to avoid unnecessary overhead.
571  *
572  * Some states are clearly the result of legacy drawing and texturing methods. For example, TTEXTURE
573  * states should really be removed and the textures changed to ones with alpha channel. In the future,
574  * the whole modesetting code will probably be refactored to something more maintainable.
575  *
576  * \section Textures Textures
577  *
578  * Textures are loaded from a texture subdir in data directory. In the old code, textures were identified
579  * by file name and loaded using some D3D util code. With new code and OpenGL backend, this approach is not
580  * efficient - name comparison, etc. takes a lot of time. In the future, textures should be loaded once
581  * at object creation time, and then referenced to as Texture structs, or even as unsigned int ID's
582  * which is what OpenGL actually wants. The old method is kept for now, with mapping between texture names
583  * and texture structs but it will also be subject to refactoring in the future.
584  */
585 class CEngine : public CSingleton<CEngine>
586 {
587 public:
588     CEngine(CApplication* app, CSystemUtils* systemUtils);
589     ~CEngine();
590 
591     //! Sets the device to be used
592     void            SetDevice(CDevice* device);
593     //! Returns the current device
594     CDevice*        GetDevice();
595 
596     //! Returns the text rendering engine
597     CText*          GetText();
598     COldModelManager* GetModelManager();
599     CPyroManager*   GetPyroManager();
600     //! Returns the light manager
601     CLightManager*  GetLightManager();
602     //! Returns the particle manager
603     CParticle*      GetParticle();
604     //! Returns the terrain manager
605     CTerrain*       GetTerrain();
606     //! Returns the water manager
607     CWater*         GetWater();
608     //! Returns the lighting manager
609     CLightning*     GetLightning();
610     //! Returns the planet manager
611     CPlanet*        GetPlanet();
612     //! Returns the fog manager
613     CCloud*         GetCloud();
614 
615     //! Sets the terrain object
616     void            SetTerrain(CTerrain* terrain);
617 
618 
619     //! Performs the initialization; must be called after device was set
620     bool            Create();
621     //! Frees all resources before exit
622     void            Destroy();
623 
624 
625     //! Called once per frame, the call is the entry point for rendering
626     void            Render();
627 
628 
629     //! Processes incoming event
630     bool            ProcessEvent(const Event& event);
631 
632     //! Called once per frame, the call is the entry point for animating the scene
633     void            FrameUpdate();
634 
635 
636     //! Writes a screenshot containing the current frame
637     void            WriteScreenShot(const std::string& fileName);
638 
639 
640     //@{
641     //! Management of animation pause mode
642     void            SetPause(bool pause);
643     bool            GetPause();
644     //@}
645 
646     //@{
647     //! Management of displaying statistic information
648     void            SetShowStats(bool show);
649     bool            GetShowStats();
650     //@}
651 
652     //! Enables/disables rendering
653     void            SetRenderEnable(bool enable);
654 
655     void            SetRenderInterface(bool enable);
656     bool            GetRenderInterface();
657 
658     //! Management of "screenshot mode" (disables interface particle rendering)
659     //@{
660     void            SetScreenshotMode(bool screenshotMode);
661     bool            GetScreenshotMode();
662     //@}
663 
664     //! Returns current size of viewport window
665     Math::IntPoint   GetWindowSize();
666 
667     //@{
668     //! Conversion functions between window and interface coordinates
669     /** Window coordinates are from top-left (0,0) to bottom-right (w,h) - size of window
670         Interface cords are from bottom-left (0,0) to top-right (1,1) - and do not depend on window size */
671     Math::Point     WindowToInterfaceCoords(Math::IntPoint pos);
672     Math::IntPoint  InterfaceToWindowCoords(Math::Point pos);
673     //@}
674 
675     //@{
676     //! Conversion functions between window and interface sizes
677     /** Unlike coordinate conversions, this is only scale conversion, not translation and scale. */
678     Math::Point      WindowToInterfaceSize(Math::IntPoint size);
679     Math::IntPoint   InterfaceToWindowSize(Math::Point size);
680     //@}
681 
682     //! Increments the triangle counter for the current frame
683     void            AddStatisticTriangle(int count);
684     //! Returns the number of triangles in current frame
685     int             GetStatisticTriangle();
686 
687     //! Sets the coordinates to display in stats window
688     void            SetStatisticPos(Math::Vector pos);
689 
690     //! Sets text to display as mission timer
691     void            SetTimerDisplay(const std::string& text);
692 
693 
694     /* *************** New mesh interface *************** */
695     //! Add new instance of static mesh
696     /**
697      * Static meshes never change their geometry or texture mapping,
698      * so specific instances can share mesh data.
699      *
700      * @param mesh mesh data
701      * @param key key unique per object class
702      * @return mesh instance handle
703      */
704     int AddStaticMesh(const std::string& key, const Gfx::CModelMesh* mesh, const Math::Matrix& worldMatrix);
705 
706     //! Removes given static mesh
707     void DeleteStaticMesh(int meshHandle);
708 
709     //! Adds a shadow spot to mesh
710     void AddStaticMeshShadowSpot(int meshHandle, const Gfx::ModelShadowSpot& shadowSpot);
711 
712     //! Returns static mesh world matrix
713     const Math::Matrix& GetStaticMeshWorldMatrix(int meshHandle);
714 
715     //! Sets transparency for static mesh
716     void SetStaticMeshTransparency(int meshHandle, float value);
717 
718 
719     /* *************** Object management *************** */
720 
721     // Base objects
722 
723     //! Creates a base object and returns its rank
724     int             CreateBaseObject();
725     //! Deletes a base object
726     void            DeleteBaseObject(int baseObjRank);
727     //! Deletes all base objects
728     void            DeleteAllBaseObjects();
729 
730     //! Copies geometry between two base objects
731     void            CopyBaseObject(int sourceBaseObjRank, int destBaseObjRank);
732 
733     //! Adds triangles to given object with the specified params
734     void AddBaseObjTriangles(int baseObjRank, const std::vector<Gfx::ModelTriangle>& triangles);
735 
736     //! Adds a tier 4 engine object directly
737     void            AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer,
738                                     std::string tex1Name, std::string tex2Name,
739                                     bool globalUpdate);
740 
741     // Objects
742 
743     //! Print debug info about an object
744     void            DebugObject(int objRank);
745 
746     //! Creates a new object and returns its rank
747     int             CreateObject();
748     //! Deletes all objects, shadows and ground spots
749     void            DeleteAllObjects();
750     //! Deletes the given object
751     void            DeleteObject(int objRank);
752 
753     //@{
754     //! Management of the base object rank for engine object
755     void            SetObjectBaseRank(int objRank, int baseObjRank);
756     int             GetObjectBaseRank(int objRank);
757     //@}
758 
759     //@{
760     //! Management of engine object type
761     void            SetObjectType(int objRank, EngineObjectType type);
762     EngineObjectType GetObjectType(int objRank);
763     //@}
764 
765     //@{
766     //! Management of object transform
767     void            SetObjectTransform(int objRank, const Math::Matrix& transform);
768     void            GetObjectTransform(int objRank, Math::Matrix& transform);
769     //@}
770 
771     //! Sets drawWorld for given object
772     void            SetObjectDrawWorld(int objRank, bool draw);
773     //! Sets drawFront for given object
774     void            SetObjectDrawFront(int objRank, bool draw);
775 
776     //! Sets the transparency level for given object
777     void            SetObjectTransparency(int objRank, float value);
778 
779     //! Returns the bounding box for an object
780     void            GetObjectBBox(int objRank, Math::Vector& min, Math::Vector& max);
781 
782     //! Returns the total number of triangles of given object
783     int             GetObjectTotalTriangles(int objRank);
784 
785     //! Returns the first found tier 4 engine object for the given params or nullptr if not found
786     EngineBaseObjDataTier* FindTriangles(int objRank, const Material& material,
787                                          int state, std::string tex1Name, std::string tex2Name);
788 
789     //! Returns a partial list of triangles for given object
790     int             GetPartialTriangles(int objRank, float percent, int maxCount,
791                                         std::vector<EngineTriangle>& triangles);
792 
793     //! Changes the 2nd texure for given object
794     void            ChangeSecondTexture(int objRank, const std::string& tex2Name);
795 
796     //! Changes (recalculates) texture mapping for given object
797     void            ChangeTextureMapping(int objRank, const Material& mat, int state,
798                                          const std::string& tex1Name, const std::string& tex2Name,
799                                          EngineTextureMapping mode,
800                                          float au, float bu, float av, float bv);
801 
802     //! Changes texture mapping for robot tracks
803     void            TrackTextureMapping(int objRank, const Material& mat, int state,
804                                         const std::string& tex1Name, const std::string& tex2Name,
805                                         EngineTextureMapping mode,
806                                         float pos, float factor, float tl, float ts, float tt);
807 
808     //! Detects the target object that is selected with the mouse
809     /** Returns the rank of the object or -1. */
810     int             DetectObject(Math::Point mouse, Math::Vector& targetPos, bool terrain = false);
811 
812     //! Creates a shadow for the given object
813     void            CreateShadowSpot(int objRank);
814     //! Deletes the shadow for given object
815     void            DeleteShadowSpot(int objRank);
816 
817     //@{
818     //! Management of different shadow params
819     void            SetObjectShadowSpotHide(int objRank, bool hide);
820     void            SetObjectShadowSpotType(int objRank, EngineShadowType type);
821     void            SetObjectShadowSpotPos(int objRank, const Math::Vector& pos);
822     void            SetObjectShadowSpotAngle(int objRank, float angle);
823     void            SetObjectShadowSpotRadius(int objRank, float radius);
824     void            SetObjectShadowSpotIntensity(int objRank, float intensity);
825     void            SetObjectShadowSpotHeight(int objRank, float height);
826     void            UpdateObjectShadowSpotNormal(int objRank);
827     //@}
828 
829     //! Lists the ranks of objects and subobjects selected
830     void            SetHighlightRank(int* rankList);
831     //! Returns the highlighted rectangle
832     bool            GetHighlight(Math::Point& p1, Math::Point& p2);
833 
834     //! Deletes all ground spots
835     void            DeleteAllGroundSpots();
836     //! Creates a new ground spot and returns its rank
837     int             CreateGroundSpot();
838     //! Deletes the given ground spot
839     void            DeleteGroundSpot(int rank);
840 
841     //@{
842     //! Management of different ground spot params
843     void            SetObjectGroundSpotPos(int rank, const Math::Vector& pos);
844     void            SetObjectGroundSpotRadius(int rank, float radius);
845     void            SetObjectGroundSpotColor(int rank, const Color& color);
846     void            SetObjectGroundSpotMinMax(int rank, float min, float max);
847     void            SetObjectGroundSpotSmooth(int rank, float smooth);
848     //@}
849 
850     //! Creates the ground mark with the given params
851     void            CreateGroundMark(Math::Vector pos, float radius,
852                                      float delay1, float delay2, float delay3,
853                                      int dx, int dy, char* table);
854     //! Deletes the ground mark
855     void            DeleteGroundMark(int rank);
856 
857     //! Updates the state after creating objects
858     void            Update();
859 
860 
861     /* *************** Mode setting *************** */
862 
863     //! Sets the current rendering state
864     void            SetState(int state, const Color& color = Color(1.0f, 1.0f, 1.0f, 1.0f));
865 
866     //! Sets the current material
867     void            SetMaterial(const Material& mat);
868 
869     //! Specifies the location and direction of view
870     void SetViewParams(const Math::Vector &eyePt, const Math::Vector &lookatPt, const Math::Vector &upVec);
871 
872     //! Updates the textures used for drawing ground spot
873     void        UpdateGroundSpotTextures();
874 
875     //! Loads texture, creating it if not already present
876     Texture         LoadTexture(const std::string& name);
877     //! Loads texture from existing image
878     Texture         LoadTexture(const std::string& name, CImage* image);
879     //! Loads texture, creating it with given params if not already present
880     Texture         LoadTexture(const std::string& name, const TextureCreateParams& params);
881     //! Loads all necessary textures
882     bool            LoadAllTextures();
883 
884     //! Changes colors in a texture
885     //@{
886     bool            ChangeTextureColor(const std::string& texName,
887                                        const std::string& srcName,
888                                        Color colorRef1, Color colorNew1,
889                                        Color colorRef2, Color colorNew2,
890                                        float tolerance1, float tolerance2,
891                                        Math::Point ts, Math::Point ti,
892                                        Math::Point *exclude = nullptr,
893                                        float shift = 0.0f, bool hsv = false);
894     bool            ChangeTextureColor(const std::string& texName,
895                                        Color colorRef1, Color colorNew1,
896                                        Color colorRef2, Color colorNew2,
897                                        float tolerance1, float tolerance2,
898                                        Math::Point ts, Math::Point ti,
899                                        Math::Point *exclude = nullptr,
900                                        float shift = 0.0f, bool hsv = false);
901     //@}
902 
903     //! Sets texture for given stage; if not present in cache, the texture is loaded
904     /** If loading fails, returns false. */
905     bool            SetTexture(const std::string& name, int stage = 0);
906     //! Sets texture for given stage
907     void            SetTexture(const Texture& tex, int stage = 0);
908 
909     //! Deletes the given texture, unloading it and removing from cache
910     void            DeleteTexture(const std::string& texName);
911     //! Deletes the given texture, unloading it and removing from cache
912     void            DeleteTexture(const Texture& tex);
913 
914     //! Creates or updates the given texture with given image data
915     void            CreateOrUpdateTexture(const std::string& texName, CImage* img);
916 
917     //! Empties the texture cache
918     void            FlushTextureCache();
919 
920     //! Defines of the distance field of vision
921     void            SetTerrainVision(float vision);
922 
923     //@{
924     //! Management of camera vertical field-of-view angle.
925     /** This is specified in radians.
926     Horizontal FoV is calculated based on vertical FoV and aspect ratio.
927     0.75 = normal
928     1.50 = wide-angle */
929     void            SetFocus(float focus);
930     //! Deprecated alias for GetVFovAngle
931     float           GetFocus();
932     float           GetVFovAngle();
933     float           GetHFovAngle();
934     //@}
935 
936     //@{
937     //! Management of the global mode of contamination
938     // NOTE: This is an user configuration setting
939     void            SetDirty(bool mode);
940     bool            GetDirty();
941     //@}
942 
943     //@{
944     //! Management of the global mode of horizontal fog patches
945     // NOTE: This is an user configuration setting
946     void            SetFog(bool mode);
947     bool            GetFog();
948     //@}
949 
950     //@{
951     //! Management of the global mode of secondary texturing
952     void            SetSecondTexture(const std::string& texNum);
953     const std::string& GetSecondTexture();
954     //@}
955 
956     //@{
957     //! Management of view mode
958     void            SetRankView(int rank);
959     int             GetRankView();
960     //@}
961 
962     //! Whether to draw the world
963     void            SetDrawWorld(bool draw);
964 
965     //! Whether to draw the world on the interface
966     void            SetDrawFront(bool draw);
967 
968     //@{
969     //! Ambient color management
970     void            SetAmbientColor(const Color& color, int rank = 0);
971     Color           GetAmbientColor(int rank = 0);
972     //@}
973 
974     //@{
975     //! Color management under water
976     void            SetWaterAddColor(const Color& color);
977     Color           GetWaterAddColor();
978     //@}
979 
980     //@{
981     //! Management of the fog color
982     void            SetFogColor(const Color& color, int rank = 0);
983     Color           GetFogColor(int rank = 0);
984     //@}
985 
986     //@{
987     //! Management of the depth of field.
988     /** Beyond this distance, nothing is visible.
989         Shortly (according SetFogStart), one enters the fog. */
990     void            SetDeepView(float length, int rank = 0, bool ref=false);
991     float           GetDeepView(int rank = 0);
992     //@}
993 
994 
995     //@{
996     //! Management the start of fog.
997     /** With 0.0, the fog from the point of view (fog max).
998         With 1.0, the fog from the depth of field (no fog). */
999     void            SetFogStart(float start, int rank = 0);
1000     float           GetFogStart(int rank = 0);
1001     //@}
1002 
1003     //@{
1004     //! Management of the background image to use
1005     void            SetBackground(const std::string& name, Color up = Color(), Color down = Color(),
1006                                   Color cloudUp = Color(), Color cloudDown = Color(),
1007                                   bool full = false, bool scale = false);
1008     void            GetBackground(std::string& name, Color& up, Color& down,
1009                                   Color& cloudUp, Color& cloudDown,
1010                                   bool& full, bool& scale);
1011     //@}
1012 
1013     //! Specifies the name of foreground texture
1014     void            SetForegroundName(const std::string& name);
1015     //! Specifies whether to draw the foreground
1016     void            SetOverFront(bool front);
1017     //! Sets the foreground overlay color
1018     void            SetOverColor(const Color& color = Color(), int mode = ENG_RSTATE_TCOLOR_BLACK);
1019 
1020     //@{
1021     //! Management of the particle density
1022     // NOTE: This is an user configuration setting
1023     void            SetParticleDensity(float value);
1024     float           GetParticleDensity();
1025     //@}
1026 
1027     //! Adapts particle factor according to particle density
1028     float           ParticleAdapt(float factor);
1029 
1030     //@{
1031     //! Management of the distance of clipping.
1032     // NOTE: This is an user configuration setting
1033     void            SetClippingDistance(float value);
1034     float           GetClippingDistance();
1035     //@}
1036 
1037     //@{
1038     //! Management the texture filter mode
1039     // NOTE: This is an user configuration setting
1040     void            SetTextureFilterMode(TexFilter value);
1041     TexFilter       GetTextureFilterMode();
1042     //@}
1043 
1044     //@{
1045     //! Management the mipmap level for textures
1046     // NOTE: This is an user configuration setting
1047     void            SetTextureMipmapLevel(int value);
1048     int             GetTextureMipmapLevel();
1049     //@}
1050 
1051     //@{
1052     //! Management the anisotropy level for textures
1053     // NOTE: This is an user configuration setting
1054     void            SetTextureAnisotropyLevel(int value);
1055     int             GetTextureAnisotropyLevel();
1056     //@}
1057 
1058     //@{
1059     //! Management of shadow mapping
1060     // NOTE: These are user configuration settings
1061     bool            IsShadowMappingSupported();
1062     void            SetShadowMapping(bool value);
1063     bool            GetShadowMapping();
1064     void            SetShadowMappingOffscreen(bool value);
1065     bool            GetShadowMappingOffscreen();
1066     void            SetShadowMappingOffscreenResolution(int resolution);
1067     int             GetShadowMappingOffscreenResolution();
1068     bool            IsShadowMappingQualitySupported();
1069     void            SetShadowMappingQuality(bool value);
1070     bool            GetShadowMappingQuality();
1071     void            SetTerrainShadows(bool value);
1072     bool            GetTerrainShadows();
1073     //@}
1074 
1075     //@{
1076     //! Management of vertical synchronization
1077     // NOTE: This is an user configuration setting
1078     void            SetVSync(int value);
1079     int             GetVSync();
1080     //@}
1081 
1082     //@{
1083     //! Management of shadow color
1084     // NOTE: This is a setting configurable only in INI file
1085     void            SetShadowColor(float value);
1086     float           GetShadowColor();
1087     //@}
1088 
1089     //@{
1090     //! Management of shadow range
1091     // NOTE: This is a setting configurable only in INI file
1092     void            SetShadowRange(float value);
1093     float           GetShadowRange();
1094     //@}
1095 
1096     //@{
1097     //! Management of shadow range
1098     // NOTE: This is an user configuration setting
1099     void            SetMultiSample(int value);
1100     int             GetMultiSample();
1101     //@}
1102 
1103     //@{
1104     //! Management the mode of background
1105     void            SetBackForce(bool present);
1106     bool            GetBackForce();
1107     //@}
1108 
1109     //@{
1110     //! Managing the mode of dynamic lights.
1111     // NOTE: This is an user configuration setting
1112     void            SetLightMode(bool present);
1113     bool            GetLightMode();
1114     //@}
1115 
1116     //@{
1117     //! Management of the indentation mode while editing (CEdit)
1118     // NOTE: This is an user configuration setting
1119     // TODO: Move to CSettings
1120     void            SetEditIndentMode(bool autoIndent);
1121     bool            GetEditIndentMode();
1122     //@}
1123 
1124     //@{
1125     //! Management of tab indent when editing (CEdit)
1126     // NOTE: This is an user configuration setting
1127     // TODO: Move to CSettings
1128     void            SetEditIndentValue(int value);
1129     int             GetEditIndentValue();
1130     //@}
1131 
1132     //@{
1133     //! Management of precision of robot tracks
1134     void            SetTracePrecision(float factor);
1135     float           GetTracePrecision();
1136     //@}
1137 
1138     //@{
1139     //! Management of mouse cursor type
1140     void            SetMouseType(EngineMouseType type);
1141     EngineMouseType GetMouseType();
1142     //@}
1143 
1144     //@{
1145     //! Management of pause blur
1146     void            SetPauseBlurEnabled(bool enable);
1147     bool            GetPauseBlurEnabled();
1148     //@}
1149 
1150     //! Returns the view matrix
1151     const Math::Matrix& GetMatView();
1152     //! Returns the projection matrix
1153     const Math::Matrix& GetMatProj();
1154     //! Returns the camera center point
1155     TEST_VIRTUAL Math::Vector GetEyePt();
1156     //! Returns the camera target point
1157     TEST_VIRTUAL Math::Vector GetLookatPt();
1158     //! Returns the horizontal direction angle of view
1159     float           GetEyeDirH();
1160     //! Returns the vertical direction angle of view
1161     float           GetEyeDirV();
1162     //! Indicates whether a point is visible
1163     bool            IsVisiblePoint(const Math::Vector& pos);
1164 
1165     //! Resets the projection matrix after changes
1166     void            UpdateMatProj();
1167 
1168     //! Updates the scene after a change of parameters
1169     void            ApplyChange();
1170 
1171     void            RenderDebugSphere(const Math::Sphere&, const Math::Matrix& transform = Math::Matrix{}, const Color& = Color{0.0f, 0.0f, 1.0f, 1.0f});
1172     void            RenderDebugBox(const Math::Vector& mins, const Math::Vector& maxs, const Math::Matrix& transform = Math::Matrix{}, const Color& = Color{0.0f, 0.0f, 1.0f, 1.0f});
1173 
1174     void            SetDebugLights(bool debugLights);
1175     bool            GetDebugLights();
1176     void            DebugDumpLights();
1177 
1178     void            SetDebugResources(bool debugResources);
1179     bool            GetDebugResources();
1180 
1181     void            SetDebugGoto(bool debugGoto);
1182     bool            GetDebugGoto();
1183     void            AddDebugGotoLine(std::vector<Gfx::VertexCol> line);
1184     void            SetDebugGotoBitmap(std::unique_ptr<CImage> debugImage);
1185 
1186     void            SetWindowCoordinates();
1187     void            SetInterfaceCoordinates();
1188 
1189     void            EnablePauseBlur();
1190     void            DisablePauseBlur();
1191 
1192     //! Reloads all textures
1193     /** This additionally sends EVENT_RELOAD_TEXTURES to reload all textures not maintained by CEngine **/
1194     void ReloadAllTextures();
1195 
1196 protected:
1197     //! Resets some states and flushes textures after device was changed (e.g. resoulution changed)
1198     /** Instead of calling this directly, send EVENT_RESOLUTION_CHANGED event **/
1199     void            ResetAfterVideoConfigChanged();
1200 
1201     //! Prepares the interface for 3D scene
1202     void        Draw3DScene();
1203     //! Capture the 3D scene for pause blur
1204     void        Capture3DScene();
1205     //! Draw the 3D scene capured for pause blur
1206     void        DrawCaptured3DScene();
1207     //! Renders shadow map
1208     void        RenderShadowMap();
1209     //! Enables or disables shadow mapping
1210     void        UseShadowMapping(bool enable);
1211     //! Enables or disables MSAA
1212     void        UseMSAA(bool enable);
1213     //! Draw 3D object
1214     void        DrawObject(const EngineBaseObjDataTier& p4);
1215     //! Draws the user interface over the scene
1216     void        DrawInterface();
1217 
1218     //! Draws old-style shadow spots
1219     void        DrawShadowSpots();
1220     //! Draws the gradient background
1221     void        DrawBackground();
1222     //! Draws the gradient background
1223     void        DrawBackgroundGradient(const Color& up, const Color& down);
1224     //! Draws the image background
1225     void        DrawBackgroundImage();
1226     //! Draws all the planets
1227     void        DrawPlanet();
1228     //! Draws the image foreground
1229     void        DrawForegroundImage();
1230     //! Draws the foreground color
1231     void        DrawOverColor();
1232     //! Draws the rectangle of the object highlighted
1233     void        DrawHighlight();
1234     //! Draws the mouse cursor
1235     void        DrawMouse();
1236     //! Draw part of mouse cursor sprite
1237     void        DrawMouseSprite(Math::IntPoint pos, Math::IntPoint size, int icon);
1238     //! Draw statistic texts
1239     void        DrawStats();
1240     //! Draw mission timer
1241     void        DrawTimer();
1242     void        RenderPendingDebugDraws();
1243 
1244     //! Creates a new tier 2 object (texture)
1245     EngineBaseObjTexTier&  AddLevel2(EngineBaseObject& p1, const std::string& tex1Name, const std::string& tex2Name);
1246     //! Creates a new tier 3 object (data)
1247     EngineBaseObjDataTier& AddLevel3(EngineBaseObjTexTier &p3, EngineTriangleType type,
1248                                      const Material& material, int state);
1249 
1250     //! Create texture and add it to cache
1251     Texture CreateTexture(const std::string &texName, const TextureCreateParams &params, CImage* image = nullptr);
1252 
1253     //! Tests whether the given object is visible
1254     bool        IsVisible(int objRank);
1255 
1256     //! Detects whether an object is affected by the mouse
1257     bool        DetectBBox(int objRank, Math::Point mouse);
1258 
1259     //! Compute and return the 2D box on screen of any object
1260     bool        GetBBox2D(int objRank, Math::Point& min, Math::Point& max);
1261 
1262     //! Detects whether the mouse is in a triangle.
1263     bool        DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRank, float& dist, Math::Vector& pos);
1264 
1265     //! Transforms a 3D point (x, y, z) in 2D space (x, y, -) of the window
1266     /** The coordinated p2D.z gives the distance. */
1267     bool        TransformPoint(Math::Vector& p2D, int objRank, Math::Vector p3D);
1268 
1269     //! Calculates the distances between the viewpoint and the origin of different objects
1270     void        ComputeDistance();
1271 
1272     //! Updates geometric parameters of objects (bounding box and radius)
1273     void        UpdateGeometry();
1274 
1275     //! Updates a given static buffer
1276     void        UpdateStaticBuffer(EngineBaseObjDataTier& p4);
1277 
1278     //! Updates static buffers of changed objects
1279     void        UpdateStaticBuffers();
1280 
1281     void            AddBaseObjTriangles(int baseObjRank, const std::vector<VertexTex2>& vertices,
1282                                         const Material& material, int state,
1283                                         std::string tex1Name, std::string tex2Name);
1284 
1285     int GetEngineState(const ModelTriangle& triangle);
1286 
1287     struct WriteScreenShotData
1288     {
1289         std::unique_ptr<CImage> img;
1290         std::string fileName;
1291     };
1292     static void WriteScreenShotThread(std::unique_ptr<WriteScreenShotData> data);
1293 
1294 protected:
1295     CApplication*     m_app;
1296     CSystemUtils*     m_systemUtils;
1297     CSoundInterface*  m_sound;
1298     CDevice*          m_device;
1299     CTerrain*         m_terrain;
1300     std::unique_ptr<COldModelManager> m_modelManager;
1301     std::unique_ptr<CText>            m_text;
1302     std::unique_ptr<CLightManager>    m_lightMan;
1303     std::unique_ptr<CParticle>        m_particle;
1304     std::unique_ptr<CWater>           m_water;
1305     std::unique_ptr<CCloud>           m_cloud;
1306     std::unique_ptr<CLightning>       m_lightning;
1307     std::unique_ptr<CPlanet>          m_planet;
1308     std::unique_ptr<CPyroManager> m_pyroManager;
1309 
1310     //! Last encountered error
1311     std::string     m_error;
1312 
1313     SystemTimeStamp* m_lastFrameTime;
1314     SystemTimeStamp* m_currentFrameTime;
1315     int             m_fpsCounter;
1316     float           m_fps;
1317 
1318     //! Whether to show stats (FPS, etc)
1319     bool            m_showStats;
1320     //! Rendering enabled?
1321     bool            m_render;
1322     //! Render / hide the UI?
1323     bool            m_renderInterface;
1324 
1325     //! Screenshot mode?
1326     bool            m_screenshotMode;
1327 
1328     //! Projection matrix for 3D scene
1329     Math::Matrix    m_matProj;
1330     //! View matrix for 3D scene
1331     Math::Matrix    m_matView;
1332     //! Camera vertical field-of-view angle for 3D scene. A.k.a. m_vfov
1333     float           m_focus;
1334     //! Horizontal field-of-view angle, calculated from vertical FOV and aspect ratio
1335     float           m_hfov;
1336 
1337     //! Projection matrix for rendering shadow maps
1338     Math::Matrix    m_shadowProjMat;
1339     //! View matrix for rendering shadow maps
1340     Math::Matrix    m_shadowViewMat;
1341     //! Texture matrix for rendering shadow maps
1342     Math::Matrix    m_shadowTextureMat;
1343     //! Texture bias for sampling shadow maps
1344     Math::Matrix    m_shadowBias;
1345 
1346     //! Vertical synchronization controll
1347     int m_vsync;
1348 
1349     //! World matrix for 2D interface
1350     Math::Matrix    m_matWorldInterface;
1351     //! Projection matrix for 2D interface
1352     Math::Matrix    m_matProjInterface;
1353     //! View matrix for 2D interface
1354     Math::Matrix    m_matViewInterface;
1355 
1356     //! Current size of viewport window
1357     Math::IntPoint   m_size;
1358 
1359     //! Base objects (also level 1 tier list)
1360     std::vector<EngineBaseObject> m_baseObjects;
1361     //! Object parameters
1362     std::vector<EngineObject>     m_objects;
1363     //! Shadow list
1364     std::vector<EngineShadow>     m_shadowSpots;
1365     //! Ground spot list
1366     std::vector<EngineGroundSpot> m_groundSpots;
1367     //! Ground mark
1368     EngineGroundMark              m_groundMark;
1369 
1370     //! Location of camera
1371     Math::Vector    m_eyePt;
1372     //! Camera target
1373     Math::Vector    m_lookatPt;
1374     float           m_eyeDirH;
1375     float           m_eyeDirV;
1376     int             m_rankView;
1377     Color           m_ambientColor[2];
1378     Color           m_backColor[2];
1379     Color           m_fogColor[2];
1380     float           m_deepView[2];
1381     float           m_fogStart[2];
1382     Color           m_waterAddColor;
1383     int             m_statisticTriangle;
1384     Math::Vector    m_statisticPos;
1385     bool            m_updateGeometry;
1386     bool            m_updateStaticBuffers;
1387     bool            m_firstGroundSpot;
1388     std::string     m_secondTex;
1389     bool            m_backgroundFull;
1390     bool            m_backgroundScale;
1391     std::string     m_backgroundName;
1392     Texture         m_backgroundTex;
1393     Color           m_backgroundColorUp;
1394     Color           m_backgroundColorDown;
1395     Color           m_backgroundCloudUp;
1396     Color           m_backgroundCloudDown;
1397     bool            m_overFront;
1398     Color           m_overColor;
1399     int             m_overMode;
1400     std::string     m_foregroundName;
1401     Texture         m_foregroundTex;
1402     bool            m_drawWorld;
1403     bool            m_drawFront;
1404     float           m_terrainVision;
1405     bool            m_backForce;
1406     float           m_tracePrecision;
1407     bool            m_pauseBlurEnabled;
1408 
1409     bool            m_dirty;
1410     bool            m_fog;
1411     float           m_particleDensity;
1412     float           m_clippingDistance;
1413     bool            m_lightMode;
1414     bool            m_editIndentMode;
1415     int             m_editIndentValue;
1416 
1417     Texture         m_shadowMap;
1418 
1419     struct PendingDebugDraw
1420     {
1421         std::vector<VertexCol> vertices;
1422         std::vector<int> firsts;
1423         std::vector<int> counts;
1424     }
1425     m_pendingDebugDraws;
1426 
1427     //! Ranks of highlighted objects
1428     int             m_highlightRank[100];
1429     //! Highlight visible?
1430     bool            m_highlight;
1431     //! Time counter for highlight animation
1432     float           m_highlightTime;
1433     //@{
1434     //! Highlight rectangle points
1435     Math::Point     m_highlightP1;
1436     Math::Point     m_highlightP2;
1437     //@}
1438 
1439     //! Default texture create params
1440     TextureCreateParams m_defaultTexParams;
1441     //! Create params for terrain textures
1442     TextureCreateParams m_terrainTexParams;
1443     //! Requested texture mipmap level
1444     int m_textureMipmapLevel;
1445     //! Requested texture anisotropy level
1446     int m_textureAnisotropy;
1447     //! true if shadow mapping enabled
1448     bool m_shadowMapping;
1449     //! true enables offscreen shadow rendering
1450     bool m_offscreenShadowRendering;
1451     //! Offscreen shadow rendering resolution
1452     int m_offscreenShadowRenderingResolution;
1453     //! true enables higher quality shadows
1454     bool m_qualityShadows;
1455     //! true enables casting shadows by terrain
1456     bool m_terrainShadows;
1457     //! Shadow color
1458     float m_shadowColor;
1459     //! Shadow range
1460     float m_shadowRange;
1461     //! Number of samples for multisample rendering
1462     int m_multisample;
1463 
1464     //! Map of loaded textures (by name)
1465     std::map<std::string, Texture> m_texNameMap;
1466     //! Reverse map of loaded textures (by texture)
1467     std::map<Texture, std::string> m_revTexNameMap;
1468     //! Blacklist map of textures
1469     /** Textures on this list were not successful in first loading,
1470      *  so are disabled for subsequent load calls. */
1471     std::set<std::string> m_texBlacklist;
1472 
1473     //! Texture with mouse cursors
1474     Texture         m_miceTexture;
1475     //! Type of mouse cursor
1476     EngineMouseType m_mouseType;
1477 
1478     //! Last engine render state (-1 at the beginning of frame)
1479     int             m_lastState;
1480     //! Last color set with render state
1481     Color           m_lastColor;
1482     //! Last texture names for 2 used texture stages
1483     std::string     m_lastTexture[2];
1484     //! Last material
1485     Material        m_lastMaterial;
1486 
1487     //! True when drawing 2D UI
1488     bool            m_interfaceMode;
1489 
1490     bool            m_debugLights;
1491     bool            m_debugDumpLights;
1492     bool            m_debugCrashSpheres = false;
1493     bool            m_debugResources = false;
1494     bool            m_debugGoto = false;
1495 
1496     std::string     m_timerText;
1497 
1498     std::unordered_map<std::string, int> m_staticMeshBaseObjects;
1499 
1500     std::vector<std::vector<VertexCol>> m_displayGoto;
1501     std::unique_ptr<CImage> m_displayGotoImage;
1502 
1503     //! Pause the animation updates
1504     bool            m_pause = false;
1505 
1506     //! true means that current 3D scene was captured and is not to be rendered again
1507     bool            m_worldCaptured = false;
1508     //! true means that currently rendered world is to be captured
1509     bool            m_captureWorld = false;
1510     //! Texture with captured 3D world
1511     Texture         m_capturedWorldTexture;
1512 };
1513 
1514 
1515 } // namespace Gfx
1516