Use configured resolution for login/outgame/ingame
[ryzomcore.git] / nel / src / 3d / ps_quad.cpp
blob8ce6ce8215217c39ef76b45701246ecbaafef147
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
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.
8 //
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/>.
17 #include "std3d.h"
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"
27 #ifdef DEBUG_NEW
28 #define new DEBUG_NEW
29 #endif
31 namespace NL3D
36 ///////////////////////////
37 // constant definition //
38 ///////////////////////////
41 static const uint dotBufSize = 1024; // size used for point particles batching
43 ////////////////////
44 // vertex buffers //
45 ////////////////////
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;
54 //==========
55 CVertexBuffer CPSQuad::_VBPosTex1Tex2;
56 CVertexBuffer CPSQuad::_VBPosTex1ColTex2;
57 CVertexBuffer CPSQuad::_VBPosTex1AnimTex2;
58 CVertexBuffer CPSQuad::_VBPosTex1AnimColTex2;
59 //==========
60 CVertexBuffer CPSQuad::_VBPosTex1Tex2Anim;
61 CVertexBuffer CPSQuad::_VBPosTex1ColTex2Anim;
62 CVertexBuffer CPSQuad::_VBPosTex1AnimTex2Anim;
63 CVertexBuffer CPSQuad::_VBPosTex1AnimColTex2Anim;
65 /// tmp : ram
66 CVertexBuffer RAMVBPos;
67 CVertexBuffer RAMVBPosCol;
68 CVertexBuffer RAMVBPosTex1;
69 CVertexBuffer RAMVBPosTex1Col;
70 CVertexBuffer RAMVBPosTex1Anim;
71 CVertexBuffer RAMVBPosTex1AnimCol;
72 //==========
73 CVertexBuffer RAMVBPosTex1Tex2;
74 CVertexBuffer RAMVBPosTex1ColTex2;
75 CVertexBuffer RAMVBPosTex1AnimTex2;
76 CVertexBuffer RAMVBPosTex1AnimColTex2;
77 //==========
78 CVertexBuffer RAMVBPosTex1Tex2Anim;
79 CVertexBuffer RAMVBPosTex1ColTex2Anim;
80 CVertexBuffer RAMVBPosTex1AnimTex2Anim;
81 CVertexBuffer RAMVBPosTex1AnimColTex2Anim;
86 CVertexBuffer * const CPSQuad::_VbTab[] =
88 // tex1 only
89 &_VBPos, &_VBPosCol, &_VBPosTex1, &_VBPosTex1Col,
90 NULL, NULL, &_VBPosTex1Anim, &_VBPosTex1AnimCol,
91 // tex1 & tex2
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)
98 // tex1 & tex2
99 NULL, NULL, &_VBPosTex1Tex2Anim, &_VBPosTex1ColTex2Anim,
100 NULL, NULL, &_VBPosTex1AnimTex2Anim, &_VBPosTex1AnimColTex2Anim,
103 CVertexBuffer * const RAMVbTab[] =
105 // tex1 only
106 &RAMVBPos, &RAMVBPosCol, &RAMVBPosTex1, &RAMVBPosTex1Col,
107 NULL, NULL, &RAMVBPosTex1Anim, &RAMVBPosTex1AnimCol,
108 // tex1 & tex2
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)
115 // tex1 & tex2
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;
135 vb.lock (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);
211 // tmp
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)
219 uint flags = 0;
220 if (_ColorScheme) flags |= (uint) VBCol;
221 if (_TexGroup)
223 flags |= VBTex | VBTexAnimated;
225 else if (_Tex)
227 flags |= VBTex;
230 if (flags & VBTex)
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;
242 else
244 flags |= VBTex2;
247 else
249 if ((flags & VBTex) && (_TexScroll[0].x != 0 || _TexScroll[0].y != 0)) flags |= VBTexAnimated;
250 if (_Texture2)
252 if (_MainOp != Decal && (_TexScroll[1].x != 0 || _TexScroll[1].y != 0))
254 flags |= VBTex2 | VBTex2Animated;
256 else
258 flags |= VBTex2;
264 /*if (TestWantAGPCPSQuad)
266 nlassert((flags & ~VBFullMask) == 0); // check for overflow
267 nlassert(_VbTab[flags] != NULL);
268 return *(_VbTab[flags]); // get the vb
270 else
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)
282 setTexture(tex);
283 init();
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 ///==================================================================================
290 CPSQuad::~CPSQuad()
292 NL_PS_FUNC(CPSQuad_CPSQuadDtor)
295 ///==================================================================================
296 uint32 CPSQuad::getNumWantedTris() const
298 NL_PS_FUNC(CPSQuad_getNumWantedTris)
299 nlassert(_Owner);
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())
336 touch();
338 else
340 _Mat.setTexture(0, _TexGroup ? (ITexture *) _TexGroup : (ITexture *) _Tex);
344 ///==================================================================================
345 bool CPSQuad::completeBBox(NLMISC::CAABBox &box) const
347 NL_PS_FUNC(CPSQuad_completeBBox)
348 if (!_SizeScheme)
350 CPSUtil::addRadiusToAABBox(box, _ParticleSize);
352 else
354 CPSUtil::addRadiusToAABBox(box, std::max(fabsf(_SizeScheme->getMaxValue()), fabsf(_SizeScheme->getMinValue())));
356 return true ;
359 ///==================================================================================
360 void CPSQuad::resize(uint32 size)
362 NL_PS_FUNC(CPSQuad_resize)
363 nlassert(size < (1 << 16));
364 resizeSize(size);
365 resizeColor(size);
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);
378 else
380 _Mat.setColor(CRGBA::White);
381 } */
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);
393 serialMaterial(f);
394 if (ver > 1)
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)
405 if (!num) return;
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);
420 dest += stride << 2;
422 while (--num);
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)
430 if (!num) return;
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);
447 dest += stride << 2;
448 ++timePt;
450 while (--num);
452 else
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);
467 dest += stride << 2;
468 ++timePt;
470 while (--num);
474 //==============================================================
475 void CPSQuad::updateVbColNUVForRender(CVertexBuffer &vb, uint32 startIndex, uint32 size, uint32 srcStep, IDriver &drv)
477 NL_PS_FUNC(CPSQuad_updateVbColNUVForRender)
478 nlassert(_Owner);
480 if (!size) return;
482 CVertexBufferReadWrite vba;
483 vb.lock (vba);
485 if (_ColorScheme)
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);
506 currIndexIncr = 1;
508 else
510 currIndex = &_TextureIndex;
511 currIndexIncr = 0;
514 uint32 left = size;
515 while (left--)
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
527 currUV += stride4;
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);
553 else
555 FillQuadCoordsLocalTime((uint8 *) vba.getTexCoordPointer(0, 0), vb.getVertexSize(), _TexScroll[0], *_Owner, startIndex, size, srcStep);
559 else
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);
568 else
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);
586 else
588 FillQuadCoordsLocalTime((uint8 *) vba.getTexCoordPointer(0, 1), vb.getVertexSize(), _TexScroll[1], *_Owner, startIndex, size, srcStep);
592 else
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);
601 else
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());
627 else
629 _Mat.setColor(ps.getGlobalColor());
632 else
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());
647 else
649 CPSMaterial::forceModulateConstantColor(true, ps.getGlobalColor());
652 else
654 forceModulateConstantColor(false);
655 NLMISC::CRGBA col;
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);
664 else
666 col = _Color;
668 _Mat.setColor(col);
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())
725 if (_Tex)
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);
732 else
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();
739 if (tex2)
741 tex2->setWrapS(_TexScroll[1].x == 0 ? ITexture::Clamp : ITexture::Repeat);
742 tex2->setWrapT(_TexScroll[1].y == 0 ? ITexture::Clamp : ITexture::Repeat);
745 else
747 if (_Tex)
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)
756 } // NL3D