1 //
2 // Copyright (c) 2008-2017 the Urho3D project.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #pragma once
24 
25 #include "../Container/ArrayPtr.h"
26 #include "../Container/HashSet.h"
27 #include "../Core/Mutex.h"
28 #include "../Core/Object.h"
29 #include "../Graphics/GraphicsDefs.h"
30 #include "../Graphics/ShaderVariation.h"
31 #include "../Math/Color.h"
32 #include "../Math/Plane.h"
33 #include "../Math/Rect.h"
34 #include "../Resource/Image.h"
35 
36 struct SDL_Window;
37 
38 namespace Urho3D
39 {
40 
41 class ConstantBuffer;
42 class File;
43 class Image;
44 class IndexBuffer;
45 class GPUObject;
46 class GraphicsImpl;
47 class RenderSurface;
48 class Shader;
49 class ShaderPrecache;
50 class ShaderProgram;
51 class ShaderVariation;
52 class Texture;
53 class Texture2D;
54 class Texture2DArray;
55 class TextureCube;
56 class Vector3;
57 class Vector4;
58 class VertexBuffer;
59 class VertexDeclaration;
60 
61 struct ShaderParameter;
62 
63 /// CPU-side scratch buffer for vertex data updates.
64 struct ScratchBuffer
65 {
ScratchBufferScratchBuffer66     ScratchBuffer() :
67         size_(0),
68         reserved_(false)
69     {
70     }
71 
72     /// Buffer data.
73     SharedArrayPtr<unsigned char> data_;
74     /// Data size.
75     unsigned size_;
76     /// Reserved flag.
77     bool reserved_;
78 };
79 
80 /// %Graphics subsystem. Manages the application window, rendering state and GPU resources.
81 class URHO3D_API Graphics : public Object
82 {
83     URHO3D_OBJECT(Graphics, Object);
84 
85 public:
86     /// Construct.
87     Graphics(Context* context);
88     /// Destruct. Release the Direct3D11 device and close the window.
89     virtual ~Graphics();
90 
91     /// Set external window handle. Only effective before setting the initial screen mode.
92     void SetExternalWindow(void* window);
93     /// Set window title.
94     void SetWindowTitle(const String& windowTitle);
95     /// Set window icon.
96     void SetWindowIcon(Image* windowIcon);
97     /// Set window position. Sets initial position if window is not created yet.
98     void SetWindowPosition(const IntVector2& position);
99     /// Set window position. Sets initial position if window is not created yet.
100     void SetWindowPosition(int x, int y);
101     /// Set screen mode. Return true if successful.
102     bool SetMode
103         (int width, int height, bool fullscreen, bool borderless, bool resizable, bool highDPI, bool vsync, bool tripleBuffer,
104             int multiSample, int monitor, int refreshRate);
105     /// Set screen resolution only. Return true if successful.
106     bool SetMode(int width, int height);
107     /// Set whether the main window uses sRGB conversion on write.
108     void SetSRGB(bool enable);
109     /// Set whether rendering output is dithered. Default true on OpenGL. No effect on Direct3D.
110     void SetDither(bool enable);
111     /// Set whether to flush the GPU command buffer to prevent multiple frames being queued and uneven frame timesteps. Default off, may decrease performance if enabled. Not currently implemented on OpenGL.
112     void SetFlushGPU(bool enable);
113     /// Set forced use of OpenGL 2 even if OpenGL 3 is available. Must be called before setting the screen mode for the first time. Default false. No effect on Direct3D9 & 11.
114     void SetForceGL2(bool enable);
115     /// Set allowed screen orientations as a space-separated list of "LandscapeLeft", "LandscapeRight", "Portrait" and "PortraitUpsideDown". Affects currently only iOS platform.
116     void SetOrientations(const String& orientations);
117     /// Toggle between full screen and windowed mode. Return true if successful.
118     bool ToggleFullscreen();
119     /// Close the window.
120     void Close();
121     /// Take a screenshot. Return true if successful.
122     bool TakeScreenShot(Image& destImage);
123     /// Begin frame rendering. Return true if device available and can render.
124     bool BeginFrame();
125     /// End frame rendering and swap buffers.
126     void EndFrame();
127     /// Clear any or all of rendertarget, depth buffer and stencil buffer.
128     void Clear(unsigned flags, const Color& color = Color(0.0f, 0.0f, 0.0f, 0.0f), float depth = 1.0f, unsigned stencil = 0);
129     /// Resolve multisampled backbuffer to a texture rendertarget. The texture's size should match the viewport size.
130     bool ResolveToTexture(Texture2D* destination, const IntRect& viewport);
131     /// Resolve a multisampled texture on itself.
132     bool ResolveToTexture(Texture2D* texture);
133     /// Resolve a multisampled cube texture on itself.
134     bool ResolveToTexture(TextureCube* texture);
135     /// Draw non-indexed geometry.
136     void Draw(PrimitiveType type, unsigned vertexStart, unsigned vertexCount);
137     /// Draw indexed geometry.
138     void Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount);
139     /// Draw indexed geometry with vertex index offset.
140     void Draw(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex, unsigned vertexCount);
141     /// Draw indexed, instanced geometry. An instancing vertex buffer must be set.
142     void DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned minVertex, unsigned vertexCount,
143         unsigned instanceCount);
144     /// Draw indexed, instanced geometry with vertex index offset.
145     void DrawInstanced(PrimitiveType type, unsigned indexStart, unsigned indexCount, unsigned baseVertexIndex, unsigned minVertex,
146         unsigned vertexCount, unsigned instanceCount);
147     /// Set vertex buffer.
148     void SetVertexBuffer(VertexBuffer* buffer);
149     /// Set multiple vertex buffers.
150     bool SetVertexBuffers(const PODVector<VertexBuffer*>& buffers, unsigned instanceOffset = 0);
151     /// Set multiple vertex buffers.
152     bool SetVertexBuffers(const Vector<SharedPtr<VertexBuffer> >& buffers, unsigned instanceOffset = 0);
153     /// Set index buffer.
154     void SetIndexBuffer(IndexBuffer* buffer);
155     /// Set shaders.
156     void SetShaders(ShaderVariation* vs, ShaderVariation* ps);
157     /// Set shader float constants.
158     void SetShaderParameter(StringHash param, const float* data, unsigned count);
159     /// Set shader float constant.
160     void SetShaderParameter(StringHash param, float value);
161     /// Set shader integer constant.
162     void SetShaderParameter(StringHash param, int value);
163     /// Set shader boolean constant.
164     void SetShaderParameter(StringHash param, bool value);
165     /// Set shader color constant.
166     void SetShaderParameter(StringHash param, const Color& color);
167     /// Set shader 2D vector constant.
168     void SetShaderParameter(StringHash param, const Vector2& vector);
169     /// Set shader 3x3 matrix constant.
170     void SetShaderParameter(StringHash param, const Matrix3& matrix);
171     /// Set shader 3D vector constant.
172     void SetShaderParameter(StringHash param, const Vector3& vector);
173     /// Set shader 4x4 matrix constant.
174     void SetShaderParameter(StringHash param, const Matrix4& matrix);
175     /// Set shader 4D vector constant.
176     void SetShaderParameter(StringHash param, const Vector4& vector);
177     /// Set shader 3x4 matrix constant.
178     void SetShaderParameter(StringHash param, const Matrix3x4& matrix);
179     /// Set shader constant from a variant. Supported variant types: bool, float, vector2, vector3, vector4, color.
180     void SetShaderParameter(StringHash param, const Variant& value);
181     /// Check whether a shader parameter group needs update. Does not actually check whether parameters exist in the shaders.
182     bool NeedParameterUpdate(ShaderParameterGroup group, const void* source);
183     /// Check whether a shader parameter exists on the currently set shaders.
184     bool HasShaderParameter(StringHash param);
185     /// Check whether the current vertex or pixel shader uses a texture unit.
186     bool HasTextureUnit(TextureUnit unit);
187     /// Clear remembered shader parameter source group.
188     void ClearParameterSource(ShaderParameterGroup group);
189     /// Clear remembered shader parameter sources.
190     void ClearParameterSources();
191     /// Clear remembered transform shader parameter sources.
192     void ClearTransformSources();
193     /// Set texture.
194     void SetTexture(unsigned index, Texture* texture);
195     /// Bind texture unit 0 for update. Called by Texture. Used only on OpenGL.
196     void SetTextureForUpdate(Texture* texture);
197     /// Dirty texture parameters of all textures (when global settings change.)
198     void SetTextureParametersDirty();
199     /// Set default texture filtering mode. Called by Renderer before rendering.
200     void SetDefaultTextureFilterMode(TextureFilterMode mode);
201     /// Set default texture anisotropy level. Called by Renderer before rendering.
202     void SetDefaultTextureAnisotropy(unsigned level);
203     /// Reset all rendertargets, depth-stencil surface and viewport.
204     void ResetRenderTargets();
205     /// Reset specific rendertarget.
206     void ResetRenderTarget(unsigned index);
207     /// Reset depth-stencil surface.
208     void ResetDepthStencil();
209     /// Set rendertarget.
210     void SetRenderTarget(unsigned index, RenderSurface* renderTarget);
211     /// Set rendertarget.
212     void SetRenderTarget(unsigned index, Texture2D* texture);
213     /// Set depth-stencil surface.
214     void SetDepthStencil(RenderSurface* depthStencil);
215     /// Set depth-stencil surface.
216     void SetDepthStencil(Texture2D* texture);
217     /// Set viewport.
218     void SetViewport(const IntRect& rect);
219     /// Set blending and alpha-to-coverage modes. Alpha-to-coverage is not supported on Direct3D9.
220     void SetBlendMode(BlendMode mode, bool alphaToCoverage = false);
221     /// Set color write on/off.
222     void SetColorWrite(bool enable);
223     /// Set hardware culling mode.
224     void SetCullMode(CullMode mode);
225     /// Set depth bias.
226     void SetDepthBias(float constantBias, float slopeScaledBias);
227     /// Set depth compare.
228     void SetDepthTest(CompareMode mode);
229     /// Set depth write on/off.
230     void SetDepthWrite(bool enable);
231     /// Set polygon fill mode.
232     void SetFillMode(FillMode mode);
233     /// Set line antialiasing on/off.
234     void SetLineAntiAlias(bool enable);
235     /// Set scissor test.
236     void SetScissorTest(bool enable, const Rect& rect = Rect::FULL, bool borderInclusive = true);
237     /// Set scissor test.
238     void SetScissorTest(bool enable, const IntRect& rect);
239     /// Set stencil test.
240     void SetStencilTest
241         (bool enable, CompareMode mode = CMP_ALWAYS, StencilOp pass = OP_KEEP, StencilOp fail = OP_KEEP, StencilOp zFail = OP_KEEP,
242             unsigned stencilRef = 0, unsigned compareMask = M_MAX_UNSIGNED, unsigned writeMask = M_MAX_UNSIGNED);
243     /// Set a custom clipping plane. The plane is specified in world space, but is dependent on the view and projection matrices.
244     void SetClipPlane(bool enable, const Plane& clipPlane = Plane::UP, const Matrix3x4& view = Matrix3x4::IDENTITY,
245         const Matrix4& projection = Matrix4::IDENTITY);
246     /// Begin dumping shader variation names to an XML file for precaching.
247     void BeginDumpShaders(const String& fileName);
248     /// End dumping shader variations names.
249     void EndDumpShaders();
250     /// Precache shader variations from an XML file generated with BeginDumpShaders().
251     void PrecacheShaders(Deserializer& source);
252     /// Set shader cache directory, Direct3D only. This can either be an absolute path or a path within the resource system.
253     void SetShaderCacheDir(const String& path);
254 
255     /// Return whether rendering initialized.
256     bool IsInitialized() const;
257 
258     /// Return graphics implementation, which holds the actual API-specific resources.
GetImpl()259     GraphicsImpl* GetImpl() const { return impl_; }
260 
261     /// Return OS-specific external window handle. Null if not in use.
GetExternalWindow()262     void* GetExternalWindow() const { return externalWindow_; }
263 
264     /// Return SDL window.
GetWindow()265     SDL_Window* GetWindow() const { return window_; }
266 
267     /// Return window title.
GetWindowTitle()268     const String& GetWindowTitle() const { return windowTitle_; }
269 
270     /// Return graphics API name.
GetApiName()271     const String& GetApiName() const { return apiName_; }
272 
273     /// Return window position.
274     IntVector2 GetWindowPosition() const;
275 
276     /// Return window width in pixels.
GetWidth()277     int GetWidth() const { return width_; }
278 
279     /// Return window height in pixels.
GetHeight()280     int GetHeight() const { return height_; }
281 
282     /// Return multisample mode (1 = no multisampling.)
GetMultiSample()283     int GetMultiSample() const { return multiSample_; }
284 
285     /// Return window size in pixels.
GetSize()286     IntVector2 GetSize() const { return IntVector2(width_, height_); }
287 
288     /// Return whether window is fullscreen.
GetFullscreen()289     bool GetFullscreen() const { return fullscreen_; }
290 
291     /// Return whether window is borderless.
GetBorderless()292     bool GetBorderless() const { return borderless_; }
293 
294     /// Return whether window is resizable.
GetResizable()295     bool GetResizable() const { return resizable_; }
296 
297     /// Return whether window is high DPI.
GetHighDPI()298     bool GetHighDPI() const { return highDPI_; }
299 
300     /// Return whether vertical sync is on.
GetVSync()301     bool GetVSync() const { return vsync_; }
302 
303     /// Return refresh rate when using vsync in fullscreen
GetRefreshRate()304     int GetRefreshRate() const { return refreshRate_; }
305 
306     /// Return the current monitor index. Effective on in fullscreen
GetMonitor()307     int GetMonitor() const { return monitor_; }
308 
309     /// Return whether triple buffering is enabled.
GetTripleBuffer()310     bool GetTripleBuffer() const { return tripleBuffer_; }
311 
312     /// Return whether the main window is using sRGB conversion on write.
GetSRGB()313     bool GetSRGB() const { return sRGB_; }
314 
315     /// Return whether rendering output is dithered.
316     bool GetDither() const;
317 
318     /// Return whether the GPU command buffer is flushed each frame.
GetFlushGPU()319     bool GetFlushGPU() const { return flushGPU_; }
320 
321     /// Return whether OpenGL 2 use is forced. Effective only on OpenGL.
GetForceGL2()322     bool GetForceGL2() const { return forceGL2_; }
323 
324     /// Return allowed screen orientations.
GetOrientations()325     const String& GetOrientations() const { return orientations_; }
326 
327     /// Return whether graphics context is lost and can not render or load GPU resources.
328     bool IsDeviceLost() const;
329 
330     /// Return number of primitives drawn this frame.
GetNumPrimitives()331     unsigned GetNumPrimitives() const { return numPrimitives_; }
332 
333     /// Return number of batches drawn this frame.
GetNumBatches()334     unsigned GetNumBatches() const { return numBatches_; }
335 
336     /// Return dummy color texture format for shadow maps. Is "NULL" (consume no video memory) if supported.
GetDummyColorFormat()337     unsigned GetDummyColorFormat() const { return dummyColorFormat_; }
338 
339     /// Return shadow map depth texture format, or 0 if not supported.
GetShadowMapFormat()340     unsigned GetShadowMapFormat() const { return shadowMapFormat_; }
341 
342     /// Return 24-bit shadow map depth texture format, or 0 if not supported.
GetHiresShadowMapFormat()343     unsigned GetHiresShadowMapFormat() const { return hiresShadowMapFormat_; }
344 
345     /// Return whether hardware instancing is supported.
GetInstancingSupport()346     bool GetInstancingSupport() const { return instancingSupport_; }
347 
348     /// Return whether light pre-pass rendering is supported.
GetLightPrepassSupport()349     bool GetLightPrepassSupport() const { return lightPrepassSupport_; }
350 
351     /// Return whether deferred rendering is supported.
GetDeferredSupport()352     bool GetDeferredSupport() const { return deferredSupport_; }
353 
354     /// Return whether anisotropic texture filtering is supported.
GetAnisotropySupport()355     bool GetAnisotropySupport() const { return anisotropySupport_; }
356 
357     /// Return whether shadow map depth compare is done in hardware.
GetHardwareShadowSupport()358     bool GetHardwareShadowSupport() const { return hardwareShadowSupport_; }
359 
360     /// Return whether a readable hardware depth format is available.
GetReadableDepthSupport()361     bool GetReadableDepthSupport() const { return GetReadableDepthFormat() != 0; }
362 
363     /// Return whether sRGB conversion on texture sampling is supported.
GetSRGBSupport()364     bool GetSRGBSupport() const { return sRGBSupport_; }
365 
366     /// Return whether sRGB conversion on rendertarget writing is supported.
GetSRGBWriteSupport()367     bool GetSRGBWriteSupport() const { return sRGBWriteSupport_; }
368 
369     /// Return supported fullscreen resolutions (third component is refreshRate). Will be empty if listing the resolutions is not supported on the platform (e.g. Web).
370     PODVector<IntVector3> GetResolutions(int monitor) const;
371     /// Return supported multisampling levels.
372     PODVector<int> GetMultiSampleLevels() const;
373     /// Return the desktop resolution.
374     IntVector2 GetDesktopResolution(int monitor) const;
375     /// Return the number of currently connected monitors.
376     int GetMonitorCount() const;
377     /// Return hardware format for a compressed image format, or 0 if unsupported.
378     unsigned GetFormat(CompressedFormat format) const;
379     /// Return a shader variation by name and defines.
380     ShaderVariation* GetShader(ShaderType type, const String& name, const String& defines = String::EMPTY) const;
381     /// Return a shader variation by name and defines.
382     ShaderVariation* GetShader(ShaderType type, const char* name, const char* defines) const;
383     /// Return current vertex buffer by index.
384     VertexBuffer* GetVertexBuffer(unsigned index) const;
385 
386     /// Return current index buffer.
GetIndexBuffer()387     IndexBuffer* GetIndexBuffer() const { return indexBuffer_; }
388 
389     /// Return current vertex shader.
GetVertexShader()390     ShaderVariation* GetVertexShader() const { return vertexShader_; }
391 
392     /// Return current pixel shader.
GetPixelShader()393     ShaderVariation* GetPixelShader() const { return pixelShader_; }
394 
395     /// Return shader program. This is an API-specific class and should not be used by applications.
396     ShaderProgram* GetShaderProgram() const;
397 
398     /// Return texture unit index by name.
399     TextureUnit GetTextureUnit(const String& name);
400     /// Return texture unit name by index.
401     const String& GetTextureUnitName(TextureUnit unit);
402     /// Return current texture by texture unit index.
403     Texture* GetTexture(unsigned index) const;
404 
405     /// Return default texture filtering mode.
GetDefaultTextureFilterMode()406     TextureFilterMode GetDefaultTextureFilterMode() const { return defaultTextureFilterMode_; }
407 
408     /// Return default texture max. anisotropy level.
GetDefaultTextureAnisotropy()409     unsigned GetDefaultTextureAnisotropy() const { return defaultTextureAnisotropy_; }
410 
411     /// Return current rendertarget by index.
412     RenderSurface* GetRenderTarget(unsigned index) const;
413 
414     /// Return current depth-stencil surface.
GetDepthStencil()415     RenderSurface* GetDepthStencil() const { return depthStencil_; }
416 
417     /// Return the viewport coordinates.
GetViewport()418     IntRect GetViewport() const { return viewport_; }
419 
420     /// Return blending mode.
GetBlendMode()421     BlendMode GetBlendMode() const { return blendMode_; }
422 
423     /// Return whether alpha-to-coverage is enabled.
GetAlphaToCoverage()424     bool GetAlphaToCoverage() const { return alphaToCoverage_; }
425 
426     /// Return whether color write is enabled.
GetColorWrite()427     bool GetColorWrite() const { return colorWrite_; }
428 
429     /// Return hardware culling mode.
GetCullMode()430     CullMode GetCullMode() const { return cullMode_; }
431 
432     /// Return depth constant bias.
GetDepthConstantBias()433     float GetDepthConstantBias() const { return constantDepthBias_; }
434 
435     /// Return depth slope scaled bias.
GetDepthSlopeScaledBias()436     float GetDepthSlopeScaledBias() const { return slopeScaledDepthBias_; }
437 
438     /// Return depth compare mode.
GetDepthTest()439     CompareMode GetDepthTest() const { return depthTestMode_; }
440 
441     /// Return whether depth write is enabled.
GetDepthWrite()442     bool GetDepthWrite() const { return depthWrite_; }
443 
444     /// Return polygon fill mode.
GetFillMode()445     FillMode GetFillMode() const { return fillMode_; }
446 
447     /// Return whether line antialiasing is enabled.
GetLineAntiAlias()448     bool GetLineAntiAlias() const { return lineAntiAlias_; }
449 
450     /// Return whether stencil test is enabled.
GetStencilTest()451     bool GetStencilTest() const { return stencilTest_; }
452 
453     /// Return whether scissor test is enabled.
GetScissorTest()454     bool GetScissorTest() const { return scissorTest_; }
455 
456     /// Return scissor rectangle coordinates.
GetScissorRect()457     const IntRect& GetScissorRect() const { return scissorRect_; }
458 
459     /// Return stencil compare mode.
GetStencilTestMode()460     CompareMode GetStencilTestMode() const { return stencilTestMode_; }
461 
462     /// Return stencil operation to do if stencil test passes.
GetStencilPass()463     StencilOp GetStencilPass() const { return stencilPass_; }
464 
465     /// Return stencil operation to do if stencil test fails.
GetStencilFail()466     StencilOp GetStencilFail() const { return stencilFail_; }
467 
468     /// Return stencil operation to do if depth compare fails.
GetStencilZFail()469     StencilOp GetStencilZFail() const { return stencilZFail_; }
470 
471     /// Return stencil reference value.
GetStencilRef()472     unsigned GetStencilRef() const { return stencilRef_; }
473 
474     /// Return stencil compare bitmask.
GetStencilCompareMask()475     unsigned GetStencilCompareMask() const { return stencilCompareMask_; }
476 
477     /// Return stencil write bitmask.
GetStencilWriteMask()478     unsigned GetStencilWriteMask() const { return stencilWriteMask_; }
479 
480     /// Return whether a custom clipping plane is in use.
GetUseClipPlane()481     bool GetUseClipPlane() const { return useClipPlane_; }
482 
483     /// Return shader cache directory, Direct3D only.
GetShaderCacheDir()484     const String& GetShaderCacheDir() const { return shaderCacheDir_; }
485 
486     /// Return current rendertarget width and height.
487     IntVector2 GetRenderTargetDimensions() const;
488 
489     /// Window was resized through user interaction. Called by Input subsystem.
490     void OnWindowResized();
491     /// Window was moved through user interaction. Called by Input subsystem.
492     void OnWindowMoved();
493     /// Restore GPU objects and reinitialize state. Requires an open window. Used only on OpenGL.
494     void Restore();
495     /// Maximize the window.
496     void Maximize();
497     /// Minimize the window.
498     void Minimize();
499     /// Add a GPU object to keep track of. Called by GPUObject.
500     void AddGPUObject(GPUObject* object);
501     /// Remove a GPU object. Called by GPUObject.
502     void RemoveGPUObject(GPUObject* object);
503     /// Reserve a CPU-side scratch buffer.
504     void* ReserveScratchBuffer(unsigned size);
505     /// Free a CPU-side scratch buffer.
506     void FreeScratchBuffer(void* buffer);
507     /// Clean up too large scratch buffers.
508     void CleanupScratchBuffers();
509     /// Clean up shader parameters when a shader variation is released or destroyed.
510     void CleanupShaderPrograms(ShaderVariation* variation);
511     /// Clean up a render surface from all FBOs. Used only on OpenGL.
512     void CleanupRenderSurface(RenderSurface* surface);
513     /// Get or create a constant buffer. Will be shared between shaders if possible.
514     ConstantBuffer* GetOrCreateConstantBuffer(ShaderType type, unsigned index, unsigned size);
515     /// Mark the FBO needing an update. Used only on OpenGL.
516     void MarkFBODirty();
517     /// Bind a VBO, avoiding redundant operation. Used only on OpenGL.
518     void SetVBO(unsigned object);
519     /// Bind a UBO, avoiding redundant operation. Used only on OpenGL.
520     void SetUBO(unsigned object);
521 
522     /// Return the API-specific alpha texture format.
523     static unsigned GetAlphaFormat();
524     /// Return the API-specific luminance texture format.
525     static unsigned GetLuminanceFormat();
526     /// Return the API-specific luminance alpha texture format.
527     static unsigned GetLuminanceAlphaFormat();
528     /// Return the API-specific RGB texture format.
529     static unsigned GetRGBFormat();
530     /// Return the API-specific RGBA texture format.
531     static unsigned GetRGBAFormat();
532     /// Return the API-specific RGBA 16-bit texture format.
533     static unsigned GetRGBA16Format();
534     /// Return the API-specific RGBA 16-bit float texture format.
535     static unsigned GetRGBAFloat16Format();
536     /// Return the API-specific RGBA 32-bit float texture format.
537     static unsigned GetRGBAFloat32Format();
538     /// Return the API-specific RG 16-bit texture format.
539     static unsigned GetRG16Format();
540     /// Return the API-specific RG 16-bit float texture format.
541     static unsigned GetRGFloat16Format();
542     /// Return the API-specific RG 32-bit float texture format.
543     static unsigned GetRGFloat32Format();
544     /// Return the API-specific single channel 16-bit float texture format.
545     static unsigned GetFloat16Format();
546     /// Return the API-specific single channel 32-bit float texture format.
547     static unsigned GetFloat32Format();
548     /// Return the API-specific linear depth texture format.
549     static unsigned GetLinearDepthFormat();
550     /// Return the API-specific hardware depth-stencil texture format.
551     static unsigned GetDepthStencilFormat();
552     /// Return the API-specific readable hardware depth format, or 0 if not supported.
553     static unsigned GetReadableDepthFormat();
554     /// Return the API-specific texture format from a textual description, for example "rgb".
555     static unsigned GetFormat(const String& formatName);
556 
557     /// Return UV offset required for pixel perfect rendering.
GetPixelUVOffset()558     static const Vector2& GetPixelUVOffset() { return pixelUVOffset; }
559 
560     /// Return maximum number of supported bones for skinning.
561     static unsigned GetMaxBones();
562     /// Return whether is using an OpenGL 3 context. Return always false on Direct3D9 & Direct3D11.
563     static bool GetGL3Support();
564 
565 private:
566     /// Create the application window.
567     bool OpenWindow(int width, int height, bool resizable, bool borderless);
568     /// Create the application window icon.
569     void CreateWindowIcon();
570     /// Adjust the window for new resolution and fullscreen mode.
571     void AdjustWindow(int& newWidth, int& newHeight, bool& newFullscreen, bool& newBorderless, int& monitor);
572     /// Create the Direct3D11 device and swap chain. Requires an open window. Can also be called again to recreate swap chain. Return true on success.
573     bool CreateDevice(int width, int height, int multiSample);
574     /// Update Direct3D11 swap chain state for a new mode and create views for the backbuffer & default depth buffer. Return true on success.
575     bool UpdateSwapChain(int width, int height);
576     /// Create the Direct3D9 interface.
577     bool CreateInterface();
578     /// Create the Direct3D9 device.
579     bool CreateDevice(unsigned adapter, unsigned deviceType);
580     /// Reset the Direct3D9 device.
581     void ResetDevice();
582     /// Notify all GPU resources so they can release themselves as needed. Used only on Direct3D9.
583     void OnDeviceLost();
584     /// Notify all GPU resources so they can recreate themselves as needed. Used only on Direct3D9.
585     void OnDeviceReset();
586     /// Set vertex buffer stream frequency. Used only on Direct3D9.
587     void SetStreamFrequency(unsigned index, unsigned frequency);
588     /// Reset stream frequencies. Used only on Direct3D9.
589     void ResetStreamFrequencies();
590     /// Check supported rendering features.
591     void CheckFeatureSupport();
592     /// Reset cached rendering state.
593     void ResetCachedState();
594     /// Initialize texture unit mappings.
595     void SetTextureUnitMappings();
596     /// Process dirtied state before draw.
597     void PrepareDraw();
598     /// Create intermediate texture for multisampled backbuffer resolve. No-op if already exists.
599     void CreateResolveTexture();
600     /// Clean up all framebuffers. Called when destroying the context. Used only on OpenGL.
601     void CleanupFramebuffers();
602     /// Create a framebuffer using either extension or core functionality. Used only on OpenGL.
603     unsigned CreateFramebuffer();
604     /// Delete a framebuffer using either extension or core functionality. Used only on OpenGL.
605     void DeleteFramebuffer(unsigned fbo);
606     /// Bind a framebuffer using either extension or core functionality. Used only on OpenGL.
607     void BindFramebuffer(unsigned fbo);
608     /// Bind a framebuffer color attachment using either extension or core functionality. Used only on OpenGL.
609     void BindColorAttachment(unsigned index, unsigned target, unsigned object, bool isRenderBuffer);
610     /// Bind a framebuffer depth attachment using either extension or core functionality. Used only on OpenGL.
611     void BindDepthAttachment(unsigned object, bool isRenderBuffer);
612     /// Bind a framebuffer stencil attachment using either extension or core functionality. Used only on OpenGL.
613     void BindStencilAttachment(unsigned object, bool isRenderBuffer);
614     /// Check FBO completeness using either extension or core functionality. Used only on OpenGL.
615     bool CheckFramebuffer();
616     /// Set vertex attrib divisor. No-op if unsupported. Used only on OpenGL.
617     void SetVertexAttribDivisor(unsigned location, unsigned divisor);
618     /// Release/clear GPU objects and optionally close the window. Used only on OpenGL.
619     void Release(bool clearGPUObjects, bool closeWindow);
620 
621     /// Mutex for accessing the GPU objects vector from several threads.
622     Mutex gpuObjectMutex_;
623     /// Implementation.
624     GraphicsImpl* impl_;
625     /// SDL window.
626     SDL_Window* window_;
627     /// Window title.
628     String windowTitle_;
629     /// Window icon image.
630     WeakPtr<Image> windowIcon_;
631     /// External window, null if not in use (default.)
632     void* externalWindow_;
633     /// Window width in pixels.
634     int width_;
635     /// Window height in pixels.
636     int height_;
637     /// Window position.
638     IntVector2 position_;
639     /// Multisampling mode.
640     int multiSample_;
641     /// Fullscreen flag.
642     bool fullscreen_;
643     /// Borderless flag.
644     bool borderless_;
645     /// Resizable flag.
646     bool resizable_;
647     /// High DPI flag.
648     bool highDPI_;
649     /// Vertical sync flag.
650     bool vsync_;
651     /// Refresh rate in Hz. Only used in fullscreen, 0 when windowed
652     int refreshRate_;
653     /// Monitor index. Only used in fullscreen, 0 when windowed
654     int monitor_;
655     /// Triple buffering flag.
656     bool tripleBuffer_;
657     /// Flush GPU command buffer flag.
658     bool flushGPU_;
659     /// Force OpenGL 2 flag. Only used on OpenGL.
660     bool forceGL2_;
661     /// sRGB conversion on write flag for the main window.
662     bool sRGB_;
663     /// Light pre-pass rendering support flag.
664     bool lightPrepassSupport_;
665     /// Deferred rendering support flag.
666     bool deferredSupport_;
667     /// Anisotropic filtering support flag.
668     bool anisotropySupport_;
669     /// DXT format support flag.
670     bool dxtTextureSupport_;
671     /// ETC1 format support flag.
672     bool etcTextureSupport_;
673     /// PVRTC formats support flag.
674     bool pvrtcTextureSupport_;
675     /// Hardware shadow map depth compare support flag.
676     bool hardwareShadowSupport_;
677     /// Instancing support flag.
678     bool instancingSupport_;
679     /// sRGB conversion on read support flag.
680     bool sRGBSupport_;
681     /// sRGB conversion on write support flag.
682     bool sRGBWriteSupport_;
683     /// Number of primitives this frame.
684     unsigned numPrimitives_;
685     /// Number of batches this frame.
686     unsigned numBatches_;
687     /// Largest scratch buffer request this frame.
688     unsigned maxScratchBufferRequest_;
689     /// GPU objects.
690     PODVector<GPUObject*> gpuObjects_;
691     /// Scratch buffers.
692     Vector<ScratchBuffer> scratchBuffers_;
693     /// Shadow map dummy color texture format.
694     unsigned dummyColorFormat_;
695     /// Shadow map depth texture format.
696     unsigned shadowMapFormat_;
697     /// Shadow map 24-bit depth texture format.
698     unsigned hiresShadowMapFormat_;
699     /// Vertex buffers in use.
700     VertexBuffer* vertexBuffers_[MAX_VERTEX_STREAMS];
701     /// Index buffer in use.
702     IndexBuffer* indexBuffer_;
703     /// Current vertex declaration hash.
704     unsigned long long vertexDeclarationHash_;
705     /// Current primitive type.
706     unsigned primitiveType_;
707     /// Vertex shader in use.
708     ShaderVariation* vertexShader_;
709     /// Pixel shader in use.
710     ShaderVariation* pixelShader_;
711     /// Textures in use.
712     Texture* textures_[MAX_TEXTURE_UNITS];
713     /// Texture unit mappings.
714     HashMap<String, TextureUnit> textureUnits_;
715     /// Rendertargets in use.
716     RenderSurface* renderTargets_[MAX_RENDERTARGETS];
717     /// Depth-stencil surface in use.
718     RenderSurface* depthStencil_;
719     /// Viewport coordinates.
720     IntRect viewport_;
721     /// Default texture filtering mode.
722     TextureFilterMode defaultTextureFilterMode_;
723     /// Default texture max. anisotropy level.
724     unsigned defaultTextureAnisotropy_;
725     /// Blending mode.
726     BlendMode blendMode_;
727     /// Alpha-to-coverage enable.
728     bool alphaToCoverage_;
729     /// Color write enable.
730     bool colorWrite_;
731     /// Hardware culling mode.
732     CullMode cullMode_;
733     /// Depth constant bias.
734     float constantDepthBias_;
735     /// Depth slope scaled bias.
736     float slopeScaledDepthBias_;
737     /// Depth compare mode.
738     CompareMode depthTestMode_;
739     /// Depth write enable flag.
740     bool depthWrite_;
741     /// Line antialiasing enable flag.
742     bool lineAntiAlias_;
743     /// Polygon fill mode.
744     FillMode fillMode_;
745     /// Scissor test enable flag.
746     bool scissorTest_;
747     /// Scissor test rectangle.
748     IntRect scissorRect_;
749     /// Stencil test compare mode.
750     CompareMode stencilTestMode_;
751     /// Stencil operation on pass.
752     StencilOp stencilPass_;
753     /// Stencil operation on fail.
754     StencilOp stencilFail_;
755     /// Stencil operation on depth fail.
756     StencilOp stencilZFail_;
757     /// Stencil test reference value.
758     unsigned stencilRef_;
759     /// Stencil compare bitmask.
760     unsigned stencilCompareMask_;
761     /// Stencil write bitmask.
762     unsigned stencilWriteMask_;
763     /// Current custom clip plane in post-projection space.
764     Vector4 clipPlane_;
765     /// Stencil test enable flag.
766     bool stencilTest_;
767     /// Custom clip plane enable flag.
768     bool useClipPlane_;
769     /// Remembered shader parameter sources.
770     const void* shaderParameterSources_[MAX_SHADER_PARAMETER_GROUPS];
771     /// Base directory for shaders.
772     String shaderPath_;
773     /// Cache directory for Direct3D binary shaders.
774     String shaderCacheDir_;
775     /// File extension for shaders.
776     String shaderExtension_;
777     /// Last used shader in shader variation query.
778     mutable WeakPtr<Shader> lastShader_;
779     /// Last used shader name in shader variation query.
780     mutable String lastShaderName_;
781     /// Shader precache utility.
782     SharedPtr<ShaderPrecache> shaderPrecache_;
783     /// Allowed screen orientations.
784     String orientations_;
785     /// Graphics API name.
786     String apiName_;
787 
788     /// Pixel perfect UV offset.
789     static const Vector2 pixelUVOffset;
790     /// OpenGL3 support flag.
791     static bool gl3Support;
792 };
793 
794 /// Register Graphics library objects.
795 void URHO3D_API RegisterGraphicsLibrary(Context* context);
796 
797 }
798