Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / src / 3d / driver / opengl / driver_opengl.h
blobec9b59345b63ca3791ff48d9d28862b93f9cbef6
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010-2020 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 // Return monitor info and positon in multi monitor setup or false if monitor not found.
1003 bool getMonitorByName(const std::string &name, sint32 &x, sint32 &y, uint32 &w, uint32 &h) const;
1005 enum EWindowStyle { EWSWindowed, EWSFullscreen };
1007 void setWindowSize(uint32 width, uint32 height);
1009 EWindowStyle getWindowStyle() const;
1010 bool setWindowStyle(EWindowStyle windowStyle);
1012 // Methods to manage screen resolutions
1013 bool restoreScreenMode();
1014 bool saveScreenMode();
1015 bool setScreenMode(const GfxMode &mode);
1017 // Test if cursor is in the client area. always true when software cursor is used and window visible
1018 // (displayed in software when DirectInput is used)
1019 bool isSystemCursorInClientArea();
1021 // Check if RGBA cursors are supported
1022 bool isAlphaBlendedCursorSupported();
1024 // Update cursor appearance
1025 void updateCursor(bool forceRebuild = false);
1027 // Create default cursors
1028 void createCursors();
1030 // Release all cursors
1031 void releaseCursors();
1033 // Convert a NLMISC::CBitmap to nlCursor
1034 bool convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &cursor, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY);
1036 // Return the best cursor size depending on specified width and height
1037 bool getBestCursorSize(uint srcWidth, uint srcHeight, uint &dstWidth, uint &dstHeight);
1039 // build a cursor from src, src should have the same size that the hardware cursor
1040 // or a assertion is thrown
1041 nlCursor buildCursor(const NLMISC::CBitmap &src, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY);
1043 // reset the cursor shape to the system arrow
1044 void setSystemArrow();
1046 // Get the proj matrix setupped in GL
1047 void refreshProjMatrixFromGL();
1049 bool setupVertexBuffer(CVertexBuffer& VB);
1050 // Activate Texture Environnement. Do it with caching.
1051 bool activateTexture(uint stage, ITexture *tex);
1052 // NB: this test _CurrentTexEnv[] and _CurrentTexEnvSpecial[].
1053 void activateTexEnvMode(uint stage, const CMaterial::CTexEnv &env);
1054 void activateTexEnvColor(uint stage, const CMaterial::CTexEnv &env);
1055 // Force Activate Texture Environnement. no caching here. TexEnvSpecial is disabled.
1056 void forceActivateTexEnvMode(uint stage, const CMaterial::CTexEnv &env);
1057 void activateTexEnvColor(uint stage, NLMISC::CRGBA col);
1058 void forceActivateTexEnvColor(uint stage, NLMISC::CRGBA col)
1060 static const float OO255= 1.0f/255;
1061 _CurrentTexEnv[stage].ConstantColor= col;
1062 // Setup the gl cte color.
1063 _DriverGLStates.activeTextureARB(stage);
1064 GLfloat glcol[4];
1065 glcol[0]= col.R*OO255;
1066 glcol[1]= col.G*OO255;
1067 glcol[2]= col.B*OO255;
1068 glcol[3]= col.A*OO255;
1069 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, glcol);
1071 void forceActivateTexEnvColor(uint stage, const CMaterial::CTexEnv &env)
1073 H_AUTO_OGL(CDriverGL_forceActivateTexEnvColor)
1074 forceActivateTexEnvColor(stage, env.ConstantColor);
1078 /// nv texture shaders. Should be used only if this caps is present!
1079 void enableNVTextureShader(bool enabled);
1080 // check nv texture shader consistency
1081 void verifyNVTextureShaderConfig();
1083 // Called by doRefreshRenderSetup(). set _LightSetupDirty to false
1084 void cleanLightSetup ();
1086 // According to extensions, retrieve GL tex format of the texture.
1087 GLint getGlTextureFormat(ITexture& tex, bool &compressed);
1090 // Clip the wanted rectangle with window. return true if rect is not NULL.
1091 bool clipRect(NLMISC::CRect &rect);
1093 // Copy the frame buffer to a texture
1094 void copyFrameBufferToTexture(ITexture *tex,
1095 uint32 level,
1096 uint32 offsetx,
1097 uint32 offsety,
1098 uint32 x,
1099 uint32 y,
1100 uint32 width,
1101 uint32 height,
1102 uint cubeFace = 0
1104 // is this texture a rectangle texture ?
1105 virtual bool isTextureRectangle(ITexture * tex) const;
1107 /// \name Material multipass.
1108 /** NB: setupMaterial() must be called before thoses methods.
1110 // @{
1111 /// init multipass for _CurrentMaterial. return number of pass required to render this material.
1112 sint beginMultiPass();
1113 /// active the ith pass of this material.
1114 void setupPass(uint pass);
1115 /// end multipass for this material.
1116 void endMultiPass();
1117 // @}
1119 /// LastVB for UV setup.
1120 CVertexBufferInfo _LastVB;
1121 CIndexBufferInfo _LastIB;
1123 /// setup a texture stage with an UV from VB.
1124 void setupUVPtr(uint stage, CVertexBufferInfo &VB, uint uvId);
1127 /// \name Lightmap.
1128 // @{
1129 void computeLightMapInfos(const CMaterial &mat);
1130 sint beginLightMapMultiPass();
1131 void setupLightMapPass(uint pass);
1132 void endLightMapMultiPass();
1134 /// Temp Variables computed in beginLightMapMultiPass(). Reused in setupLightMapPass().
1135 uint _NLightMaps;
1136 uint _NLightMapPerPass;
1137 uint _NLightMapPass;
1138 bool _LightMapNoMulAddFallBack;
1139 // This array is the LUT from lmapId in [0, _NLightMaps[, to original lightmap id in material.
1140 std::vector<uint> _LightMapLUT;
1142 // last stage env.
1143 CMaterial::CTexEnv _LightMapLastStageEnv;
1145 // Caching
1146 bool _LastVertexSetupIsLightMap;
1147 sint8 _LightMapUVMap[IDRV_MAT_MAXTEXTURES];
1149 // restore std vertex Setup.
1150 void resetLightMapVertexSetup();
1152 // @}
1154 /// \name Specular.
1155 // @{
1156 sint beginSpecularMultiPass();
1157 void setupSpecularPass(uint pass);
1158 void endSpecularMultiPass();
1159 void setupSpecularBegin();
1160 void setupSpecularEnd();
1161 bool _SpecularBatchOn;
1162 // @}
1165 /// \name Water
1166 // @{
1167 sint beginWaterMultiPass();
1168 void setupWaterPass(uint pass);
1169 void endWaterMultiPass();
1170 // @}
1172 /// \name Per pixel lighting
1173 // @{
1174 // per pixel lighting with specular
1175 sint beginPPLMultiPass();
1176 void setupPPLPass(uint pass);
1177 void endPPLMultiPass();
1179 // per pixel lighting, no specular
1180 sint beginPPLNoSpecMultiPass();
1181 void setupPPLNoSpecPass(uint pass);
1182 void endPPLNoSpecMultiPass();
1184 typedef NLMISC::CSmartPtr<CTextureCube> TSPTextureCube;
1185 typedef std::vector<TSPTextureCube> TTexCubeVect;
1186 TTexCubeVect _SpecularTextureCubes; // the cube maps used to compute the specular lighting.
1189 /// 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
1190 CTextureCube *getSpecularCubeMap(uint exp);
1192 // get (and if necessary, build) the cube map used for diffuse lighting
1193 CTextureCube *getDiffuseCubeMap() { return getSpecularCubeMap(1); }
1197 // @}
1199 /// \name Caustics
1200 // @{
1201 /*sint beginCausticsMultiPass(const CMaterial &mat);
1202 void setupCausticsPass(const CMaterial &mat, uint pass);
1203 void endCausticsMultiPass(const CMaterial &mat);*/
1204 // @}
1206 /// \name Cloud Shader
1207 sint beginCloudMultiPass ();
1208 void setupCloudPass (uint pass);
1209 void endCloudMultiPass ();
1210 // @}
1213 /// setup GL arrays, with a vb info.
1214 void setupGlArrays(CVertexBufferInfo &vb);
1216 /// Tools fct used by setupGLArrays
1217 void setupGlArraysStd(CVertexBufferInfo &vb);
1218 void setupGlArraysForNVVertexProgram(CVertexBufferInfo &vb);
1219 void setupGlArraysForARBVertexProgram(CVertexBufferInfo &vb);
1220 void setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb);
1221 void toggleGlArraysForNVVertexProgram();
1222 void toggleGlArraysForARBVertexProgram();
1223 void toggleGlArraysForEXTVertexShader();
1225 /// Test/activate normalisation of normal.
1226 void enableGlNormalize(bool normalize)
1228 if(_CurrentGlNormalize!=normalize)
1230 _CurrentGlNormalize= normalize;
1231 if(normalize)
1232 glEnable(GL_NORMALIZE);
1233 else
1234 glDisable(GL_NORMALIZE);
1238 // refresh matrixes and lights.
1239 void refreshRenderSetup()
1241 // check if something to change.
1242 if(_RenderSetupDirty)
1244 doRefreshRenderSetup();
1247 void doRefreshRenderSetup();
1249 void setLightInternal(uint8 num, const CLight& light);
1250 void enableLightInternal(uint8 num, bool enable);
1251 void setupLightMapDynamicLighting(bool enable);
1254 /// \name VertexBufferHard
1255 // @{
1256 CPtrSet<IVertexBufferHardGL> _VertexBufferHardSet;
1257 friend class CVertexArrayRangeNVidia;
1258 friend class CVertexBufferHardGLNVidia;
1259 friend class CVertexArrayRangeATI;
1260 friend class CVertexArrayRangeARB;
1261 friend class CVertexBufferHardARB;
1262 friend class CVertexBufferHardGLATI;
1263 friend class CVertexArrayRangeMapObjectATI;
1264 friend class CVertexBufferHardGLMapObjectATI;
1265 friend class CVBDrvInfosGL;
1267 // The VertexArrayRange activated.
1268 IVertexArrayRange *_CurrentVertexArrayRange;
1269 // The VertexBufferHardGL activated.
1270 IVertexBufferHardGL *_CurrentVertexBufferHard;
1271 // current setup passed to nglVertexArrayRangeNV()
1272 void *_NVCurrentVARPtr;
1273 uint32 _NVCurrentVARSize;
1275 // Info got from ATI or NVidia extension.
1276 bool _SupportVBHard;
1277 bool _SlowUnlockVBHard;
1278 uint32 _MaxVerticesByVBHard;
1280 // The AGP VertexArrayRange.
1281 IVertexArrayRange *_AGPVertexArrayRange;
1282 // The VRAM VertexArrayRange.
1283 IVertexArrayRange *_VRAMVertexArrayRange;
1286 void resetVertexArrayRange();
1288 void fenceOnCurVBHardIfNeeded(IVertexBufferHardGL *newVBHard);
1291 // @}
1294 /// \name Profiling
1295 // @{
1296 CPrimitiveProfile _PrimitiveProfileIn;
1297 CPrimitiveProfile _PrimitiveProfileOut;
1298 uint32 _AllocatedTextureMemory;
1299 uint32 _NbSetupMaterialCall;
1300 uint32 _NbSetupModelMatrixCall;
1301 bool _SumTextureMemoryUsed;
1302 std::vector<CTextureDrvInfosGL *> _TextureUsed;
1303 uint computeMipMapMemoryUsage(uint w, uint h, GLint glfmt) const;
1305 // VBHard Lock Profiling
1306 struct CVBHardProfile
1308 NLMISC::CRefPtr<CVertexBuffer> VBHard;
1309 NLMISC::TTicks AccumTime;
1310 // true if the VBHard was not always the same for the same chronogical place.
1311 bool Change;
1312 CVBHardProfile()
1314 AccumTime= 0;
1315 Change= false;
1318 // The Profiles in chronogical order.
1319 bool _VBHardProfiling;
1320 std::vector<CVBHardProfile> _VBHardProfiles;
1321 uint _CurVBHardLockCount;
1322 uint _NumVBHardProfileFrame;
1323 void appendVBHardLockProfile(NLMISC::TTicks time, CVertexBuffer *vb);
1325 // @}
1331 /// \name Vertex Program
1332 // @{
1334 // Order of preference
1335 // - activeVertexProgram
1336 // - CMaterial pass[n] VP (uses activeVertexProgram, but does not override if one already set by code)
1337 // - default generic VP that mimics fixed pipeline / no VP with fixed pipeline
1340 * Does the driver supports vertex program, but emulated by CPU ?
1342 virtual bool isVertexProgramEmulated() const;
1344 /** Return true if the driver supports the specified vertex program profile.
1346 virtual bool supportVertexProgram(CVertexProgram::TProfile profile) const;
1348 /** Compile the given vertex program, return if successful.
1349 * If a vertex program was set active before compilation,
1350 * the state of the active vertex program is undefined behaviour afterwards.
1352 virtual bool compileVertexProgram(CVertexProgram *program);
1354 /** Set the active vertex program. This will override vertex programs specified in CMaterial render calls.
1355 * Also used internally by setupMaterial(CMaterial) when getVertexProgram returns NULL.
1356 * The vertex program is activated immediately.
1358 virtual bool activeVertexProgram(CVertexProgram *program);
1359 // @}
1363 /// \name Pixel Program
1364 // @{
1366 // Order of preference
1367 // - activePixelProgram
1368 // - CMaterial pass[n] PP (uses activePixelProgram, but does not override if one already set by code)
1369 // - PP generated from CMaterial (uses activePixelProgram, but does not override if one already set by code)
1371 /** Return true if the driver supports the specified pixel program profile.
1373 virtual bool supportPixelProgram(CPixelProgram::TProfile profile = CPixelProgram::arbfp1) const;
1375 /** Compile the given pixel program, return if successful.
1376 * If a pixel program was set active before compilation,
1377 * the state of the active pixel program is undefined behaviour afterwards.
1379 virtual bool compilePixelProgram(CPixelProgram *program);
1381 /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls.
1382 * Also used internally by setupMaterial(CMaterial) when getPixelProgram returns NULL.
1383 * The pixel program is activated immediately.
1385 virtual bool activePixelProgram(CPixelProgram *program);
1386 // @}
1390 /// \name Geometry Program
1391 // @{
1393 // Order of preference
1394 // - activeGeometryProgram
1395 // - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code)
1396 // - none
1398 /** Return true if the driver supports the specified pixel program profile.
1400 virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const { return false; }
1402 /** Compile the given pixel program, return if successful.
1403 * If a pixel program was set active before compilation,
1404 * the state of the active pixel program is undefined behaviour afterwards.
1406 virtual bool compileGeometryProgram(CGeometryProgram *program) { return false; }
1408 /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls.
1409 * Also used internally by setupMaterial(CMaterial) when getGeometryProgram returns NULL.
1410 * The pixel program is activated immediately.
1412 virtual bool activeGeometryProgram(CGeometryProgram *program) { return false; }
1413 // @}
1417 /// \name Program parameters
1418 // @{
1419 // Set parameters
1420 inline void setUniform4fInl(TProgram program, uint index, float f0, float f1, float f2, float f3);
1421 inline void setUniform4fvInl(TProgram program, uint index, size_t num, const float *src);
1422 virtual void setUniform1f(TProgram program, uint index, float f0);
1423 virtual void setUniform2f(TProgram program, uint index, float f0, float f1);
1424 virtual void setUniform3f(TProgram program, uint index, float f0, float f1, float f2);
1425 virtual void setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3);
1426 virtual void setUniform1i(TProgram program, uint index, sint32 i0);
1427 virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1);
1428 virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2);
1429 virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3);
1430 virtual void setUniform1ui(TProgram program, uint index, uint32 ui0);
1431 virtual void setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1);
1432 virtual void setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2);
1433 virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3);
1434 virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v);
1435 virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3);
1436 virtual void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba);
1437 virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m);
1438 virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src);
1439 virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src);
1440 virtual void setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src);
1441 // Set builtin parameters
1442 virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform);
1443 virtual void setUniformFog(TProgram program, uint index);
1444 // Set feature parameters
1445 virtual bool isUniformProgramState() { return false; }
1446 // @}
1452 virtual void enableVertexProgramDoubleSidedColor(bool doubleSided);
1453 virtual bool supportVertexProgramDoubleSidedColor() const;
1455 virtual bool supportMADOperator() const ;
1459 /// \name Vertex program implementation
1460 // @{
1461 bool activeNVVertexProgram (CVertexProgram *program);
1462 bool activeARBVertexProgram (CVertexProgram *program);
1463 bool activeEXTVertexShader (CVertexProgram *program);
1465 bool compileNVVertexProgram (CVertexProgram *program);
1466 bool compileARBVertexProgram (CVertexProgram *program);
1467 bool compileEXTVertexShader (CVertexProgram *program);
1468 //@}
1471 /// \name Pixel program implementation
1472 // @{
1473 bool activeARBPixelProgram (CPixelProgram *program);
1474 bool setupPixelProgram (CPixelProgram *program, GLuint id/*, bool &specularWritten*/);
1475 //@}
1478 /// \fallback for material shaders
1479 // @{
1480 /// test whether the given shader is supported, and gives back a supported shader
1481 CMaterial::TShader getSupportedShader(CMaterial::TShader shader);
1482 // @}
1484 bool isVertexProgramEnabled () const
1486 // Don't use glIsEnabled, too slow.
1487 return _VertexProgramEnabled;
1490 bool isPixelProgramEnabled () const
1492 // Don't use glIsEnabled, too slow.
1493 return _PixelProgramEnabled;
1496 // Track state of activeVertexProgram()
1497 bool _VertexProgramEnabled;
1498 // Track state of activePixelProgram()
1499 bool _PixelProgramEnabled;
1501 // Say if last setupGlArrays() was a VertexProgram setup.
1502 bool _LastSetupGLArrayVertexProgram;
1504 // The last vertex program that was setupped
1505 NLMISC::CRefPtr<CVertexProgram> _LastSetuppedVP;
1507 // The last pixel program that was setupped
1508 NLMISC::CRefPtr<CPixelProgram> _LastSetuppedPP;
1510 bool _ForceDXTCCompression;
1511 /// Divisor for textureResize (power).
1512 uint _ForceTextureResizePower;
1513 // enforcement of native fragment program check
1514 bool _ForceNativeFragmentPrograms;
1517 // user texture matrix
1518 NLMISC::CMatrix _UserTexMat[IDRV_MAT_MAXTEXTURES];
1519 uint _UserTexMatEnabled; // bitm ask for user texture coords
1520 //NLMISC::CMatrix _UserTexMat[IDRV_MAT_MAXTEXTURES];
1522 // Static const
1523 static const uint NumCoordinatesType[CVertexBuffer::NumType];
1524 static const uint GLType[CVertexBuffer::NumType];
1525 static const uint GLVertexAttribIndex[CVertexBuffer::NumValue];
1526 static const bool GLTypeIsIntegral[CVertexBuffer::NumType];
1527 static const uint GLMatrix[IDriver::NumMatrix];
1528 static const uint GLTransform[IDriver::NumTransform];
1530 /// \name Caustics shaders
1531 // @{
1532 NLMISC::CSmartPtr<CTextureCube> _CausticCubeMap; // a cube map used for the rendering of caustics
1533 static void initCausticCubeMap();
1534 // @}
1536 /// Same as getNbTextureStages(), but faster because inline, and not virtual!!
1537 uint inlGetNumTextStages() const { return _Extensions.NbTextureStages; }
1540 NLMISC::CRGBA _CurrentBlendConstantColor;
1542 /// \name EXTVertexShader specifics.
1543 // @{
1544 // Variants offset used for :
1545 // Secondary color
1546 // Fog Coords
1547 // Skin Weight
1548 // Palette Skin
1549 // This mean that they must have 4 components
1550 public:
1551 enum EEVSVariants { EVSSecondaryColorVariant = 0, EVSFogCoordsVariant = 1, EVSSkinWeightVariant = 2, EVSPaletteSkinVariant = 3, EVSNumVariants };
1552 private:
1553 // Handle for standard gl arrays
1554 GLuint _EVSPositionHandle;
1555 GLuint _EVSNormalHandle;
1556 GLuint _EVSColorHandle;
1557 GLuint _EVSTexHandle[8];
1558 // Handle of the first constant c[0]. In vertex program we have 96 constant c[0] .. c[95]
1559 GLuint _EVSConstantHandle;
1560 // number of constant
1561 static const uint _EVSNumConstant;
1563 bool setupEXTVertexShader(const CVPParser::TProgram &program, GLuint id, uint variants[EVSNumVariants], uint16 &usedInputRegisters);
1564 bool setupARBVertexProgram (const CVPParser::TProgram &parsedProgram, GLuint id, bool &specularWritten);
1566 // @}
1568 // init EMBM settings (set each stage to modify the next)
1569 void initEMBM();
1573 // Monitor color parameters backup
1574 bool _NeedToRestoreGammaRamp;
1575 uint16 _GammaRampBackuped[3*256];
1578 /// \fragment shaders
1579 // @{
1581 GLuint ATIWaterShaderHandleNoDiffuseMap; // water support on R200
1582 GLuint ATIWaterShaderHandle; // water support on R200
1583 GLuint ATICloudShaderHandle; // cloud support for R200 and more
1585 GLuint ARBWaterShader[4]; // water support on R300, NV30 & the like
1588 void initFragmentShaders();
1589 void deleteFragmentShaders();
1590 void deleteARBFragmentPrograms();
1592 void setupWaterPassR200(const CMaterial &mat);
1593 void setupWaterPassARB(const CMaterial &mat);
1594 void setupWaterPassNV20(const CMaterial &mat);
1595 // @}
1598 bool _PolygonSmooth;
1600 // driver version for ATI hardware (0 if unknown)
1601 uint _ATIDriverVersion;
1602 bool _ATIFogRangeFixed;
1604 void retrieveATIDriverVersion();
1606 /// \Render to texture
1607 // @{
1608 CSmartPtr<ITexture> _TextureTarget;
1609 uint32 _TextureTargetLevel;
1610 uint32 _TextureTargetX;
1611 uint32 _TextureTargetY;
1612 uint32 _TextureTargetWidth;
1613 uint32 _TextureTargetHeight;
1614 bool _TextureTargetUpload;
1615 uint _TextureTargetCubeFace;
1616 // @}
1617 // misc
1618 public:
1619 friend class COcclusionQueryGL;
1620 static GLenum NLCubeFaceToGLCubeFace[6];
1621 static CMaterial::CTexEnv _TexEnvReplace;
1622 // occlusion query
1623 TOcclusionQueryList _OcclusionQueryList;
1624 COcclusionQueryGL *_CurrentOcclusionQuery;
1625 protected:
1626 // is the window active ,
1627 bool _WndActive;
1628 uint64 _SwapBufferCounter;
1629 public:
1630 void incrementResetCounter() { ++_ResetCounter; }
1631 bool isWndActive() const { return _WndActive; }
1632 const IVertexBufferHardGL *getCurrentVertexBufferHard() const { return _CurrentVertexBufferHard; }
1633 // For debug : dump list of mapped buffers
1634 #ifdef NL_DEBUG
1635 void dumpMappedBuffers();
1636 #endif
1638 emptyProc ExitFunc;
1640 // tmp for debug
1641 void checkTextureOn() const;
1642 private:
1643 /** Bind a texture at stage 0 for the good texture mode(2d or cube)
1644 * Parameters / part of the texture are ready to be changed in the gl after that
1645 * _CurrentTexture & _CurrentTextureInfoGL are not modified !
1647 inline void bindTextureWithMode(ITexture &tex);
1648 /** Force to set clamp & wrap mode for the given texture
1649 * Setup is done for texture currently bind to the gl, so calling bindTextureWithMode is necessary
1651 inline void setupTextureBasicParameters(ITexture &tex);
1655 // ***************************************************************************
1656 class CVertexProgamDrvInfosGL : public IProgramDrvInfos
1658 public:
1659 // The GL Id.
1660 GLuint ID;
1662 // ARB_vertex_program specific -> must know if specular part is written
1663 bool SpecularWritten;
1665 /** EXTVertexShader specific
1666 * handle of allocated variants
1668 GLuint Variants[CDriverGL::EVSNumVariants];
1669 /** EXTVertexShader specific
1670 * Used input registers.
1671 * This allow to activate only the gl arrays that are needed by a given shader.
1673 uint16 UsedVertexComponents;
1676 // The gl id is auto created here.
1677 CVertexProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it);
1679 virtual uint getUniformIndex(const char *name) const
1681 std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
1682 if (it != ParamIndices.end()) return it->second;
1683 return std::numeric_limits<uint>::max();
1686 std::map<std::string, uint> ParamIndices;
1689 // ***************************************************************************
1690 class CPixelProgamDrvInfosGL : public IProgramDrvInfos
1692 public:
1693 // The GL Id.
1694 GLuint ID;
1696 // The gl id is auto created here.
1697 CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it);
1699 virtual uint getUniformIndex(const char *name) const
1701 std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
1702 if (it != ParamIndices.end()) return it->second;
1703 return std::numeric_limits<uint>::max();
1706 std::map<std::string, uint> ParamIndices;
1709 #ifdef NL_STATIC
1710 } // NLDRIVERGL/ES
1711 #endif
1713 } // NL3D
1715 #endif // NL_DRIVER_OPENGL_H