Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / nel / src / gui / view_polygon.cpp
blob4706f30f34888b7d0c1929dea0ce731ed0b7b272
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 //
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/>.
20 #include "stdpch.h"
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;
29 #ifdef DEBUG_NEW
30 #define new DEBUG_NEW
31 #endif
33 namespace NLGUI
36 // *********************************************************************************
37 CViewPolygon::CViewPolygon( const TCtorParam &param ) : CViewBase( param )
39 // Construct
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;
50 _Tris.clear();
51 std::list<CPolygon> polys;
52 if (_Poly.toConvexPolygons(polys, NLMISC::CMatrix::Identity))
54 _Tris.clear();
55 for(std::list<CPolygon>::iterator it = polys.begin(); it != polys.end(); ++it)
57 it->toTriFan(_Tris);
60 else
62 nlwarning("CViewPolygon : conversion to conex polygons failed");
63 _Tris.clear();
65 _Touched = true;
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;
89 if (!_Parent) return;
90 CViewRenderer &vr = *CViewRenderer::getInstance();
91 if (_Touched)
93 _RealTris.clear();
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
106 _RealTris.clear();
107 sint32 cx, cy, cw, ch;
108 vr.getClipWindow(cx, cy, cw, ch);
109 // per tri clip
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]);
121 else
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;
134 sint count = 3;
136 if ((sint32) minCorner.x < cx)
138 // clip left
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)
145 // clip right
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)
153 // clip bottom
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)
160 // clip top
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);
166 if (count >= 3)
168 for(uint k = 0; k < (uint) (count - 2); ++k)
170 _RealTris.push_back(NLMISC::CTriangle(pPos0[0], pPos0[k + 1], pPos0[k + 2]));
175 _Touched = false;
177 if (_RealTris.empty()) return;
178 CRGBA col;
179 if(getModulateGlobalColor())
181 col.modulateFromColor (_Color, CWidgetManager::getInstance()->getGlobalColorForContent());
183 else
185 col= _Color;
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
195 _Touched = true;
198 // *********************************************************************************
199 void CViewPolygon::setAlpha(sint32 a)
201 _Color.A = (uint8) a;