1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010-2020 Winch Gate Property Limited
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>
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"
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"
52 typedef HCURSOR nlCursor
;
53 #define EmptyCursor NULL
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))
69 #define NL_D3D_CACHE_TEST(label, cond) if (cond)
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)
99 #define H_AUTO_D3D(label)
105 CFpuRestorer() { _FPControlWord
= _controlfp(0, 0); }
108 _controlfp(_FPControlWord
, ~0);
111 unsigned int _FPControlWord
;
117 CFpuChecker(const char *label
) { _FPControlWord
= _controlfp(0, 0); _Label
= label
; }
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
)))
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 // ***************************************************************************
155 const uint MAX_NUM_QUADS
= 32767; // max number of quads in a single draw call
157 using NLMISC::CMatrix
;
158 using NLMISC::CVector
;
161 class CTextureDrvInfosD3D
;
162 class COcclusionQueryD3D
;
163 class CVolatileVertexBuffer
;
164 class CVolatileIndexBuffer
;
166 typedef std::list
<COcclusionQueryD3D
*> TOcclusionQueryList
;
168 // ***************************************************************************
169 class COcclusionQueryD3D
: public IOcclusionQuery
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
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();
182 virtual TOcclusionType
getOcclusionType();
183 virtual uint
getVisibleCount();
187 using NLMISC::CRefCount
;
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
205 ItShaderDrvInfoPtrList _DriverIterator
;
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 // --------------------------------------------------
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(); }
244 // Private. For Driver only.
246 NLMISC::CRefPtr
<IShaderDrvInfos
> _DrvInfo
;
256 // ***************************************************************************
257 class CTextureDrvInfosD3D
: public ITextureDrvInfos
261 ANY DATA ADDED HERE MUST BE SWAPPED IN swapTextureHandle() !!
265 LPDIRECT3DBASETEXTURE9 Texture
;
266 IDirect3DTexture9
*Texture2d
;
267 IDirect3DCubeTexture9
*TextureCube
;
269 // The texture format and size
270 D3DFORMAT DestFormat
;
274 // This is the owner driver.
277 // Is the internal format of the texture is a compressed one?
281 // Is a render target ?
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
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
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
354 // The human readable values
355 D3DVERTEXELEMENT9 VertexElements
[CVertexBuffer::NumValue
+1];
357 // The driver pointer
358 IDirect3DVertexDeclaration9
*VertexDecl
;
362 // ***************************************************************************
363 class CVBDrvInfosD3D
: public IVBDrvInfos
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;
376 bool Volatile
:1; // Volatile vertex buffer
379 uint VolatileLockTime
; // Volatile vertex buffer
381 CVolatileVertexBuffer
*VolatileVertexBuffer
;
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
400 IDirect3DIndexBuffer9
*IndexBuffer
;
401 uint Offset
; // Index buffer offset
402 bool Volatile
:1; // Volatile index buffer
404 uint VolatileLockTime
; // Volatile index buffer
405 CVolatileIndexBuffer
*VolatileIndexBuffer
;
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
429 D3DXHANDLE TextureHandle
[MaxShaderTexture
];
432 D3DXHANDLE ColorHandle
[MaxShaderTexture
];
435 D3DXHANDLE FactorHandle
[MaxShaderTexture
];
438 D3DXHANDLE ScalarFloatHandle
[MaxShaderTexture
];
440 CShaderDrvInfosD3D(CDriverD3D
*drv
, ItShaderDrvInfoPtrList it
);
441 virtual ~CShaderDrvInfosD3D();
445 // ***************************************************************************
447 // Normal shader description
448 class CNormalShaderDesc
453 H_AUTO_D3D(CNormalShaderDesc_CNormalShaderDesc
);
454 memset (this, 0, sizeof(CNormalShaderDesc
));
456 ~CNormalShaderDesc ()
459 PixelShader
->Release();
461 bool StageUsed
[IDRV_MAT_MAXTEXTURES
];
462 uint32 TexEnvMode
[IDRV_MAT_MAXTEXTURES
];
464 bool operator==(const CNormalShaderDesc
&other
) const
467 for (i
=0; i
<IDRV_MAT_MAXTEXTURES
; i
++)
468 if ((StageUsed
[i
] != other
.StageUsed
[i
]) || (StageUsed
[i
] && (TexEnvMode
[i
] != other
.TexEnvMode
[i
])))
473 IDirect3DPixelShader9
*PixelShader
;
478 // base class for recorded state in an effect
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
506 void apply(class CDriverD3D
&drv
);
508 std::vector
<CStateRecord
*> States
;
518 CFXInputValue() : Set(false) {}
520 bool operator==(const CFXInputValue
&other
)
522 if (!Set
) return !(other
.Set
);
523 return (Value
== other
.Value
) != 0;
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
];
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;
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;
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;
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;
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);
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;
601 // .fx cache based on input parameters
606 CFXInputParams Params
;
607 // cache for .fx states
608 std::vector
<CFXPassRecord
> Passes
;
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
);
617 void setConstants(CShaderDrvInfosD3D
*si
);
622 // optimisation of an effect 2
623 class CFXPassRecorder
: public ID3DXEffectStateManager
626 CFXPassRecord
*Target
;
627 class CDriverD3D
*Driver
;
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
658 D3DMATERIAL9 Material
;
659 D3DCOLOR UnlightedColor
;
660 BOOL SpecularEnabled
;
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
];
701 CMaterialDrvInfosD3D(IDriver
*drv
, ItMatDrvInfoPtrList it
) : IMaterialDrvInfos(drv
, it
)
703 H_AUTO_D3D(CMaterialDrvInfosD3D_CMaterialDrvInfosD3D
);
705 PixelShaderUnlightedNoVertexColor
= NULL
;
706 std::fill(RGBPipe
, RGBPipe
+ IDRV_MAT_MAXTEXTURES
, true);
707 std::fill(AlphaPipe
, AlphaPipe
+ IDRV_MAT_MAXTEXTURES
, true);
709 NumUsedTexStages
= 0;
711 ~CMaterialDrvInfosD3D()
715 void buildTexEnv (uint stage
, const CMaterial::CTexEnv
&env
, bool textured
);
722 // ***************************************************************************
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
737 CVolatileVertexBuffer();
738 ~CVolatileVertexBuffer();
741 IDirect3DVertexBuffer9
*VertexBuffer
;
743 CVertexBuffer::TLocation Location
;
748 /* size is in bytes */
749 void init (CVertexBuffer::TLocation location
, uint size
, uint maxSize
, CDriverD3D
*driver
);
752 // Runtime buffer access, no-blocking lock.
753 void *lock (uint size
, uint stride
, uint
&offset
);
756 // Runtime reset (called at the beginning of the frame rendering), blocking lock here.
760 // ***************************************************************************
762 class CVolatileIndexBuffer
765 CVolatileIndexBuffer();
766 ~CVolatileIndexBuffer();
769 IDirect3DIndexBuffer9
*IndexBuffer
;
771 CIndexBuffer::TLocation Location
;
772 // current position in bytes!
776 CIndexBuffer::TFormat Format
;
778 /* size is in bytes */
779 void init (CIndexBuffer::TLocation location
, uint sizeInBytes
, uint maxSize
, CDriverD3D
*driver
, CIndexBuffer::TFormat format
);
782 // Runtime buffer access, no-blocking lock. Re
783 void *lock (uint size
, uint
&offset
);
786 // Runtime reset (called at the beginning of the frame rendering), blocking lock here.
792 // ***************************************************************************
794 class CDriverD3D
: public IDriver
, public ID3DXEffectStateManager
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,
831 MatrixStateRemap
= 24,
833 MaxVertexProgramConstantState
=96,
834 MaxPixelShaderConstantState
=96,
837 // Prefered pixel formats
840 // Number of pixel format choice for each pixel format
841 FinalPixelFormatChoice
= 5,
844 // Construction / destruction
846 virtual ~CDriverD3D();
848 virtual bool isLost() const { return _Lost
; }
849 // ***************************************************************************
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
);
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
);
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;
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;};
928 virtual bool setupMaterial(CMaterial
& mat
);
930 virtual bool supportCloudRenderSinglePass () const;
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
);
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
);
991 virtual bool activeVertexBuffer(CVertexBuffer
& VB
);
994 virtual bool activeIndexBuffer(CIndexBuffer
& IB
);
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();
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);
1033 virtual TMessageBoxId
systemMessageBox (const char* message
, const char* title
, TMessageBoxType type
=okType
, TMessageBoxIcon icon
=noIcon
);
1034 virtual uint64
getSwapBufferCounter() const { return _SwapBufferCounter
; }
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
);
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
);
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]) {}
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 */ }
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
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
);
1144 /// \name Pixel Program
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
);
1171 /// \name Geometry Program
1174 // Order of preference
1175 // - activeGeometryProgram
1176 // - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code)
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; }
1198 /// \name Program 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
¶ms
); // set all user-provided params from the storage
1227 virtual bool isUniformProgramState() { return false; }
1234 virtual void enableVertexProgramDoubleSidedColor(bool doubleSided
);
1235 virtual bool supportVertexProgramDoubleSidedColor() const;
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
);
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
; }
1272 uint
inlGetNumTextStages() const { return _NbNeLTextureStages
; }
1277 // Hardware render variables, like matrices, render states
1278 struct CRenderVariable
1282 NextModified
= NULL
;
1286 // Type of render state
1293 VertexProgramPtrState
,
1294 PixelShaderPtrState
,
1295 VertexProgramConstantState
,
1296 PixelShaderConstantState
,
1305 CRenderVariable
*NextModified
;
1307 virtual void apply(CDriverD3D
*driver
) = 0;
1311 struct CRenderState
: public CRenderVariable
1319 D3DRENDERSTATETYPE StateID
;
1322 virtual void apply(CDriverD3D
*driver
);
1325 // Render texture state
1326 struct CTextureState
: public CRenderVariable
1330 Type
= TextureState
;
1331 DeviceValue
= 0xcccccccc;
1334 D3DTEXTURESTAGESTATETYPE StateID
;
1337 virtual void apply(CDriverD3D
*driver
);
1341 // Render texture index state
1342 struct CTextureIndexState
: public CRenderVariable
1344 CTextureIndexState()
1346 Type
= TextureIndexState
;
1352 virtual void apply(CDriverD3D
*driver
);
1356 struct CTexturePtrState
: public CRenderVariable
1360 Type
= TexturePtrState
;
1364 LPDIRECT3DBASETEXTURE9 Texture
;
1365 virtual void apply(CDriverD3D
*driver
);
1369 struct CVertexProgramPtrState
: public CRenderVariable
1371 CVertexProgramPtrState()
1373 Type
= VertexProgramPtrState
;
1374 VertexProgram
= NULL
;
1376 LPDIRECT3DVERTEXSHADER9 VertexProgram
;
1378 const CVertexProgram
*VP
;
1379 virtual void apply(CDriverD3D
*driver
);
1383 struct CPixelShaderPtrState
: public CRenderVariable
1385 CPixelShaderPtrState()
1387 Type
= PixelShaderPtrState
;
1390 LPDIRECT3DPIXELSHADER9 PixelShader
;
1391 virtual void apply(CDriverD3D
*driver
);
1394 // Vertex buffer constants state
1395 struct CVertexProgramConstantState
: public CRenderVariable
1397 CVertexProgramConstantState()
1399 Type
= VertexProgramConstantState
;
1409 virtual void apply(CDriverD3D
*driver
);
1412 // Pixel shader constants state
1413 struct CPixelShaderConstantState
: public CRenderVariable
1415 CPixelShaderConstantState()
1417 Type
= PixelShaderConstantState
;
1427 virtual void apply(CDriverD3D
*driver
);
1430 // Render sampler state
1431 struct CSamplerState
: public CRenderVariable
1435 Type
= SamplerState
;
1438 D3DSAMPLERSTATETYPE StateID
;
1440 virtual void apply(CDriverD3D
*driver
);
1444 struct CMatrixState
: public CRenderVariable
1450 D3DTRANSFORMSTATETYPE TransformType
;
1452 virtual void apply(CDriverD3D
*driver
);
1455 // Render vertex buffer
1456 struct CVBState
: public CRenderVariable
1461 VertexBuffer
= NULL
;
1464 IDirect3DVertexBuffer9
*VertexBuffer
;
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
1481 IDirect3DIndexBuffer9
*IndexBuffer
;
1482 virtual void apply(CDriverD3D
*driver
);
1485 // Render vertex decl
1486 struct CVertexDeclState
: public CRenderVariable
1492 DeclAliasDiffuseToSpecular
= NULL
;
1493 DeclNoDiffuse
= NULL
;
1495 AliasDiffuseToSpecular
= false;
1496 EnableVertexColor
= false;
1498 IDirect3DVertexDeclaration9
*Decl
;
1499 IDirect3DVertexDeclaration9
*DeclAliasDiffuseToSpecular
;
1500 IDirect3DVertexDeclaration9
*DeclNoDiffuse
;
1502 bool AliasDiffuseToSpecular
;
1503 bool EnableVertexColor
;
1504 virtual void apply(CDriverD3D
*driver
);
1507 // Render vertex buffer
1508 struct CLightState
: public CRenderVariable
1514 SettingsTouched
= false;
1515 EnabledTouched
= true;
1516 Light
.Type
= D3DLIGHT_POINT
;
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;
1532 bool SettingsTouched
;
1533 bool EnabledTouched
;
1536 virtual void apply(CDriverD3D
*driver
);
1540 struct CRenderTargetState
: public CRenderVariable
1542 CRenderTargetState()
1544 Type
= RenderTargetState
;
1549 TargetOwned
= false;
1551 IDirect3DSurface9
*Target
;
1556 virtual void apply(CDriverD3D
*driver
);
1560 struct CMaterialState
: public CRenderVariable
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
);
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();
1617 // Touch a render variable
1618 inline void touchRenderVariable (CRenderVariable
*renderVariable
)
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
);
1637 nlassert (_DeviceInterface
);
1638 nlassert (renderState
<MaxRenderState
);
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
);
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
);
1664 nlassert (_DeviceInterface
);
1665 nlassert (stage
<MaxTexture
);
1666 nlassert (textureState
<MaxTextureState
);
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
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
);
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
)
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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.
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
);
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
);
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
);
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
);
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
);
2027 inline uint
remapMatrixIndex (D3DTRANSFORMSTATETYPE type
)
2029 H_AUTO_D3D(CDriverD3D_remapMatrixIndex
);
2031 return (D3DTRANSFORMSTATETYPE
)(MatrixStateRemap
+ type
- 256);
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
);
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
;
2093 touchRenderVariable (&_RenderTarget
);
2095 _ScissorTouched
= true;
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
)
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
);
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
;
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
¶meters
, 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
,
2177 bool aliasDiffuseToSpecular
,
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
);
2197 CShaderDrvInfosD3D
*drvInfo
= static_cast<CShaderDrvInfosD3D
*>((IShaderDrvInfos
*)_CurrentShader
->_DrvInfo
);
2198 if (_CurrentMaterialInfo
->FXCache
)
2200 nlassert(_CurrentMaterialInfo
);
2201 _CurrentMaterialInfo
->FXCache
->applyPass(*this, drvInfo
, pass
);
2205 #if (DIRECT3D_VERSION >= 0x0900) && (D3D_SDK_VERSION >= 32)
2206 drvInfo
->Effect
->BeginPass (pass
);
2207 drvInfo
->Effect
->EndPass ();
2209 drvInfo
->Effect
->Pass (pass
);
2214 // Update render states
2215 updateRenderVariablesInternal();
2218 void beginMultiPass ()
2220 H_AUTO_D3D(CDriverD3D_beginMultiPass
);
2223 // Does the shader validated ?
2224 validateShader(_CurrentShader
);
2226 // Init default state value
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);
2245 drvInfo
->Effect
->Begin (&_CurrentShaderPassCount
, D3DXFX_DONOTSAVESTATE
|D3DXFX_DONOTSAVESHADERSTATE
);
2249 // No shader setuped
2250 _CurrentShaderPassCount
= 1;
2253 void endMultiPass ()
2255 H_AUTO_D3D(CDriverD3D_endMultiPass
);
2258 CShaderDrvInfosD3D
*drvInfo
= static_cast<CShaderDrvInfosD3D
*>((IShaderDrvInfos
*)_CurrentShader
->_DrvInfo
);
2259 if (_CurrentMaterialInfo
->FXCache
)
2261 _CurrentMaterialInfo
->FXCache
->end(drvInfo
);
2265 drvInfo
->Effect
->End ();
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
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
);
2325 void findNearestFullscreenVideoMode();
2327 TShaderDrvInfoPtrList _ShaderDrvInfos
;
2330 std::wstring _WindowClass
;
2334 bool _DestroyWindow
;
2337 bool _HandlePossibleSizeChangeNextSize
;
2338 GfxMode _CurrentMode
;
2343 enum TColorDepth
{ ColorDepth16
= 0, ColorDepth32
, ColorDepthCount
};
2345 TColorDepth _ColorDepth
;
2346 std::string _CurrName
;
2347 NLMISC::CRGBA _CurrCol
;
2353 nlCursor _DefaultCursor
;
2355 bool _AlphaBlendedCursorSupported
;
2356 bool _AlphaBlendedCursorSupportRetrieved
;
2361 NLMISC::CBitmap Src
;
2362 TColorDepth ColorDepth
;
2365 uint HotspotOffsetX
;
2366 uint HotspotOffsetY
;
2372 #if defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
2378 CCursor
& operator= (const CCursor
& from
);
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
;
2397 D3DDEVTYPE _Rasterizer
;
2400 IDirect3DDevice9
*_DeviceInterface
;
2404 NLMISC::CEventEmitterMulti _EventEmitter
; // this can contains a win emitter and eventually a direct input emitter
2406 // Some matrices (Local -> Model -> World -> Screen)
2408 CVector _PZBCameraPos
;
2410 CMatrix _UserModelMtx
;
2411 CMatrix _UserViewMtx
;
2413 CViewport _Viewport
;
2415 D3DVIEWPORT9 _D3DViewport
;
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
;
2429 float _FrustumRight
;
2431 float _FrustumBottom
;
2432 float _FrustumZNear
;
2437 // Vertex memory available
2438 uint32 _AGPMemoryAllocated
;
2439 uint32 _VRAMMemoryAllocated
;
2442 D3DFORMAT _PreferedTextureFormat
[ITexture::UploadFormatCount
];
2443 uint _ForceTextureResizePower
;
2444 bool _ForceDXTCCompression
:1;
2445 bool _TextureCubeSupported
;
2446 bool _VertexProgram
;
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
;
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
;
2467 uint32 _PixelShaderVersion
;
2468 uint32 _MaxPrimitiveCount
;
2469 uint32 _MaxVertexIndex
;
2470 uint _MaxNumPerStageConstantLighted
;
2471 uint _MaxNumPerStageConstantUnlighted
;
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.
2496 // Index buffer lock profiling
2499 NLMISC::CRefPtr
<CIndexBuffer
> IB
;
2500 NLMISC::TTicks AccumTime
;
2501 // true if the VBHard was not always the same for the same chronogical place.
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.
2519 std::vector
<CIBProfile
> _IBProfiles
;
2520 uint _CurIBLockCount
;
2521 uint _NumIBProfileFrame
;
2523 NLMISC::TTicks _VolatileIBLockTime
;
2524 NLMISC::TTicks _VolatileVBLockTime
;
2526 void appendIBLockProfile(NLMISC::TTicks time
, CIndexBuffer
*ib
);
2529 std::set
<CVBDrvInfosD3D
*> _VertexBufferHardSet
;
2531 // The render variables
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
;
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
;
2557 bool _UseVertexColor
;
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
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];
2595 CIndexBuffer _QuadIndexes
;
2596 CIndexBuffer _QuadIndexesAGP
;
2598 // The last setuped shader
2599 CD3DShaderFX
*_CurrentShader
;
2600 UINT _CurrentShaderPassCount
;
2604 CRefPtr
<ITexture
> NeLTexture
;
2605 LPDIRECT3DBASETEXTURE9 D3DTexture
;
2607 const std::vector
<CTextureRef
> &getCurrentShaderTextures() const { return _CurrentShaderTextures
; }
2609 std::vector
<CTextureRef
> _CurrentShaderTextures
;
2611 // The last material setuped
2612 CMaterial
*_CurrentMaterial
;
2614 CMaterialDrvInfosD3D
*_CurrentMaterialInfo
;
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
;
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
;
2661 bool _OcclusionQuerySupported
;
2662 TOcclusionQueryList _OcclusionQueryList
;
2665 float _DepthRangeNear
;
2666 float _DepthRangeFar
;
2668 bool _ScissorTouched
;
2669 uint8 _CurrentUVRouting
[MaxTexture
];
2670 bool _MustRestoreLight
;
2671 D3DXMATRIX _D3DMatrixIdentity
;
2673 uint _AnisotropicFilter
;
2676 bool _CurStencilTest
;
2677 DWORD _CurStencilFunc
;
2678 DWORD _CurStencilRef
;
2679 DWORD _CurStencilMask
;
2680 DWORD _CurStencilOpFail
;
2681 DWORD _CurStencilOpZFail
;
2682 DWORD _CurStencilOpZPass
;
2683 DWORD _CurStencilWriteMask
;
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)
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
;
2710 WORD _DesktopGammaRamp
[256 * 3];
2711 bool _DesktopGammaRampValid
;
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
);
2756 std::set
<CVBDrvInfosD3D
*> _LockedBuffers
;
2763 nlassert(!_SceneBegun
);
2764 if (_DeviceInterface
->BeginScene() != D3D_OK
) return false;
2771 nlassert(_SceneBegun
);
2772 if (_DeviceInterface
->EndScene() != D3D_OK
) return false;
2773 _SceneBegun
= false;
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]; \
2817 d3d_mt._21 = nl_mt_ptr[4]; \
2818 d3d_mt._22 = nl_mt_ptr[5]; \
2819 d3d_mt._23 = nl_mt_ptr[7]; \
2821 d3d_mt._31 = nl_mt_ptr[12]; \
2822 d3d_mt._32 = nl_mt_ptr[13]; \
2823 d3d_mt._33 = nl_mt_ptr[15]; \
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);
2858 // ***************************************************************************
2859 // set a D3DCOLORVALUE
2860 inline void setColor(D3DCOLORVALUE
&dest
, float r
, float g
, float b
, float 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
);
2894 extern HINSTANCE HInstDLL
;
2897 #endif // NL_DRIVER_DIRECT3D_H