Show bonus/malus timer text if available
[ryzomcore.git] / nel / src / 3d / driver / opengl / driver_opengl.h
blob5be157403b25df608950b2e61ba9c3d089ff1626
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2010 Robert TIMM (rti) <mail@rtti.de>
6 // Copyright (C) 2010 Thibaut GIRKA (ThibG) <thib@sitedethib.com>
7 // Copyright (C) 2013-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 //
9 // This program is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU Affero General Public License as
11 // published by the Free Software Foundation, either version 3 of the
12 // License, or (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Affero General Public License for more details.
19 // You should have received a copy of the GNU Affero General Public License
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #ifndef NL_DRIVER_OPENGL_H
23 #define NL_DRIVER_OPENGL_H
25 #include "nel/misc/types_nl.h"
27 //#define NL_PROFILE_DRIVER_OGL
28 #ifdef NL_PROFILE_DRIVER_OGL
29 # define H_AUTO_OGL(label) H_AUTO(label)
30 #else
31 # define H_AUTO_OGL(label)
32 #endif
34 #ifdef NL_OS_MAC
35 # import <Cocoa/Cocoa.h>
36 # import "mac/cocoa_opengl_view.h"
37 #elif defined (NL_OS_UNIX)
38 # ifdef XF86VIDMODE
39 # include <X11/extensions/xf86vmode.h>
40 # endif //XF86VIDMODE
41 #endif // NL_OS_UNIX
43 #include "nel/misc/matrix.h"
44 #include "nel/misc/smart_ptr.h"
45 #include "nel/misc/rgba.h"
46 #include "nel/misc/event_emitter.h"
47 #include "nel/misc/bit_set.h"
48 #include "nel/misc/hierarchical_timer.h"
49 #include "nel/misc/bitmap.h"
50 #include "nel/misc/common.h"
51 #include "nel/misc/heap_memory.h"
52 #include "nel/misc/event_emitter_multi.h"
53 #include "nel/misc/time_nl.h"
55 #include "nel/3d/driver.h"
56 #include "nel/3d/material.h"
57 #include "nel/3d/vertex_buffer.h"
58 #include "nel/3d/ptr_set.h"
59 #include "nel/3d/texture_cube.h"
60 #include "nel/3d/vertex_program_parse.h"
61 #include "nel/3d/viewport.h"
62 #include "nel/3d/scissor.h"
63 #include "nel/3d/light.h"
64 #include "nel/3d/occlusion_query.h"
66 #include "driver_opengl_states.h"
67 #include "driver_opengl_extension.h"
70 #ifdef NL_OS_WINDOWS
71 #include "nel/misc/win_event_emitter.h"
72 #elif defined(NL_OS_MAC)
73 #include "mac/cocoa_event_emitter.h"
74 #elif defined (NL_OS_UNIX)
75 #include "unix_event_emitter.h"
76 #endif // NL_OS_UNIX
79 // For optimisation consideration, allow 256 lightmaps at max.
80 #define NL3D_DRV_MAX_LIGHTMAP 256
84 #define CHECK_GL_ERROR { \
85 GLenum error = glGetError(); \
86 if (error != GL_NO_ERROR)\
88 displayGLError(error);\
89 nlassert(0);\
94 #define UNSUPPORTED_INDEX_OFFSET_MSG "Unsupported by driver, check IDriver::supportIndexOffset."
96 using NLMISC::CMatrix;
97 using NLMISC::CVector;
99 namespace NL3D {
101 #ifdef NL_STATIC
102 #ifdef USE_OPENGLES
103 namespace NLDRIVERGLES {
104 #else
105 namespace NLDRIVERGL {
106 #endif
107 #endif
109 class CDriverGL;
110 class IVertexArrayRange;
111 class IVertexBufferHardGL;
112 class COcclusionQueryGL;
114 void displayGLError(GLenum error);
116 #ifdef NL_OS_WINDOWS
118 bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
119 typedef HCURSOR nlCursor;
120 #define EmptyCursor (nlCursor)NULL
122 #elif defined (NL_OS_MAC)
124 bool GlWndProc(CDriverGL *driver, const void* e);
125 typedef void* nlCursor;
126 #define EmptyCursor (nlCursor)NULL
128 #elif defined (NL_OS_UNIX)
130 bool GlWndProc(CDriverGL *driver, XEvent &e);
131 typedef Cursor nlCursor;
132 #define EmptyCursor None
134 #endif
136 typedef std::list<COcclusionQueryGL *> TOcclusionQueryList;
138 // ***************************************************************************
139 class COcclusionQueryGL : public IOcclusionQuery
141 public:
142 GLuint ID; // id of gl object
143 NLMISC::CRefPtr<CDriverGL> Driver; // owner driver
144 TOcclusionQueryList::iterator Iterator; // iterator in owner driver list of queries
145 TOcclusionType OcclusionType; // current type of occlusion
146 uint VisibleCount; // number of samples that passed the test
147 // From IOcclusionQuery
148 virtual void begin();
149 virtual void end();
150 virtual TOcclusionType getOcclusionType();
151 virtual uint getVisibleCount();
154 // ***************************************************************************
155 class CDepthStencilFBO : public NLMISC::CRefCount
157 public:
158 CDepthStencilFBO(CDriverGL *driver, uint width, uint height);
159 ~CDepthStencilFBO();
161 uint Width;
162 uint Height;
164 GLuint DepthFBOId;
165 GLuint StencilFBOId;
167 private:
168 CDriverGL *m_Driver;
171 // ***************************************************************************
172 class CTextureDrvInfosGL : public ITextureDrvInfos
174 public:
176 ANY DATA ADDED HERE MUST BE SWAPPED IN swapTextureHandle() !!
179 // The GL Id.
180 GLuint ID;
181 // Is the internal format of the texture is a compressed one?
182 bool Compressed;
183 // Is the internal format of the texture has mipmaps?
184 bool MipMap;
186 // This is the computed size of what memory this texture take.
187 uint32 TextureMemory;
188 // This is the owner driver.
189 CDriverGL *_Driver;
191 // enum to use for this texture (GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV..)
192 GLenum TextureMode;
194 // FBO Id
195 GLuint FBOId;
197 // depth stencil FBO id
198 bool AttachDepthStencil;
199 NLMISC::CSmartPtr<CDepthStencilFBO> DepthStencilFBO;
200 bool InitFBO;
202 // The current wrap modes assigned to the texture.
203 ITexture::TWrapMode WrapS;
204 ITexture::TWrapMode WrapT;
205 ITexture::TMagFilter MagFilter;
206 ITexture::TMinFilter MinFilter;
208 // The gl id is auto created here.
209 CTextureDrvInfosGL(IDriver *drv, ItTexDrvInfoPtrMap it, CDriverGL *drvGl, bool isRectangleTexture);
210 // The gl id is auto deleted here.
211 ~CTextureDrvInfosGL();
212 // For Debug info. return the memory cost of this texture
213 virtual uint getTextureMemoryUsed() const {return TextureMemory;}
215 bool initFrameBufferObject(ITexture * tex);
216 bool activeFrameBufferObject(ITexture * tex);
218 std::vector<CTextureDrvInfosGL *>::size_type TextureUsedIdx;
222 // ***************************************************************************
223 class CVBDrvInfosGL : public IVBDrvInfos
225 public:
226 CVBDrvInfosGL(CDriverGL *drv, ItVBDrvInfoPtrList it, CVertexBuffer *vb);
228 // Verex buffer hard ?
229 IVertexBufferHardGL *_VBHard;
230 class CDriverGL *_DriverGL;
231 uint8 *_SystemMemory;
234 // From IVBDrvInfos
235 virtual ~CVBDrvInfosGL();
236 virtual uint8 *lock (uint first, uint last, bool readOnly);
237 virtual void unlock (uint first, uint last);
241 // ***************************************************************************
242 class CShaderGL : public IMaterialDrvInfos
244 public:
245 GLenum SrcBlend;
246 GLenum DstBlend;
247 GLenum ZComp;
249 GLfloat Emissive[4];
250 GLfloat Ambient[4];
251 GLfloat Diffuse[4];
252 GLfloat Specular[4];
253 // For fast comp.
254 uint32 PackedEmissive;
255 uint32 PackedAmbient;
256 uint32 PackedDiffuse;
257 uint32 PackedSpecular;
259 // The supported Shader type.
260 CMaterial::TShader SupportedShader;
262 CShaderGL(IDriver *drv, ItMatDrvInfoPtrList it) : IMaterialDrvInfos(drv, it) {}
266 // ***************************************************************************
267 /// Info for the last VertexBuffer setuped (iether normal or hard).
268 class CVertexBufferInfo
270 public:
271 uint16 VertexFormat;
272 uint16 VertexSize;
273 uint32 NumVertices;
274 CVertexBuffer::TType Type[CVertexBuffer::NumValue];
275 uint8 UVRouting[CVertexBuffer::MaxStage];
277 // NB: ptrs are invalid if VertexFormat does not support the compoennt. must test VertexFormat, not the ptr.
278 void *ValuePtr[CVertexBuffer::NumValue];
281 enum TVBMode { TVBModeNone = 0, SysMem, HwNVIDIA, HwARB, HwATI }; // standard VBs, or Hard VBs using different extensions
283 // Kind of vb
284 TVBMode VBMode;
285 // the handle of ATI or ARB vertex object
286 uint VertexObjectId;
288 CVertexBufferInfo()
290 VBMode = TVBModeNone;
293 void setupVertexBuffer(CVertexBuffer &vb);
294 void setupVertexBufferHard(IVertexBufferHardGL &vb);
299 // ***************************************************************************
300 /// Info for the last IndexBuffer setuped (iether normal or hard).
301 class CIndexBufferInfo
303 public:
304 const void *_Values;
305 CIndexBuffer::TFormat _Format;
307 CIndexBufferInfo ();
308 void setupIndexBuffer(CIndexBuffer &vb);
313 // ***************************************************************************
314 class CDriverGL : public IDriver
316 public:
318 // Some constants
319 enum { MaxLight=8 };
321 CDriverGL();
322 virtual ~CDriverGL();
324 virtual bool isLost() const { return false; } // there's no notion of 'lost device" in OpenGL
326 virtual bool init (uintptr_t windowIcon = 0, emptyProc exitFunc = 0);
328 virtual void disableHardwareVertexProgram();
329 virtual void disableHardwarePixelProgram();
330 virtual void disableHardwareVertexArrayAGP();
331 virtual void disableHardwareTextureShader();
333 virtual bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable);
334 virtual bool setMode(const GfxMode& mode);
335 virtual bool getModes(std::vector<GfxMode> &modes);
336 virtual bool getCurrentScreenMode(GfxMode &mode);
337 virtual void beginDialogMode();
338 virtual void endDialogMode();
340 /// Set title of the NeL window
341 virtual void setWindowTitle(const ucstring &title);
343 /// Set icon(s) of the NeL window
344 virtual void setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps);
346 /// Set position of the NeL window
347 virtual void setWindowPos(sint32 x, sint32 y);
349 /// Show or hide the NeL window
350 virtual void showWindow(bool show);
352 virtual nlWindow getDisplay()
354 return _win;
357 virtual bool copyTextToClipboard(const std::string &text);
358 virtual bool pasteTextFromClipboard(std::string &text);
360 virtual uint32 getAvailableVertexAGPMemory ();
361 virtual uint32 getAvailableVertexVRAMMemory ();
363 virtual emptyProc getWindowProc();
365 virtual bool activate();
367 virtual uint getNbTextureStages() const;
369 virtual bool isTextureExist(const ITexture&tex);
371 virtual NLMISC::IEventEmitter *getEventEmitter() { return&_EventEmitter; };
373 virtual bool clear2D(CRGBA rgba);
375 virtual bool clearZBuffer(float zval=1);
376 virtual bool clearStencilBuffer(float stencilval=0);
377 virtual void setColorMask (bool bRed, bool bGreen, bool bBlue, bool bAlpha);
378 virtual void setDepthRange(float znear, float zfar);
379 virtual void getDepthRange(float &znear, float &zfar) const;
381 virtual bool setupTexture (ITexture& tex);
383 virtual bool setupTextureEx (ITexture& tex, bool bUpload, bool &bAllUploaded, bool bMustRecreateSharedTexture= false);
384 virtual bool uploadTexture (ITexture& tex, NLMISC::CRect& rect, uint8 nNumMipMap);
385 virtual bool uploadTextureCube (ITexture& tex, NLMISC::CRect& rect, uint8 nNumMipMap, uint8 nNumFace);
387 virtual void forceDXTCCompression(bool dxtcComp);
388 virtual void setAnisotropicFilter(sint filter);
389 virtual uint getAnisotropicFilter() const;
390 virtual uint getAnisotropicFilterMaximum() const;
392 virtual void forceTextureResize(uint divisor);
394 /// Setup texture env functions. Used by setupMaterial
395 void setTextureEnvFunction(uint stage, CMaterial& mat);
397 /// setup the texture matrix for a given number of stages (starting from 0)
398 void setupUserTextureMatrix(uint numStages, CMaterial& mat);
400 /// disable all texture matrix
401 void disableUserTextureMatrix();
403 /// For objects with caustics, setup the first texture (which actually is the one from the material)
404 /*static inline void setupCausticsFirstTex(const CMaterial &mat);
406 /// For objects with caustics, setup the caustic texture itself
407 static inline void setupCausticsSecondTex(uint stage);*/
409 virtual bool setupMaterial(CMaterial& mat);
411 virtual void startSpecularBatch();
412 virtual void endSpecularBatch();
414 virtual void setFrustum(float left, float right, float bottom, float top, float znear, float zfar, bool perspective = true);
415 virtual void setFrustumMatrix(CMatrix &frust);
416 virtual CMatrix getFrustumMatrix();
417 virtual float getClipSpaceZMin() const { return -1.f; }
419 virtual void setupViewMatrix(const CMatrix& mtx);
421 virtual void setupViewMatrixEx(const CMatrix& mtx, const CVector &cameraPos);
423 virtual void setupModelMatrix(const CMatrix& mtx);
425 virtual CMatrix getViewMatrix() const;
427 virtual void forceNormalize(bool normalize)
429 _ForceNormalize= normalize;
430 // if ForceNormalize, must enable GLNormalize now.
431 if(normalize)
432 enableGlNormalize(true);
435 virtual bool isForceNormalize() const
437 return _ForceNormalize;
440 virtual void getNumPerStageConstant(uint &lightedMaterial, uint &unlightedMaterial) const;
442 virtual bool supportVertexBufferHard() const;
444 virtual bool supportVolatileVertexBuffer() const;
446 virtual bool supportCloudRenderSinglePass() const;
448 virtual bool supportIndexOffset() const { return false; /* feature only supported in D3D for now */ }
451 virtual bool slowUnlockVertexBufferHard() const;
453 virtual uint getMaxVerticesByVertexBufferHard() const;
455 virtual bool initVertexBufferHard(uint agpMem, uint vramMem);
457 virtual bool activeVertexBuffer(CVertexBuffer& VB);
459 virtual bool activeIndexBuffer(CIndexBuffer& IB);
461 virtual void mapTextureStageToUV(uint stage, uint uv);
463 virtual bool renderLines(CMaterial& mat, uint32 firstIndex, uint32 nlines);
464 virtual bool renderTriangles(CMaterial& Mat, uint32 firstIndex, uint32 ntris);
465 virtual bool renderSimpleTriangles(uint32 firstTri, uint32 ntris);
466 virtual bool renderRawPoints(CMaterial& Mat, uint32 startIndex, uint32 numPoints);
467 virtual bool renderRawLines(CMaterial& Mat, uint32 startIndex, uint32 numLines);
468 virtual bool renderRawTriangles(CMaterial& Mat, uint32 startIndex, uint32 numTris);
469 virtual bool renderRawQuads(CMaterial& Mat, uint32 startIndex, uint32 numQuads);
471 virtual bool renderLinesWithIndexOffset(CMaterial& /* mat */, uint32 /* firstIndex */, uint32 /* nlines */, uint /* indexOffset */) { nlassertex(0, (UNSUPPORTED_INDEX_OFFSET_MSG)); return false; }
472 virtual bool renderTrianglesWithIndexOffset(CMaterial& /* mat */, uint32 /* firstIndex */, uint32 /* ntris */, uint /* indexOffset */) { nlassertex(0, (UNSUPPORTED_INDEX_OFFSET_MSG)); return false; }
473 virtual bool renderSimpleTrianglesWithIndexOffset(uint32 /* firstIndex */, uint32 /* ntris */, uint /* indexOffset */) { nlassertex(0, (UNSUPPORTED_INDEX_OFFSET_MSG)); return false; }
475 virtual bool swapBuffers();
477 virtual void setSwapVBLInterval(uint interval);
479 virtual uint getSwapVBLInterval();
481 virtual void profileRenderedPrimitives(CPrimitiveProfile &pIn, CPrimitiveProfile &pOut);
483 virtual uint32 profileAllocatedTextureMemory();
485 virtual uint32 profileSetupedMaterials() const;
487 virtual uint32 profileSetupedModelMatrix() const;
489 void enableUsedTextureMemorySum (bool enable);
491 uint32 getUsedTextureMemory() const;
493 virtual void startProfileVBHardLock();
495 virtual void endProfileVBHardLock(std::vector<std::string> &result);
497 virtual void profileVBHardAllocation(std::vector<std::string> &result);
499 virtual void startProfileIBLock();
501 virtual void endProfileIBLock(std::vector<std::string> &result);
503 virtual void profileIBAllocation(std::vector<std::string> &result);
505 virtual bool release();
507 virtual TMessageBoxId systemMessageBox (const char* message, const char* title, TMessageBoxType type=okType, TMessageBoxIcon icon=noIcon);
509 virtual void setupScissor (const class CScissor& scissor);
511 virtual void setupViewport (const class CViewport& viewport);
513 virtual void getViewport(CViewport &viewport);
516 virtual uint32 getImplementationVersion () const
518 return ReleaseVersion;
521 virtual const char* getDriverInformation ()
523 return "Opengl 1.2 NeL Driver";
526 virtual const char* getVideocardInformation ();
528 virtual sint getTotalVideoMemory() const;
530 virtual bool isActive ();
532 virtual uint8 getBitPerPixel ();
534 virtual void showCursor (bool b);
536 // between 0.0 and 1.0
537 virtual void setMousePos(float x, float y);
539 virtual void setCapture (bool b);
541 // see if system cursor is currently captured
542 virtual bool isSystemCursorCaptured();
544 // Add a new cursor (name is case unsensitive)
545 virtual void addCursor(const std::string &name, const NLMISC::CBitmap &bitmap);
547 // Display a cursor from its name (case unsensitive)
548 virtual void setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild = false);
550 // Change default scale for all cursors
551 virtual void setCursorScale(float scale);
553 virtual void getWindowSize (uint32 &width, uint32 &height);
555 virtual void getWindowPos (sint32 &x, sint32 &y);
557 virtual void getBuffer (CBitmap &bitmap);
559 virtual void getZBuffer (std::vector<float> &zbuffer);
561 virtual void getBufferPart (CBitmap &bitmap, NLMISC::CRect &rect);
563 // copy the first texture in a second one of different dimensions
564 virtual bool stretchRect(ITexture * srcText, NLMISC::CRect &srcRect, ITexture * destText, NLMISC::CRect &destRect);
566 // return true if driver support Bloom effect.
567 virtual bool supportBloomEffect() const;
569 // return true if driver support non-power of two textures
570 virtual bool supportNonPowerOfTwoTextures() const;
572 virtual bool activeFrameBufferObject(ITexture * tex);
574 virtual void getZBufferPart (std::vector<float> &zbuffer, NLMISC::CRect &rect);
576 virtual bool setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width, uint32 height,
577 uint32 mipmapLevel, uint32 cubeFace);
579 virtual ITexture *getRenderTarget() const;
581 virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y,
582 uint32 width, uint32 height, uint32 mipmapLevel);
584 virtual bool textureCoordinateAlternativeMode() const { return false; };
586 virtual bool getRenderTargetSize (uint32 &width, uint32 &height);
589 virtual bool fillBuffer (CBitmap &bitmap);
591 virtual void setPolygonMode (TPolygonMode mode);
593 virtual uint getMaxLight () const;
595 virtual void setLight (uint8 num, const CLight& light);
597 virtual void enableLight (uint8 num, bool enable=true);
599 virtual void setPerPixelLightingLight(CRGBA diffuse, CRGBA specular, float shininess);
601 virtual void setLightMapDynamicLight (bool enable, const CLight& light);
603 virtual void setAmbientColor (CRGBA color);
605 /// \name Fog support.
606 // @{
607 virtual bool fogEnabled();
608 virtual void enableFog(bool enable);
609 /// setup fog parameters. fog must enabled to see result. start and end are in [0,1] range.
610 virtual void setupFog(float start, float end, CRGBA color);
611 virtual float getFogStart() const;
612 virtual float getFogEnd() const;
613 virtual CRGBA getFogColor() const;
614 // @}
616 /// \name texture addressing modes
617 // @{
618 virtual bool supportTextureShaders() const;
620 virtual bool supportWaterShader() const;
622 virtual bool supportTextureAddrMode(CMaterial::TTexAddressingMode mode) const;
624 virtual void setMatrix2DForTextureOffsetAddrMode(const uint stage, const float mat[4]);
625 // @}
627 /// \name EMBM support
628 // @{
629 virtual bool supportEMBM() const;
630 virtual bool isEMBMSupportedAtStage(uint stage) const;
631 virtual void setEMBMMatrix(const uint stage, const float mat[4]);
632 // @}
634 virtual bool supportPerPixelLighting(bool specular) const;
637 /// \name Misc
638 // @{
639 virtual bool supportBlendConstantColor() const;
640 virtual void setBlendConstantColor(NLMISC::CRGBA col);
641 virtual NLMISC::CRGBA getBlendConstantColor() const;
642 virtual bool setMonitorColorProperties (const CMonitorColorProperties &properties);
643 virtual void finish();
644 virtual void flush();
645 virtual void enablePolygonSmoothing(bool smooth);
646 virtual bool isPolygonSmoothingEnabled() const;
647 // @}
650 virtual void swapTextureHandle(ITexture &tex0, ITexture &tex1);
652 virtual uintptr_t getTextureHandle(const ITexture&tex);
654 /// \name Material multipass.
655 /** NB: setupMaterial() must be called before thoses methods.
656 * NB: This is intended to be use with the rendering of simple primitives.
657 * NB: Other render calls performs the needed setup automatically
659 // @{
660 /// init multipass for _CurrentMaterial. return number of pass required to render this material.
661 virtual sint beginMaterialMultiPass() { return beginMultiPass(); }
662 /// active the ith pass of this material.
663 virtual void setupMaterialPass(uint pass) { setupPass(pass); }
664 /// end multipass for this material.
665 virtual void endMaterialMultiPass() { endMultiPass(); }
666 // @}
668 /// Adaptor information
669 virtual uint getNumAdapter() const;
670 virtual bool getAdapter(uint adapter, CAdapter &desc) const;
671 virtual bool setAdapter(uint adapter);
673 virtual CVertexBuffer::TVertexColorType getVertexColorFormat() const;
675 // Bench
676 virtual void startBench (bool wantStandardDeviation = false, bool quick = false, bool reset = true);
677 virtual void endBench ();
678 virtual void displayBench (class NLMISC::CLog *log);
680 virtual bool supportOcclusionQuery() const;
681 virtual IOcclusionQuery *createOcclusionQuery();
682 virtual void deleteOcclusionQuery(IOcclusionQuery *oq);
684 // Test whether this device supports the frame buffer object mecanism
685 virtual bool supportTextureRectangle() const;
686 virtual bool supportFrameBufferObject() const;
687 virtual bool supportPackedDepthStencil() const;
689 virtual uint64 getSwapBufferCounter() const { return _SwapBufferCounter; }
691 virtual void setCullMode(TCullMode cullMode);
692 virtual TCullMode getCullMode() const;
694 virtual void enableStencilTest(bool enable);
695 virtual bool isStencilTestEnabled() const;
696 virtual void stencilFunc(TStencilFunc stencilFunc, int ref, uint mask);
697 virtual void stencilOp(TStencilOp fail, TStencilOp zfail, TStencilOp zpass);
698 virtual void stencilMask(uint mask);
700 GfxMode _CurrentMode;
701 sint32 _WindowX;
702 sint32 _WindowY;
703 bool _WindowFocus;
705 #ifdef NL_OS_MAC
706 NLMISC::CCocoaEventEmitter _EventEmitter;
707 #endif
709 private:
710 virtual class IVertexBufferHardGL *createVertexBufferHard(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb);
711 friend class CTextureDrvInfosGL;
712 friend class CVertexProgamDrvInfosGL;
713 friend class CPixelProgamDrvInfosGL;
714 friend class CDepthStencilFBO;
716 private:
717 // Version of the driver. Not the interface version!! Increment when implementation of the driver change.
718 static const uint32 ReleaseVersion;
720 // Windows
721 nlWindow _win;
722 bool _WindowVisible;
723 bool _DestroyWindow;
724 bool _Maximized;
725 uint _Interval;
726 bool _Resizable;
728 sint32 _DecorationWidth;
729 sint32 _DecorationHeight;
731 // cursors
732 enum TColorDepth { ColorDepth16 = 0, ColorDepth32, ColorDepthCount };
734 TColorDepth _ColorDepth;
735 std::string _CurrName;
736 NLMISC::CRGBA _CurrCol;
737 uint8 _CurrRot;
738 uint _CurrHotSpotX;
739 uint _CurrHotSpotY;
740 float _CursorScale;
741 bool _MouseCaptured;
743 nlCursor _DefaultCursor;
744 nlCursor _BlankCursor;
746 bool _AlphaBlendedCursorSupported;
747 bool _AlphaBlendedCursorSupportRetrieved;
749 class CCursor
751 public:
752 NLMISC::CBitmap Src;
753 TColorDepth ColorDepth;
754 uint OrigHeight;
755 float HotspotScale;
756 uint HotspotOffsetX;
757 uint HotspotOffsetY;
758 sint HotSpotX;
759 sint HotSpotY;
760 nlCursor Cursor;
761 NLMISC::CRGBA Col;
762 uint8 Rot;
763 #if defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
764 Display *Dpy;
765 #endif
766 public:
767 CCursor();
768 ~CCursor();
769 CCursor& operator= (const CCursor& from);
771 void reset();
774 struct CStrCaseUnsensitiveCmp
776 bool operator()(const std::string &lhs, const std::string &rhs) const
778 return NLMISC::nlstricmp(lhs, rhs) < 0;
782 typedef std::map<std::string, CCursor, CStrCaseUnsensitiveCmp> TCursorMap;
784 TCursorMap _Cursors;
786 #ifdef USE_OPENGLES
787 EGLDisplay _EglDisplay;
788 EGLContext _EglContext;
789 EGLSurface _EglSurface;
790 #elif defined(NL_OS_WINDOWS)
791 HGLRC _hRC;
792 HDC _hDC;
793 PIXELFORMATDESCRIPTOR _pfd;
795 // Off-screen rendering in Dib section
796 HPBUFFERARB _PBuffer;
797 #elif defined(NL_OS_MAC)
798 NSOpenGLContext* _ctx;
799 #elif defined(NL_OS_UNIX)
800 GLXContext _ctx;
801 #endif
803 #ifdef NL_OS_WINDOWS
805 bool convertBitmapToIcon(const NLMISC::CBitmap &bitmap, HICON &icon, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col = NLMISC::CRGBA::White, sint hotSpotX = 0, sint hotSpotY = 0, bool cursor = false);
807 friend bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
809 static uint _Registered;
810 DEVMODE _OldScreenMode;
811 NLMISC::CEventEmitterMulti _EventEmitter; // this can contains a win emitter and eventually a direct input emitter
813 #elif defined(NL_OS_MAC)
815 friend bool GlWndProc(CDriverGL*, const void*);
817 CocoaOpenGLView* _glView;
818 NSAutoreleasePool* _autoreleasePool;
819 uint16 _backBufferHeight;
820 uint16 _backBufferWidth;
822 NSView* containerView() { return (NSView*)_win; }
823 void setupApplicationMenu();
825 #elif defined (NL_OS_UNIX)
827 bool convertBitmapToIcon(const NLMISC::CBitmap &bitmap, std::vector<long> &icon);
829 friend bool GlWndProc(CDriverGL *driver, XEvent &e);
831 Display* _dpy;
832 NLMISC::CUnixEventEmitter _EventEmitter;
833 XVisualInfo* _visual_info;
834 uint32 _xrandr_version;
835 uint32 _xvidmode_version;
836 uint32 _xrender_version;
838 #ifdef HAVE_XRANDR
839 sint _OldSizeID;
840 #endif // HAVE_XRANDR
842 #ifdef XF86VIDMODE
843 sint _OldDotClock; // old dotclock
844 XF86VidModeModeLine _OldScreenMode; // old modeline
845 sint _OldX, _OldY; //Viewport settings
846 #endif //XF86VIDMODE
848 #endif // NL_OS_UNIX
850 bool _Initialized;
852 /// \name Driver Caps.
853 // @{
854 // OpenGL extensions Extensions.
855 CGlExtensions _Extensions;
856 // @}
859 // The forceNormalize() state.
860 bool _ForceNormalize;
862 // To know if light setup has been changed from last render() ( any call to setupViewMatrix() or setLight() ).
863 bool _LightSetupDirty;
865 // To know if the modelview matrix setup has been changed from last render() (any call to setupViewMatrix() / setupModelMatrix() ).
866 bool _ModelViewMatrixDirty;
868 // To know if the projection matrix has been changed
869 bool _ProjMatDirty;
871 // Mirror the gl projection matrix when _ProjMatDirty = false
872 NLMISC::CMatrix _GLProjMat;
874 // Ored of _LightSetupDirty and _ModelViewMatrixDirty
875 bool _RenderSetupDirty;
877 // Backup znear and zfar
878 float _OODeltaZ;
880 // Current View matrix, in NEL basis. This is the parameter passed in setupViewMatrix*().
881 CMatrix _UserViewMtx;
882 // Current (OpenGL basis) View matrix.
883 // NB: if setuped with setupViewMatrixEx(), _ViewMtx.Pos()==(0,0,0)
884 CMatrix _ViewMtx;
885 // Matrix used for specular
886 CMatrix _SpecularTexMtx;
887 // Precision ZBuffer: The Current cameraPosition, to remove from each model Position.
888 CVector _PZBCameraPos;
891 // Current computed (OpenGL basis) ModelView matrix.
892 // NB: This matrix have already substracted the _PZBCameraPos
893 // Hence this matrix represent the Exact eye-space basis (only _ViewMtx is a bit tricky).
894 CMatrix _ModelViewMatrix;
896 // Fog.
897 bool _FogEnabled;
898 float _FogEnd, _FogStart;
899 GLfloat _CurrentFogColor[4];
903 // current viewport and scissor
904 CViewport _CurrViewport;
905 CScissor _CurrScissor;
907 // viewport before call to setRenderTarget, if BFO extension is supported
908 CViewport _OldViewport;
910 // Current FBO render target
911 CSmartPtr<ITexture> _RenderTargetFBO;
913 // Share the same backbuffer for FBO render targets with window size
914 std::vector<CDepthStencilFBO *> _DepthStencilFBOs;
916 // Num lights return by GL_MAX_LIGHTS
917 uint _MaxDriverLight;
918 // real mirror of GL state
919 uint _LightMode[MaxLight]; // Light mode.
920 CVector _WorldLightPos[MaxLight]; // World position of the lights.
921 CVector _WorldLightDirection[MaxLight]; // World direction of the lights.
922 bool _LightDirty[MaxLight]; // Light that need a View position setup in refreshRenderSetup().
923 // For Lightmap Dynamic Lighting
924 CLight _LightMapDynamicLight;
925 bool _LightMapDynamicLightEnabled;
926 bool _LightMapDynamicLightDirty;
927 // this is the backup of standard lighting (cause GL states may be modified by Lightmap Dynamic Lighting)
928 CLight _UserLight0;
929 bool _UserLightEnable[MaxLight];
931 //\name description of the per pixel light
932 // @{
933 void checkForPerPixelLightingSupport();
934 bool _SupportPerPixelShader;
935 bool _SupportPerPixelShaderNoSpec;
936 float _PPLExponent;
937 NLMISC::CRGBA _PPLightDiffuseColor;
938 NLMISC::CRGBA _PPLightSpecularColor;
939 // @}
943 /// \name Prec settings, for optimisation.
944 // @{
946 // Special Texture environnements.
947 enum CTexEnvSpecial {
948 TexEnvSpecialDisabled= 0,
949 TexEnvSpecialLightMap,
950 TexEnvSpecialSpecularStage1,
951 TexEnvSpecialSpecularStage1NoText,
952 TexEnvSpecialPPLStage0,
953 TexEnvSpecialPPLStage2,
954 TexEnvSpecialCloudStage0,
955 TexEnvSpecialCloudStage1
958 // NB: CRefPtr are not used for mem/spped optimisation. setupMaterial() and setupTexture() reset those states.
959 CMaterial* _CurrentMaterial;
960 CMaterial::TShader _CurrentMaterialSupportedShader;
962 /* NB : this pointers handles the caching of glBindTexture() and setTextureMode() calls.
964 ITexture* _CurrentTexture[IDRV_MAT_MAXTEXTURES];
966 CTextureDrvInfosGL* _CurrentTextureInfoGL[IDRV_MAT_MAXTEXTURES];
967 CMaterial::CTexEnv _CurrentTexEnv[IDRV_MAT_MAXTEXTURES];
968 // Special Texture Environnement.
969 CTexEnvSpecial _CurrentTexEnvSpecial[IDRV_MAT_MAXTEXTURES];
970 // Texture addressing mode
971 GLenum _CurrentTexAddrMode[IDRV_MAT_MAXTEXTURES];
972 // Reset texture shaders to their initial state if they are used
973 void resetTextureShaders();
974 /** set texture shaders from stage 0 to stage IDRV_MAT_MAXTEXTURES - 1
975 * textures are needed to setup the right kind of shader (cubic or 2d texture)
977 void setTextureShaders(const uint8 *addressingModes, const NLMISC::CSmartPtr<ITexture> *textures);
978 // activation of texture shaders
979 bool _NVTextureShaderEnabled;
980 // Which stages support EMBM
981 bool _StageSupportEMBM[IDRV_MAT_MAXTEXTURES];
982 // Anisotropic filtering value
983 float _AnisotropicFilter;
985 // Prec settings for material.
986 CDriverGLStates _DriverGLStates;
987 // Optim: To not test change in Materials states if just texture has changed. Very useful for landscape.
988 uint32 _MaterialAllTextureTouchedFlag;
990 // @}
992 bool _CurrentGlNormalize;
994 private:
995 bool createContext();
996 bool setupDisplay();
997 bool unInit();
999 bool createWindow(const GfxMode& mode);
1000 bool destroyWindow();
1002 enum EWindowStyle { EWSWindowed, EWSFullscreen };
1004 void setWindowSize(uint32 width, uint32 height);
1006 EWindowStyle getWindowStyle() const;
1007 bool setWindowStyle(EWindowStyle windowStyle);
1009 // Methods to manage screen resolutions
1010 bool restoreScreenMode();
1011 bool saveScreenMode();
1012 bool setScreenMode(const GfxMode &mode);
1014 // Test if cursor is in the client area. always true when software cursor is used and window visible
1015 // (displayed in software when DirectInput is used)
1016 bool isSystemCursorInClientArea();
1018 // Check if RGBA cursors are supported
1019 bool isAlphaBlendedCursorSupported();
1021 // Update cursor appearance
1022 void updateCursor(bool forceRebuild = false);
1024 // Create default cursors
1025 void createCursors();
1027 // Release all cursors
1028 void releaseCursors();
1030 // Convert a NLMISC::CBitmap to nlCursor
1031 bool convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &cursor, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY);
1033 // Return the best cursor size depending on specified width and height
1034 bool getBestCursorSize(uint srcWidth, uint srcHeight, uint &dstWidth, uint &dstHeight);
1036 // build a cursor from src, src should have the same size that the hardware cursor
1037 // or a assertion is thrown
1038 nlCursor buildCursor(const NLMISC::CBitmap &src, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY);
1040 // reset the cursor shape to the system arrow
1041 void setSystemArrow();
1043 // Get the proj matrix setupped in GL
1044 void refreshProjMatrixFromGL();
1046 bool setupVertexBuffer(CVertexBuffer& VB);
1047 // Activate Texture Environnement. Do it with caching.
1048 bool activateTexture(uint stage, ITexture *tex);
1049 // NB: this test _CurrentTexEnv[] and _CurrentTexEnvSpecial[].
1050 void activateTexEnvMode(uint stage, const CMaterial::CTexEnv &env);
1051 void activateTexEnvColor(uint stage, const CMaterial::CTexEnv &env);
1052 // Force Activate Texture Environnement. no caching here. TexEnvSpecial is disabled.
1053 void forceActivateTexEnvMode(uint stage, const CMaterial::CTexEnv &env);
1054 void activateTexEnvColor(uint stage, NLMISC::CRGBA col);
1055 void forceActivateTexEnvColor(uint stage, NLMISC::CRGBA col)
1057 static const float OO255= 1.0f/255;
1058 _CurrentTexEnv[stage].ConstantColor= col;
1059 // Setup the gl cte color.
1060 _DriverGLStates.activeTextureARB(stage);
1061 GLfloat glcol[4];
1062 glcol[0]= col.R*OO255;
1063 glcol[1]= col.G*OO255;
1064 glcol[2]= col.B*OO255;
1065 glcol[3]= col.A*OO255;
1066 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, glcol);
1068 void forceActivateTexEnvColor(uint stage, const CMaterial::CTexEnv &env)
1070 H_AUTO_OGL(CDriverGL_forceActivateTexEnvColor)
1071 forceActivateTexEnvColor(stage, env.ConstantColor);
1075 /// nv texture shaders. Should be used only if this caps is present!
1076 void enableNVTextureShader(bool enabled);
1077 // check nv texture shader consistency
1078 void verifyNVTextureShaderConfig();
1080 // Called by doRefreshRenderSetup(). set _LightSetupDirty to false
1081 void cleanLightSetup ();
1083 // According to extensions, retrieve GL tex format of the texture.
1084 GLint getGlTextureFormat(ITexture& tex, bool &compressed);
1087 // Clip the wanted rectangle with window. return true if rect is not NULL.
1088 bool clipRect(NLMISC::CRect &rect);
1090 // Copy the frame buffer to a texture
1091 void copyFrameBufferToTexture(ITexture *tex,
1092 uint32 level,
1093 uint32 offsetx,
1094 uint32 offsety,
1095 uint32 x,
1096 uint32 y,
1097 uint32 width,
1098 uint32 height,
1099 uint cubeFace = 0
1101 // is this texture a rectangle texture ?
1102 virtual bool isTextureRectangle(ITexture * tex) const;
1104 /// \name Material multipass.
1105 /** NB: setupMaterial() must be called before thoses methods.
1107 // @{
1108 /// init multipass for _CurrentMaterial. return number of pass required to render this material.
1109 sint beginMultiPass();
1110 /// active the ith pass of this material.
1111 void setupPass(uint pass);
1112 /// end multipass for this material.
1113 void endMultiPass();
1114 // @}
1116 /// LastVB for UV setup.
1117 CVertexBufferInfo _LastVB;
1118 CIndexBufferInfo _LastIB;
1120 /// setup a texture stage with an UV from VB.
1121 void setupUVPtr(uint stage, CVertexBufferInfo &VB, uint uvId);
1124 /// \name Lightmap.
1125 // @{
1126 void computeLightMapInfos(const CMaterial &mat);
1127 sint beginLightMapMultiPass();
1128 void setupLightMapPass(uint pass);
1129 void endLightMapMultiPass();
1131 /// Temp Variables computed in beginLightMapMultiPass(). Reused in setupLightMapPass().
1132 uint _NLightMaps;
1133 uint _NLightMapPerPass;
1134 uint _NLightMapPass;
1135 bool _LightMapNoMulAddFallBack;
1136 // This array is the LUT from lmapId in [0, _NLightMaps[, to original lightmap id in material.
1137 std::vector<uint> _LightMapLUT;
1139 // last stage env.
1140 CMaterial::CTexEnv _LightMapLastStageEnv;
1142 // Caching
1143 bool _LastVertexSetupIsLightMap;
1144 sint8 _LightMapUVMap[IDRV_MAT_MAXTEXTURES];
1146 // restore std vertex Setup.
1147 void resetLightMapVertexSetup();
1149 // @}
1151 /// \name Specular.
1152 // @{
1153 sint beginSpecularMultiPass();
1154 void setupSpecularPass(uint pass);
1155 void endSpecularMultiPass();
1156 void setupSpecularBegin();
1157 void setupSpecularEnd();
1158 bool _SpecularBatchOn;
1159 // @}
1162 /// \name Water
1163 // @{
1164 sint beginWaterMultiPass();
1165 void setupWaterPass(uint pass);
1166 void endWaterMultiPass();
1167 // @}
1169 /// \name Per pixel lighting
1170 // @{
1171 // per pixel lighting with specular
1172 sint beginPPLMultiPass();
1173 void setupPPLPass(uint pass);
1174 void endPPLMultiPass();
1176 // per pixel lighting, no specular
1177 sint beginPPLNoSpecMultiPass();
1178 void setupPPLNoSpecPass(uint pass);
1179 void endPPLNoSpecMultiPass();
1181 typedef NLMISC::CSmartPtr<CTextureCube> TSPTextureCube;
1182 typedef std::vector<TSPTextureCube> TTexCubeVect;
1183 TTexCubeVect _SpecularTextureCubes; // the cube maps used to compute the specular lighting.
1186 /// get (and if necessary, build) a cube map used for specular lighting. The range for exponent is limited, and only the best fit is used
1187 CTextureCube *getSpecularCubeMap(uint exp);
1189 // get (and if necessary, build) the cube map used for diffuse lighting
1190 CTextureCube *getDiffuseCubeMap() { return getSpecularCubeMap(1); }
1194 // @}
1196 /// \name Caustics
1197 // @{
1198 /*sint beginCausticsMultiPass(const CMaterial &mat);
1199 void setupCausticsPass(const CMaterial &mat, uint pass);
1200 void endCausticsMultiPass(const CMaterial &mat);*/
1201 // @}
1203 /// \name Cloud Shader
1204 sint beginCloudMultiPass ();
1205 void setupCloudPass (uint pass);
1206 void endCloudMultiPass ();
1207 // @}
1210 /// setup GL arrays, with a vb info.
1211 void setupGlArrays(CVertexBufferInfo &vb);
1213 /// Tools fct used by setupGLArrays
1214 void setupGlArraysStd(CVertexBufferInfo &vb);
1215 void setupGlArraysForNVVertexProgram(CVertexBufferInfo &vb);
1216 void setupGlArraysForARBVertexProgram(CVertexBufferInfo &vb);
1217 void setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb);
1218 void toggleGlArraysForNVVertexProgram();
1219 void toggleGlArraysForARBVertexProgram();
1220 void toggleGlArraysForEXTVertexShader();
1222 /// Test/activate normalisation of normal.
1223 void enableGlNormalize(bool normalize)
1225 if(_CurrentGlNormalize!=normalize)
1227 _CurrentGlNormalize= normalize;
1228 if(normalize)
1229 glEnable(GL_NORMALIZE);
1230 else
1231 glDisable(GL_NORMALIZE);
1235 // refresh matrixes and lights.
1236 void refreshRenderSetup()
1238 // check if something to change.
1239 if(_RenderSetupDirty)
1241 doRefreshRenderSetup();
1244 void doRefreshRenderSetup();
1246 void setLightInternal(uint8 num, const CLight& light);
1247 void enableLightInternal(uint8 num, bool enable);
1248 void setupLightMapDynamicLighting(bool enable);
1251 /// \name VertexBufferHard
1252 // @{
1253 CPtrSet<IVertexBufferHardGL> _VertexBufferHardSet;
1254 friend class CVertexArrayRangeNVidia;
1255 friend class CVertexBufferHardGLNVidia;
1256 friend class CVertexArrayRangeATI;
1257 friend class CVertexArrayRangeARB;
1258 friend class CVertexBufferHardARB;
1259 friend class CVertexBufferHardGLATI;
1260 friend class CVertexArrayRangeMapObjectATI;
1261 friend class CVertexBufferHardGLMapObjectATI;
1262 friend class CVBDrvInfosGL;
1264 // The VertexArrayRange activated.
1265 IVertexArrayRange *_CurrentVertexArrayRange;
1266 // The VertexBufferHardGL activated.
1267 IVertexBufferHardGL *_CurrentVertexBufferHard;
1268 // current setup passed to nglVertexArrayRangeNV()
1269 void *_NVCurrentVARPtr;
1270 uint32 _NVCurrentVARSize;
1272 // Info got from ATI or NVidia extension.
1273 bool _SupportVBHard;
1274 bool _SlowUnlockVBHard;
1275 uint32 _MaxVerticesByVBHard;
1277 // The AGP VertexArrayRange.
1278 IVertexArrayRange *_AGPVertexArrayRange;
1279 // The VRAM VertexArrayRange.
1280 IVertexArrayRange *_VRAMVertexArrayRange;
1283 void resetVertexArrayRange();
1285 void fenceOnCurVBHardIfNeeded(IVertexBufferHardGL *newVBHard);
1288 // @}
1291 /// \name Profiling
1292 // @{
1293 CPrimitiveProfile _PrimitiveProfileIn;
1294 CPrimitiveProfile _PrimitiveProfileOut;
1295 uint32 _AllocatedTextureMemory;
1296 uint32 _NbSetupMaterialCall;
1297 uint32 _NbSetupModelMatrixCall;
1298 bool _SumTextureMemoryUsed;
1299 std::vector<CTextureDrvInfosGL *> _TextureUsed;
1300 uint computeMipMapMemoryUsage(uint w, uint h, GLint glfmt) const;
1302 // VBHard Lock Profiling
1303 struct CVBHardProfile
1305 NLMISC::CRefPtr<CVertexBuffer> VBHard;
1306 NLMISC::TTicks AccumTime;
1307 // true if the VBHard was not always the same for the same chronogical place.
1308 bool Change;
1309 CVBHardProfile()
1311 AccumTime= 0;
1312 Change= false;
1315 // The Profiles in chronogical order.
1316 bool _VBHardProfiling;
1317 std::vector<CVBHardProfile> _VBHardProfiles;
1318 uint _CurVBHardLockCount;
1319 uint _NumVBHardProfileFrame;
1320 void appendVBHardLockProfile(NLMISC::TTicks time, CVertexBuffer *vb);
1322 // @}
1328 /// \name Vertex Program
1329 // @{
1331 // Order of preference
1332 // - activeVertexProgram
1333 // - CMaterial pass[n] VP (uses activeVertexProgram, but does not override if one already set by code)
1334 // - default generic VP that mimics fixed pipeline / no VP with fixed pipeline
1337 * Does the driver supports vertex program, but emulated by CPU ?
1339 virtual bool isVertexProgramEmulated() const;
1341 /** Return true if the driver supports the specified vertex program profile.
1343 virtual bool supportVertexProgram(CVertexProgram::TProfile profile) const;
1345 /** Compile the given vertex program, return if successful.
1346 * If a vertex program was set active before compilation,
1347 * the state of the active vertex program is undefined behaviour afterwards.
1349 virtual bool compileVertexProgram(CVertexProgram *program);
1351 /** Set the active vertex program. This will override vertex programs specified in CMaterial render calls.
1352 * Also used internally by setupMaterial(CMaterial) when getVertexProgram returns NULL.
1353 * The vertex program is activated immediately.
1355 virtual bool activeVertexProgram(CVertexProgram *program);
1356 // @}
1360 /// \name Pixel Program
1361 // @{
1363 // Order of preference
1364 // - activePixelProgram
1365 // - CMaterial pass[n] PP (uses activePixelProgram, but does not override if one already set by code)
1366 // - PP generated from CMaterial (uses activePixelProgram, but does not override if one already set by code)
1368 /** Return true if the driver supports the specified pixel program profile.
1370 virtual bool supportPixelProgram(CPixelProgram::TProfile profile = CPixelProgram::arbfp1) const;
1372 /** Compile the given pixel program, return if successful.
1373 * If a pixel program was set active before compilation,
1374 * the state of the active pixel program is undefined behaviour afterwards.
1376 virtual bool compilePixelProgram(CPixelProgram *program);
1378 /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls.
1379 * Also used internally by setupMaterial(CMaterial) when getPixelProgram returns NULL.
1380 * The pixel program is activated immediately.
1382 virtual bool activePixelProgram(CPixelProgram *program);
1383 // @}
1387 /// \name Geometry Program
1388 // @{
1390 // Order of preference
1391 // - activeGeometryProgram
1392 // - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code)
1393 // - none
1395 /** Return true if the driver supports the specified pixel program profile.
1397 virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const { return false; }
1399 /** Compile the given pixel program, return if successful.
1400 * If a pixel program was set active before compilation,
1401 * the state of the active pixel program is undefined behaviour afterwards.
1403 virtual bool compileGeometryProgram(CGeometryProgram *program) { return false; }
1405 /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls.
1406 * Also used internally by setupMaterial(CMaterial) when getGeometryProgram returns NULL.
1407 * The pixel program is activated immediately.
1409 virtual bool activeGeometryProgram(CGeometryProgram *program) { return false; }
1410 // @}
1414 /// \name Program parameters
1415 // @{
1416 // Set parameters
1417 inline void setUniform4fInl(TProgram program, uint index, float f0, float f1, float f2, float f3);
1418 inline void setUniform4fvInl(TProgram program, uint index, size_t num, const float *src);
1419 virtual void setUniform1f(TProgram program, uint index, float f0);
1420 virtual void setUniform2f(TProgram program, uint index, float f0, float f1);
1421 virtual void setUniform3f(TProgram program, uint index, float f0, float f1, float f2);
1422 virtual void setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3);
1423 virtual void setUniform1i(TProgram program, uint index, sint32 i0);
1424 virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1);
1425 virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2);
1426 virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3);
1427 virtual void setUniform1ui(TProgram program, uint index, uint32 ui0);
1428 virtual void setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1);
1429 virtual void setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2);
1430 virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3);
1431 virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v);
1432 virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3);
1433 virtual void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba);
1434 virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m);
1435 virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src);
1436 virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src);
1437 virtual void setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src);
1438 // Set builtin parameters
1439 virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform);
1440 virtual void setUniformFog(TProgram program, uint index);
1441 // Set feature parameters
1442 virtual bool isUniformProgramState() { return false; }
1443 // @}
1449 virtual void enableVertexProgramDoubleSidedColor(bool doubleSided);
1450 virtual bool supportVertexProgramDoubleSidedColor() const;
1452 virtual bool supportMADOperator() const ;
1456 /// \name Vertex program implementation
1457 // @{
1458 bool activeNVVertexProgram (CVertexProgram *program);
1459 bool activeARBVertexProgram (CVertexProgram *program);
1460 bool activeEXTVertexShader (CVertexProgram *program);
1462 bool compileNVVertexProgram (CVertexProgram *program);
1463 bool compileARBVertexProgram (CVertexProgram *program);
1464 bool compileEXTVertexShader (CVertexProgram *program);
1465 //@}
1468 /// \name Pixel program implementation
1469 // @{
1470 bool activeARBPixelProgram (CPixelProgram *program);
1471 bool setupPixelProgram (CPixelProgram *program, GLuint id/*, bool &specularWritten*/);
1472 //@}
1475 /// \fallback for material shaders
1476 // @{
1477 /// test whether the given shader is supported, and gives back a supported shader
1478 CMaterial::TShader getSupportedShader(CMaterial::TShader shader);
1479 // @}
1481 bool isVertexProgramEnabled () const
1483 // Don't use glIsEnabled, too slow.
1484 return _VertexProgramEnabled;
1487 bool isPixelProgramEnabled () const
1489 // Don't use glIsEnabled, too slow.
1490 return _PixelProgramEnabled;
1493 // Track state of activeVertexProgram()
1494 bool _VertexProgramEnabled;
1495 // Track state of activePixelProgram()
1496 bool _PixelProgramEnabled;
1498 // Say if last setupGlArrays() was a VertexProgram setup.
1499 bool _LastSetupGLArrayVertexProgram;
1501 // The last vertex program that was setupped
1502 NLMISC::CRefPtr<CVertexProgram> _LastSetuppedVP;
1504 // The last pixel program that was setupped
1505 NLMISC::CRefPtr<CPixelProgram> _LastSetuppedPP;
1507 bool _ForceDXTCCompression;
1508 /// Divisor for textureResize (power).
1509 uint _ForceTextureResizePower;
1510 // enforcement of native fragment program check
1511 bool _ForceNativeFragmentPrograms;
1514 // user texture matrix
1515 NLMISC::CMatrix _UserTexMat[IDRV_MAT_MAXTEXTURES];
1516 uint _UserTexMatEnabled; // bitm ask for user texture coords
1517 //NLMISC::CMatrix _UserTexMat[IDRV_MAT_MAXTEXTURES];
1519 // Static const
1520 static const uint NumCoordinatesType[CVertexBuffer::NumType];
1521 static const uint GLType[CVertexBuffer::NumType];
1522 static const uint GLVertexAttribIndex[CVertexBuffer::NumValue];
1523 static const bool GLTypeIsIntegral[CVertexBuffer::NumType];
1524 static const uint GLMatrix[IDriver::NumMatrix];
1525 static const uint GLTransform[IDriver::NumTransform];
1527 /// \name Caustics shaders
1528 // @{
1529 NLMISC::CSmartPtr<CTextureCube> _CausticCubeMap; // a cube map used for the rendering of caustics
1530 static void initCausticCubeMap();
1531 // @}
1533 /// Same as getNbTextureStages(), but faster because inline, and not virtual!!
1534 uint inlGetNumTextStages() const { return _Extensions.NbTextureStages; }
1537 NLMISC::CRGBA _CurrentBlendConstantColor;
1539 /// \name EXTVertexShader specifics.
1540 // @{
1541 // Variants offset used for :
1542 // Secondary color
1543 // Fog Coords
1544 // Skin Weight
1545 // Palette Skin
1546 // This mean that they must have 4 components
1547 public:
1548 enum EEVSVariants { EVSSecondaryColorVariant = 0, EVSFogCoordsVariant = 1, EVSSkinWeightVariant = 2, EVSPaletteSkinVariant = 3, EVSNumVariants };
1549 private:
1550 // Handle for standard gl arrays
1551 GLuint _EVSPositionHandle;
1552 GLuint _EVSNormalHandle;
1553 GLuint _EVSColorHandle;
1554 GLuint _EVSTexHandle[8];
1555 // Handle of the first constant c[0]. In vertex program we have 96 constant c[0] .. c[95]
1556 GLuint _EVSConstantHandle;
1557 // number of constant
1558 static const uint _EVSNumConstant;
1560 bool setupEXTVertexShader(const CVPParser::TProgram &program, GLuint id, uint variants[EVSNumVariants], uint16 &usedInputRegisters);
1561 bool setupARBVertexProgram (const CVPParser::TProgram &parsedProgram, GLuint id, bool &specularWritten);
1563 // @}
1565 // init EMBM settings (set each stage to modify the next)
1566 void initEMBM();
1570 // Monitor color parameters backup
1571 bool _NeedToRestoreGammaRamp;
1572 uint16 _GammaRampBackuped[3*256];
1575 /// \fragment shaders
1576 // @{
1578 GLuint ATIWaterShaderHandleNoDiffuseMap; // water support on R200
1579 GLuint ATIWaterShaderHandle; // water support on R200
1580 GLuint ATICloudShaderHandle; // cloud support for R200 and more
1582 GLuint ARBWaterShader[4]; // water support on R300, NV30 & the like
1585 void initFragmentShaders();
1586 void deleteFragmentShaders();
1587 void deleteARBFragmentPrograms();
1589 void setupWaterPassR200(const CMaterial &mat);
1590 void setupWaterPassARB(const CMaterial &mat);
1591 void setupWaterPassNV20(const CMaterial &mat);
1592 // @}
1595 bool _PolygonSmooth;
1597 // driver version for ATI hardware (0 if unknown)
1598 uint _ATIDriverVersion;
1599 bool _ATIFogRangeFixed;
1601 void retrieveATIDriverVersion();
1603 /// \Render to texture
1604 // @{
1605 CSmartPtr<ITexture> _TextureTarget;
1606 uint32 _TextureTargetLevel;
1607 uint32 _TextureTargetX;
1608 uint32 _TextureTargetY;
1609 uint32 _TextureTargetWidth;
1610 uint32 _TextureTargetHeight;
1611 bool _TextureTargetUpload;
1612 uint _TextureTargetCubeFace;
1613 // @}
1614 // misc
1615 public:
1616 friend class COcclusionQueryGL;
1617 static GLenum NLCubeFaceToGLCubeFace[6];
1618 static CMaterial::CTexEnv _TexEnvReplace;
1619 // occlusion query
1620 TOcclusionQueryList _OcclusionQueryList;
1621 COcclusionQueryGL *_CurrentOcclusionQuery;
1622 protected:
1623 // is the window active ,
1624 bool _WndActive;
1625 uint64 _SwapBufferCounter;
1626 public:
1627 void incrementResetCounter() { ++_ResetCounter; }
1628 bool isWndActive() const { return _WndActive; }
1629 const IVertexBufferHardGL *getCurrentVertexBufferHard() const { return _CurrentVertexBufferHard; }
1630 // For debug : dump list of mapped buffers
1631 #ifdef NL_DEBUG
1632 void dumpMappedBuffers();
1633 #endif
1635 emptyProc ExitFunc;
1637 // tmp for debug
1638 void checkTextureOn() const;
1639 private:
1640 /** Bind a texture at stage 0 for the good texture mode(2d or cube)
1641 * Parameters / part of the texture are ready to be changed in the gl after that
1642 * _CurrentTexture & _CurrentTextureInfoGL are not modified !
1644 inline void bindTextureWithMode(ITexture &tex);
1645 /** Force to set clamp & wrap mode for the given texture
1646 * Setup is done for texture currently bind to the gl, so calling bindTextureWithMode is necessary
1648 inline void setupTextureBasicParameters(ITexture &tex);
1652 // ***************************************************************************
1653 class CVertexProgamDrvInfosGL : public IProgramDrvInfos
1655 public:
1656 // The GL Id.
1657 GLuint ID;
1659 // ARB_vertex_program specific -> must know if specular part is written
1660 bool SpecularWritten;
1662 /** EXTVertexShader specific
1663 * handle of allocated variants
1665 GLuint Variants[CDriverGL::EVSNumVariants];
1666 /** EXTVertexShader specific
1667 * Used input registers.
1668 * This allow to activate only the gl arrays that are needed by a given shader.
1670 uint16 UsedVertexComponents;
1673 // The gl id is auto created here.
1674 CVertexProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it);
1676 virtual uint getUniformIndex(const char *name) const
1678 std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
1679 if (it != ParamIndices.end()) return it->second;
1680 return std::numeric_limits<uint>::max();
1683 std::map<std::string, uint> ParamIndices;
1686 // ***************************************************************************
1687 class CPixelProgamDrvInfosGL : public IProgramDrvInfos
1689 public:
1690 // The GL Id.
1691 GLuint ID;
1693 // The gl id is auto created here.
1694 CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it);
1696 virtual uint getUniformIndex(const char *name) const
1698 std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
1699 if (it != ParamIndices.end()) return it->second;
1700 return std::numeric_limits<uint>::max();
1703 std::map<std::string, uint> ParamIndices;
1706 #ifdef NL_STATIC
1707 } // NLDRIVERGL/ES
1708 #endif
1710 } // NL3D
1712 #endif // NL_DRIVER_OPENGL_H