1 /*
2   -----------------------------------------------------------------------------
3   This source file is part of OGRE
4   (Object-oriented Graphics Rendering Engine)
5   For the latest info, see http://www.ogre3d.org
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 
9   Permission is hereby granted, free of charge, to any person obtaining a copy
10   of this software and associated documentation files (the "Software"), to deal
11   in the Software without restriction, including without limitation the rights
12   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13   copies of the Software, and to permit persons to whom the Software is
14   furnished to do so, subject to the following conditions:
15 
16   The above copyright notice and this permission notice shall be included in
17   all copies or substantial portions of the Software.
18 
19   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25   THE SOFTWARE.
26   -----------------------------------------------------------------------------
27 */
28 
29 #ifndef __GL3PlusRenderSystem_H__
30 #define __GL3PlusRenderSystem_H__
31 
32 #include "OgreGL3PlusPrerequisites.h"
33 
34 #include "OgreMaterialManager.h"
35 #include "OgreGLSLShader.h"
36 #include "OgreRenderWindow.h"
37 #include "OgreGLRenderSystemCommon.h"
38 #include "OgreGL3PlusStateCacheManager.h"
39 
40 namespace Ogre {
41     /** \addtogroup RenderSystems RenderSystems
42     *  @{
43     */
44     /** \defgroup GL3Plus GL3Plus
45     * Implementation of GL 3 as a rendering system.
46     *  @{
47     */
48     class GLSLShaderManager;
49     class GLSLShaderFactory;
50     class GLSLProgram;
51     class HardwareBufferManager;
52 
53     /**
54        Implementation of GL 3 as a rendering system.
55     */
56     class _OgreGL3PlusExport GL3PlusRenderSystem : public GLRenderSystemCommon
57     {
58     private:
59         /// Rendering loop control
60         bool mStopRendering;
61 
62         typedef std::unordered_map<GLenum, GLuint>  BindBufferMap;
63 
64         /// Last min & mip filtering options, so we can combine them
65         FilterOptions mMinFilter;
66         FilterOptions mMipFilter;
67 
68         /// Holds texture type settings for every stage
69         GLenum mTextureTypes[OGRE_MAX_TEXTURE_LAYERS];
70 
71         GLint mLargestSupportedAnisotropy;
72 
73         /// Store last colour write state
74         bool mColourWrite[4];
75 
76         /// Store last depth write state
77         bool mDepthWrite;
78 
79         /// Store last scissor enable state
80         bool mScissorsEnabled;
81 
82         /// Store scissor box
83         int mScissorBox[4];
84 
85         /// Store last stencil mask state
86         uint32 mStencilWriteMask;
87 
88         typedef std::list<GL3PlusContext*> GL3PlusContextList;
89         /// List of background thread contexts
90         GL3PlusContextList mBackgroundContextList;
91 
92         // statecaches are per context
93         GL3PlusStateCacheManager* mStateCacheManager;
94 
95         GLSLShaderManager *mShaderManager;
96         GLSLShaderFactory* mGLSLShaderFactory;
97         HardwareBufferManager* mHardwareBufferManager;
98 
99         /** Manager object for creating render textures.
100             Direct render to texture via FBO is preferable
101             to pbuffers, which depend on the GL support used and are generally
102             unwieldy and slow. However, FBO support for stencil buffers is poor.
103         */
104         GLRTTManager *mRTTManager;
105 
106         /** These variables are used for caching RenderSystem state.
107             They are cached because OpenGL state changes can be quite expensive,
108             which is especially important on mobile or embedded systems.
109         */
110         GLenum mActiveTextureUnit;
111         BindBufferMap mActiveBufferMap;
112 
113         /// Check if the GL system has already been initialised
114         bool mGLInitialised;
115 
116 #if OGRE_NO_QUAD_BUFFER_STEREO == 0
117 		/// @copydoc RenderSystem::setDrawBuffer
118 		virtual bool setDrawBuffer(ColourBufferType colourBuffer);
119 #endif
120 
121         GLSLShader* mCurrentVertexShader;
122         GLSLShader* mCurrentFragmentShader;
123         GLSLShader* mCurrentGeometryShader;
124         GLSLShader* mCurrentHullShader;
125         GLSLShader* mCurrentDomainShader;
126         GLSLShader* mCurrentComputeShader;
127 
128         GLenum getBlendMode(SceneBlendFactor ogreBlend) const;
129 
130         void bindVertexElementToGpu(const VertexElement& elem,
131                                     const HardwareVertexBufferSharedPtr& vertexBuffer,
132                                     const size_t vertexStart);
133         /** Initialises GL extensions, must be done AFTER the GL context has been
134             established.
135         */
136         void initialiseExtensions();
137     public:
138         // Default constructor / destructor
139         GL3PlusRenderSystem();
140         ~GL3PlusRenderSystem();
141 
142         friend class ShaderGeneratorTechniqueResolverListener;
143 
144         // ----------------------------------
145         // Overridden RenderSystem functions
146         // ----------------------------------
147 
148         const String& getName(void) const;
149 
150         RenderWindow* _initialise(bool autoCreateWindow, const String& windowTitle = "OGRE Render Window");
151 
152         virtual RenderSystemCapabilities* createRenderSystemCapabilities() const;
153 
154         void initialiseFromRenderSystemCapabilities(RenderSystemCapabilities* caps, RenderTarget* primary);
155 
156         void shutdown(void);
157 
158         /// @copydoc RenderSystem::_createRenderWindow
159         RenderWindow* _createRenderWindow(const String &name, unsigned int width, unsigned int height,
160                                           bool fullScreen, const NameValuePairList *miscParams = 0);
161 
162         /// @copydoc RenderSystem::_createRenderWindows
163         bool _createRenderWindows(const RenderWindowDescriptionList& renderWindowDescriptions,
164                                   RenderWindowList& createdWindows);
165 
166         /// @copydoc RenderSystem::_createDepthBufferFor
167         DepthBuffer* _createDepthBufferFor( RenderTarget *renderTarget );
168 
169         /// Mimics D3D9RenderSystem::_getDepthStencilFormatFor, if no FBO RTT manager, outputs GL_NONE
170         void _getDepthStencilFormatFor( PixelFormat internalColourFormat, GLenum *depthFormat,
171                                         GLenum *stencilFormat );
172 
173         /// @copydoc RenderSystem::createMultiRenderTarget
174         virtual MultiRenderTarget * createMultiRenderTarget(const String & name);
175 
176 
177         void destroyRenderWindow(const String& name);
178 
179         // -----------------------------
180         // Low-level overridden members
181         // -----------------------------
182         void _setTexture(size_t unit, bool enabled, const TexturePtr &tex);
183 
184         void _setSampler(size_t unit, Sampler& sampler);
185 
186         void _setTextureAddressingMode(size_t stage, const Sampler::UVWAddressingMode& uvw);
187 
188         void _setTextureBorderColour(size_t stage, const ColourValue& colour);
189 
190         void _setTextureMipmapBias(size_t unit, float bias);
191 
192         void _setLineWidth(float width);
193 
194         void _setViewport(Viewport *vp);
195 
196         void _beginFrame(void);
197 
198         void _endFrame(void);
199 
200         void _setCullingMode(CullingMode mode);
201 
202         void _setDepthBufferParams(bool depthTest = true, bool depthWrite = true, CompareFunction depthFunction = CMPF_LESS_EQUAL);
203 
204         void _setDepthBufferCheckEnabled(bool enabled = true);
205 
206         void _setDepthBufferWriteEnabled(bool enabled = true);
207 
208         void _setDepthBufferFunction(CompareFunction func = CMPF_LESS_EQUAL);
209 
210         void _setDepthBias(float constantBias, float slopeScaleBias);
211 
212         void _setColourBufferWriteEnabled(bool red, bool green, bool blue, bool alpha);
213 
214         void _setPolygonMode(PolygonMode level);
215 
216         void setStencilCheckEnabled(bool enabled);
217         /** See
218             RenderSystem.
219         */
220         void setStencilBufferParams(CompareFunction func = CMPF_ALWAYS_PASS,
221                                     uint32 refValue = 0, uint32 compareMask = 0xFFFFFFFF, uint32 writeMask = 0xFFFFFFFF,
222                                     StencilOperation stencilFailOp = SOP_KEEP,
223                                     StencilOperation depthFailOp = SOP_KEEP,
224                                     StencilOperation passOp = SOP_KEEP,
225                     bool twoSidedOperation = false,
226                     bool readBackAsTexture = false);
227 
228         void _setTextureUnitFiltering(size_t unit, FilterType ftype, FilterOptions filter);
229 
230         void _setTextureUnitCompareFunction(size_t unit, CompareFunction function);
231 
232         void _setTextureUnitCompareEnabled(size_t unit, bool compare);
233 
234         void _setTextureLayerAnisotropy(size_t unit, unsigned int maxAnisotropy);
235 
236         void _dispatchCompute(const Vector3i& workgroupDim);
237 
238         void _render(const RenderOperation& op);
239 
240         void setScissorTest(bool enabled, size_t left = 0, size_t top = 0, size_t right = 800, size_t bottom = 600);
241 
242         void clearFrameBuffer(unsigned int buffers,
243                               const ColourValue& colour = ColourValue::Black,
244                               Real depth = 1.0f, unsigned short stencil = 0);
245         HardwareOcclusionQuery* createHardwareOcclusionQuery(void);
246         OGRE_MUTEX(mThreadInitMutex);
247         void registerThread();
248         void unregisterThread();
249         void preExtraThreadsStarted();
250         void postExtraThreadsStarted();
251 
252         // ----------------------------------
253         // GL3PlusRenderSystem specific members
254         // ----------------------------------
_getStateCacheManager()255         GL3PlusStateCacheManager * _getStateCacheManager() { return mStateCacheManager; }
256 
257         /** Create VAO on current context */
258         uint32 _createVao();
259         /** Bind VAO, context should be equal to current context, as VAOs are not shared  */
260         void _bindVao(GLContext* context, uint32 vao);
261         /** Destroy VAO immediately or defer if it was created on other context */
262         void _destroyVao(GLContext* context, uint32 vao);
263         /** Destroy FBO immediately or defer if it was created on other context */
264         void _destroyFbo(GLContext* context, uint32 fbo);
265 
266         /** Unregister a render target->context mapping. If the context of target
267             is the current context, change the context to the main context so it
268             can be destroyed safely.
269 
270             @note This is automatically called by the destructor of
271             GL3PlusContext.
272         */
273         void _unregisterContext(GL3PlusContext *context);
274         /** Switch GL context, dealing with involved internal cached states too
275          */
276         void _switchContext(GL3PlusContext *context);
277         /** One time initialization for the RenderState of a context. Things that
278             only need to be set once, like the LightingModel can be defined here.
279         */
280         void _oneTimeContextInitialization();
281         void initialiseContext(RenderWindow* primary);
282         /**
283          * Set current render target to target, enabling its GL context if needed
284          */
285         void _setRenderTarget(RenderTarget *target);
286 
287         static GLint convertCompareFunction(CompareFunction func);
288         static GLint convertStencilOp(StencilOperation op, bool invert = false);
289 
290         void bindGpuProgram(GpuProgram* prg);
291         void unbindGpuProgram(GpuProgramType gptype);
292         void bindGpuProgramParameters(GpuProgramType gptype, const GpuProgramParametersPtr& params, uint16 mask);
293         void bindGpuProgramPassIterationParameters(GpuProgramType gptype);
294 
295         /// @copydoc RenderSystem::_setSeparateSceneBlending
296         void _setSeparateSceneBlending( SceneBlendFactor sourceFactor, SceneBlendFactor destFactor, SceneBlendFactor sourceFactorAlpha, SceneBlendFactor destFactorAlpha, SceneBlendOperation op, SceneBlendOperation alphaOp );
297         /// @copydoc RenderSystem::_setAlphaRejectSettings
298         void _setAlphaRejectSettings( CompareFunction func, unsigned char value, bool alphaToCoverage );
299         /// @copydoc RenderSystem::getDisplayMonitorCount
300         unsigned int getDisplayMonitorCount() const;
301 
302         /// @copydoc RenderSystem::hasAnisotropicMipMapFilter
hasAnisotropicMipMapFilter()303         virtual bool hasAnisotropicMipMapFilter() const { return false; }
304 
305         /// @copydoc RenderSystem::beginProfileEvent
306         virtual void beginProfileEvent( const String &eventName );
307 
308         /// @copydoc RenderSystem::endProfileEvent
309         virtual void endProfileEvent( void );
310 
311         /// @copydoc RenderSystem::markProfileEvent
312         virtual void markProfileEvent( const String &eventName );
313 
314         /** @copydoc RenderTarget::copyContentsToMemory */
315         void _copyContentsToMemory(Viewport* vp, const Box& src, const PixelBox &dst, RenderWindow::FrameBuffer buffer);
316     };
317     /** @} */
318     /** @} */
319 }
320 
321 #endif
322