Merge branch 'main/rendor-staging' into fixes
[ryzomcore.git] / nel / src / 3d / driver / direct3d / driver_direct3d.h
blobeed6c222dc878f549c5eebaf8f6d747c362ecc5b
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) 2013-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 //
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #ifndef NL_DRIVER_DIRECT3D_H
22 #define NL_DRIVER_DIRECT3D_H
25 #include "nel/misc/types_nl.h"
27 // NeL includes
28 #include "nel/misc/matrix.h"
29 #include "nel/misc/smart_ptr.h"
30 #include "nel/misc/rgba.h"
31 #include "nel/misc/event_emitter.h"
32 #include "nel/misc/bit_set.h"
33 #include "nel/misc/heap_memory.h"
34 #include "nel/misc/event_emitter_multi.h"
35 #include "nel/misc/time_nl.h"
36 #include "nel/misc/hierarchical_timer.h"
37 #include "nel/misc/win_event_emitter.h"
38 #include "nel/3d/viewport.h"
39 #include "nel/3d/scissor.h"
40 #include "nel/3d/driver.h"
41 #include "nel/3d/material.h"
42 #include "nel/3d/vertex_buffer.h"
43 #include "nel/3d/index_buffer.h"
44 #include "nel/3d/ptr_set.h"
45 #include "nel/3d/texture_cube.h"
46 #include "nel/3d/occlusion_query.h"
47 #include "nel/3d/vertex_program_parse.h"
48 #include "nel/3d/light.h"
50 #include <algorithm>
52 typedef HCURSOR nlCursor;
53 #define EmptyCursor NULL
56 // *** DEBUG MACRO
58 // Define this to activate the debug mode (default is undefined)
59 //#define NL_DEBUG_D3D
61 // Define this to enable the render state caching (default is defined)
62 #define NL_D3D_USE_RENDER_STATE_CACHE
64 // allows to enable / disable cache test at runtime (for debug)
65 //#define NL_D3D_RUNTIME_DEBUG_CACHE_TEST
66 #ifdef NL_D3D_RUNTIME_DEBUG_CACHE_TEST
67 #define NL_D3D_CACHE_TEST(label, cond) if (!_CacheTest[label] || (cond))
68 #else
69 #define NL_D3D_CACHE_TEST(label, cond) if (cond)
70 #endif
73 // Define this to disable hardware vertex program (default is undefined)
74 //#define NL_DISABLE_HARDWARE_VERTEX_PROGAM
76 // Define this to disable hardware pixel shaders program (default is undefined)
77 //#define NL_DISABLE_HARDWARE_PIXEL_SHADER
79 // Define this to disable hardware vertex array AGP (default is undefined)
80 //#define NL_DISABLE_HARDWARE_VERTEX_ARRAY_AGP
82 // Define this to force the texture stage count (default is undefined)
83 //#define NL_FORCE_TEXTURE_STAGE_COUNT 2
85 // Define this to force the use of pixel shader in the normal shaders (default is undefined)
86 //#define NL_FORCE_PIXEL_SHADER_USE_FOR_NORMAL_SHADERS
88 // Define this to enable profiling by the NV Perf HUD tool (default is undefined)
89 //#define NL_D3D_USE_NV_PERF_HUD
91 // Define this to enable profiling of driver functions (default is undefined).
92 //#define NL_PROFILE_DRIVER_D3D
96 #ifdef NL_PROFILE_DRIVER_D3D
97 #define H_AUTO_D3D(label) H_AUTO(label)
98 #else
99 #define H_AUTO_D3D(label)
100 #endif
102 class CFpuRestorer
104 public:
105 CFpuRestorer() { _FPControlWord = _controlfp(0, 0); }
106 ~CFpuRestorer()
108 _controlfp(_FPControlWord, ~0);
110 private:
111 unsigned int _FPControlWord;
114 class CFpuChecker
116 public:
117 CFpuChecker(const char *label) { _FPControlWord = _controlfp(0, 0); _Label = label; }
118 ~CFpuChecker()
120 unsigned int newFP = _controlfp(0, 0);
121 if ((newFP & (_MCW_DN | _MCW_IC | _MCW_RC | _MCW_PC)) != (_FPControlWord & (_MCW_DN | _MCW_IC | _MCW_RC | _MCW_PC)))
123 nlwarning(_Label);
124 nlassert(0);
127 private:
128 const char *_Label;
129 unsigned int _FPControlWord;
135 inline bool operator==(const D3DCOLORVALUE &lhs, const D3DCOLORVALUE &rhs)
137 return lhs.r == rhs.r && lhs.g == rhs.g && lhs.b == rhs.b && lhs.a == rhs.a;
139 inline bool operator!=(const D3DCOLORVALUE &lhs, const D3DCOLORVALUE &rhs)
141 return !(lhs == rhs);
148 // ***************************************************************************
150 namespace NL3D
155 const uint MAX_NUM_QUADS = 32767; // max number of quads in a single draw call
157 using NLMISC::CMatrix;
158 using NLMISC::CVector;
160 class CDriverD3D;
161 class CTextureDrvInfosD3D;
162 class COcclusionQueryD3D;
163 class CVolatileVertexBuffer;
164 class CVolatileIndexBuffer;
166 typedef std::list<COcclusionQueryD3D *> TOcclusionQueryList;
168 // ***************************************************************************
169 class COcclusionQueryD3D : public IOcclusionQuery
171 public:
172 IDirect3DQuery9 *Query;
173 NLMISC::CRefPtr<CDriverD3D> Driver; // owner driver
174 TOcclusionQueryList::iterator Iterator; // iterator in owner driver list of queries
175 TOcclusionType OcclusionType; // current type of occlusion
176 uint VisibleCount; // number of samples that passed the test
177 bool QueryIssued;
178 bool WasLost; // tells that query was lost, so calls to end() will have not effects (there's no matching begin)
179 // From IOcclusionQuery
180 virtual void begin();
181 virtual void end();
182 virtual TOcclusionType getOcclusionType();
183 virtual uint getVisibleCount();
187 using NLMISC::CRefCount;
190 class IDriver;
191 class CDriverD3D;
193 // List typedef.
194 class IShaderDrvInfos;
195 typedef std::list<IShaderDrvInfos*> TShaderDrvInfoPtrList;
196 typedef TShaderDrvInfoPtrList::iterator ItShaderDrvInfoPtrList;
199 * Interface for shader driver infos.
201 class IShaderDrvInfos : public CRefCount
203 private:
204 CDriverD3D *_Driver;
205 ItShaderDrvInfoPtrList _DriverIterator;
207 public:
208 IShaderDrvInfos(CDriverD3D *drv, ItShaderDrvInfoPtrList it) {_Driver= drv; _DriverIterator= it;}
209 // The virtual dtor is important.
210 virtual ~IShaderDrvInfos();
215 * Shader resource for the driver. It is just a container for a ".fx" text file.
217 /* *** IMPORTANT ********************
218 * *** IF YOU MODIFY THE STRUCTURE OF THIS CLASS, PLEASE INCREMENT IDriver::InterfaceVersion TO INVALIDATE OLD DRIVER DLL
219 * **********************************
221 // --------------------------------------------------
222 class CD3DShaderFX
224 public:
225 CD3DShaderFX();
226 ~CD3DShaderFX();
228 // Load a shader file
229 bool loadShaderFile (const char *filename);
231 // Set the shader text
232 void setText (const char *text);
234 // Get the shader text
235 const char *getText () const { return _Text.c_str(); }
237 // Set the shader name
238 void setName (const char *name);
240 // Get the shader name
241 const char *getName () const { return _Name.c_str(); }
243 public:
244 // Private. For Driver only.
245 bool _ShaderChanged;
246 NLMISC::CRefPtr<IShaderDrvInfos> _DrvInfo;
247 private:
248 // The shader
249 std::string _Text;
250 // The shader name
251 std::string _Name;
256 // ***************************************************************************
257 class CTextureDrvInfosD3D : public ITextureDrvInfos
259 public:
261 ANY DATA ADDED HERE MUST BE SWAPPED IN swapTextureHandle() !!
264 // The texture
265 LPDIRECT3DBASETEXTURE9 Texture;
266 IDirect3DTexture9 *Texture2d;
267 IDirect3DCubeTexture9 *TextureCube;
269 // The texture format and size
270 D3DFORMAT DestFormat;
271 uint Width;
272 uint Height;
274 // This is the owner driver.
275 CDriverD3D *_Driver;
277 // Is the internal format of the texture is a compressed one?
278 bool SrcCompressed;
279 bool IsCube;
281 // Is a render target ?
282 bool RenderTarget;
284 // Mipmap levels
285 uint8 Levels;
286 uint8 FirstMipMap;
288 // This is the computed size of what memory this texture take.
289 uint32 TextureMemory;
291 // The current wrap modes assigned to the texture.
292 D3DTEXTUREADDRESS WrapS;
293 D3DTEXTUREADDRESS WrapT;
294 D3DTEXTUREFILTERTYPE MagFilter;
295 D3DTEXTUREFILTERTYPE MinFilter;
296 D3DTEXTUREFILTERTYPE MipFilter;
298 CTextureDrvInfosD3D(IDriver *drv, ItTexDrvInfoPtrMap it, CDriverD3D *drvGl, bool renderTarget);
299 ~CTextureDrvInfosD3D();
300 virtual uint getTextureMemoryUsed() const {return TextureMemory;}
305 // ***************************************************************************
306 class CVertexProgamDrvInfosD3D : public IProgramDrvInfos
308 public:
310 // The shader
311 IDirect3DVertexShader9 *Shader;
313 CVertexProgamDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it);
314 ~CVertexProgamDrvInfosD3D();
316 virtual uint getUniformIndex(const char *name) const
318 std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
319 if (it != ParamIndices.end()) return it->second;
320 return std::numeric_limits<uint>::max();
323 std::map<std::string, uint> ParamIndices;
327 // ***************************************************************************
328 class CPixelProgramDrvInfosD3D : public IProgramDrvInfos
330 public:
332 // The shader
333 IDirect3DPixelShader9 *Shader;
335 CPixelProgramDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it);
336 ~CPixelProgramDrvInfosD3D();
338 virtual uint getUniformIndex(const char *name) const
340 std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
341 if (it != ParamIndices.end()) return it->second;
342 return std::numeric_limits<uint>::max();
345 std::map<std::string, uint> ParamIndices;
349 // ***************************************************************************
351 class CVertexDeclaration
353 public:
354 // The human readable values
355 D3DVERTEXELEMENT9 VertexElements[CVertexBuffer::NumValue+1];
357 // The driver pointer
358 IDirect3DVertexDeclaration9 *VertexDecl;
362 // ***************************************************************************
363 class CVBDrvInfosD3D : public IVBDrvInfos
365 public:
366 IDirect3DVertexDeclaration9 *VertexDecl;
367 IDirect3DVertexDeclaration9 *VertexDeclAliasDiffuseToSpecular;
368 IDirect3DVertexDeclaration9 *VertexDeclNoDiffuse;
369 uint ColorOffset; // Fix for Radeon 7xxx series -> see remarks in CDriverD3D::createVertexDeclaration
372 IDirect3DVertexBuffer9 *VertexBuffer;
373 uint Offset; // Vertex buffer offset
374 bool UseVertexColor:1;
375 bool Hardware:1;
376 bool Volatile:1; // Volatile vertex buffer
377 bool VolatileRAM:1;
378 uint8 Stride:8;
379 uint VolatileLockTime; // Volatile vertex buffer
380 DWORD Usage;
381 CVolatileVertexBuffer *VolatileVertexBuffer;
382 CDriverD3D *Driver;
383 #ifdef NL_DEBUG
384 bool Locked;
385 #endif
387 CVBDrvInfosD3D(CDriverD3D *drv, ItVBDrvInfoPtrList it, CVertexBuffer *vb);
388 virtual ~CVBDrvInfosD3D();
389 virtual uint8 *lock (uint first, uint last, bool readOnly);
390 virtual void unlock (uint first, uint last);
395 // ***************************************************************************
397 class CIBDrvInfosD3D : public IIBDrvInfos
399 public:
400 IDirect3DIndexBuffer9 *IndexBuffer;
401 uint Offset; // Index buffer offset
402 bool Volatile:1; // Volatile index buffer
403 bool VolatileRAM:1;
404 uint VolatileLockTime; // Volatile index buffer
405 CVolatileIndexBuffer *VolatileIndexBuffer;
406 CDriverD3D *Driver;
407 std::vector<uint32> RamVersion; // If device doesn't support 32 bit indexes, works in ram (unless it a 16 bit index buffer)
408 CIBDrvInfosD3D(CDriverD3D *drv, ItIBDrvInfoPtrList it, CIndexBuffer *ib);
409 virtual ~CIBDrvInfosD3D();
410 virtual void *lock (uint first, uint last, bool readOnly);
411 virtual void unlock (uint first, uint last);
414 // ***************************************************************************
416 class CShaderDrvInfosD3D : public IShaderDrvInfos
418 public:
419 enum
421 MaxShaderTexture=8,
425 ID3DXEffect *Effect;
426 bool Validated;
428 // Texture handles
429 D3DXHANDLE TextureHandle[MaxShaderTexture];
431 // Color handles
432 D3DXHANDLE ColorHandle[MaxShaderTexture];
434 // Factor handles
435 D3DXHANDLE FactorHandle[MaxShaderTexture];
437 // Scalar handles
438 D3DXHANDLE ScalarFloatHandle[MaxShaderTexture];
440 CShaderDrvInfosD3D(CDriverD3D *drv, ItShaderDrvInfoPtrList it);
441 virtual ~CShaderDrvInfosD3D();
445 // ***************************************************************************
447 // Normal shader description
448 class CNormalShaderDesc
450 public:
451 CNormalShaderDesc ()
453 H_AUTO_D3D(CNormalShaderDesc_CNormalShaderDesc);
454 memset (this, 0, sizeof(CNormalShaderDesc));
456 ~CNormalShaderDesc ()
458 if (PixelShader)
459 PixelShader->Release();
461 bool StageUsed[IDRV_MAT_MAXTEXTURES];
462 uint32 TexEnvMode[IDRV_MAT_MAXTEXTURES];
464 bool operator==(const CNormalShaderDesc &other) const
466 uint i;
467 for (i=0; i<IDRV_MAT_MAXTEXTURES; i++)
468 if ((StageUsed[i] != other.StageUsed[i]) || (StageUsed[i] && (TexEnvMode[i] != other.TexEnvMode[i])))
469 return false;
470 return true;
473 IDirect3DPixelShader9 *PixelShader;
478 // base class for recorded state in an effect
479 class CStateRecord
481 public:
482 // apply record in a driver
483 virtual void apply(class CDriverD3D &drv) = 0;
484 virtual ~CStateRecord() {}
485 // use STL allocator for fast alloc. this works because objects are small ( < 128 bytes)
486 void *operator new(size_t size) { return CStateRecord::Allocator.allocate(size); }
487 void *operator new(size_t size, int /* blockUse */, char const * /* fileName */, int /* lineNumber */)
489 // TODO: add memory leaks detector
490 return CStateRecord::Allocator.allocate(size);
492 void operator delete(void *block) { CStateRecord::Allocator.deallocate((uint8 *) block, 1); }
493 void operator delete(void *block, int /* blockUse */, char const* /* fileName */, int /* lineNumber */)
495 // TODO: add memory leaks detector
496 CStateRecord::Allocator.deallocate((uint8 *)block, 1);
499 static std::allocator<uint8> Allocator;
502 // record of a single .fx pass
503 class CFXPassRecord
505 public:
506 void apply(class CDriverD3D &drv);
507 ~CFXPassRecord();
508 std::vector<CStateRecord *> States;
512 template <class T>
513 class CFXInputValue
515 public:
516 T Value;
517 bool Set;
518 CFXInputValue() : Set(false) {}
519 void reset();
520 bool operator==(const CFXInputValue &other)
522 if (!Set) return !(other.Set);
523 return (Value == other.Value) != 0;
527 class CFXInputParams
529 public:
530 enum { MaxNumParams = CShaderDrvInfosD3D::MaxShaderTexture };
531 CFXInputValue<LPDIRECT3DBASETEXTURE9> Textures[MaxNumParams];
532 CFXInputValue<DWORD> Colors[MaxNumParams];
533 CFXInputValue<D3DXVECTOR4> Vectors[MaxNumParams];
534 CFXInputValue<FLOAT> Floats[MaxNumParams];
535 bool Touched;
536 public:
537 CFXInputParams() { Touched = true; }
538 void setTexture(uint index, LPDIRECT3DBASETEXTURE9 value)
540 nlassert(index < MaxNumParams);
541 if (!Textures[index].Set || value != Textures[index].Value)
543 Textures[index].Value = value;
544 Textures[index].Set = true;
545 Touched = true;
548 void setColor(uint index, DWORD value)
550 nlassert(index < MaxNumParams);
551 if (!Colors[index].Set || value != Colors[index].Value)
553 Colors[index].Value = value;
554 Colors[index].Set = true;
555 Touched = true;
558 void setVector(uint index, const D3DXVECTOR4 &value)
560 nlassert(index < MaxNumParams);
561 if (!Vectors[index].Set || value != Vectors[index].Value)
563 Vectors[index].Value = value;
564 Vectors[index].Set = true;
565 Touched = true;
568 void setFloat(uint index, FLOAT value)
570 nlassert(index < MaxNumParams);
571 if (!Floats[index].Set || value != Floats[index].Value)
573 Floats[index].Value = value;
574 Floats[index].Set = true;
575 Touched = true;
580 bool operator==(const CFXInputParams &other)
582 return std::equal(Textures, Textures + CShaderDrvInfosD3D::MaxShaderTexture, other.Textures) &&
583 std::equal(Vectors, Vectors + CShaderDrvInfosD3D::MaxShaderTexture, other.Vectors) &&
584 std::equal(Colors, Colors + CShaderDrvInfosD3D::MaxShaderTexture, other.Colors) &&
585 std::equal(Floats, Floats + CShaderDrvInfosD3D::MaxShaderTexture, other.Floats);
588 void reset()
590 for(uint k = 0; k < MaxNumParams; ++k)
592 Textures[k].Set = false;
593 Colors[k].Set = false;
594 Vectors[k].Set = false;
595 Floats[k].Set = false;
597 Touched = true;
601 // .fx cache based on input parameters
602 class CFXCache
604 public:
605 // Input parameters
606 CFXInputParams Params;
607 // cache for .fx states
608 std::vector<CFXPassRecord> Passes;
609 uint Steadyness;
610 uint NumPasses;
611 public:
612 CFXCache() : Steadyness(0) {}
613 void begin(CShaderDrvInfosD3D *si, class CDriverD3D *driver);
614 void applyPass(class CDriverD3D &drv, CShaderDrvInfosD3D *si, uint passIndex);
615 void end(CShaderDrvInfosD3D *si);
616 void reset();
617 void setConstants(CShaderDrvInfosD3D *si);
622 // optimisation of an effect 2
623 class CFXPassRecorder : public ID3DXEffectStateManager
625 public:
626 CFXPassRecord *Target;
627 class CDriverD3D *Driver;
628 public:
629 CFXPassRecorder() : Target(NULL), Driver(NULL) {}
630 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj);
631 ULONG STDMETHODCALLTYPE AddRef(VOID);
632 ULONG STDMETHODCALLTYPE Release(VOID);
633 HRESULT STDMETHODCALLTYPE LightEnable(DWORD Index, BOOL Enable);
634 HRESULT STDMETHODCALLTYPE SetFVF(DWORD FVF);
635 HRESULT STDMETHODCALLTYPE SetLight(DWORD Index, CONST D3DLIGHT9* pLight);
636 HRESULT STDMETHODCALLTYPE SetMaterial(CONST D3DMATERIAL9* pMaterial);
637 HRESULT STDMETHODCALLTYPE SetNPatchMode(FLOAT nSegments);
638 HRESULT STDMETHODCALLTYPE SetPixelShader(LPDIRECT3DPIXELSHADER9 pShader);
639 HRESULT STDMETHODCALLTYPE SetPixelShaderConstantB(UINT StartRegister, CONST BOOL* pConstantData, UINT RegisterCount);
640 HRESULT STDMETHODCALLTYPE SetPixelShaderConstantF(UINT StartRegister, CONST FLOAT* pConstantData, UINT RegisterCount);
641 HRESULT STDMETHODCALLTYPE SetPixelShaderConstantI(UINT StartRegister, CONST INT* pConstantData, UINT RegisterCount);
642 HRESULT STDMETHODCALLTYPE SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
643 HRESULT STDMETHODCALLTYPE SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
644 HRESULT STDMETHODCALLTYPE SetTexture (DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture);
645 HRESULT STDMETHODCALLTYPE SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
646 HRESULT STDMETHODCALLTYPE SetTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix);
647 HRESULT STDMETHODCALLTYPE SetVertexShader(LPDIRECT3DVERTEXSHADER9 pShader);
648 HRESULT STDMETHODCALLTYPE SetVertexShaderConstantB(UINT StartRegister, CONST BOOL* pConstantData, UINT RegisterCount);
649 HRESULT STDMETHODCALLTYPE SetVertexShaderConstantF(UINT StartRegister, CONST FLOAT* pConstantData, UINT RegisterCount);
650 HRESULT STDMETHODCALLTYPE SetVertexShaderConstantI(UINT StartRegister, CONST INT* pConstantData, UINT RegisterCount);
654 // ***************************************************************************
655 struct CMaterialDrvInfosD3D : public IMaterialDrvInfos
657 public:
658 D3DMATERIAL9 Material;
659 D3DCOLOR UnlightedColor;
660 BOOL SpecularEnabled;
661 D3DBLEND SrcBlend;
662 D3DBLEND DstBlend;
663 D3DCMPFUNC ZComp;
664 DWORD AlphaRef;
665 D3DTEXTUREOP ColorOp[IDRV_MAT_MAXTEXTURES];
666 DWORD ColorArg0[IDRV_MAT_MAXTEXTURES];
667 DWORD ColorArg1[IDRV_MAT_MAXTEXTURES];
668 DWORD ColorArg2[IDRV_MAT_MAXTEXTURES];
669 uint NumColorArg[IDRV_MAT_MAXTEXTURES];
670 uint NumAlphaArg[IDRV_MAT_MAXTEXTURES];
671 D3DTEXTUREOP AlphaOp[IDRV_MAT_MAXTEXTURES];
672 DWORD AlphaArg0[IDRV_MAT_MAXTEXTURES];
673 DWORD AlphaArg1[IDRV_MAT_MAXTEXTURES];
674 DWORD AlphaArg2[IDRV_MAT_MAXTEXTURES];
675 D3DCOLOR ConstantColor[IDRV_MAT_MAXTEXTURES];
676 DWORD TexGen[IDRV_MAT_MAXTEXTURES];
677 IDirect3DPixelShader9 *PixelShader;
678 IDirect3DPixelShader9 *PixelShaderUnlightedNoVertexColor;
679 bool ActivateSpecularWorldTexMT[IDRV_MAT_MAXTEXTURES];
680 bool ActivateInvViewModelTexMT[IDRV_MAT_MAXTEXTURES];
681 bool VertexColorLighted;
682 bool NeedsConstantForDiffuse; // Must use TFactor if not vertex color in the vertex buffer
683 bool MultipleConstantNoPixelShader; // Multiple constant are possibly needed to setup the material. This flag is set only if the device has no pixel shaders
684 // In this case diffuse color will be emulated by using an unlighted material with ambient
685 bool MultiplePerStageConstant; // Are there more than one per-stage constant in the material ?
686 uint8 ConstantIndex; // Index of the constant color to use (when only one constant color is needed and NeedsConstantForDiffuse == false);
687 uint8 ConstantIndex2; // stage at which the 2nd constant is used (for emulation without pixel shaders)
689 CRGBA Constant2; // value of the 2nd constant being used (for emulation without pixel shaders)
691 uint NumUsedTexStages; // Last number of textures that were set in the material
692 // Tex Env are only built for stages at which textures are set so if the number of used texture
693 // change they must be rebuilt
695 // Relevant parts of the pixel pipe for normal shader
696 bool RGBPipe[IDRV_MAT_MAXTEXTURES];
697 bool AlphaPipe[IDRV_MAT_MAXTEXTURES];
699 CFXCache *FXCache;
701 CMaterialDrvInfosD3D(IDriver *drv, ItMatDrvInfoPtrList it) : IMaterialDrvInfos(drv, it)
703 H_AUTO_D3D(CMaterialDrvInfosD3D_CMaterialDrvInfosD3D);
704 PixelShader = NULL;
705 PixelShaderUnlightedNoVertexColor = NULL;
706 std::fill(RGBPipe, RGBPipe + IDRV_MAT_MAXTEXTURES, true);
707 std::fill(AlphaPipe, AlphaPipe + IDRV_MAT_MAXTEXTURES, true);
708 FXCache = NULL;
709 NumUsedTexStages = 0;
711 ~CMaterialDrvInfosD3D()
713 delete FXCache;
715 void buildTexEnv (uint stage, const CMaterial::CTexEnv &env, bool textured);
722 // ***************************************************************************
724 /* Volatile buffers.
726 * The volatile buffer system is a double buffer allocated during the render pass by objects that needs
727 * a temporary buffer to render vertex or indexes. Each lock allocates a buffer region
728 * and locks it with the NOOVERWRITE flag. Locks are not blocked. The buffer is reset at each frame begin.
729 * There is a double buffer to take benefit of the "over swapbuffer" parallelisme.
732 // ***************************************************************************
734 class CVolatileVertexBuffer
736 public:
737 CVolatileVertexBuffer();
738 ~CVolatileVertexBuffer();
740 CDriverD3D *Driver;
741 IDirect3DVertexBuffer9 *VertexBuffer;
742 uint Size;
743 CVertexBuffer::TLocation Location;
744 uint CurrentIndex;
745 uint MaxSize;
746 bool Locked;
748 /* size is in bytes */
749 void init (CVertexBuffer::TLocation location, uint size, uint maxSize, CDriverD3D *driver);
750 void release ();
752 // Runtime buffer access, no-blocking lock.
753 void *lock (uint size, uint stride, uint &offset);
754 void unlock ();
756 // Runtime reset (called at the beginning of the frame rendering), blocking lock here.
757 void reset ();
760 // ***************************************************************************
762 class CVolatileIndexBuffer
764 public:
765 CVolatileIndexBuffer();
766 ~CVolatileIndexBuffer();
768 CDriverD3D *Driver;
769 IDirect3DIndexBuffer9 *IndexBuffer;
770 uint Size;
771 CIndexBuffer::TLocation Location;
772 // current position in bytes!
773 uint CurrentIndex;
774 uint MaxSize;
775 bool Locked;
776 CIndexBuffer::TFormat Format;
778 /* size is in bytes */
779 void init (CIndexBuffer::TLocation location, uint sizeInBytes, uint maxSize, CDriverD3D *driver, CIndexBuffer::TFormat format);
780 void release ();
782 // Runtime buffer access, no-blocking lock. Re
783 void *lock (uint size, uint &offset);
784 void unlock ();
786 // Runtime reset (called at the beginning of the frame rendering), blocking lock here.
787 void reset ();
792 // ***************************************************************************
794 class CDriverD3D : public IDriver, public ID3DXEffectStateManager
796 public:
798 enum
800 CacheTest_CullMode = 0,
801 CacheTest_RenderState = 1,
802 CacheTest_TextureState = 2,
803 CacheTest_TextureIndexMode = 3,
804 CacheTest_TextureIndexUV = 4,
805 CacheTest_Texture = 5,
806 CacheTest_VertexProgram = 6,
807 CacheTest_PixelShader = 7,
808 CacheTest_VertexProgramConstant = 8,
809 CacheTest_PixelShaderConstant = 9,
810 CacheTest_SamplerState = 10,
811 CacheTest_VertexBuffer = 11,
812 CacheTest_IndexBuffer = 12,
813 CacheTest_VertexDecl = 13,
814 CacheTest_Matrix = 14,
815 CacheTest_RenderTarget = 15,
816 CacheTest_MaterialState = 16,
817 CacheTest_DepthRange = 17,
818 CacheTest_Count
821 // Some constants
822 enum
824 MaxLight=8,
825 MaxRenderState=256,
826 MaxTextureState=36,
827 MaxTexture=8,
828 MaxSamplerState=16,
829 MaxSampler=8,
831 MatrixStateRemap = 24,
832 MaxMatrixState=32,
833 MaxVertexProgramConstantState=96,
834 MaxPixelShaderConstantState=96,
837 // Prefered pixel formats
838 enum
840 // Number of pixel format choice for each pixel format
841 FinalPixelFormatChoice = 5,
844 // Construction / destruction
845 CDriverD3D();
846 virtual ~CDriverD3D();
848 virtual bool isLost() const { return _Lost; }
849 // ***************************************************************************
850 // Implementation
851 // see nel\src\3d\driver.h
852 // ***************************************************************************
854 // Mode initialisation, requests
855 virtual bool init (uintptr_t windowIcon = 0, emptyProc exitFunc = 0);
856 virtual bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable);
857 virtual bool release();
858 virtual bool setMode(const GfxMode& mode);
859 virtual bool getModes(std::vector<GfxMode> &modes);
860 virtual bool getCurrentScreenMode(GfxMode &mode);
861 virtual void beginDialogMode();
862 virtual void endDialogMode();
863 virtual bool activate();
864 virtual bool isActive ();
865 virtual bool initVertexBufferHard(uint agpMem, uint vramMem);
867 // Windows interface
868 virtual nlWindow getDisplay();
869 virtual emptyProc getWindowProc();
870 virtual NLMISC::IEventEmitter *getEventEmitter();
871 virtual void getWindowSize (uint32 &width, uint32 &height);
872 virtual void getWindowPos (sint32 &x, sint32 &y);
873 virtual uint8 getBitPerPixel ();
875 /// Set the title of the NeL window
876 virtual void setWindowTitle(const ucstring &title);
878 /// Set icon(s) of the NeL window
879 virtual void setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps);
881 /// Set the position of the NeL window
882 virtual void setWindowPos(sint32 x, sint32 y);
884 /// Show or hide the NeL window
885 virtual void showWindow(bool show);
887 // Driver parameters
888 virtual void disableHardwareVertexProgram();
889 virtual void disableHardwarePixelProgram();
890 virtual void disableHardwareIndexArrayAGP();
891 virtual void disableHardwareVertexArrayAGP();
892 virtual void disableHardwareTextureShader();
893 virtual void forceDXTCCompression(bool dxtcComp);
894 virtual void setAnisotropicFilter(sint filter);
895 virtual uint getAnisotropicFilter() const;
896 virtual uint getAnisotropicFilterMaximum() const;
897 virtual void forceTextureResize(uint divisor);
899 // Driver information
900 virtual uint getNumAdapter() const;
901 virtual bool getAdapter(uint adapter, CAdapter &desc) const;
902 virtual bool setAdapter(uint adapter);
903 virtual uint32 getAvailableVertexAGPMemory ();
904 virtual uint32 getAvailableVertexVRAMMemory ();
905 virtual uint getNbTextureStages() const;
906 virtual void getNumPerStageConstant(uint &lightedMaterial, uint &unlightedMaterial) const;
907 virtual bool supportVertexBufferHard() const;
908 virtual bool supportVolatileVertexBuffer() const;
909 virtual bool supportIndexBufferHard() const;
910 // todo hulud d3d vertex buffer hard
911 virtual bool slowUnlockVertexBufferHard() const {return false;};
912 virtual uint getMaxVerticesByVertexBufferHard() const;
913 virtual uint32 getImplementationVersion () const;
914 virtual const char* getDriverInformation ();
915 virtual const char* getVideocardInformation ();
916 virtual sint getTotalVideoMemory () const;
917 virtual CVertexBuffer::TVertexColorType getVertexColorFormat() const;
919 // Textures
920 virtual bool isTextureExist(const ITexture&tex);
921 virtual bool setupTexture (ITexture& tex);
922 virtual bool setupTextureEx (ITexture& tex, bool bUpload, bool &bAllUploaded, bool bMustRecreateSharedTexture= false);
923 virtual bool uploadTexture (ITexture& tex, NLMISC::CRect& rect, uint8 nNumMipMap);
924 // todo hulud d3d texture
925 virtual bool uploadTextureCube (ITexture& /* tex */, NLMISC::CRect& /* rect */, uint8 /* nNumMipMap */, uint8 /* nNumFace */) {return false;};
927 // Material
928 virtual bool setupMaterial(CMaterial& mat);
930 virtual bool supportCloudRenderSinglePass () const;
932 // Buffer
933 virtual bool clear2D(CRGBA rgba);
934 virtual bool clearZBuffer(float zval=1);
935 virtual bool clearStencilBuffer(float stencilval=0);
936 virtual void setColorMask (bool bRed, bool bGreen, bool bBlue, bool bAlpha);
937 virtual bool swapBuffers();
938 virtual void getBuffer (CBitmap &bitmap); // Only 32 bits back buffer supported
939 virtual void setDepthRange(float znear, float zfar);
940 virtual void getDepthRange(float &znear, float &zfar) const;
942 virtual void getZBuffer (std::vector<float> &zbuffer);
943 virtual void getBufferPart (CBitmap &bitmap, NLMISC::CRect &rect);
945 // return true if driver support Bloom effect.
946 virtual bool supportBloomEffect() const;
948 // return true if driver support non-power of two textures
949 virtual bool supportNonPowerOfTwoTextures() const;
951 // copy the first texture in a second one of different dimensions
952 virtual bool stretchRect (ITexture * srcText, NLMISC::CRect &srcRect, ITexture * destText, NLMISC::CRect &destRect); // Only 32 bits back buffer supported
953 virtual bool isTextureRectangle(ITexture * /* tex */) const {return false;}
954 IDirect3DSurface9* getSurfaceTexture(ITexture * text);
955 void getDirect3DRect(NLMISC::CRect &rect, RECT & d3dRect);
957 // todo hulud d3d buffers
958 virtual void getZBufferPart (std::vector<float> &zbuffer, NLMISC::CRect &rect);
959 virtual bool setRenderTarget (ITexture *tex, uint32 x, uint32 y, uint32 width, uint32 height, uint32 mipmapLevel, uint32 cubeFace);
960 virtual ITexture *getRenderTarget() const;
961 virtual bool copyTargetToTexture (ITexture *tex, uint32 offsetx, uint32 offsety, uint32 x, uint32 y, uint32 width,
962 uint32 height, uint32 mipmapLevel);
963 virtual bool textureCoordinateAlternativeMode() const { return true; };
964 virtual bool getRenderTargetSize (uint32 &width, uint32 &height);
965 virtual bool fillBuffer (CBitmap &bitmap);
967 // Performances
968 virtual void startSpecularBatch();
969 virtual void endSpecularBatch();
970 virtual void setSwapVBLInterval(uint interval);
971 virtual uint getSwapVBLInterval();
972 virtual void swapTextureHandle(ITexture &tex0, ITexture &tex1);
973 virtual uintptr_t getTextureHandle(const ITexture&tex);
975 // Matrix, viewport and frustum
976 virtual void setFrustum(float left, float right, float bottom, float top, float znear, float zfar, bool perspective = true);
977 virtual void setFrustumMatrix(CMatrix &frust);
978 virtual CMatrix getFrustumMatrix();
979 virtual float getClipSpaceZMin() const { return 0.f; }
980 virtual void setupViewMatrix(const CMatrix& mtx);
981 virtual void setupViewMatrixEx(const CMatrix& mtx, const CVector &cameraPos);
982 virtual void setupModelMatrix(const CMatrix& mtx);
983 virtual CMatrix getViewMatrix() const;
984 virtual void forceNormalize(bool normalize);
985 virtual bool isForceNormalize() const;
986 virtual void setupScissor (const class CScissor& scissor);
987 virtual void setupViewport (const class CViewport& viewport);
988 virtual void getViewport(CViewport &viewport);
990 // Vertex buffers
991 virtual bool activeVertexBuffer(CVertexBuffer& VB);
993 // Index buffers
994 virtual bool activeIndexBuffer(CIndexBuffer& IB);
996 // UV
997 virtual void mapTextureStageToUV(uint stage, uint uv);
999 // Indexed primitives
1000 virtual bool renderLines(CMaterial& mat, uint32 firstIndex, uint32 nlines);
1001 virtual bool renderTriangles(CMaterial& Mat, uint32 firstIndex, uint32 ntris);
1002 virtual bool renderSimpleTriangles(uint32 firstTri, uint32 ntris);
1003 // Indexed primitives with index offset
1004 virtual bool renderLinesWithIndexOffset(CMaterial& mat, uint32 firstIndex, uint32 nlines, uint indexOffset);
1005 virtual bool renderTrianglesWithIndexOffset(CMaterial& mat, uint32 firstIndex, uint32 ntris, uint indexOffset);
1006 virtual bool renderSimpleTrianglesWithIndexOffset(uint32 firstIndex, uint32 ntris, uint indexOffset);
1007 // Unindexed primitives with index offset
1008 virtual bool renderRawPoints(CMaterial& Mat, uint32 startIndex, uint32 numPoints);
1009 virtual bool renderRawLines(CMaterial& Mat, uint32 startIndex, uint32 numLines);
1010 virtual bool renderRawTriangles(CMaterial& Mat, uint32 startIndex, uint32 numTris);
1011 virtual bool renderRawQuads(CMaterial& Mat, uint32 startIndex, uint32 numQuads);
1013 virtual void setPolygonMode (TPolygonMode mode);
1014 virtual void finish();
1015 virtual void flush();
1017 // Profile
1018 virtual void profileRenderedPrimitives(CPrimitiveProfile &pIn, CPrimitiveProfile &pOut);
1019 virtual uint32 profileAllocatedTextureMemory();
1020 virtual uint32 profileSetupedMaterials() const;
1021 virtual uint32 profileSetupedModelMatrix() const;
1022 virtual void enableUsedTextureMemorySum (bool enable);
1023 virtual uint32 getUsedTextureMemory() const;
1024 virtual void startProfileVBHardLock();
1025 virtual void endProfileVBHardLock(std::vector<std::string> &result);
1026 virtual void profileVBHardAllocation(std::vector<std::string> &result);
1027 virtual void startProfileIBLock();
1028 virtual void endProfileIBLock(std::vector<std::string> &result);
1029 virtual void profileIBAllocation(std::vector<std::string> &result);
1030 //virtual void profileIBAllocation(std::vector<std::string> &result);
1032 // Misc
1033 virtual TMessageBoxId systemMessageBox (const char* message, const char* title, TMessageBoxType type=okType, TMessageBoxIcon icon=noIcon);
1034 virtual uint64 getSwapBufferCounter() const { return _SwapBufferCounter; }
1036 // Inputs
1037 virtual void showCursor (bool b);
1038 virtual void setMousePos(float x, float y);
1039 virtual void setCapture (bool b);
1041 // see if system cursor is currently captured
1042 virtual bool isSystemCursorCaptured();
1044 // Add a new cursor (name is case unsensitive)
1045 virtual void addCursor(const std::string &name, const NLMISC::CBitmap &bitmap);
1047 // Display a cursor from its name (case unsensitive)
1048 virtual void setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild = false);
1050 // Change default scale for all cursors
1051 virtual void setCursorScale(float scale);
1053 // Lights
1054 virtual uint getMaxLight () const;
1055 virtual void setLight (uint8 num, const CLight& light);
1056 virtual void enableLight (uint8 num, bool enable=true);
1057 virtual void setLightMapDynamicLight (bool enable, const CLight& light);
1058 // todo hulud d3d light
1059 virtual void setPerPixelLightingLight(CRGBA /* diffuse */, CRGBA /* specular */, float /* shininess */) {}
1060 virtual void setAmbientColor (CRGBA color);
1062 // Fog
1063 virtual bool fogEnabled();
1064 virtual void enableFog(bool enable);
1065 virtual void setupFog(float start, float end, CRGBA color);
1066 virtual float getFogStart() const;
1067 virtual float getFogEnd() const;
1068 virtual CRGBA getFogColor() const;
1070 // Texture addressing modes
1071 // todo hulud d3d adressing mode
1072 virtual bool supportTextureShaders() const {return false;};
1073 virtual bool supportMADOperator() const;
1074 // todo hulud d3d adressing mode
1075 virtual bool supportWaterShader() const;
1076 // todo hulud d3d adressing mode
1077 virtual bool supportTextureAddrMode(CMaterial::TTexAddressingMode /* mode */) const {return false;};
1078 // todo hulud d3d adressing mode
1079 virtual void setMatrix2DForTextureOffsetAddrMode(const uint /* stage */, const float /* mat */[4]) {}
1081 // EMBM support
1082 virtual bool supportEMBM() const;
1083 virtual bool isEMBMSupportedAtStage(uint stage) const;
1084 virtual void setEMBMMatrix(const uint stage, const float mat[4]);
1085 virtual bool supportPerPixelLighting(bool /* specular */) const {return false;};
1087 // index offset support
1088 virtual bool supportIndexOffset() const { return true; /* always supported with D3D driver */ }
1090 // Blend
1091 virtual bool supportBlendConstantColor() const;
1092 virtual void setBlendConstantColor(NLMISC::CRGBA col);
1093 virtual NLMISC::CRGBA getBlendConstantColor() const;
1095 // Monitor properties
1096 virtual bool setMonitorColorProperties (const CMonitorColorProperties &properties);
1098 // Polygon smoothing
1099 virtual void enablePolygonSmoothing(bool smooth);
1100 virtual bool isPolygonSmoothingEnabled() const;
1102 // Material multipass
1103 virtual sint beginMaterialMultiPass();
1104 virtual void setupMaterialPass(uint pass);
1105 virtual void endMaterialMultiPass();
1112 /// \name Vertex Program
1113 // @{
1115 // Order of preference
1116 // - activeVertexProgram
1117 // - CMaterial pass[n] VP (uses activeVertexProgram, but does not override if one already set by code)
1118 // - default generic VP that mimics fixed pipeline / no VP with fixed pipeline
1121 * Does the driver supports vertex program, but emulated by CPU ?
1123 virtual bool isVertexProgramEmulated() const;
1125 /** Return true if the driver supports the specified vertex program profile.
1127 virtual bool supportVertexProgram(CVertexProgram::TProfile profile) const;
1129 /** Compile the given vertex program, return if successful.
1130 * If a vertex program was set active before compilation,
1131 * the state of the active vertex program is undefined behaviour afterwards.
1133 virtual bool compileVertexProgram(CVertexProgram *program);
1135 /** Set the active vertex program. This will override vertex programs specified in CMaterial render calls.
1136 * Also used internally by setupMaterial(CMaterial) when getVertexProgram returns NULL.
1137 * The vertex program is activated immediately.
1139 virtual bool activeVertexProgram(CVertexProgram *program);
1140 // @}
1144 /// \name Pixel Program
1145 // @{
1147 // Order of preference
1148 // - activePixelProgram
1149 // - CMaterial pass[n] PP (uses activePixelProgram, but does not override if one already set by code)
1150 // - PP generated from CMaterial (uses activePixelProgram, but does not override if one already set by code)
1152 /** Return true if the driver supports the specified pixel program profile.
1154 virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const;
1156 /** Compile the given pixel program, return if successful.
1157 * If a pixel program was set active before compilation,
1158 * the state of the active pixel program is undefined behaviour afterwards.
1160 virtual bool compilePixelProgram(CPixelProgram *program);
1162 /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls.
1163 * Also used internally by setupMaterial(CMaterial) when getPixelProgram returns NULL.
1164 * The pixel program is activated immediately.
1166 virtual bool activePixelProgram(CPixelProgram *program);
1167 // @}
1171 /// \name Geometry Program
1172 // @{
1174 // Order of preference
1175 // - activeGeometryProgram
1176 // - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code)
1177 // - none
1179 /** Return true if the driver supports the specified pixel program profile.
1181 virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const { return false; }
1183 /** Compile the given pixel program, return if successful.
1184 * If a pixel program was set active before compilation,
1185 * the state of the active pixel program is undefined behaviour afterwards.
1187 virtual bool compileGeometryProgram(CGeometryProgram *program) { return false; }
1189 /** Set the active pixel program. This will override pixel programs specified in CMaterial render calls.
1190 * Also used internally by setupMaterial(CMaterial) when getGeometryProgram returns NULL.
1191 * The pixel program is activated immediately.
1193 virtual bool activeGeometryProgram(CGeometryProgram *program) { return false; }
1194 // @}
1198 /// \name Program parameters
1199 // @{
1200 // Set parameters
1201 virtual void setUniform1f(TProgram program, uint index, float f0);
1202 virtual void setUniform2f(TProgram program, uint index, float f0, float f1);
1203 virtual void setUniform3f(TProgram program, uint index, float f0, float f1, float f2);
1204 virtual void setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3);
1205 virtual void setUniform1i(TProgram program, uint index, sint32 i0);
1206 virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1);
1207 virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2);
1208 virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3);
1209 virtual void setUniform1ui(TProgram program, uint index, uint32 ui0);
1210 virtual void setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1);
1211 virtual void setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2);
1212 virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3);
1213 virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v);
1214 virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3);
1215 virtual void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba);
1216 virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m);
1217 virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src);
1218 virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src);
1219 virtual void setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src);
1220 // Set builtin parameters
1221 virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform);
1222 virtual void setUniformFog(TProgram program, uint index);
1223 // Set feature parameters
1224 virtual bool setUniformDriver(TProgram program); // set all driver-specific features params (based on program->features->DriverFlags)
1225 virtual bool setUniformMaterial(TProgram program, CMaterial &material); // set all material-specific feature params (based on program->features->MaterialFlags)
1226 virtual void setUniformParams(TProgram program, CGPUProgramParams &params); // set all user-provided params from the storage
1227 virtual bool isUniformProgramState() { return false; }
1228 // @}
1234 virtual void enableVertexProgramDoubleSidedColor(bool doubleSided);
1235 virtual bool supportVertexProgramDoubleSidedColor() const;
1237 // Occlusion query
1238 virtual bool supportOcclusionQuery() const;
1239 virtual IOcclusionQuery *createOcclusionQuery();
1240 virtual void deleteOcclusionQuery(IOcclusionQuery *oq);
1244 /** Shader implementation
1246 * Shader can assume this states are setuped:
1247 * TextureTransformFlags[n] = DISABLE;
1248 * TexCoordIndex[n] = n;
1249 * ColorOp[n] = DISABLE;
1250 * AlphaOp[n] = DISABLE;
1252 bool activeShader(CD3DShaderFX *shd);
1254 // Bench
1255 virtual void startBench (bool wantStandardDeviation = false, bool quick = false, bool reset = true);
1256 virtual void endBench ();
1257 virtual void displayBench (class NLMISC::CLog *log);
1260 virtual void setCullMode(TCullMode cullMode);
1261 virtual TCullMode getCullMode() const;
1263 virtual void enableStencilTest(bool enable);
1264 virtual bool isStencilTestEnabled() const;
1265 virtual void stencilFunc(TStencilFunc stencilFunc, int ref, uint mask);
1266 virtual void stencilOp(TStencilOp fail, TStencilOp zfail, TStencilOp zpass);
1267 virtual void stencilMask(uint mask);
1269 uint32 getMaxVertexIndex() const { return _MaxVertexIndex; }
1271 // *** Inline info
1272 uint inlGetNumTextStages() const { return _NbNeLTextureStages; }
1274 //private:
1275 public:
1277 // Hardware render variables, like matrices, render states
1278 struct CRenderVariable
1280 CRenderVariable()
1282 NextModified = NULL;
1283 Modified = false;
1286 // Type of render state
1287 enum
1289 RenderState = 0,
1290 TextureState,
1291 TextureIndexState,
1292 TexturePtrState,
1293 VertexProgramPtrState,
1294 PixelShaderPtrState,
1295 VertexProgramConstantState,
1296 PixelShaderConstantState,
1297 SamplerState,
1298 MatrixState,
1299 VBState,
1300 IBState,
1301 VertexDecl,
1302 LightState,
1303 RenderTargetState,
1304 } Type;
1305 CRenderVariable *NextModified;
1306 bool Modified;
1307 virtual void apply(CDriverD3D *driver) = 0;
1310 // Render state
1311 struct CRenderState : public CRenderVariable
1313 CRenderState()
1315 Type = RenderState;
1316 Value= 0;
1317 ValueSet = false;
1319 D3DRENDERSTATETYPE StateID;
1320 DWORD Value;
1321 bool ValueSet;
1322 virtual void apply(CDriverD3D *driver);
1325 // Render texture state
1326 struct CTextureState : public CRenderVariable
1328 CTextureState()
1330 Type = TextureState;
1331 DeviceValue = 0xcccccccc;
1333 DWORD StageID;
1334 D3DTEXTURESTAGESTATETYPE StateID;
1335 DWORD Value;
1336 DWORD DeviceValue;
1337 virtual void apply(CDriverD3D *driver);
1341 // Render texture index state
1342 struct CTextureIndexState : public CRenderVariable
1344 CTextureIndexState()
1346 Type = TextureIndexState;
1348 DWORD StageID;
1349 DWORD TexGenMode;
1350 DWORD UVChannel;
1351 bool TexGen;
1352 virtual void apply(CDriverD3D *driver);
1355 // Render texture
1356 struct CTexturePtrState : public CRenderVariable
1358 CTexturePtrState()
1360 Type = TexturePtrState;
1361 Texture = NULL;
1363 DWORD StageID;
1364 LPDIRECT3DBASETEXTURE9 Texture;
1365 virtual void apply(CDriverD3D *driver);
1368 // Render texture
1369 struct CVertexProgramPtrState : public CRenderVariable
1371 CVertexProgramPtrState()
1373 Type = VertexProgramPtrState;
1374 VertexProgram = NULL;
1376 LPDIRECT3DVERTEXSHADER9 VertexProgram;
1377 // for debug
1378 const CVertexProgram *VP;
1379 virtual void apply(CDriverD3D *driver);
1382 // Render texture
1383 struct CPixelShaderPtrState : public CRenderVariable
1385 CPixelShaderPtrState()
1387 Type = PixelShaderPtrState;
1388 PixelShader = NULL;
1390 LPDIRECT3DPIXELSHADER9 PixelShader;
1391 virtual void apply(CDriverD3D *driver);
1394 // Vertex buffer constants state
1395 struct CVertexProgramConstantState : public CRenderVariable
1397 CVertexProgramConstantState()
1399 Type = VertexProgramConstantState;
1401 enum
1403 Float= 0,
1404 Int,
1405 Undef,
1406 } ValueType;
1407 uint StateID;
1408 DWORD Values[4];
1409 virtual void apply(CDriverD3D *driver);
1412 // Pixel shader constants state
1413 struct CPixelShaderConstantState : public CRenderVariable
1415 CPixelShaderConstantState()
1417 Type = PixelShaderConstantState;
1419 enum
1421 Float= 0,
1422 Int,
1423 Undef,
1424 } ValueType;
1425 uint StateID;
1426 DWORD Values[4];
1427 virtual void apply(CDriverD3D *driver);
1430 // Render sampler state
1431 struct CSamplerState : public CRenderVariable
1433 CSamplerState()
1435 Type = SamplerState;
1437 DWORD SamplerID;
1438 D3DSAMPLERSTATETYPE StateID;
1439 DWORD Value;
1440 virtual void apply(CDriverD3D *driver);
1443 // Render matrix
1444 struct CMatrixState : public CRenderVariable
1446 CMatrixState()
1448 Type = MatrixState;
1450 D3DTRANSFORMSTATETYPE TransformType;
1451 D3DXMATRIX Matrix;
1452 virtual void apply(CDriverD3D *driver);
1455 // Render vertex buffer
1456 struct CVBState : public CRenderVariable
1458 CVBState()
1460 Type = VBState;
1461 VertexBuffer = NULL;
1462 ColorOffset = 0;
1464 IDirect3DVertexBuffer9 *VertexBuffer;
1465 UINT Offset;
1466 UINT Stride;
1467 CVertexBuffer::TPreferredMemory PrefferedMemory;
1468 DWORD Usage; // d3d vb usage
1469 uint ColorOffset; // Fix for Radeon 7xxx series (see remark in CDriverD3D::createVertexDeclaration)
1470 virtual void apply(CDriverD3D *driver);
1473 // Render index buffer
1474 struct CIBState : public CRenderVariable
1476 CIBState()
1478 Type = IBState;
1479 IndexBuffer = NULL;
1481 IDirect3DIndexBuffer9 *IndexBuffer;
1482 virtual void apply(CDriverD3D *driver);
1485 // Render vertex decl
1486 struct CVertexDeclState : public CRenderVariable
1488 CVertexDeclState()
1490 Type = VertexDecl;
1491 Decl = NULL;
1492 DeclAliasDiffuseToSpecular = NULL;
1493 DeclNoDiffuse = NULL;
1494 Stride= 0;
1495 AliasDiffuseToSpecular = false;
1496 EnableVertexColor = false;
1498 IDirect3DVertexDeclaration9 *Decl;
1499 IDirect3DVertexDeclaration9 *DeclAliasDiffuseToSpecular;
1500 IDirect3DVertexDeclaration9 *DeclNoDiffuse;
1501 uint Stride;
1502 bool AliasDiffuseToSpecular;
1503 bool EnableVertexColor;
1504 virtual void apply(CDriverD3D *driver);
1507 // Render vertex buffer
1508 struct CLightState : public CRenderVariable
1510 CLightState()
1512 Type = LightState;
1513 Enabled = false;
1514 SettingsTouched = false;
1515 EnabledTouched = true;
1516 Light.Type = D3DLIGHT_POINT;
1517 Light.Range = 1;
1518 Light.Falloff = 1;
1519 Light.Position.x = 0;
1520 Light.Position.y = 0;
1521 Light.Position.z = 0;
1522 Light.Direction.x = 1;
1523 Light.Direction.y = 0;
1524 Light.Direction.z = 0;
1525 Light.Attenuation0 = 1;
1526 Light.Attenuation1 = 1;
1527 Light.Attenuation2 = 1;
1528 Light.Theta = 0;
1529 Light.Phi = 0;
1531 uint8 LightIndex;
1532 bool SettingsTouched;
1533 bool EnabledTouched;
1534 bool Enabled;
1535 D3DLIGHT9 Light;
1536 virtual void apply(CDriverD3D *driver);
1539 // Render target
1540 struct CRenderTargetState : public CRenderVariable
1542 CRenderTargetState()
1544 Type = RenderTargetState;
1545 Target = NULL;
1546 Texture = NULL;
1547 Level = 0;
1548 CubeFace = 0;
1549 TargetOwned = false;
1551 IDirect3DSurface9 *Target;
1552 ITexture *Texture;
1553 uint8 Level;
1554 uint8 CubeFace;
1555 bool TargetOwned;
1556 virtual void apply(CDriverD3D *driver);
1559 // material state
1560 struct CMaterialState : public CRenderVariable
1562 CMaterialState()
1564 //Current.Power = -1.f;
1565 Current.Diffuse.r = Current.Diffuse.g = Current.Diffuse.b = Current.Diffuse.a = 0.f;
1566 Current.Ambient.r = Current.Ambient.g = Current.Ambient.b = Current.Ambient.a = 0.f;
1567 Current.Specular.r = Current.Specular.g = Current.Specular.b = Current.Specular.a = 0.f;
1568 Current.Emissive.r = Current.Emissive.g = Current.Emissive.b = Current.Emissive.a = 0.f;
1569 Current.Power = 0.f;
1571 D3DMATERIAL9 Current;
1572 virtual void apply(CDriverD3D *driver);
1576 // Friends
1577 friend void D3DWndProc(CDriverD3D *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
1578 friend class CTextureDrvInfosD3D;
1579 friend class CVBDrvInfosD3D;
1580 friend class CIBDrvInfosD3D;
1581 friend class CVolatileVertexBuffer;
1582 friend class CVolatileIndexBuffer;
1584 // Init render states
1585 void initRenderVariables();
1587 // Reset render states
1588 void resetRenderVariables();
1590 // Replace all arguments of color / alpha operators in the pixel pipe with the given value
1591 void replaceAllArgument(DWORD from, DWORD to, DWORD blendOpFrom);
1593 // Replace all arguments of color / alpha operators in the pixel pipe at the given stage with the given value
1594 void replaceAllArgumentAtStage(uint stage, DWORD from, DWORD to, DWORD blendOpFrom);
1595 void replaceAllRGBArgumentAtStage(uint stage, DWORD from, DWORD to, DWORD blendOpFrom);
1596 void replaceAllAlphaArgumentAtStage(uint stage, DWORD from, DWORD to, DWORD blendOpFrom);
1598 // Replace a the given color / alpha op
1599 void replaceArgumentAtStage(D3DTEXTURESTAGESTATETYPE state, DWORD stage, DWORD from, DWORD to);
1601 // Setup lighting & material so that it produces the given constant color (useful to simulate a per stage constant using diffuse)
1602 void setupConstantDiffuseColorFromLightedMaterial(D3DCOLOR color);
1604 // Update all modified render states, reset current material
1605 void updateRenderVariables();
1607 // Update all modified render states, assume current material is still alive
1608 void updateRenderVariablesInternal();
1610 // Reset the driver, release the lost resources
1611 bool reset (const GfxMode& mode);
1613 // Handle window size change
1614 bool handlePossibleSizeChange();
1616 public:
1617 // Touch a render variable
1618 inline void touchRenderVariable (CRenderVariable *renderVariable)
1620 // Modified ?
1621 if (!renderVariable->Modified)
1623 // Link to modified states
1624 renderVariable->NextModified = _ModifiedRenderState;
1625 _ModifiedRenderState = renderVariable;
1626 renderVariable->Modified = true;
1632 // Access render states
1633 inline void setRenderState (D3DRENDERSTATETYPE renderState, DWORD value)
1635 H_AUTO_D3D(CDriverD3D_setRenderState);
1636 #ifdef NL_DEBUG
1637 nlassert (_DeviceInterface);
1638 nlassert (renderState<MaxRenderState);
1639 #endif
1640 // Ref on the state
1641 CRenderState &_renderState = _RenderStateCache[renderState];
1642 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1643 NL_D3D_CACHE_TEST(CacheTest_RenderState, _renderState.Value != value || !_renderState.ValueSet)
1644 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1646 _renderState.Value = value;
1647 _renderState.ValueSet = true;
1648 touchRenderVariable (&_renderState);
1653 public:
1655 // compute wrap mode flag in D3D format for that texture
1656 // texture must have been setuped already
1657 void setupTextureWrapMode(ITexture& tex);
1659 // Access texture states
1660 inline void setTextureState (DWORD stage, D3DTEXTURESTAGESTATETYPE textureState, DWORD value)
1662 H_AUTO_D3D(CDriverD3D_setTextureState);
1663 #ifdef NL_DEBUG
1664 nlassert (_DeviceInterface);
1665 nlassert (stage<MaxTexture);
1666 nlassert (textureState<MaxTextureState);
1667 #endif
1668 // Ref on the state
1669 CTextureState &_textureState = _TextureStateCache[stage][textureState];
1670 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1671 NL_D3D_CACHE_TEST(CacheTest_TextureState, _textureState.Value != value)
1672 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1674 _textureState.Value = value;
1675 touchRenderVariable (&_textureState);
1681 // Access texture index states
1682 inline void setTextureIndexMode (DWORD stage, bool texGenEnabled, DWORD value)
1684 H_AUTO_D3D(CDriverD3D_setTextureIndexMode);
1685 nlassert (_DeviceInterface);
1686 nlassert (stage<MaxTexture);
1688 CTextureIndexState &_textureState = _TextureIndexStateCache[stage];
1689 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1690 NL_D3D_CACHE_TEST(CacheTest_TextureIndexMode, _textureState.TexGen = (texGenEnabled || _textureState.TexGenMode != value))
1691 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1693 // Ref on the state
1694 _textureState.TexGen = texGenEnabled;
1695 _textureState.TexGenMode = value;
1696 touchRenderVariable (&_textureState);
1701 // Access texture index states
1702 inline void setTextureIndexUV (DWORD stage, DWORD value)
1704 H_AUTO_D3D(CDriverD3D_setTextureIndexUV);
1705 nlassert (_DeviceInterface);
1706 nlassert (stage<MaxTexture);
1708 // Ref on the state
1709 CTextureIndexState &_textureState = _TextureIndexStateCache[stage];
1710 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1711 NL_D3D_CACHE_TEST(CacheTest_TextureIndexUV, _textureState.TexGen || _textureState.UVChannel != value)
1712 #endif
1714 _textureState.TexGen = false;
1715 _textureState.UVChannel = value;
1716 touchRenderVariable (&_textureState);
1720 // Access texture states
1721 inline void setTexture (DWORD stage, LPDIRECT3DBASETEXTURE9 texture)
1723 H_AUTO_D3D(CDriverD3D_setTexture);
1724 nlassert (_DeviceInterface);
1725 nlassert (stage<MaxTexture);
1727 // Ref on the state
1728 CTexturePtrState &_textureState = _TexturePtrStateCache[stage];
1729 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1730 NL_D3D_CACHE_TEST(CacheTest_RenderState, _textureState.Texture != texture)
1731 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1733 _textureState.Texture = texture;
1734 touchRenderVariable (&_textureState);
1738 // Set a NeL texture states
1739 inline void setTexture (DWORD stage, ITexture *texture)
1741 H_AUTO_D3D(CDriverD3D_setTexture2);
1742 nlassert (_DeviceInterface);
1743 nlassert (stage<MaxTexture);
1745 // Set the texture parameters
1746 CTextureDrvInfosD3D *d3dtext = getTextureD3D(*texture);
1747 setTexture (stage, d3dtext->Texture);
1748 setSamplerState (stage, D3DSAMP_ADDRESSU, d3dtext->WrapS);
1749 setSamplerState (stage, D3DSAMP_ADDRESSV, d3dtext->WrapT);
1750 setSamplerState (stage, D3DSAMP_MAGFILTER, d3dtext->MagFilter);
1751 setSamplerState (stage, D3DSAMP_MINFILTER, d3dtext->MinFilter);
1752 setSamplerState (stage, D3DSAMP_MIPFILTER, d3dtext->MipFilter);
1753 setSamplerState (stage, D3DSAMP_MAXANISOTROPY, _AnisotropicFilter);
1755 // Profile, log the use of this texture
1756 if (_SumTextureMemoryUsed)
1758 // Insert the pointer of this texture
1759 _TextureUsed.insert (d3dtext);
1763 // Access vertex program
1764 inline void setVertexProgram (LPDIRECT3DVERTEXSHADER9 vertexProgram, const CVertexProgram *vp)
1766 H_AUTO_D3D(CDriverD3D_setVertexProgram);
1767 nlassert (_DeviceInterface);
1769 // Ref on the state
1770 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1771 NL_D3D_CACHE_TEST(CacheTest_VertexProgram, _VertexProgramCache.VertexProgram != vertexProgram)
1772 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1774 _VertexProgramCache.VertexProgram = vertexProgram;
1775 _VertexProgramCache.VP = vp;
1776 touchRenderVariable (&_VertexProgramCache);
1780 // Access pixel shader
1781 inline void setPixelShader (LPDIRECT3DPIXELSHADER9 pixelShader)
1783 H_AUTO_D3D(CDriverD3D_setPixelShader);
1784 nlassert (_DeviceInterface);
1786 // Ref on the state
1787 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1788 NL_D3D_CACHE_TEST(CacheTest_PixelShader, _PixelShaderCache.PixelShader != pixelShader)
1789 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1791 _PixelShaderCache.PixelShader = pixelShader;
1792 touchRenderVariable (&_PixelShaderCache);
1796 // Access vertex program constant
1797 inline void setVertexProgramConstant (uint index, const float *values)
1799 H_AUTO_D3D(CDriverD3D_setVertexProgramConstant);
1800 nlassert (_DeviceInterface);
1801 nlassert (index<MaxVertexProgramConstantState);
1803 // Ref on the state
1804 CVertexProgramConstantState &state = _VertexProgramConstantCache[index];
1805 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1806 bool doUpdate = ((*(float*)(state.Values+0)) != values[0]) ||
1807 ((*(float*)(state.Values+1)) != values[1]) ||
1808 ((*(float*)(state.Values+2)) != values[2]) ||
1809 ((*(float*)(state.Values+3)) != values[3]) ||
1810 (state.ValueType != CVertexProgramConstantState::Float);
1811 NL_D3D_CACHE_TEST(CacheTest_VertexProgramConstant, doUpdate)
1812 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1814 *(float*)(state.Values+0) = values[0];
1815 *(float*)(state.Values+1) = values[1];
1816 *(float*)(state.Values+2) = values[2];
1817 *(float*)(state.Values+3) = values[3];
1818 state.ValueType = CVertexProgramConstantState::Float;
1819 touchRenderVariable (&state);
1823 // Access vertex program constant
1824 inline void setVertexProgramConstant (uint index, const int *values)
1826 H_AUTO_D3D(CDriverD3D_setVertexProgramConstant);
1827 nlassert (_DeviceInterface);
1828 nlassert (index<MaxVertexProgramConstantState);
1830 // Ref on the state
1831 CVertexProgramConstantState &state = _VertexProgramConstantCache[index];
1832 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1833 bool doUpdate = ((*(int*)(state.Values+0)) != values[0]) ||
1834 ((*(int*)(state.Values+1)) != values[1]) ||
1835 ((*(int*)(state.Values+2)) != values[2]) ||
1836 ((*(int*)(state.Values+3)) != values[3]) ||
1837 (state.ValueType != CVertexProgramConstantState::Int);
1838 NL_D3D_CACHE_TEST(CacheTest_VertexProgramConstant, doUpdate)
1839 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1841 *(int*)(state.Values+0) = values[0];
1842 *(int*)(state.Values+1) = values[1];
1843 *(int*)(state.Values+2) = values[2];
1844 *(int*)(state.Values+3) = values[3];
1845 state.ValueType = CVertexProgramConstantState::Int;
1846 touchRenderVariable (&state);
1850 // Access pixel shader constant
1851 inline void setPixelShaderConstant (uint index, const float *values)
1853 H_AUTO_D3D(CDriverD3D_setPixelShaderConstant);
1854 nlassert (_DeviceInterface);
1855 nlassert (index<MaxPixelShaderConstantState);
1857 // Ref on the state
1858 CPixelShaderConstantState &state = _PixelShaderConstantCache[index];
1859 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1860 bool doUpdate = ((*(float*)(state.Values+0)) != values[0]) ||
1861 ((*(float*)(state.Values+1)) != values[1]) ||
1862 ((*(float*)(state.Values+2)) != values[2]) ||
1863 ((*(float*)(state.Values+3)) != values[3]) ||
1864 (state.ValueType != CPixelShaderConstantState::Float);
1865 NL_D3D_CACHE_TEST(CacheTest_PixelShaderConstant, doUpdate)
1866 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1868 *(float*)(state.Values+0) = values[0];
1869 *(float*)(state.Values+1) = values[1];
1870 *(float*)(state.Values+2) = values[2];
1871 *(float*)(state.Values+3) = values[3];
1872 state.ValueType = CPixelShaderConstantState::Float;
1873 touchRenderVariable (&state);
1877 // Access vertex program constant
1878 inline void setPixelShaderConstant (uint index, const int *values)
1880 H_AUTO_D3D(CDriverD3D_setPixelShaderConstant);
1881 nlassert (_DeviceInterface);
1882 nlassert (index<MaxPixelShaderConstantState);
1884 // Ref on the state
1885 CPixelShaderConstantState &state = _PixelShaderConstantCache[index];
1886 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1887 bool doUpdate = ((*(int*)(state.Values+0)) != values[0]) ||
1888 ((*(int*)(state.Values+1)) != values[1]) ||
1889 ((*(int*)(state.Values+2)) != values[2]) ||
1890 ((*(int*)(state.Values+3)) != values[3]) ||
1891 (state.ValueType != CPixelShaderConstantState::Int);
1892 NL_D3D_CACHE_TEST(CacheTest_PixelShaderConstant, doUpdate)
1893 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1895 *(int*)(state.Values+0) = values[0];
1896 *(int*)(state.Values+1) = values[1];
1897 *(int*)(state.Values+2) = values[2];
1898 *(int*)(state.Values+3) = values[3];
1899 state.ValueType = CPixelShaderConstantState::Int;
1900 touchRenderVariable (&state);
1904 // Access sampler states
1905 inline void setSamplerState (DWORD sampler, D3DSAMPLERSTATETYPE samplerState, DWORD value)
1907 H_AUTO_D3D(CDriverD3D_setSamplerState);
1908 nlassert (_DeviceInterface);
1909 nlassert (sampler<MaxSampler);
1910 nlassert ((int)samplerState<(int)MaxSamplerState);
1912 // Ref on the state
1913 CSamplerState &_samplerState = _SamplerStateCache[sampler][samplerState];
1914 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1915 NL_D3D_CACHE_TEST(CacheTest_SamplerState, _samplerState.Value != value)
1916 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1918 _samplerState.Value = value;
1919 touchRenderVariable (&_samplerState);
1923 // Set the vertex buffer
1924 inline void setVertexBuffer (IDirect3DVertexBuffer9 *vertexBuffer, UINT offset, UINT stride, bool useVertexColor, uint size, CVertexBuffer::TPreferredMemory pm, DWORD usage, uint colorOffset)
1926 H_AUTO_D3D(CDriverD3D_setVertexBuffer);
1927 nlassert (_DeviceInterface);
1929 // Ref on the state
1930 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1931 //NL_D3D_CACHE_TEST(CacheTest_VertexBuffer, (_VertexBufferCache.VertexBuffer != vertexBuffer) || (_VertexBufferCache.Offset != offset) || (stride != _VertexBufferCache.Stride) || (colorOffset != _VertexBufferCache.ColorOffset))
1932 NL_D3D_CACHE_TEST(CacheTest_VertexBuffer, (_VertexBufferCache.VertexBuffer != vertexBuffer) || (_VertexBufferCache.Offset != offset) || (stride != _VertexBufferCache.Stride) || (colorOffset != _VertexBufferCache.ColorOffset))
1934 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1936 _VertexBufferCache.VertexBuffer = vertexBuffer;
1937 _VertexBufferCache.Offset = 0;
1938 _VertexBufferCache.Stride = stride;
1939 _VertexBufferCache.PrefferedMemory = pm;
1940 _VertexBufferCache.Usage = usage;
1941 _VertexBufferCache.ColorOffset = colorOffset;
1942 touchRenderVariable (&_VertexBufferCache);
1944 /* Work around for a NVIDIA bug in driver 53.03 - 56.72
1945 * Sometime, after a lock D3DLOCK_NOOVERWRITE, the D3DTSS_TEXCOORDINDEX state seams to change.
1946 * So, force it at every vertex buffer set.
1948 if (_IsGeforce)
1950 touchRenderVariable (&_TextureStateCache[0][D3DTSS_TEXCOORDINDEX]);
1951 touchRenderVariable (&_TextureStateCache[1][D3DTSS_TEXCOORDINDEX]);
1952 touchRenderVariable (&_TextureStateCache[2][D3DTSS_TEXCOORDINDEX]);
1953 touchRenderVariable (&_TextureStateCache[3][D3DTSS_TEXCOORDINDEX]);
1956 _UseVertexColor = useVertexColor;
1957 _VertexBufferSize = size;
1958 _VertexBufferOffset = offset;
1961 // Force to alias diffuse color to specular color in the current vertex buffer
1962 inline void setAliasDiffuseToSpecular(bool enable)
1964 H_AUTO_D3D(CDriverD3D_setAliasDiffuseToSpecular);
1965 // Ref on the state
1966 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1967 NL_D3D_CACHE_TEST(CacheTest_VertexBuffer, enable != _VertexDeclCache.AliasDiffuseToSpecular)
1968 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1970 _VertexDeclCache.AliasDiffuseToSpecular = enable;
1971 touchRenderVariable (&_VertexDeclCache);
1975 // Enable / disable vertex color from the vertex declaration
1976 inline void setEnableVertexColor(bool enable)
1978 H_AUTO_D3D(CDriverD3D_setEnableVertexColor);
1979 // Ref on the state
1980 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1981 NL_D3D_CACHE_TEST(CacheTest_VertexBuffer, enable != _VertexDeclCache.EnableVertexColor)
1982 #endif // NL_D3D_USE_RENDER_STATE_CACHE
1984 _VertexDeclCache.EnableVertexColor = enable;
1985 touchRenderVariable (&_VertexDeclCache);
1986 touchRenderVariable (&_VertexBufferCache);
1990 // Set the index buffer
1991 inline void setIndexBuffer (IDirect3DIndexBuffer9 *indexBuffer, uint offset)
1993 H_AUTO_D3D(CDriverD3D_setIndexBuffer);
1994 nlassert (_DeviceInterface);
1996 // Ref on the state
1997 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
1998 NL_D3D_CACHE_TEST(CacheTest_IndexBuffer, _IndexBufferCache.IndexBuffer != indexBuffer)
1999 #endif // NL_D3D_USE_RENDER_STATE_CACHE
2001 _IndexBufferCache.IndexBuffer = indexBuffer;
2002 touchRenderVariable (&_IndexBufferCache);
2004 _IndexBufferOffset = offset;
2007 // Set the vertex declaration
2008 inline void setVertexDecl (IDirect3DVertexDeclaration9 *vertexDecl, IDirect3DVertexDeclaration9 *vertexDeclAliasDiffuseToSpecular, IDirect3DVertexDeclaration9 *vertexDeclNoDiffuse, uint stride)
2010 H_AUTO_D3D(CDriverD3D_setVertexDecl);
2011 nlassert (_DeviceInterface);
2013 // Ref on the state
2014 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
2015 NL_D3D_CACHE_TEST(CacheTest_VertexDecl, stride != _VertexDeclCache.Stride || _VertexDeclCache.Decl != vertexDecl || _VertexDeclCache.DeclAliasDiffuseToSpecular != vertexDeclAliasDiffuseToSpecular || vertexDeclNoDiffuse != _VertexDeclCache.DeclNoDiffuse)
2016 #endif // NL_D3D_USE_RENDER_STATE_CACHE
2018 _VertexDeclCache.Decl = vertexDecl;
2019 _VertexDeclCache.DeclAliasDiffuseToSpecular = vertexDeclAliasDiffuseToSpecular;
2020 _VertexDeclCache.Stride = stride;
2021 _VertexDeclCache.DeclNoDiffuse = vertexDeclNoDiffuse;
2022 touchRenderVariable (&_VertexDeclCache);
2026 // Access matrices
2027 inline uint remapMatrixIndex (D3DTRANSFORMSTATETYPE type)
2029 H_AUTO_D3D(CDriverD3D_remapMatrixIndex);
2030 if (type>=256)
2031 return (D3DTRANSFORMSTATETYPE)(MatrixStateRemap + type - 256);
2032 else
2033 return (uint)type;
2035 inline void setMatrix (D3DTRANSFORMSTATETYPE type, const D3DXMATRIX &matrix)
2037 H_AUTO_D3D(CDriverD3D_setMatrix);
2038 nlassert (_DeviceInterface);
2040 // Remap high matrices indexes
2041 type = (D3DTRANSFORMSTATETYPE)remapMatrixIndex (type);
2042 nlassert ((int)type<(int)MaxMatrixState);
2044 CMatrixState &theMatrix = _MatrixCache[type];
2045 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
2046 bool doUpdate = (matrix._11 != theMatrix.Matrix._11) ||
2047 (matrix._12 != theMatrix.Matrix._12) ||
2048 (matrix._13 != theMatrix.Matrix._13) ||
2049 (matrix._14 != theMatrix.Matrix._14) ||
2050 (matrix._21 != theMatrix.Matrix._21) ||
2051 (matrix._22 != theMatrix.Matrix._22) ||
2052 (matrix._23 != theMatrix.Matrix._23) ||
2053 (matrix._24 != theMatrix.Matrix._24) ||
2054 (matrix._31 != theMatrix.Matrix._31) ||
2055 (matrix._32 != theMatrix.Matrix._32) ||
2056 (matrix._33 != theMatrix.Matrix._33) ||
2057 (matrix._34 != theMatrix.Matrix._34) ||
2058 (matrix._41 != theMatrix.Matrix._41) ||
2059 (matrix._42 != theMatrix.Matrix._42) ||
2060 (matrix._43 != theMatrix.Matrix._43) ||
2061 (matrix._44 != theMatrix.Matrix._44);
2062 NL_D3D_CACHE_TEST(CacheTest_Matrix, doUpdate)
2063 #endif // NL_D3D_USE_RENDER_STATE_CACHE
2065 theMatrix.Matrix = matrix;
2066 touchRenderVariable (&theMatrix);
2070 // Access texture states
2071 inline void setRenderTarget (IDirect3DSurface9 *target, ITexture *texture, uint8 level, uint8 cubeFace)
2073 H_AUTO_D3D(CDriverD3D_setRenderTarget);
2074 nlassert (_DeviceInterface);
2076 // Ref on the state
2077 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
2078 NL_D3D_CACHE_TEST(CacheTest_RenderTarget, _RenderTarget.Target != target)
2079 #endif // NL_D3D_USE_RENDER_STATE_CACHE
2081 if (_RenderTarget.TargetOwned)
2083 nlassert(_RenderTarget.Target);
2084 _RenderTarget.Target->Release();
2086 _RenderTarget.Target = target;
2087 _RenderTarget.Texture = texture;
2088 _RenderTarget.Level = level;
2089 _RenderTarget.CubeFace = cubeFace;
2090 _RenderTarget.TargetOwned = target;
2091 target->AddRef();
2093 touchRenderVariable (&_RenderTarget);
2095 _ScissorTouched = true;
2100 public:
2101 void setMaterialState(const D3DMATERIAL9 &material)
2103 H_AUTO_D3D(setMaterialState);
2104 #ifdef NL_D3D_USE_RENDER_STATE_CACHE
2105 bool update = material.Power != _MaterialState.Current.Power ||
2106 material.Ambient != _MaterialState.Current.Ambient ||
2107 material.Emissive != _MaterialState.Current.Emissive ||
2108 material.Diffuse != _MaterialState.Current.Diffuse ||
2109 material.Specular != _MaterialState.Current.Specular;
2110 NL_D3D_CACHE_TEST(CacheTest_MaterialState, update)
2111 #endif
2113 _MaterialState.Current = material;
2114 touchRenderVariable(&_MaterialState);
2121 // Get the d3dtext mirror of an existing setuped texture.
2122 static inline CTextureDrvInfosD3D* getTextureD3D(ITexture& tex)
2124 H_AUTO_D3D(CDriverD3D_getTextureD3D);
2125 CTextureDrvInfosD3D* d3dtex;
2126 d3dtex= (CTextureDrvInfosD3D*)(ITextureDrvInfos*)(tex.TextureDrvShare->DrvTexture);
2127 return d3dtex;
2130 // Get the d3dtext mirror of an existing setuped pixel program.
2131 static inline CPixelProgramDrvInfosD3D* getPixelProgramD3D(CPixelProgram& pixelProgram)
2133 H_AUTO_D3D(CDriverD3D_getPixelProgramD3D);
2134 CPixelProgramDrvInfosD3D* d3dPixelProgram;
2135 d3dPixelProgram = (CPixelProgramDrvInfosD3D*)(IProgramDrvInfos*)(pixelProgram.m_DrvInfo);
2136 return d3dPixelProgram;
2139 // Get the d3dtext mirror of an existing setuped vertex program.
2140 static inline CVertexProgamDrvInfosD3D* getVertexProgramD3D(CVertexProgram& vertexProgram)
2142 H_AUTO_D3D(CDriverD3D_getVertexProgramD3D);
2143 CVertexProgamDrvInfosD3D* d3dVertexProgram;
2144 d3dVertexProgram = (CVertexProgamDrvInfosD3D*)(IProgramDrvInfos*)(vertexProgram.m_DrvInfo);
2145 return d3dVertexProgram;
2148 // *** Init helper
2150 bool isDepthFormatOk(UINT adapter, D3DDEVTYPE rasterizer, D3DFORMAT DepthFormat, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat);
2151 bool isTextureFormatOk(UINT adapter, D3DDEVTYPE rasterizer, D3DFORMAT TextureFormat, D3DFORMAT AdapterFormat);
2152 bool fillPresentParameter (D3DPRESENT_PARAMETERS &parameters, D3DFORMAT &adapterFormat, const GfxMode& mode, const D3DDISPLAYMODE &adapterMode);
2154 // *** Texture helper
2156 D3DFORMAT getD3DDestTextureFormat (ITexture& tex);
2157 // Generates the texture, degades it, creates / resizes the d3d surface. Don't fill the surface.
2158 bool generateD3DTexture (ITexture& tex, bool textureDegradation, D3DFORMAT &destFormat, D3DFORMAT &srcFormat, bool &cube);
2159 // Return the memory used by the surface described iwith the parameters
2160 uint32 computeTextureMemoryUsage (uint width, uint height, uint levels, D3DFORMAT destFormat, bool cube);
2161 // Upload a texture part
2162 bool uploadTextureInternal (ITexture& tex, NLMISC::CRect& rect, uint8 destMipmap, uint8 srcMipmap, D3DFORMAT destFormat, D3DFORMAT srcFormat);
2164 // *** Matrix helper
2166 // Update _D3DModelView and _D3DModelViewProjection matrices. Call this if the model, the projection or the view matrix are modified
2167 void updateMatrices ();
2168 // Update the projection matrix. Call this if the driver resolution, the viewport or the frustum changes.
2169 void updateProjectionMatrix ();
2171 // *** Vertex buffer helper
2173 // Create a vertex declaration
2174 bool createVertexDeclaration (uint16 vertexFormat, const uint8 *typeArray,
2175 IDirect3DVertexDeclaration9 **vertexDecl,
2176 uint &colorOffset,
2177 bool aliasDiffuseToSpecular,
2178 bool bypassDiffuse,
2179 uint *stride = NULL
2182 // *** Index buffer helper
2184 // *** Multipass helpers
2186 void initInternalShaders();
2187 void releaseInternalShaders();
2188 bool setShaderTexture (uint textureHandle, ITexture *texture, CFXCache *cache);
2190 bool validateShader(CD3DShaderFX *shader);
2192 void activePass (uint pass)
2194 H_AUTO_D3D(CDriverD3D_activePass);
2195 if (_CurrentShader)
2197 CShaderDrvInfosD3D *drvInfo = static_cast<CShaderDrvInfosD3D*>((IShaderDrvInfos*)_CurrentShader->_DrvInfo);
2198 if (_CurrentMaterialInfo->FXCache)
2200 nlassert(_CurrentMaterialInfo);
2201 _CurrentMaterialInfo->FXCache->applyPass(*this, drvInfo, pass);
2203 else
2205 #if (DIRECT3D_VERSION >= 0x0900) && (D3D_SDK_VERSION >= 32)
2206 drvInfo->Effect->BeginPass (pass);
2207 drvInfo->Effect->EndPass ();
2208 #else
2209 drvInfo->Effect->Pass (pass);
2210 #endif
2214 // Update render states
2215 updateRenderVariablesInternal();
2218 void beginMultiPass ()
2220 H_AUTO_D3D(CDriverD3D_beginMultiPass);
2221 if (_CurrentShader)
2223 // Does the shader validated ?
2224 validateShader(_CurrentShader);
2226 // Init default state value
2227 uint i;
2228 for (i=0; i<MaxTexture; i++)
2230 setTextureState (i, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
2231 setTextureIndexMode (i, false, D3DTSS_TCI_PASSTHRU);
2232 setTextureIndexUV (i, i);
2233 setTextureState (i, D3DTSS_COLOROP, D3DTOP_DISABLE);
2234 //setTextureState (i, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
2237 CShaderDrvInfosD3D *drvInfo = static_cast<CShaderDrvInfosD3D*>((IShaderDrvInfos*)_CurrentShader->_DrvInfo);
2238 if (_CurrentMaterialInfo->FXCache)
2240 nlassert(_CurrentMaterialInfo);
2241 _CurrentMaterialInfo->FXCache->begin(drvInfo, this);
2243 else
2245 drvInfo->Effect->Begin (&_CurrentShaderPassCount, D3DXFX_DONOTSAVESTATE|D3DXFX_DONOTSAVESHADERSTATE);
2248 else
2249 // No shader setuped
2250 _CurrentShaderPassCount = 1;
2253 void endMultiPass ()
2255 H_AUTO_D3D(CDriverD3D_endMultiPass);
2256 if (_CurrentShader)
2258 CShaderDrvInfosD3D *drvInfo = static_cast<CShaderDrvInfosD3D*>((IShaderDrvInfos*)_CurrentShader->_DrvInfo);
2259 if (_CurrentMaterialInfo->FXCache)
2261 _CurrentMaterialInfo->FXCache->end(drvInfo);
2263 else
2265 drvInfo->Effect->End ();
2270 // render helpers
2271 bool renderPrimitives(D3DPRIMITIVETYPE primitiveType, uint numVertexPerPrim, CMaterial& mat, uint firstVertex, uint32 nPrims);
2272 bool renderIndexedPrimitives(D3DPRIMITIVETYPE primitiveType, uint numVertexPerPrim, CMaterial& mat, uint32 firstIndex, uint32 nPrims, uint indexOffset = 0);
2273 bool renderSimpleIndexedPrimitives(D3DPRIMITIVETYPE primitiveType, uint numVertexPerPrim, uint32 firstIndex, uint32 nPrims, uint indexOffset = 0);
2274 void convertToIndices16(uint firstIndex, uint numIndices);
2276 // Returns true if this material needs a constant color for the diffuse component
2277 static bool needsConstantForDiffuse (CMaterial &mat);
2279 /* Returns true if this normal needs constant. If true, numConstant is the number of needed constants, firstConstant is the first
2280 constants needed. */
2281 static bool needsConstants (uint &numConstant, uint &firstConstant, uint &secondConstant, CMaterial &mat);
2283 // For normal shader, compute part of the pipeline that are worth setting
2284 // For example : if alpha output if not used (no alpha test or blend), then the alpha part won't be set at all
2285 static void computeRelevantTexEnv(CMaterial &mat, bool rgbPipe[IDRV_MAT_MAXTEXTURES], bool alphaPipe[IDRV_MAT_MAXTEXTURES]);
2287 // Build a pixel shader for normal shader
2288 IDirect3DPixelShader9 *buildPixelShader (const CNormalShaderDesc &normalShaderDesc, bool unlightedNoVertexColor);
2291 // Notify all the shaders drivers info that a device has been lost
2292 void notifyAllShaderDrvOfLostDevice();
2293 // Notify all the shaders drivers info that a device has been reset
2294 void notifyAllShaderDrvOfResetDevice();
2296 // *** Debug helpers
2298 void setDebugMaterial();
2300 // ** From ID3DXEffectStateManager
2301 public:
2302 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj);
2303 ULONG STDMETHODCALLTYPE AddRef(VOID);
2304 ULONG STDMETHODCALLTYPE Release(VOID);
2305 HRESULT STDMETHODCALLTYPE LightEnable(DWORD Index, BOOL Enable);
2306 HRESULT STDMETHODCALLTYPE SetFVF(DWORD FVF);
2307 HRESULT STDMETHODCALLTYPE SetLight(DWORD Index, CONST D3DLIGHT9* pLight);
2308 HRESULT STDMETHODCALLTYPE SetMaterial(CONST D3DMATERIAL9* pMaterial);
2309 HRESULT STDMETHODCALLTYPE SetNPatchMode(FLOAT nSegments);
2310 HRESULT STDMETHODCALLTYPE SetPixelShader(LPDIRECT3DPIXELSHADER9 pShader);
2311 HRESULT STDMETHODCALLTYPE SetPixelShaderConstantB(UINT StartRegister, CONST BOOL* pConstantData, UINT RegisterCount);
2312 HRESULT STDMETHODCALLTYPE SetPixelShaderConstantF(UINT StartRegister, CONST FLOAT* pConstantData, UINT RegisterCount);
2313 HRESULT STDMETHODCALLTYPE SetPixelShaderConstantI(UINT StartRegister, CONST INT* pConstantData, UINT RegisterCount);
2314 HRESULT STDMETHODCALLTYPE SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
2315 HRESULT STDMETHODCALLTYPE SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
2316 HRESULT STDMETHODCALLTYPE SetTexture (DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture);
2317 HRESULT STDMETHODCALLTYPE SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
2318 HRESULT STDMETHODCALLTYPE SetTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix);
2319 HRESULT STDMETHODCALLTYPE SetVertexShader(LPDIRECT3DVERTEXSHADER9 pShader);
2320 HRESULT STDMETHODCALLTYPE SetVertexShaderConstantB(UINT StartRegister, CONST BOOL* pConstantData, UINT RegisterCount);
2321 HRESULT STDMETHODCALLTYPE SetVertexShaderConstantF(UINT StartRegister, CONST FLOAT* pConstantData, UINT RegisterCount);
2322 HRESULT STDMETHODCALLTYPE SetVertexShaderConstantI(UINT StartRegister, CONST INT* pConstantData, UINT RegisterCount);
2323 private:
2325 void findNearestFullscreenVideoMode();
2327 TShaderDrvInfoPtrList _ShaderDrvInfos;
2329 // Windows
2330 std::wstring _WindowClass;
2331 HWND _HWnd;
2332 sint32 _WindowX;
2333 sint32 _WindowY;
2334 bool _DestroyWindow;
2335 bool _Maximized;
2336 bool _WindowFocus;
2337 bool _HandlePossibleSizeChangeNextSize;
2338 GfxMode _CurrentMode;
2339 uint _Interval;
2340 bool _FullScreen;
2342 // cursors
2343 enum TColorDepth { ColorDepth16 = 0, ColorDepth32, ColorDepthCount };
2345 TColorDepth _ColorDepth;
2346 std::string _CurrName;
2347 NLMISC::CRGBA _CurrCol;
2348 uint8 _CurrRot;
2349 uint _CurrHotSpotX;
2350 uint _CurrHotSpotY;
2351 float _CursorScale;
2353 nlCursor _DefaultCursor;
2355 bool _AlphaBlendedCursorSupported;
2356 bool _AlphaBlendedCursorSupportRetrieved;
2358 class CCursor
2360 public:
2361 NLMISC::CBitmap Src;
2362 TColorDepth ColorDepth;
2363 uint OrigHeight;
2364 float HotspotScale;
2365 uint HotspotOffsetX;
2366 uint HotspotOffsetY;
2367 sint HotSpotX;
2368 sint HotSpotY;
2369 nlCursor Cursor;
2370 NLMISC::CRGBA Col;
2371 uint8 Rot;
2372 #if defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
2373 Display *Dpy;
2374 #endif
2375 public:
2376 CCursor();
2377 ~CCursor();
2378 CCursor& operator= (const CCursor& from);
2380 void reset();
2383 struct CStrCaseUnsensitiveCmp
2385 bool operator()(const std::string &lhs, const std::string &rhs) const
2387 return NLMISC::nlstricmp(lhs, rhs) < 0;
2391 typedef std::map<std::string, CCursor, CStrCaseUnsensitiveCmp> TCursorMap;
2393 TCursorMap _Cursors;
2395 // Directx
2396 uint32 _Adapter;
2397 D3DDEVTYPE _Rasterizer;
2398 LPDIRECT3D9 _D3D;
2399 public:
2400 IDirect3DDevice9 *_DeviceInterface;
2401 private:
2403 // Events
2404 NLMISC::CEventEmitterMulti _EventEmitter; // this can contains a win emitter and eventually a direct input emitter
2406 // Some matrices (Local -> Model -> World -> Screen)
2407 public:
2408 CVector _PZBCameraPos;
2409 private:
2410 CMatrix _UserModelMtx;
2411 CMatrix _UserViewMtx;
2412 public:
2413 CViewport _Viewport;
2414 private:
2415 D3DVIEWPORT9 _D3DViewport;
2416 public:
2417 CScissor _Scissor;
2418 private:
2419 float _OODeltaZ; // Backup znear and zfar
2420 D3DXMATRIX _D3DSpecularWorldTex; // World (as in NeL) to model matrix.
2421 D3DXMATRIX _D3DModelView; // Local to world (as in D3D) matrix.
2422 D3DXMATRIX _D3DModelViewProjection; // Local to screen (as in D3D) matrix.
2423 D3DXMATRIX _D3DInvModelView; // World (as in DX) to local matrix.
2424 bool _ForceNormalize;
2425 bool _FrustumPerspective;
2426 bool _InvertCullMode;
2427 bool _DoubleSided;
2428 float _FrustumLeft;
2429 float _FrustumRight;
2430 float _FrustumTop;
2431 float _FrustumBottom;
2432 float _FrustumZNear;
2433 float _FrustumZFar;
2434 float _FogStart;
2435 float _FogEnd;
2437 // Vertex memory available
2438 uint32 _AGPMemoryAllocated;
2439 uint32 _VRAMMemoryAllocated;
2441 // Textures caps
2442 D3DFORMAT _PreferedTextureFormat[ITexture::UploadFormatCount];
2443 uint _ForceTextureResizePower;
2444 bool _ForceDXTCCompression:1;
2445 bool _TextureCubeSupported;
2446 bool _VertexProgram;
2447 bool _PixelProgram;
2448 uint16 _PixelProgramVersion;
2449 bool _DisableHardwareVertexProgram;
2450 bool _DisableHardwarePixelProgram;
2451 bool _DisableHardwareVertexArrayAGP;
2452 bool _DisableHardwareIndexArrayAGP;
2453 bool _DisableHardwarePixelShader;
2454 bool _MADOperatorSupported;
2455 bool _EMBMSupported;
2456 bool _CubbedMipMapSupported;
2457 bool _IsGeforce;
2458 bool _NonPowerOfTwoTexturesSupported;
2459 uint _MaxAnisotropy;
2460 bool _AnisotropicMinSupported;
2461 bool _AnisotropicMagSupported;
2462 bool _AnisotropicMinCubeSupported;
2463 bool _AnisotropicMagCubeSupported;
2464 uint _NbNeLTextureStages; // Number of texture stage for NeL (max IDRV_MAT_MAXTEXTURES)
2465 uint _MaxVerticesByVertexBufferHard;
2466 uint _MaxLight;
2467 uint32 _PixelShaderVersion;
2468 uint32 _MaxPrimitiveCount;
2469 uint32 _MaxVertexIndex;
2470 uint _MaxNumPerStageConstantLighted;
2471 uint _MaxNumPerStageConstantUnlighted;
2473 // Profiling
2474 CPrimitiveProfile _PrimitiveProfileIn;
2475 CPrimitiveProfile _PrimitiveProfileOut;
2476 uint32 _AllocatedTextureMemory;
2477 uint32 _NbSetupMaterialCall;
2478 uint32 _NbSetupModelMatrixCall;
2479 bool _SumTextureMemoryUsed;
2480 std::set<CTextureDrvInfosD3D*> _TextureUsed;
2482 // VBHard Lock Profiling
2483 struct CVBHardProfile
2485 NLMISC::CRefPtr<CVertexBuffer> VBHard;
2486 NLMISC::TTicks AccumTime;
2487 // true if the VBHard was not always the same for the same chronogical place.
2488 bool Change;
2489 CVBHardProfile()
2491 AccumTime= 0;
2492 Change= false;
2496 // Index buffer lock profiling
2497 struct CIBProfile
2499 NLMISC::CRefPtr<CIndexBuffer> IB;
2500 NLMISC::TTicks AccumTime;
2501 // true if the VBHard was not always the same for the same chronogical place.
2502 bool Change;
2503 CIBProfile()
2505 AccumTime= 0;
2506 Change= false;
2510 // The vb hard Profiles in chronogical order.
2511 bool _VBHardProfiling;
2512 std::vector<CVBHardProfile> _VBHardProfiles;
2513 uint _CurVBHardLockCount;
2514 uint _NumVBHardProfileFrame;
2515 void appendVBHardLockProfile(NLMISC::TTicks time, CVertexBuffer *vb);
2517 // The index buffer profile in chronogical order.
2518 bool _IBProfiling;
2519 std::vector<CIBProfile> _IBProfiles;
2520 uint _CurIBLockCount;
2521 uint _NumIBProfileFrame;
2522 public:
2523 NLMISC::TTicks _VolatileIBLockTime;
2524 NLMISC::TTicks _VolatileVBLockTime;
2525 private:
2526 void appendIBLockProfile(NLMISC::TTicks time, CIndexBuffer *ib);
2528 // VBHard profile
2529 std::set<CVBDrvInfosD3D*> _VertexBufferHardSet;
2531 // The render variables
2532 public:
2533 CRenderState _RenderStateCache[MaxRenderState];
2534 CTextureState _TextureStateCache[MaxTexture][MaxTextureState];
2535 CTextureIndexState _TextureIndexStateCache[MaxTexture];
2536 CTexturePtrState _TexturePtrStateCache[MaxTexture];
2537 CSamplerState _SamplerStateCache[MaxSampler][MaxSamplerState];
2538 CMatrixState _MatrixCache[MaxMatrixState];
2539 CVertexProgramPtrState _VertexProgramCache;
2540 CPixelShaderPtrState _PixelShaderCache;
2541 CVertexProgramConstantState _VertexProgramConstantCache[MaxVertexProgramConstantState];
2542 CPixelShaderConstantState _PixelShaderConstantCache[MaxPixelShaderConstantState];
2543 CVertexDeclState _VertexDeclCache;
2544 CLightState _LightCache[MaxLight];
2545 CRenderTargetState _RenderTarget;
2546 CMaterialState _MaterialState;
2547 private:
2549 // last activation of vertex buffer / index buffer
2550 NLMISC::CRefPtr<CIBDrvInfosD3D> _LastIndexBufferInfo;
2552 // Vertex buffer cache
2553 CVBState _VertexBufferCache;
2554 uint _VertexBufferSize;
2555 uint _VertexBufferOffset;
2556 public:
2557 bool _UseVertexColor;
2558 private:
2560 // Index buffer cache
2561 CIBState _IndexBufferCache;
2562 uint _IndexBufferOffset; // Current index buffer offset
2563 CIndexBuffer::TFormat _CurrIndexBufferFormat; // updated at call to activeIndexBuffer
2565 // The last vertex buffer needs vertex color
2566 bool _FogEnabled;
2568 NLMISC::CRefPtr<CVertexProgram> _VertexProgramUser;
2569 NLMISC::CRefPtr<CPixelProgram> _PixelProgramUser;
2571 // *** Internal resources
2573 // Current render pass
2574 uint _CurrentRenderPass;
2577 // Volatile double buffers
2578 CVolatileVertexBuffer *_VolatileVertexBufferRAM[2];
2579 CVolatileVertexBuffer *_VolatileVertexBufferAGP[2];
2580 CVolatileIndexBuffer *_VolatileIndexBuffer16RAM[2];
2581 CVolatileIndexBuffer *_VolatileIndexBuffer16AGP[2];
2582 CVolatileIndexBuffer *_VolatileIndexBuffer32RAM[2];
2583 CVolatileIndexBuffer *_VolatileIndexBuffer32AGP[2];
2585 // Special 16 bit index buffer for quads
2586 IDirect3DIndexBuffer9 *_QuadIB;
2588 // Vertex declaration list
2589 std::list<CVertexDeclaration> _VertexDeclarationList;
2591 // Pixel shader list
2592 std::list<CNormalShaderDesc> _NormalPixelShaders[2];
2594 // Quad indexes
2595 CIndexBuffer _QuadIndexes;
2596 CIndexBuffer _QuadIndexesAGP;
2598 // The last setuped shader
2599 CD3DShaderFX *_CurrentShader;
2600 UINT _CurrentShaderPassCount;
2601 public:
2602 struct CTextureRef
2604 CRefPtr<ITexture> NeLTexture;
2605 LPDIRECT3DBASETEXTURE9 D3DTexture;
2607 const std::vector<CTextureRef> &getCurrentShaderTextures() const { return _CurrentShaderTextures; }
2608 private:
2609 std::vector<CTextureRef> _CurrentShaderTextures;
2611 // The last material setuped
2612 CMaterial *_CurrentMaterial;
2613 public:
2614 CMaterialDrvInfosD3D *_CurrentMaterialInfo;
2615 private:
2617 // Optim: To not test change in Materials states if just texture has changed. Very useful for landscape.
2618 uint32 _MaterialAllTextureTouchedFlag;
2620 // The modified render variables list
2621 CRenderVariable *_ModifiedRenderState;
2623 // Internal shaders
2624 CD3DShaderFX _ShaderLightmap0;
2625 CD3DShaderFX _ShaderLightmap1;
2626 CD3DShaderFX _ShaderLightmap2;
2627 CD3DShaderFX _ShaderLightmap3;
2628 CD3DShaderFX _ShaderLightmap4;
2629 CD3DShaderFX _ShaderLightmap0Blend;
2630 CD3DShaderFX _ShaderLightmap1Blend;
2631 CD3DShaderFX _ShaderLightmap2Blend;
2632 CD3DShaderFX _ShaderLightmap3Blend;
2633 CD3DShaderFX _ShaderLightmap4Blend;
2634 CD3DShaderFX _ShaderLightmap0X2;
2635 CD3DShaderFX _ShaderLightmap1X2;
2636 CD3DShaderFX _ShaderLightmap2X2;
2637 CD3DShaderFX _ShaderLightmap3X2;
2638 CD3DShaderFX _ShaderLightmap4X2;
2639 CD3DShaderFX _ShaderLightmap0BlendX2;
2640 CD3DShaderFX _ShaderLightmap1BlendX2;
2641 CD3DShaderFX _ShaderLightmap2BlendX2;
2642 CD3DShaderFX _ShaderLightmap3BlendX2;
2643 CD3DShaderFX _ShaderLightmap4BlendX2;
2644 CD3DShaderFX _ShaderCloud;
2645 CD3DShaderFX _ShaderWaterNoDiffuse;
2646 CD3DShaderFX _ShaderWaterDiffuse;
2649 // Backup frame buffer
2650 IDirect3DSurface9 *_BackBuffer;
2652 // Static bitmap buffer to convert rgba to bgra
2653 static std::vector<uint8> _TempBuffer;
2655 // Version of the driver. Not the interface version!! Increment when implementation of the driver change.
2656 static const uint32 ReleaseVersion;
2658 uint64 _SwapBufferCounter;
2660 // occlusion query
2661 bool _OcclusionQuerySupported;
2662 TOcclusionQueryList _OcclusionQueryList;
2664 // depth range
2665 float _DepthRangeNear;
2666 float _DepthRangeFar;
2668 bool _ScissorTouched;
2669 uint8 _CurrentUVRouting[MaxTexture];
2670 bool _MustRestoreLight;
2671 D3DXMATRIX _D3DMatrixIdentity;
2672 DWORD _FogColor;
2673 uint _AnisotropicFilter;
2675 // stencil buffer
2676 bool _CurStencilTest;
2677 DWORD _CurStencilFunc;
2678 DWORD _CurStencilRef;
2679 DWORD _CurStencilMask;
2680 DWORD _CurStencilOpFail;
2681 DWORD _CurStencilOpZFail;
2682 DWORD _CurStencilOpZPass;
2683 DWORD _CurStencilWriteMask;
2685 public:
2687 // private, for access by COcclusionQueryD3D
2688 COcclusionQueryD3D *_CurrentOcclusionQuery;
2690 // *** Lightmap Dynamic Light
2691 // For Lightmap Dynamic Lighting
2692 CLight _LightMapDynamicLight;
2693 bool _LightMapDynamicLightEnabled;
2694 bool _LightMapDynamicLightDirty;
2695 CMaterial::TShader _CurrentMaterialSupportedShader;
2696 // this is the backup of standard lighting (cause GL states may be modified by Lightmap Dynamic Lighting)
2697 CLight _UserLight0;
2698 bool _UserLightEnable[MaxLight];
2699 // methods to enable / disable DX light, without affecting _LightMapDynamicLight*, or _UserLight0*
2700 void setLightInternal(uint8 num, const CLight& light);
2701 void enableLightInternal(uint8 num, bool enable);
2702 // on/off Lights for LightMap mode: only the first light is enabled in lightmap mode
2703 void setupLightMapDynamicLighting(bool enable);
2705 TCullMode _CullMode;
2707 bool _Lost;
2708 bool _SceneBegun;
2710 WORD _DesktopGammaRamp[256 * 3];
2711 bool _DesktopGammaRampValid;
2713 // for debug only
2714 static bool _CacheTest[CacheTest_Count];
2716 static std::vector<uint16> _QuadIndices; // tmp : quads indices -> to allow support of quads on devices that don't have 32 bit indices
2718 // reset an index buffer and force it to be reallocated
2719 void deleteIndexBuffer(CIBDrvInfosD3D *ib);
2720 // Build 16 bit index buffer for quad
2721 bool buildQuadIndexBuffer();
2723 // Test if cursor is in the client area. always true when software cursor is used and window visible
2724 // (displayed in software when DirectInput is used)
2725 bool isSystemCursorInClientArea();
2727 // Check if RGBA cursors are supported
2728 bool isAlphaBlendedCursorSupported();
2730 // Update cursor appearance
2731 void updateCursor(bool forceRebuild = false);
2733 // Create default cursors
2734 void createCursors();
2736 // Release all cursors
2737 void releaseCursors();
2739 // Convert a NLMISC::CBitmap to nlCursor
2740 bool convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &cursor, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY);
2742 // build a cursor from src, src should have the same size that the hardware cursor
2743 // or a assertion is thrown
2744 nlCursor buildCursor(const NLMISC::CBitmap &src, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY);
2746 // reset the cursor shape to the system arrow
2747 void setSystemArrow();
2749 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);
2751 virtual bool copyTextToClipboard(const std::string &text);
2752 virtual bool pasteTextFromClipboard(std::string &text);
2754 public:
2755 #ifdef NL_DEBUG
2756 std::set<CVBDrvInfosD3D *> _LockedBuffers;
2757 #endif
2759 emptyProc ExitFunc;
2761 bool beginScene()
2763 nlassert(!_SceneBegun);
2764 if (_DeviceInterface->BeginScene() != D3D_OK) return false;
2765 _SceneBegun = true;
2766 return true;
2769 bool endScene()
2771 nlassert(_SceneBegun);
2772 if (_DeviceInterface->EndScene() != D3D_OK) return false;
2773 _SceneBegun = false;
2774 return true;
2777 bool hasSceneBegun() const { return _SceneBegun; }
2779 // Clip the wanted rectangle with window. return true if rect is not NULL.
2780 bool clipRect(NLMISC::CRect &rect);
2782 friend class IShaderDrvInfos;
2784 void removeShaderDrvInfoPtr(ItShaderDrvInfoPtrList shaderIt);
2788 #define NL_D3DCOLOR_RGBA(rgba) (D3DCOLOR_ARGB(rgba.A,rgba.R,rgba.G,rgba.B))
2789 #define D3DCOLOR_NL_RGBA(rgba) (NLMISC::CRGBA((uint8)((rgba>>16)&0xff), (uint8)((rgba>>8)&0xff), (uint8)(rgba&0xff), (uint8)((rgba>>24)&0xff)))
2790 #define NL_D3DCOLORVALUE_RGBA(dest,rgba) \
2791 dest.a=(float)rgba.A*(1.f/255.f);dest.r=(float)rgba.R*(1.f/255.f);dest.g=(float)rgba.G*(1.f/255.f);dest.b=(float)rgba.B*(1.f/255.f);
2792 #define NL_D3D_MATRIX(d3d_mt,nl_mt) \
2793 { const float *nl_mt_ptr = nl_mt.get(); \
2794 d3d_mt._11 = nl_mt_ptr[0]; \
2795 d3d_mt._21 = nl_mt_ptr[4]; \
2796 d3d_mt._31 = nl_mt_ptr[8]; \
2797 d3d_mt._41 = nl_mt_ptr[12]; \
2798 d3d_mt._12 = nl_mt_ptr[1]; \
2799 d3d_mt._22 = nl_mt_ptr[5]; \
2800 d3d_mt._32 = nl_mt_ptr[9]; \
2801 d3d_mt._42 = nl_mt_ptr[13]; \
2802 d3d_mt._13 = nl_mt_ptr[2]; \
2803 d3d_mt._23 = nl_mt_ptr[6]; \
2804 d3d_mt._33 = nl_mt_ptr[10]; \
2805 d3d_mt._43 = nl_mt_ptr[14]; \
2806 d3d_mt._14 = nl_mt_ptr[3]; \
2807 d3d_mt._24 = nl_mt_ptr[7]; \
2808 d3d_mt._34 = nl_mt_ptr[11]; \
2809 d3d_mt._44 = nl_mt_ptr[15]; }
2810 // build matrix for texture 2D transform (special case in D3D)
2811 #define NL_D3D_TEX2D_MATRIX(d3d_mt,nl_mt) \
2812 { const float *nl_mt_ptr = nl_mt.get(); \
2813 d3d_mt._11 = nl_mt_ptr[0]; \
2814 d3d_mt._12 = nl_mt_ptr[1]; \
2815 d3d_mt._13 = nl_mt_ptr[3]; \
2816 d3d_mt._14 = 0.f; \
2817 d3d_mt._21 = nl_mt_ptr[4]; \
2818 d3d_mt._22 = nl_mt_ptr[5]; \
2819 d3d_mt._23 = nl_mt_ptr[7]; \
2820 d3d_mt._24 = 0.f; \
2821 d3d_mt._31 = nl_mt_ptr[12]; \
2822 d3d_mt._32 = nl_mt_ptr[13]; \
2823 d3d_mt._33 = nl_mt_ptr[15]; \
2824 d3d_mt._34 = 0.f; \
2825 d3d_mt._41 = 0.f; \
2826 d3d_mt._42 = 0.f; \
2827 d3d_mt._43 = 0.f; \
2828 d3d_mt._44 = 1.f; }
2835 #define NL_D3DVECTOR_VECTOR(dest,vect) dest.x=(vect).x;dest.y=(vect).y;dest.z=(vect).z;
2836 #define FTODW(f) (*((DWORD*)&(f)))
2837 #define D3DCOLOR_FLOATS(floats,rgba) {floats[0]=(float)((rgba>>16)&0xff) * (1.f/255.f);floats[1]=(float)((rgba>>8)&0xff) * (1.f/255.f);\
2838 floats[2]=(float)(rgba&0xff) * (1.f/255.f);floats[3]=(float)((rgba>>24)&0xff) * (1.f/255.f);}
2839 #define NL_FLOATS(floats,rgba) {floats[0] = (float)rgba.R * (1.f/255.f);floats[1] = (float)rgba.G * (1.f/255.f);\
2840 floats[2] = (float)rgba.B * (1.f/255.f);floats[3] = (float)rgba.A * (1.f/255.f);}
2842 // ***************************************************************************
2843 // nbPixels is pixel count, not a byte count !
2844 inline void copyRGBA2BGRA (uint32 *dest, const uint32 *src, uint nbPixels)
2846 H_AUTO_D3D(CDriverD3D_copyRGBA2BGRA);
2847 while (nbPixels != 0)
2849 register uint32 color = *src;
2850 *dest = (color & 0xff00ff00) | ((color&0xff)<<16) | ((color&0xff0000)>>16);
2851 dest++;
2852 src++;
2853 nbPixels--;
2858 // ***************************************************************************
2859 // set a D3DCOLORVALUE
2860 inline void setColor(D3DCOLORVALUE &dest, float r, float g, float b, float a)
2862 dest.r = r;
2863 dest.g = g;
2864 dest.b = b;
2865 dest.a = a;
2868 // ***************************************************************************
2869 // set a D3DCOLORVALUE from & D3DCOLOR
2870 inline void setColor(D3DCOLORVALUE &dest, const D3DCOLOR &src)
2872 dest.r = (1.f / 255.f) * ((src >> 16) & 0xff);
2873 dest.g = (1.f / 255.f) * ((src >> 8) & 0xff);
2874 dest.b = (1.f / 255.f) * (src & 0xff);
2875 dest.a = (1.f / 255.f) * (src >> 24);
2878 // ***************************************************************************
2879 // set a D3DCOLORVALUE from a CRGBA
2880 inline void setColor(D3DCOLORVALUE &dest, const NLMISC::CRGBA &src)
2882 dest.r = (1.f / 255.f) * src.R;
2883 dest.g = (1.f / 255.f) * src.G;
2884 dest.b = (1.f / 255.f) * src.B;
2885 dest.a = (1.f / 255.f) * src.A;
2888 // ***************************************************************************
2889 void fillQuadIndexes (uint16 *indexes, uint first, uint last);
2891 } // NL3D
2893 #ifndef NL_STATIC
2894 extern HINSTANCE HInstDLL;
2895 #endif
2897 #endif // NL_DRIVER_DIRECT3D_H