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/core/device.h
22  * \brief Abstract graphics device - CDevice class and related structs/enums
23  */
24 
25 #pragma once
26 
27 #include "graphics/core/color.h"
28 #include "graphics/core/texture.h"
29 #include "graphics/core/vertex.h"
30 
31 #include "math/intpoint.h"
32 
33 #include <memory>
34 #include <string>
35 
36 
37 class CImage;
38 struct ImageData;
39 
40 namespace Math
41 {
42 struct Matrix;
43 struct Vector;
44 } // namespace Math
45 
46 
47 // Graphics module namespace
48 namespace Gfx
49 {
50 
51 class CFramebuffer;
52 struct FramebufferParams;
53 struct Light;
54 struct Material;
55 struct Vertex;
56 struct VertexCol;
57 struct VertexTex2;
58 
59 /**
60  * \struct DeviceConfig
61  * \brief General config for graphics device
62  *
63  * These settings are common window options set by SDL.
64  */
65 struct DeviceConfig
66 {
67     //! Screen size
68     Math::IntPoint size = Math::IntPoint(800, 600);
69     //! Bits per pixel
70     int bpp = 32;
71     //! Full screen
72     bool fullScreen = false;
73     //! Resizeable window
74     bool resizeable = true;
75     //! Double buffering
76     bool doubleBuf = true;
77     //! No window frame (also set with full screen)
78     bool noFrame = false;
79 
80     //! Size of red channel in bits
81     int redSize = 8;
82     //! Size of green channel in bits
83     int greenSize = 8;
84     //! Size of blue channel in bits
85     int blueSize = 8;
86     //! Size of alpha channel in bits
87     int alphaSize = 8;
88     //! Color depth in bits
89     int depthSize = 24;
90     //! Stencil depth in bits
91     int stencilSize = 8;
92 
93     //! Force hardware acceleration (video mode set will fail on lack of hw accel)
94     bool hardwareAccel = true;
95 
96     //! Loads the default values
LoadDefaultDeviceConfig97     void LoadDefault()
98     {
99         *this = DeviceConfig();
100     }
101 };
102 
103 /**
104 * \struct DeviceCapabilities
105 * \brief This structs contains various capabilities of graphics device
106 */
107 struct DeviceCapabilities
108 {
109     bool multitexturingSupported = false;
110     int maxTextures = 1;
111     int maxTextureSize = 1024;
112 
113     int maxLights = 8;
114 
115     bool shadowMappingSupported = false;
116 
117     bool framebufferSupported = false;
118     int maxRenderbufferSize = 0;
119 
120     bool anisotropySupported = false;
121     int maxAnisotropy = 1;
122 
123     bool multisamplingSupported = false;
124     int maxSamples = 1;
125 };
126 
127 /**
128  * \enum TextureUnit
129  * \brief Texture unit values for binding textures
130  *
131  * These enums should be used for indexing textures instead of raw integers.
132  */
133 enum TextureUnit
134 {
135     TEXTURE_PRIMARY = 0,
136     TEXTURE_SECONDARY = 1,
137     TEXTURE_SHADOW = 2,
138 };
139 
140 /**
141  * \enum TransformType
142  * \brief Type of transformation in rendering pipeline
143  */
144 enum TransformType
145 {
146     TRANSFORM_WORLD,
147     TRANSFORM_VIEW,
148     TRANSFORM_PROJECTION,
149     TRANSFORM_SHADOW
150 };
151 
152 /**
153  * \enum RenderState
154  * \brief Render states that can be enabled/disabled
155  */
156 enum RenderState
157 {
158     RENDER_STATE_LIGHTING,
159     RENDER_STATE_BLENDING,
160     RENDER_STATE_FOG,
161     RENDER_STATE_DEPTH_TEST,
162     RENDER_STATE_DEPTH_WRITE,
163     RENDER_STATE_ALPHA_TEST,
164     RENDER_STATE_CULLING,
165     RENDER_STATE_DEPTH_BIAS,
166     RENDER_STATE_SHADOW_MAPPING,
167 };
168 
169 /**
170 * \enum RenderMode
171 * \brief Render modes the graphics device can be in
172 */
173 enum RenderMode
174 {
175     RENDER_MODE_NORMAL,
176     RENDER_MODE_INTERFACE,
177     RENDER_MODE_SHADOW,
178 };
179 
180 /**
181  * \enum CompFunc
182  * \brief Type of function used to compare values
183  */
184 enum CompFunc
185 {
186     COMP_FUNC_NEVER,
187     COMP_FUNC_LESS,
188     COMP_FUNC_EQUAL,
189     COMP_FUNC_NOTEQUAL,
190     COMP_FUNC_LEQUAL,
191     COMP_FUNC_GREATER,
192     COMP_FUNC_GEQUAL,
193     COMP_FUNC_ALWAYS
194 };
195 
196 /**
197  * \enum BlendFunc
198  * \brief Type of blending function
199  */
200 enum BlendFunc
201 {
202     BLEND_ZERO,
203     BLEND_ONE,
204     BLEND_SRC_COLOR,
205     BLEND_INV_SRC_COLOR,
206     BLEND_DST_COLOR,
207     BLEND_INV_DST_COLOR,
208     BLEND_SRC_ALPHA,
209     BLEND_INV_SRC_ALPHA,
210     BLEND_DST_ALPHA,
211     BLEND_INV_DST_ALPHA,
212     BLEND_SRC_ALPHA_SATURATE
213 };
214 
215 /**
216  * \enum FogMode
217  * \brief Type of fog calculation function
218  */
219 enum FogMode
220 {
221     FOG_LINEAR,
222     FOG_EXP,
223     FOG_EXP2
224 };
225 
226 /**
227  * \enum CullMode
228  * \brief Culling mode for polygons
229  */
230 enum CullMode
231 {
232     //! Cull clockwise faces
233     CULL_CW,
234     //! Cull counter-clockwise faces
235     CULL_CCW
236 };
237 
238 /**
239  * \enum ShadeModel
240  * \brief Shade model used in rendering
241  */
242 enum ShadeModel
243 {
244     SHADE_FLAT,
245     SHADE_SMOOTH
246 };
247 
248 /**
249  * \enum FillMode
250  * \brief Polygon fill mode
251  */
252 enum FillMode
253 {
254     //! Draw only points
255     FILL_POINT,
256     //! Draw only lines
257     FILL_LINES,
258     //! Draw full polygons
259     FILL_POLY
260 };
261 
262 /**
263  * \enum PrimitiveType
264  * \brief Type of primitive to render
265  */
266 enum PrimitiveType
267 {
268     PRIMITIVE_POINTS,
269     PRIMITIVE_LINES,
270     PRIMITIVE_LINE_STRIP,
271     PRIMITIVE_LINE_LOOP,
272     PRIMITIVE_TRIANGLES,
273     PRIMITIVE_TRIANGLE_STRIP,
274     PRIMITIVE_TRIANGLE_FAN
275 };
276 
277 /**
278  * \enum FrustumPlane
279  * \brief Planes of frustum space
280  *
281  * Bitset of flags - can be OR'd together.
282  */
283 enum FrustumPlane
284 {
285     FRUSTUM_PLANE_LEFT   = 0x01,
286     FRUSTUM_PLANE_RIGHT  = 0x02,
287     FRUSTUM_PLANE_TOP    = 0x04,
288     FRUSTUM_PLANE_BOTTOM = 0x08,
289     FRUSTUM_PLANE_FRONT  = 0x10,
290     FRUSTUM_PLANE_BACK   = 0x20,
291     FRUSTUM_PLANE_ALL = FRUSTUM_PLANE_LEFT   | FRUSTUM_PLANE_RIGHT  |
292                         FRUSTUM_PLANE_TOP    | FRUSTUM_PLANE_BOTTOM |
293                         FRUSTUM_PLANE_FRONT  | FRUSTUM_PLANE_BACK
294 };
295 
296 /**
297  * \enum RenderTarget
298  * \brief Render targets for rendering to textures
299  */
300 enum RenderTarget
301 {
302     RENDER_TARGET_COLOR,
303     RENDER_TARGET_DEPTH,
304     RENDER_TARGET_STENCIL
305 };
306 
307 class CFrameBufferPixels
308 {
309 public:
~CFrameBufferPixels()310     virtual ~CFrameBufferPixels() {}
311 
312     virtual void* GetPixelsData() = 0;
313 };
314 
315 /**
316  * \class CDevice
317  * \brief Abstract interface of graphics device
318  *
319  * It is based on DIRECT3DDEVICE class from DirectX to make it easier to port existing code.
320  * It encapsulates the general graphics device state and provides a common interface
321  * to graphics-specific functions which will be used throughout the program,
322  * both in CEngine class and in UI classes. Note that it doesn't contain all functions from DirectX,
323  * only those that were used in old code.
324  *
325  */
326 class CDevice
327 {
328 protected:
329     std::string m_errorMessage;
330 
331     //! Capabilities of this device
332     //! Should only be changed by code in concrete device implementation
333     DeviceCapabilities m_capabilities;
334 
335 public:
~CDevice()336     virtual ~CDevice() {}
337 
338     //! Returns last error message or empty string
GetError()339     inline std::string GetError()
340     {
341         return m_errorMessage;
342     }
343 
344     //! Returns device capabilities
GetCapabilities()345     const DeviceCapabilities& GetCapabilities()
346     {
347         return m_capabilities;
348     }
349 
350     //! Provides a hook to debug graphics code (implementation-specific)
351     virtual void DebugHook() = 0;
352 
353     //! Displays light positions to aid in debuggings
354     virtual void DebugLights() = 0;
355 
356     //! Returns a name of this device
357     virtual std::string GetName() = 0;
358 
359     //! Initializes the device, setting the initial state
360     virtual bool Create() = 0;
361     //! Destroys the device, releasing every acquired resource
362     virtual void Destroy() = 0;
363 
364     //! Changes configuration
365     virtual void ConfigChanged(const DeviceConfig &newConfig) = 0;
366 
367     //! Begins drawing the 3D scene
368     virtual void BeginScene() = 0;
369     //! Ends drawing the 3D scene
370     virtual void EndScene() = 0;
371 
372     //! Clears the screen to blank
373     virtual void Clear() = 0;
374 
375     //! Sets current rendering mode
376     virtual void SetRenderMode(RenderMode mode) = 0;
377 
378     //! Sets the transform matrix of given type
379     virtual void SetTransform(TransformType type, const Math::Matrix &matrix) = 0;
380 
381     //! Sets the current material
382     virtual void SetMaterial(const Material &material) = 0;
383 
384     //! Returns the maximum number of lights available
385     virtual int GetMaxLightCount() = 0;
386     //! Sets the light at given index
387     virtual void SetLight(int index, const Light &light) = 0;
388     //! Enables/disables the light at given index
389     virtual void SetLightEnabled(int index, bool enabled) = 0;
390 
391     //! Creates a texture from image; the image can be safely removed after that
392     virtual Texture CreateTexture(CImage *image, const TextureCreateParams &params) = 0;
393     //! Creates a texture from raw image data; image data can be freed after that
394     virtual Texture CreateTexture(ImageData *data, const TextureCreateParams &params) = 0;
395     //! Creates a depth texture with specific dimensions and depth
396     virtual Texture CreateDepthTexture(int width, int height, int depth) = 0;
397     //! Updates a part of texture from raw image data
398     virtual void UpdateTexture(const Texture& texture, Math::IntPoint offset, ImageData* data, TexImgFormat format) = 0;
399     //! Deletes a given texture, freeing it from video memory
400     virtual void DestroyTexture(const Texture &texture) = 0;
401     //! Deletes all textures created so far
402     virtual void DestroyAllTextures() = 0;
403 
404     //! Returns the maximum number of multitexture stages
405     virtual int GetMaxTextureStageCount() = 0;
406     //! Sets the texture at given texture stage
407     virtual void SetTexture(int index, const Texture &texture) = 0;
408     //! Sets the texture image by ID at given texture stage
409     virtual void SetTexture(int index, unsigned int textureId) = 0;
410     //! Enables/disables the given texture stage
411     virtual void SetTextureEnabled(int index, bool enabled) = 0;
412 
413     //! Sets the params for texture stage with given index
414     virtual void SetTextureStageParams(int index, const TextureStageParams &params) = 0;
415 
416     //! Sets only the texture wrap modes (for faster than thru stage params)
417     virtual void SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wrapT) = 0;
418 
419     //! Renders primitive composed of vertices with single texture
420     virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices    , int vertexCount,
421                                Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) = 0;
422     //! Renders primitive composed of vertices with multitexturing (2 textures)
423     virtual void DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount,
424                                Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) = 0;
425     //! Renders primitive composed of vertices with solid color
426     virtual void DrawPrimitive(PrimitiveType type, const VertexCol *vertices , int vertexCount) = 0;
427 
428     //! Renders primitives composed of lists of vertices with single texture
429     virtual void DrawPrimitives(PrimitiveType type, const Vertex *vertices,
430         int first[], int count[], int drawCount,
431         Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) = 0;
432     //! Renders primitives composed of lists of vertices with multitexturing (2 textures)
433     virtual void DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
434         int first[], int count[], int drawCount,
435         Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) = 0;
436     //! Renders primitives composed of lists of vertices with solid color
437     virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
438         int first[], int count[], int drawCount) = 0;
439 
440     //! Creates a static buffer composed of given primitives with single texture vertices
441     virtual unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) = 0;
442 
443     //! Creates a static buffer composed of given primitives with multitexturing
444     virtual unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) = 0;
445 
446     //! Creates a static buffer composed of given primitives with solid color
447     virtual unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) = 0;
448 
449     //! Updates the static buffer composed of given primitives with single texture vertices
450     virtual void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) = 0;
451 
452     //! Updates the static buffer composed of given primitives with multitexturing
453     virtual void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) = 0;
454 
455     //! Updates the static buffer composed of given primitives with solid color
456     virtual void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) = 0;
457 
458     //! Draws a static buffer
459     virtual void DrawStaticBuffer(unsigned int bufferId) = 0;
460 
461     //! Deletes a static buffer
462     virtual void DestroyStaticBuffer(unsigned int bufferId) = 0;
463 
464     //! Tests whether a sphere is (partially) within the frustum volume
465     //! Returns a mask of frustum planes for which the test is positive
466     virtual int ComputeSphereVisibility(const Math::Vector &center, float radius) = 0;
467 
468     //! Changes rendering viewport
469     virtual void SetViewport(int x, int y, int width, int height) = 0;
470 
471     //! Enables/disables the given render state
472     virtual void SetRenderState(RenderState state, bool enabled) = 0;
473 
474     //! Sets the color mask
475     virtual void SetColorMask(bool red, bool green, bool blue, bool alpha) = 0;
476 
477     //! Sets the function of depth test
478     virtual void SetDepthTestFunc(CompFunc func) = 0;
479 
480     //! Sets the depth bias (constant value added to Z-coords)
481     virtual void SetDepthBias(float factor, float units) = 0;
482 
483     //! Sets the alpha test function and reference value
484     virtual void SetAlphaTestFunc(CompFunc func, float refValue) = 0;
485 
486     //! Sets the blending functions for source and destination operations
487     virtual void SetBlendFunc(BlendFunc srcBlend, BlendFunc dstBlend) = 0;
488 
489     //! Sets the clear color
490     virtual void SetClearColor(const Color &color) = 0;
491 
492     //! Sets the global ambient color
493     virtual void SetGlobalAmbient(const Color &color) = 0;
494 
495     //! Sets the fog parameters: mode, color, start distance, end distance and density (for exp models)
496     virtual void SetFogParams(FogMode mode, const Color &color, float start, float end, float density) = 0;
497 
498     //! Sets the current cull mode
499     virtual void SetCullMode(CullMode mode) = 0;
500 
501     //! Sets the shade model
502     virtual void SetShadeModel(ShadeModel model) = 0;
503 
504     //! Sets shadow color
505     virtual void SetShadowColor(float value) = 0;
506 
507     //! Sets the current fill mode
508     virtual void SetFillMode(FillMode mode) = 0;
509 
510     //! Copies content of framebuffer to texture
511     virtual void CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height) = 0;
512 
513     //! Returns the pixels of the entire screen
514     virtual std::unique_ptr<CFrameBufferPixels> GetFrameBufferPixels() const = 0;
515 
516     //! Returns framebuffer with given name or nullptr if it doesn't exist
517     virtual CFramebuffer* GetFramebuffer(std::string name) = 0;
518 
519     //! Creates new framebuffer with given name or nullptr if it's not possible
520     virtual CFramebuffer* CreateFramebuffer(std::string name, const FramebufferParams& params) = 0;
521 
522     //! Deletes framebuffer
523     virtual void DeleteFramebuffer(std::string name) = 0;
524 
525     //! Checks if anisotropy is supported
526     virtual bool IsAnisotropySupported() = 0;
527 
528     //! Returns max anisotropy level supported
529     virtual int GetMaxAnisotropyLevel() = 0;
530 
531     //! Returns max samples supported
532     virtual int GetMaxSamples() = 0;
533 
534     //! Checks if shadow mapping is supported
535     virtual bool IsShadowMappingSupported() = 0;
536 
537     //! Returns max texture size supported
538     virtual int GetMaxTextureSize() = 0;
539 
540     //! Checks if framebuffers are supported
541     virtual bool IsFramebufferSupported() = 0;
542 };
543 
544 
545 } // namespace Gfx
546