1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/3d/ps_quad.h"
20 #include "nel/3d/ps_macro.h"
21 #include "nel/3d/driver.h"
22 #include "nel/3d/ps_attrib_maker.h"
23 #include "nel/3d/texture_grouped.h"
24 #include "nel/3d/particle_system.h"
25 #include "nel/3d/ps_iterator.h"
36 ///////////////////////////
37 // constant definition //
38 ///////////////////////////
41 static const uint dotBufSize
= 1024; // size used for point particles batching
47 /// the various kind of vertex buffers we need for quads
48 CVertexBuffer
CPSQuad::_VBPos
;
49 CVertexBuffer
CPSQuad::_VBPosCol
;
50 CVertexBuffer
CPSQuad::_VBPosTex1
;
51 CVertexBuffer
CPSQuad::_VBPosTex1Col
;
52 CVertexBuffer
CPSQuad::_VBPosTex1Anim
;
53 CVertexBuffer
CPSQuad::_VBPosTex1AnimCol
;
55 CVertexBuffer
CPSQuad::_VBPosTex1Tex2
;
56 CVertexBuffer
CPSQuad::_VBPosTex1ColTex2
;
57 CVertexBuffer
CPSQuad::_VBPosTex1AnimTex2
;
58 CVertexBuffer
CPSQuad::_VBPosTex1AnimColTex2
;
60 CVertexBuffer
CPSQuad::_VBPosTex1Tex2Anim
;
61 CVertexBuffer
CPSQuad::_VBPosTex1ColTex2Anim
;
62 CVertexBuffer
CPSQuad::_VBPosTex1AnimTex2Anim
;
63 CVertexBuffer
CPSQuad::_VBPosTex1AnimColTex2Anim
;
66 CVertexBuffer RAMVBPos
;
67 CVertexBuffer RAMVBPosCol
;
68 CVertexBuffer RAMVBPosTex1
;
69 CVertexBuffer RAMVBPosTex1Col
;
70 CVertexBuffer RAMVBPosTex1Anim
;
71 CVertexBuffer RAMVBPosTex1AnimCol
;
73 CVertexBuffer RAMVBPosTex1Tex2
;
74 CVertexBuffer RAMVBPosTex1ColTex2
;
75 CVertexBuffer RAMVBPosTex1AnimTex2
;
76 CVertexBuffer RAMVBPosTex1AnimColTex2
;
78 CVertexBuffer RAMVBPosTex1Tex2Anim
;
79 CVertexBuffer RAMVBPosTex1ColTex2Anim
;
80 CVertexBuffer RAMVBPosTex1AnimTex2Anim
;
81 CVertexBuffer RAMVBPosTex1AnimColTex2Anim
;
86 CVertexBuffer
* const CPSQuad::_VbTab
[] =
89 &_VBPos
, &_VBPosCol
, &_VBPosTex1
, &_VBPosTex1Col
,
90 NULL
, NULL
, &_VBPosTex1Anim
, &_VBPosTex1AnimCol
,
92 NULL
, NULL
, &_VBPosTex1Tex2
, &_VBPosTex1ColTex2
,
93 NULL
, NULL
, &_VBPosTex1AnimTex2
, &_VBPosTex1AnimColTex2
,
94 // tex2 & !tex1 (invalid)
95 NULL
, NULL
, NULL
, NULL
,
96 NULL
, NULL
, NULL
, NULL
,
97 // tex2 & !tex1 (invalid)
99 NULL
, NULL
, &_VBPosTex1Tex2Anim
, &_VBPosTex1ColTex2Anim
,
100 NULL
, NULL
, &_VBPosTex1AnimTex2Anim
, &_VBPosTex1AnimColTex2Anim
,
103 CVertexBuffer
* const RAMVbTab
[] =
106 &RAMVBPos
, &RAMVBPosCol
, &RAMVBPosTex1
, &RAMVBPosTex1Col
,
107 NULL
, NULL
, &RAMVBPosTex1Anim
, &RAMVBPosTex1AnimCol
,
109 NULL
, NULL
, &RAMVBPosTex1Tex2
, &RAMVBPosTex1ColTex2
,
110 NULL
, NULL
, &RAMVBPosTex1AnimTex2
, &RAMVBPosTex1AnimColTex2
,
111 // tex2 & !tex1 (invalid)
112 NULL
, NULL
, NULL
, NULL
,
113 NULL
, NULL
, NULL
, NULL
,
114 // tex2 & !tex1 (invalid)
116 NULL
, NULL
, &RAMVBPosTex1Tex2Anim
, &RAMVBPosTex1ColTex2Anim
,
117 NULL
, NULL
, &RAMVBPosTex1AnimTex2Anim
, &RAMVBPosTex1AnimColTex2Anim
,
123 //////////////////////////////////
124 // CPSQuad implementation //
125 //////////////////////////////////
128 ///==================================================================================
129 /// fill textures coordinates for a quad vb
130 static void SetupQuadVBTexCoords(CVertexBuffer
&vb
, uint texCoordSet
)
132 NL_PS_FUNC(SetupQuadVBTexCoords
)
133 nlassert(texCoordSet
< 2);
134 CVertexBufferReadWrite vba
;
136 // the size used for buffer can't be higher than quad buf size
137 // to have too large buffer will broke the cache
138 for (uint32 k
= 0; k
< CPSQuad::quadBufSize
; ++k
)
141 vba
.setTexCoord(k
* 4, texCoordSet
, CUV(0, 0));
142 vba
.setTexCoord(k
* 4 + 1, texCoordSet
, CUV(1, 0));
143 vba
.setTexCoord(k
* 4 + 2, texCoordSet
, CUV(1, 1));
144 vba
.setTexCoord(k
* 4 + 3, texCoordSet
, CUV(0, 1));
148 ///==================================================================================
149 /// this static method init vertex buffers
150 void CPSQuad::initVertexBuffers()
152 NL_PS_FUNC(CPSQuad_initVertexBuffers
)
153 for (uint k
= 0; k
< 32; ++k
)
155 CVertexBuffer
*vb
= _VbTab
[k
];
156 if (vb
) // valid vb ?
158 vb
->setName("CPSQuad");
159 vb
->setPreferredMemory(CVertexBuffer::AGPVolatile
, true);
160 uint32 vf
= CVertexBuffer::PositionFlag
;
161 /// setup vertex format
162 if (k
& (uint
) VBCol
) vf
|= CVertexBuffer::PrimaryColorFlag
;
163 if (k
& (uint
) VBTex
|| k
& (uint
) VBTexAnimated
) vf
|= CVertexBuffer::TexCoord0Flag
;
164 if (k
& (uint
) VBTex2
|| k
& (uint
) VBTex2Animated
) vf
|= CVertexBuffer::TexCoord1Flag
;
165 vb
->setVertexFormat(vf
);
166 vb
->setNumVertices(quadBufSize
<< 2);
168 if ((k
& (uint
) VBTex
) && !(k
& (uint
) VBTexAnimated
))
170 SetupQuadVBTexCoords(*vb
, 0);
173 if ((k
& (uint
) VBTex2
) && !(k
& (uint
) VBTex2Animated
))
175 SetupQuadVBTexCoords(*vb
, 1);
181 for (uint k = 0; k < 32; ++k)
183 CVertexBuffer *vb = RAMVbTab[k];
184 if (vb) // valid vb ?
186 vb->setName("CPSQuadRAM");
187 vb->setPreferredMemory(CVertexBuffer::RAMPreferred, false);
188 uint32 vf = CVertexBuffer::PositionFlag;
189 /// setup vertex format
190 if (k & (uint) VBCol) vf |= CVertexBuffer::PrimaryColorFlag;
191 if (k & (uint) VBTex || k & (uint) VBTexAnimated) vf |= CVertexBuffer::TexCoord0Flag;
192 if (k & (uint) VBTex2 || k & (uint) VBTex2Animated) vf |= CVertexBuffer::TexCoord1Flag;
193 vb->setVertexFormat(vf);
194 vb->setNumVertices(quadBufSize << 2);
196 if ((k & (uint) VBTex) && !(k & (uint) VBTexAnimated))
198 SetupQuadVBTexCoords(*vb, 0);
201 if ((k & (uint) VBTex2) && !(k & (uint) VBTex2Animated))
203 SetupQuadVBTexCoords(*vb, 1);
212 //volatile bool TestWantAGPCPSQuad = true;
214 ///==================================================================================
215 /// choose the vertex buffex that we need
216 CVertexBuffer
&CPSQuad::getNeededVB(IDriver
&drv
)
218 NL_PS_FUNC(CPSQuad_getNeededVB
)
220 if (_ColorScheme
) flags
|= (uint
) VBCol
;
223 flags
|= VBTex
| VBTexAnimated
;
232 /// check if multitexturing is enabled, and which texture are enabled and / or animated
233 if (CPSMultiTexturedParticle::isMultiTextureEnabled())
235 if (isAlternateTextureUsed(drv
) && _AlternateTexture2
)
237 if ((flags
& VBTex
) && (_TexScrollAlternate
[0].x
!= 0 || _TexScrollAlternate
[0].y
!= 0)) flags
|= VBTexAnimated
;
238 if (_AlternateOp
!= Decal
&& (_TexScrollAlternate
[1].x
!= 0 || _TexScrollAlternate
[1].y
!= 0))
240 flags
|= VBTex2
| VBTex2Animated
;
249 if ((flags
& VBTex
) && (_TexScroll
[0].x
!= 0 || _TexScroll
[0].y
!= 0)) flags
|= VBTexAnimated
;
252 if (_MainOp
!= Decal
&& (_TexScroll
[1].x
!= 0 || _TexScroll
[1].y
!= 0))
254 flags
|= VBTex2
| VBTex2Animated
;
264 /*if (TestWantAGPCPSQuad)
266 nlassert((flags
& ~VBFullMask
) == 0); // check for overflow
267 nlassert(_VbTab
[flags
] != NULL
);
268 return *(_VbTab
[flags
]); // get the vb
272 nlassert((flags & ~VBFullMask) == 0); // check for overflow
273 nlassert(RAMVbTab[flags] != NULL);
274 return *(RAMVbTab[flags]); // get the vb
278 ///==================================================================================
279 CPSQuad::CPSQuad(CSmartPtr
<ITexture
> tex
)
281 NL_PS_FUNC(CPSQuad_CPSQuad
)
284 // we don't init the _IndexBuffer for now, as it will be when resize is called
285 if (CParticleSystem::getSerializeIdentifierFlag()) _Name
= std::string("quad");
289 ///==================================================================================
292 NL_PS_FUNC(CPSQuad_CPSQuadDtor
)
295 ///==================================================================================
296 uint32
CPSQuad::getNumWantedTris() const
298 NL_PS_FUNC(CPSQuad_getNumWantedTris
)
300 //return _Owner->getMaxSize() << 1;
301 return _Owner
->getSize() << 1;
304 ///==================================================================================
305 bool CPSQuad::hasTransparentFaces(void)
307 NL_PS_FUNC(CPSQuad_hasTransparentFaces
)
308 return getBlendingMode() != CPSMaterial::alphaTest
;
311 ///==================================================================================
312 bool CPSQuad::hasOpaqueFaces(void)
314 NL_PS_FUNC(CPSQuad_hasOpaqueFaces
)
315 return !hasTransparentFaces();
318 ///==================================================================================
319 void CPSQuad::init(void)
321 NL_PS_FUNC(CPSQuad_init
)
322 _Mat
.setLighting(false);
323 _Mat
.setDoubleSided(true);
326 updateMatAndVbForColor();
327 updateMatAndVbForTexture();
330 ///==================================================================================
331 void CPSQuad::updateMatAndVbForTexture(void)
333 NL_PS_FUNC(CPSQuad_updateMatAndVbForTexture
)
334 if (CPSMultiTexturedParticle::isMultiTextureEnabled())
340 _Mat
.setTexture(0, _TexGroup
? (ITexture
*) _TexGroup
: (ITexture
*) _Tex
);
344 ///==================================================================================
345 bool CPSQuad::completeBBox(NLMISC::CAABBox
&box
) const
347 NL_PS_FUNC(CPSQuad_completeBBox
)
350 CPSUtil::addRadiusToAABBox(box
, _ParticleSize
);
354 CPSUtil::addRadiusToAABBox(box
, std::max(fabsf(_SizeScheme
->getMaxValue()), fabsf(_SizeScheme
->getMinValue())));
359 ///==================================================================================
360 void CPSQuad::resize(uint32 size
)
362 NL_PS_FUNC(CPSQuad_resize
)
363 nlassert(size
< (1 << 16));
366 resizeTextureIndex(size
);
369 //==============================================================
370 void CPSQuad::updateMatAndVbForColor(void)
372 NL_PS_FUNC(CPSQuad_updateMatAndVbForColor
)
373 // no vb to setup, now..
374 /* if (!_ColorScheme)
376 _Mat.setColor(_Color);
380 _Mat.setColor(CRGBA::White);
384 //==============================================================
385 void CPSQuad::serial(NLMISC::IStream
&f
)
387 NL_PS_FUNC(CPSQuad_serial
)
388 sint ver
= f
.serialVersion(2);
389 CPSParticle::serial(f
);
390 CPSSizedParticle::serialSizeScheme(f
);
391 CPSColoredParticle::serialColorScheme(f
);
392 CPSTexturedParticle::serialTextureScheme(f
);
396 CPSMultiTexturedParticle::serialMultiTex(f
);
400 //==============================================================
401 // static func used to fill texture coordinates of quads, with global time
402 static void FillQuadCoords(uint8
*dest
, uint stride
, const NLMISC::CVector2f
&speed
, float time
, uint num
)
404 NL_PS_FUNC(FillQuadCoords
)
406 const float topV
= speed
.y
* time
;
407 const float bottomV
= topV
+ 1.f
;
408 const float leftU
= speed
.x
* time
;
409 const float rightU
= leftU
+ 1.f
;
414 ((NLMISC::CUV
*) dest
)->set(leftU
, topV
);
415 ((NLMISC::CUV
*) (dest
+ stride
))->set(rightU
, topV
);
416 ((NLMISC::CUV
*) (dest
+ (stride
<< 1)))->set(rightU
, bottomV
);
417 ((NLMISC::CUV
*) (dest
+ (stride
* 3)))->set(leftU
, bottomV
);
425 //==============================================================
426 // static func used to fill texture coordinates of quads, with local time
427 static void FillQuadCoordsLocalTime(uint8
*dest
, uint stride
, const NLMISC::CVector2f
&speed
, CPSLocated
&srcLoc
, uint startIndex
, uint num
, uint32 srcStep
)
429 NL_PS_FUNC(FillQuadCoordsLocalTime
)
432 if (srcStep
== (1 << 16)) // step = 1.0 ?
434 TPSAttribTime::iterator timePt
= srcLoc
.getTime().begin() + startIndex
;
437 const float topV
= speed
.y
* *timePt
;
438 const float bottomV
= topV
+ 1.f
;
439 const float leftU
= speed
.x
* *timePt
;
440 const float rightU
= leftU
+ 1.f
;
442 ((NLMISC::CUV
*) dest
)->set(leftU
, topV
);
443 ((NLMISC::CUV
*) (dest
+ stride
))->set(rightU
, topV
);
444 ((NLMISC::CUV
*) (dest
+ (stride
<< 1)))->set(rightU
, bottomV
);
445 ((NLMISC::CUV
*) (dest
+ (stride
* 3)))->set(leftU
, bottomV
);
454 TIteratorTimeStep1616
timePt(srcLoc
.getTime().begin(), startIndex
, srcStep
);
457 const float topV
= speed
.y
* *timePt
;
458 const float bottomV
= topV
+ 1.f
;
459 const float leftU
= speed
.x
* *timePt
;
460 const float rightU
= leftU
+ 1.f
;
462 ((NLMISC::CUV
*) dest
)->set(leftU
, topV
);
463 ((NLMISC::CUV
*) (dest
+ stride
))->set(rightU
, topV
);
464 ((NLMISC::CUV
*) (dest
+ (stride
<< 1)))->set(rightU
, bottomV
);
465 ((NLMISC::CUV
*) (dest
+ (stride
* 3)))->set(leftU
, bottomV
);
474 //==============================================================
475 void CPSQuad::updateVbColNUVForRender(CVertexBuffer
&vb
, uint32 startIndex
, uint32 size
, uint32 srcStep
, IDriver
&drv
)
477 NL_PS_FUNC(CPSQuad_updateVbColNUVForRender
)
482 CVertexBufferReadWrite vba
;
487 // compute the colors, each color is replicated 4 times
488 // todo hulud d3d vertex color RGBA / BGRA
489 _ColorScheme
->make4(_Owner
, startIndex
, vba
.getColorPointer(), vb
.getVertexSize(), size
, srcStep
);
493 if (_TexGroup
) // if it has a constant texture we are sure it has been setupped before...
495 sint32 textureIndex
[quadBufSize
];
496 const uint32 stride
= vb
.getVertexSize(), stride2
= stride
<< 1, stride3
= stride2
+ stride
, stride4
= stride2
<< 1;
497 uint8
*currUV
= (uint8
*) vba
.getTexCoordPointer();
500 const sint32
*currIndex
;
501 uint32 currIndexIncr
;
503 if (_TextureIndexScheme
)
505 currIndex
= (sint32
*) _TextureIndexScheme
->make(_Owner
, startIndex
, textureIndex
, sizeof(sint32
), size
, true, srcStep
);
510 currIndex
= &_TextureIndex
;
517 // for now, we don't make texture index wrapping
518 const CTextureGrouped::TFourUV
&uvGroup
= _TexGroup
->getUVQuad((uint32
) *currIndex
);
520 // copy the 4 uv's for this face
521 *(CUV
*) currUV
= uvGroup
.uv0
;
522 *(CUV
*) (currUV
+ stride
) = uvGroup
.uv1
;
523 *(CUV
*) (currUV
+ stride2
) = uvGroup
.uv2
;
524 *(CUV
*) (currUV
+ stride3
) = uvGroup
.uv3
;
526 // point the next face
528 currIndex
+= currIndexIncr
;
532 nlassert(_Owner
&& _Owner
->getOwner());
533 const float date
= (float) _Owner
->getOwner()->getSystemDate();
536 /// todo: vertex program optimisation (& choose the vb accordingly)
538 if (CPSMultiTexturedParticle::isMultiTextureEnabled() && (_Tex
|| _TexGroup
))
541 // perform tex1 animation if needed
542 if (!_TexGroup
) // doesn't work with texGroup enabled
544 if (!isAlternateTextureUsed(drv
) || !isAlternateTexEnabled() || !_AlternateTexture2
)
546 if (_Tex
&& (_TexScroll
[0].x
!= 0 || _TexScroll
[0].y
!= 0))
548 // animation of texture 1 with main speed
549 if (!getUseLocalDate())
551 FillQuadCoords((uint8
*) vba
.getTexCoordPointer(0, 0), vb
.getVertexSize(), _TexScroll
[0], date
, size
);
555 FillQuadCoordsLocalTime((uint8
*) vba
.getTexCoordPointer(0, 0), vb
.getVertexSize(), _TexScroll
[0], *_Owner
, startIndex
, size
, srcStep
);
561 if (_Tex
&& (_TexScrollAlternate
[0].x
!= 0 || _TexScrollAlternate
[0].y
!= 0))
563 // animation of texture 1 with alternate speed
564 if (!getUseLocalDateAlt())
566 FillQuadCoords((uint8
*) vba
.getTexCoordPointer(0, 0), vb
.getVertexSize(), _TexScrollAlternate
[0], date
, size
);
570 FillQuadCoordsLocalTime((uint8
*) vba
.getTexCoordPointer(0, 0), vb
.getVertexSize(), _TexScrollAlternate
[0], *_Owner
, startIndex
, size
, srcStep
);
576 // perform tex2 animation if needed
577 if (!isAlternateTextureUsed(drv
))
579 if (_Texture2
&& (_TexScroll
[1].x
!= 0 || _TexScroll
[1].y
!= 0))
581 // animation of texture 2 with main speed
582 if (!getUseLocalDate())
584 FillQuadCoords((uint8
*) vba
.getTexCoordPointer(0, 1), vb
.getVertexSize(), _TexScroll
[1], date
, size
);
588 FillQuadCoordsLocalTime((uint8
*) vba
.getTexCoordPointer(0, 1), vb
.getVertexSize(), _TexScroll
[1], *_Owner
, startIndex
, size
, srcStep
);
594 if (_AlternateTexture2
&& isAlternateTexEnabled() && (_TexScrollAlternate
[1].x
!= 0 || _TexScrollAlternate
[1].y
!= 0))
596 // animation of texture 2 with alternate speed
597 if (!getUseLocalDateAlt())
599 FillQuadCoords((uint8
*) vba
.getTexCoordPointer(0, 1), vb
.getVertexSize(), _TexScrollAlternate
[1], date
, size
);
603 FillQuadCoordsLocalTime((uint8
*) vba
.getTexCoordPointer(0, 1), vb
.getVertexSize(), _TexScrollAlternate
[1], *_Owner
, startIndex
, size
, srcStep
);
612 ///==================================================================================
613 void CPSQuad::updateMatBeforeRendering(IDriver
*drv
, CVertexBuffer
&vb
)
615 NL_PS_FUNC(CPSQuad_updateMatBeforeRendering
)
616 nlassert(_Owner
&& _Owner
->getOwner());
617 CParticleSystem
&ps
= *(_Owner
->getOwner());
618 vb
.setUVRouting(0, 0);
619 vb
.setUVRouting(1, 1); // default uv routing
620 if (isMultiTextureEnabled())
622 setupMaterial(_Tex
, drv
, _Mat
, vb
);
623 if (ps
.getForceGlobalColorLightingFlag() || usesGlobalColorLighting())
625 _Mat
.setColor(ps
.getGlobalColorLighted());
629 _Mat
.setColor(ps
.getGlobalColor());
634 /// update the material if the global color of the system is variable
635 if (_ColorScheme
!= NULL
&&
636 (ps
.getColorAttenuationScheme() != NULL
||
637 ps
.isUserColorUsed() ||
638 ps
.getForceGlobalColorLightingFlag() ||
639 usesGlobalColorLighting()
643 if (ps
.getForceGlobalColorLightingFlag() || usesGlobalColorLighting())
645 CPSMaterial::forceModulateConstantColor(true, ps
.getGlobalColorLighted());
649 CPSMaterial::forceModulateConstantColor(true, ps
.getGlobalColor());
654 forceModulateConstantColor(false);
656 if (ps
.getForceGlobalColorLightingFlag() || usesGlobalColorLighting())
658 col
.modulateFromColor(ps
.getGlobalColorLighted(), _Color
);
660 else if (ps
.getColorAttenuationScheme() != NULL
|| ps
.isUserColorUsed())
662 col
.modulateFromColor(ps
.getGlobalColor(), _Color
);
673 // *****************************************************************************************************
674 void CPSQuad::enumTexs(std::vector
<NLMISC::CSmartPtr
<ITexture
> > &dest
, IDriver
&drv
)
676 NL_PS_FUNC(CPSQuad_enumTexs
)
677 CPSTexturedParticle::enumTexs(dest
);
678 CPSMultiTexturedParticle::enumTexs(dest
, drv
);
681 // *****************************************************************************************************
682 void CPSQuad::setZBias(float value
)
684 NL_PS_FUNC(CPSQuad_setZBias
)
685 CPSMaterial::setZBias(value
);
689 // *****************************************************************************************************
690 void CPSQuad::setTexture(CSmartPtr
<ITexture
> tex
)
692 NL_PS_FUNC(CPSQuad_setTexture
)
693 CPSTexturedParticle::setTexture(tex
);
694 CPSMultiTexturedParticle::touch();
697 // *****************************************************************************************************
698 void CPSQuad::setTextureGroup(NLMISC::CSmartPtr
<CTextureGrouped
> texGroup
)
700 NL_PS_FUNC(CPSQuad_setTextureGroup
)
701 CPSTexturedParticle::setTextureGroup(texGroup
);
702 CPSMultiTexturedParticle::touch();
705 // *****************************************************************************************************
706 void CPSQuad::setTexture2(ITexture
*tex
)
708 NL_PS_FUNC(CPSQuad_setTexture2
)
709 CPSMultiTexturedParticle::setTexture2(tex
);
712 // *****************************************************************************************************
713 void CPSQuad::setTexture2Alternate(ITexture
*tex
)
715 NL_PS_FUNC(CPSQuad_setTexture2Alternate
)
716 CPSMultiTexturedParticle::setTexture2Alternate(tex
);
719 // *****************************************************************************************************
720 void CPSQuad::updateTexWrapMode(IDriver
&drv
)
722 NL_PS_FUNC(CPSQuad_updateTexWrapMode
)
723 if (isMultiTextureEnabled())
727 if (isAlternateTextureUsed(drv
))
729 _Tex
->setWrapS(_TexScroll
[0].x
== 0 ? ITexture::Clamp
: ITexture::Repeat
);
730 _Tex
->setWrapT(_TexScroll
[0].y
== 0 ? ITexture::Clamp
: ITexture::Repeat
);
734 _Tex
->setWrapS(_TexScrollAlternate
[0].x
== 0 ? ITexture::Clamp
: ITexture::Repeat
);
735 _Tex
->setWrapT(_TexScrollAlternate
[0].y
== 0 ? ITexture::Clamp
: ITexture::Repeat
);
738 ITexture
*tex2
= isAlternateTextureUsed(drv
) ? getTexture2Alternate() : getTexture2();
741 tex2
->setWrapS(_TexScroll
[1].x
== 0 ? ITexture::Clamp
: ITexture::Repeat
);
742 tex2
->setWrapT(_TexScroll
[1].y
== 0 ? ITexture::Clamp
: ITexture::Repeat
);
749 _Tex
->setWrapS(ITexture::Clamp
);
750 _Tex
->setWrapT(ITexture::Clamp
);
752 // nb for grouped texture we assume that no mipmapping is used, and that the border is black (or white for modulate material mode)