1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "nel/gui/view_polygon.h"
23 #include "nel/gui/view_renderer.h"
24 #include "nel/gui/interface_group.h"
25 #include "nel/gui/widget_manager.h"
27 using namespace NLMISC
;
36 // *********************************************************************************
37 CViewPolygon::CViewPolygon( const TCtorParam
¶m
) : CViewBase( param
)
40 _Color
= CRGBA::White
;
44 // *********************************************************************************
45 void CViewPolygon::setVertices(const std::vector
<NLMISC::CVector
> &vertices
)
47 if (vertices
.size() == _Poly
.Vertices
.size() &&
48 std::equal(vertices
.begin(), vertices
.end(), _Poly
.Vertices
.begin())) return; // remains unchanged
49 _Poly
.Vertices
= vertices
;
51 std::list
<CPolygon
> polys
;
52 if (_Poly
.toConvexPolygons(polys
, NLMISC::CMatrix::Identity
))
55 for(std::list
<CPolygon
>::iterator it
= polys
.begin(); it
!= polys
.end(); ++it
)
62 nlwarning("CViewPolygon : conversion to conex polygons failed");
69 static inline bool totallyInside(const CVector
&minCorner
, const CVector
&maxCorner
, sint32 cx
, sint32 cy
, sint32 cw
, sint32 ch
)
71 return (sint32
) maxCorner
.x
< (cx
+ cw
) &&
72 (sint32
) minCorner
.x
>= cx
&&
73 (sint32
) maxCorner
.y
< (cy
+ ch
) &&
74 (sint32
) minCorner
.y
>= cy
;
77 static inline bool totallyOutside(const CVector
&minCorner
, const CVector
&maxCorner
, sint32 cx
, sint32 cy
, sint32 cw
, sint32 ch
)
79 return (sint32
) minCorner
.x
>= (cx
+ cw
) ||
80 (sint32
) maxCorner
.x
< cx
||
81 (sint32
) minCorner
.y
>= (cy
+ ch
) ||
82 (sint32
) maxCorner
.y
< cy
;
85 // *********************************************************************************
86 void CViewPolygon::draw()
88 if (_Tris
.empty()) return;
90 CViewRenderer
&vr
= *CViewRenderer::getInstance();
94 uint numTris
= (uint
)_Tris
.size();
95 sint32 cornerX
, cornerY
;
96 static std::vector
<NLMISC::CTriangle
> winTris
;
97 winTris
.resize(numTris
);
98 _Parent
->getCorner(cornerX
, cornerY
, _ParentPosRef
);
99 for(uint k
= 0; k
< numTris
; ++k
)
101 winTris
[k
].V0
.set((float) (_Tris
[k
].V0
.x
+ cornerX
), (float) (_Tris
[k
].V0
.y
+ cornerY
), 0.f
);
102 winTris
[k
].V1
.set((float) (_Tris
[k
].V1
.x
+ cornerX
), (float) (_Tris
[k
].V1
.y
+ cornerY
), 0.f
);
103 winTris
[k
].V2
.set((float) (_Tris
[k
].V2
.x
+ cornerX
), (float) (_Tris
[k
].V2
.y
+ cornerY
), 0.f
);
105 // recompute & reclip poly
107 sint32 cx
, cy
, cw
, ch
;
108 vr
.getClipWindow(cx
, cy
, cw
, ch
);
110 NLMISC::CVector minCorner
;
111 NLMISC::CVector maxCorner
;
112 for(uint k
= 0; k
< numTris
; ++k
)
114 winTris
[k
].getMinCorner(minCorner
);
115 winTris
[k
].getMaxCorner(maxCorner
);
116 if (totallyOutside(minCorner
, maxCorner
, cx
, cy
, cw
, ch
)) continue;
117 if (totallyInside(minCorner
, maxCorner
, cx
, cy
, cw
, ch
))
119 _RealTris
.push_back(winTris
[k
]);
123 const uint maxNumCorners
= 8;
124 static CVector outPos0
[maxNumCorners
];
125 static CVector outPos1
[maxNumCorners
];
127 outPos0
[0] = winTris
[k
].V0
;
128 outPos0
[1] = winTris
[k
].V1
;
129 outPos0
[2] = winTris
[k
].V2
;
131 CVector
*pPos0
= outPos0
;
132 CVector
*pPos1
= outPos1
;
136 if ((sint32
) minCorner
.x
< cx
)
139 CPlane
clipper(-1.f
, 0.f
, 0.f
, (float) cx
);
140 count
= clipper
.clipPolygonBack(pPos0
, pPos1
, count
);
141 std::swap(pPos0
, pPos1
);
143 if ((sint32
) maxCorner
.x
> cx
+ cw
)
146 CPlane
clipper(1.f
, 0.f
, 0.f
, - (float) (cx
+ cw
));
147 count
= clipper
.clipPolygonBack(pPos0
, pPos1
, count
);
148 std::swap(pPos0
, pPos1
);
151 if ((sint32
) minCorner
.y
< cy
)
154 CPlane
clipper(0.f
, -1.f
, 0.f
, (float) cy
);
155 count
= clipper
.clipPolygonBack(pPos0
, pPos1
, count
);
156 std::swap(pPos0
, pPos1
);
158 if ((sint32
) maxCorner
.y
> cy
+ ch
)
161 CPlane
clipper(0.f
, 1.f
, 0.f
, - (float) (cy
+ ch
));
162 count
= clipper
.clipPolygonBack(pPos0
, pPos1
, count
);
163 std::swap(pPos0
, pPos1
);
165 nlassert(count
<= 8);
168 for(uint k
= 0; k
< (uint
) (count
- 2); ++k
)
170 _RealTris
.push_back(NLMISC::CTriangle(pPos0
[0], pPos0
[k
+ 1], pPos0
[k
+ 2]));
177 if (_RealTris
.empty()) return;
179 if(getModulateGlobalColor())
181 col
.modulateFromColor (_Color
, CWidgetManager::getInstance()->getGlobalColorForContent());
186 col
.A
= (uint8
)(((sint32
)col
.A
*((sint32
)CWidgetManager::getInstance()->getGlobalColorForContent().A
+1))>>8);
188 vr
.drawUnclippedTriangles(_RenderLayer
, _RealTris
, col
);
191 // *********************************************************************************
192 void CViewPolygon::updateCoords()
194 // assume that clipping will have to be done again, real update of triangle will be done at render time
198 // *********************************************************************************
199 void CViewPolygon::setAlpha(sint32 a
)
201 _Color
.A
= (uint8
) a
;