diff --git a/code/nel/include/nel/gui/ctrl_quad.h b/code/nel/include/nel/gui/ctrl_quad.h new file mode 100644 index 000000000..2be7b5b94 --- /dev/null +++ b/code/nel/include/nel/gui/ctrl_quad.h @@ -0,0 +1,116 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#ifndef RZ_CTRL_QUAD_H +#define RZ_CTRL_QUAD_H + +#include "nel/gui/ctrl_base.h" +#include "nel/gui/view_renderer.h" +#include "nel/misc/geom_ext.h" + +namespace NLGUI +{ + + /** Display of an arbitrary textured quad in the UI. The applied texture is filtered. + * Unlike CViewBitmap, the texture is always scaled here, and this ui element coordinates + * are driven by the quad vertices coordinates (see setQuad). + * + * Derives from CCtrlBase for tooltipping support + * + * \author Nicolas Vizerie + * \author Nevrax France + * \date 12/2005 + */ + class CCtrlQuad : public CCtrlBase + { + public: + enum TWrapMode { Repeat = 0, Clamp, CustomUVs, WrapModeCount }; + + + CCtrlQuad(); + + // from CInterfaceElement + bool parse(xmlNodePtr cur,CInterfaceGroup *parentGroup); + virtual void updateCoords(); + virtual void draw(); + virtual uint32 getMemory() { return (uint32)(sizeof(*this)+_Id.size()); } + + // from CViewBase + virtual sint32 getAlpha() const { return (sint32) _Color.A; } + virtual void setAlpha (sint32 a); + + // texture + void setTexture(const std::string &texName); + std::string getTexture () const; + + // color + void setColorRGBA(NLMISC::CRGBA col) { _Color = col; } + NLMISC::CRGBA getColorRGBA() const { return _Color; } + + /** Set a new quad relative to parent pos + * x,y, w, h & hotspot are updated to fit the bounding rect of the quad + */ + void setQuad(const NLMISC::CQuad &quad); + void setQuad(const NLMISC::CVector &start, const NLMISC::CVector &end, float thickness); + /** Fit the given texture size (no hotspot for now, always centered) + * NB : current texture is not modified. + */ + void setQuad(const std::string &texName, const NLMISC::CVector &pos, float angle = 0.f, float offCenter = 0.f); + void setQuad(const NLMISC::CVector &pos, float radius, float angle = 0.f); + const NLMISC::CQuad &getQuad() const { return _Quad; } + + void setAdditif(bool additif); + bool getAdditif() const { return _Additif; } + + void setFiltered(bool filtered); + bool getFiltered() const { return _Filtered; } + + void setPattern(float umin, float umax, TWrapMode wrapMode); + + /** Set uvs for each corners -> this will change the wrap mode to CustomUVs + * Use setPattern(0.f, 0.f, CCtrlQuad::Repeat) to return to previous behavior + */ + void setCustomUVs(const NLMISC::CUV uvs[4]); + + + // from CCtrlBase, no op by default + virtual bool handleEvent (const NLGUI::CEventDescriptor &event); + + // see if this control contains the given point (in parent coords) + bool contains(const NLMISC::CVector2f &pos) const; + + // no capturable by default (just tooltip capability wanted) + virtual bool isCapturable() const { return false; } + + + private: + NLMISC::CRGBA _Color; + NLMISC::CQuad _Quad; + NLMISC::CQuadUV _RealQuad; // absolute coords + float _ClampedUCorrection; + CViewRenderer::CTextureId _TextureId; /// Accelerator + bool _Additif; + bool _Filtered; + float _UMin; + float _UMax; + TWrapMode _WrapMode; + NLMISC::CUV _CustomUVs[4]; + }; + +} + +#endif diff --git a/code/nel/src/gui/ctrl_quad.cpp b/code/nel/src/gui/ctrl_quad.cpp new file mode 100644 index 000000000..23a43fbd3 --- /dev/null +++ b/code/nel/src/gui/ctrl_quad.cpp @@ -0,0 +1,435 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "nel/gui/ctrl_quad.h" +#include "nel/gui/interface_group.h" +#include "nel/gui/widget_manager.h" +#include "nel/misc/polygon.h" + +using namespace NLMISC; + +namespace NLGUI +{ + + // ********************************************************************************* + CCtrlQuad::CCtrlQuad() : CCtrlBase(TCtorParam()), _Color(CRGBA::White), + _Additif(false), + _Filtered(true), + _UMin(0.f), + _UMax(1.f), + _WrapMode(Repeat) + { + setQuad(CQuad(CVector::Null, CVector::Null, CVector::Null, CVector::Null)); + // preset uvs for real quad + _RealQuad.Uv0.set(0.f, 0.f); + _RealQuad.Uv1.set(1.f, 0.f); + _RealQuad.Uv2.set(1.f, 1.f); + _RealQuad.Uv3.set(0.f, 1.f); + } + + // ********************************************************************************* + bool CCtrlQuad::parse(xmlNodePtr /* cur */, CInterfaceGroup * /* parentGroup */) + { + nlassert(0); // NOT IMPLEMENTED (only created dynamically at this time) + return false; + } + + // ********************************************************************************* + void CCtrlQuad::updateCoords() + { + H_AUTO(Rz_CCtrlQuad_updateCoords) + CViewBase::updateCoords(); + nlassert(_Parent); + // don't use _XReal && _YReal, because coords are given relative to parent + CVector delta((float) _Parent->getXReal(), (float) _Parent->getYReal(), 0.f); + _RealQuad.set(_Quad.V0 + delta, _Quad.V1 + delta, _Quad.V2 + delta, _Quad.V3 + delta); + } + + // ********************************************************************************* + void CCtrlQuad::draw() + { + H_AUTO(Rz_CCtrlQuad_draw) + nlassert(_Parent); + CViewRenderer &rVR = *CViewRenderer::getInstance(); + + CRGBA col; + if(getModulateGlobalColor()) + { + col.modulateFromColor (_Color, CWidgetManager::getInstance()->getGlobalColorForContent()); + } + else + { + col= _Color; + col.A = (uint8)(((sint32)col.A*((sint32)CWidgetManager::getInstance()->getGlobalColorForContent().A+1))>>8); + } + + /*if (_InheritGCAlpha) + { + // search a parent container + CInterfaceGroup *gr = getParent(); + while (gr) + { + if (gr->isGroupContainer()) + { + CGroupContainer *gc = static_cast(gr); + col.A = (uint8)(((sint32)col.A*((sint32)gc->getCurrentContainerAlpha()+1))>>8); + break; + } + gr = gr->getParent(); + } + }*/ + if (_UMin == 0.f && _UMax == 1.f && _WrapMode != CustomUVs) + { + // no pattern applied, can draw the quad in a single piece + rVR.drawQuad(_RenderLayer, _RealQuad, _TextureId, col, _Additif, _Filtered); + } + else + { + NLMISC::CQuadUV quv; + if (_WrapMode == Repeat) + { + if (_UMax == _UMin) + { + (CQuad &) quv = _RealQuad; // copy CQuad part + float u = fmodf(_UMin, 1.f); + quv.Uv0.set(u, 0.f); + quv.Uv1.set(u, 0.f); + quv.Uv2.set(u, 1.f); + quv.Uv3.set(u, 1.f); + rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); + } + else + { + // reverse corners if needed to handle case where _UVMin < _UVmax + NLMISC::CQuad srcQuad; + float umin, umax; + if (_UMax < _UMin) + { + umin = _UMax; + umax = _UMin; + srcQuad.V0 = _RealQuad.V1; + srcQuad.V1 = _RealQuad.V0; + srcQuad.V2 = _RealQuad.V3; + srcQuad.V3 = _RealQuad.V2; + } + else + { + umin = _UMin; + umax = _UMax; + srcQuad = _RealQuad; + } + + + float unitRatio = 1.f / fabsf(umax - umin); // ratio of the real quad delta x in screen for du = 1 + // texture is stretched, mutiple parts needed + float ceilUMin = ceilf(umin); + float firstDeltaU = ceilUMin - umin; + if (firstDeltaU != 0.f) + { + + // start quad + quv.V0 = srcQuad.V0; + quv.V1 = blend(srcQuad.V0, srcQuad.V1, std::min(1.f, (firstDeltaU * unitRatio))); + quv.V2 = blend(srcQuad.V3, srcQuad.V2, std::min(1.f, (firstDeltaU * unitRatio))); + quv.V3 = srcQuad.V3; + float lastU = std::min(umax + 1.f - ceilUMin, 1.f); + quv.Uv0.set(1.f - firstDeltaU, 0.f); + quv.Uv1.set(lastU, 0.f); + quv.Uv2.set(lastU, 1.f); + quv.Uv3.set(1.f - firstDeltaU, 1.f); + rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); + + if (firstDeltaU * unitRatio >= 1.f) return; + } + + // TODO optim: reuse of previous uv & pos ... (prb is that they are not always computed) + + // intermediate quads + sint numQuads = (sint) (floorf(umax) - ceilf(umin)); + + for(sint k = 0; k < numQuads; ++k) + { + float deltaU = firstDeltaU + k; + // start quad + quv.V0 = blend(srcQuad.V0, srcQuad.V1, deltaU * unitRatio); + quv.V1 = blend(srcQuad.V0, srcQuad.V1, (deltaU + 1.f) * unitRatio); + quv.V2 = blend(srcQuad.V3, srcQuad.V2, (deltaU + 1.f) * unitRatio); + quv.V3 = blend(srcQuad.V3, srcQuad.V2, deltaU * unitRatio); + quv.Uv0.set(0.f, 0.f); + quv.Uv1.set(1.f, 0.f); + quv.Uv2.set(1.f, 1.f); + quv.Uv3.set(0.f, 1.f); + rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); + } + // end quad + float lastDeltaU = umax - floorf(umax); + if (lastDeltaU != 0.f) + { + + // start quad + quv.V0 = blend(srcQuad.V1, srcQuad.V0, lastDeltaU * unitRatio); + quv.V1 = srcQuad.V1; + quv.V2 = srcQuad.V2; + quv.V3 = blend(srcQuad.V2, srcQuad.V3, lastDeltaU * unitRatio); + quv.Uv0.set(0.f, 0.f); + quv.Uv1.set(lastDeltaU, 0.f); + quv.Uv2.set(lastDeltaU, 1.f); + quv.Uv3.set(0.f, 1.f); + rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); + } + } + + } + else if (_WrapMode == Clamp) + { + if (_UMin == _UMax) + { + (CQuad &) quv = _RealQuad; // copy CQuad part + // special case + float u = _UMin; + clamp(u, 0.f, 1.f); + quv.Uv0.set(u, 0.f); + quv.Uv1.set(u, 1.f); + quv.Uv2.set(u, 1.f); + quv.Uv3.set(u, 0.f); + rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); + } + else + { + NLMISC::CQuad srcQuad; + float umin, umax; + if (_UMax < _UMin) + { + umin = _UMax; + umax = _UMin; + srcQuad.V0 = _RealQuad.V1; + srcQuad.V1 = _RealQuad.V0; + srcQuad.V2 = _RealQuad.V3; + srcQuad.V3 = _RealQuad.V2; + } + else + { + umin = _UMin; + umax = _UMax; + srcQuad = _RealQuad; + } + float startRatio = - umin / (umax - umin); // start of unclamped u (actually (0.f - umin) / (umax - umin) ) + if (umin < 0.f) + { + quv.V0 = srcQuad.V0; + quv.V1 = blend(srcQuad.V0, srcQuad.V1, std::min(1.f ,startRatio)); + quv.V2 = blend(srcQuad.V3, srcQuad.V2, std::min(1.f ,startRatio)); + quv.V3 = srcQuad.V3; + // draw first clamped part + quv.Uv0.set(0.f, 0.f); + quv.Uv1.set(0.f, 0.f); + quv.Uv2.set(0.f, 1.f); + quv.Uv3.set(0.f, 1.f); + rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); + } + if (startRatio >= 1.f) return; + float endRatio = (1.f - umin) / (umax - umin); + if (endRatio > 0.f) + { + // draw middle part if visible + // TODO optim: reuse of previous uv & pos ... (prb is that they are not always computed) + quv.V0 = blend(srcQuad.V0, srcQuad.V1, std::max(0.f , startRatio)); + quv.V1 = blend(srcQuad.V0, srcQuad.V1, std::min(1.f , endRatio)); + quv.V2 = blend(srcQuad.V3, srcQuad.V2, std::min(1.f , endRatio)); + quv.V3 = blend(srcQuad.V3, srcQuad.V2, std::max(0.f , startRatio)); + // draw first clamped part + quv.Uv0.set(std::max(0.f, umin), 0.f); + quv.Uv1.set(std::min(1.f, umax), 0.f); + quv.Uv2.set(std::min(1.f, umax), 1.f); + quv.Uv3.set(std::max(0.f, umin), 1.f); + rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); + } + if (endRatio >= 1.f) return; + // draw end part + quv.V0 = blend(srcQuad.V0, srcQuad.V1, std::max(0.f , endRatio)); + quv.V1 = srcQuad.V1; + quv.V2 = srcQuad.V2; + quv.V3 = blend(srcQuad.V3, srcQuad.V2, std::max(0.f , endRatio)); + // draw end clamped part + quv.Uv0.set(1.f, 0.f); + quv.Uv1.set(1.f, 0.f); + quv.Uv2.set(1.f, 1.f); + quv.Uv3.set(1.f, 1.f); + rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); + } + } + else + { + nlassert(_WrapMode == CustomUVs); + quv.V0 = _RealQuad.V0; + quv.V1 = _RealQuad.V1; + quv.V2 = _RealQuad.V2; + quv.V3 = _RealQuad.V3; + quv.Uv0 = _CustomUVs[0]; + quv.Uv1 = _CustomUVs[1]; + quv.Uv2 = _CustomUVs[2]; + quv.Uv3 = _CustomUVs[3]; + rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); + } + } + } + + // ********************************************************************************* + void CCtrlQuad::setAlpha(sint32 a) + { + H_AUTO(Rz_CCtrlQuad_setAlpha) + _Color.A = (uint8) a; + } + + // ********************************************************************************* + void CCtrlQuad::setTexture(const std::string &texName) + { + H_AUTO(Rz_CCtrlQuad_setTexture) + // CInterfaceManager *pIM = CInterfaceManager::getInstance(); + // CViewRenderer &rVR = *CViewRenderer::getInstance(); + _TextureId.setTexture(texName.c_str()); + } + + // ********************************************************************************* + std::string CCtrlQuad::getTexture() const + { + H_AUTO(Rz_CCtrlQuad_getTexture) + CViewRenderer &rVR = *CViewRenderer::getInstance(); + return rVR.getTextureNameFromId (_TextureId); + } + + // ********************************************************************************* + void CCtrlQuad::setQuad(const CQuad &quad) + { + H_AUTO(Rz_CCtrlQuad_setQuad) + float qXMin = minof(quad.V0.x, quad.V1.x, quad.V2.x, quad.V3.x); + float qXMax = maxof(quad.V0.x, quad.V1.x, quad.V2.x, quad.V3.x); + float qYMin = minof(quad.V0.y, quad.V1.y, quad.V2.y, quad.V3.y); + float qYMax = maxof(quad.V0.y, quad.V1.y, quad.V2.y, quad.V3.y); + setPosRef(Hotspot_BL); + setX((sint32) floorf(qXMin)); + setY((sint32) floorf(qYMin)); + setW((sint32) ceilf(qXMax) - getX()); + setH((sint32) ceilf(qYMax) - getY()); + _Quad = quad; + } + + // ********************************************************************************* + void CCtrlQuad::setQuad(const NLMISC::CVector &start, const NLMISC::CVector &end, float thickness) + { + H_AUTO(Rz_CCtrlQuad_setQuad) + CVector right = end - start; + CVector up(-right.y, right.x, 0.f); + up = thickness * up.normed(); + setQuad(CQuad(start + up, end + up, end - up, start - up)); + } + + // ********************************************************************************* + void CCtrlQuad::setQuad(const NLMISC::CVector &pos, float radius, float angle /*=0.f*/) + { + H_AUTO(Rz_CCtrlQuad_setQuad) + if (angle == 0.f) + { + setQuad(pos - radius * CVector::I, pos + radius * CVector::I, radius); + } + else + { + CVector right(radius * cosf(angle), radius * sinf(angle), 0.f); + setQuad(pos - right, pos + right, radius); + } + } + + // ********************************************************************************* + void CCtrlQuad::setQuad(const std::string &texName, const NLMISC::CVector &srcPos, float angle /*= 0.f*/, float offCenter /* = 0.f*/) + { + H_AUTO(Rz_CCtrlQuad_setQuad) + NLMISC::CVector pos = srcPos; + CViewRenderer &rVR = *CViewRenderer::getInstance(); + sint32 w, h; + rVR.getTextureSizeFromId(rVR.getTextureIdFromName(texName), w, h); + if (angle == 0.f) + { + if (offCenter != 0.f) + { + pos.x += offCenter; + } + setQuad(pos - 0.5f * w * CVector::I, pos + 0.5f * w * CVector::I, 0.5f * h); + } + else + { + CVector unitRadius(cosf(angle), sinf(angle), 0.f); + CVector radius = 0.5f * w * unitRadius; + pos += offCenter * unitRadius; + setQuad(pos - radius, pos + radius, 0.5f * h); + } + } + + // ********************************************************************************* + void CCtrlQuad::setAdditif(bool additif) + { + H_AUTO(Rz_CCtrlQuad_setAdditif) + _Additif = additif; + } + + // ********************************************************************************* + void CCtrlQuad::setFiltered(bool filtered) + { + H_AUTO(Rz_CCtrlQuad_setFiltered) + _Filtered = filtered; + } + + // ********************************************************************************* + void CCtrlQuad::setPattern(float umin, float umax, TWrapMode wrapMode) + { + H_AUTO(Rz_CCtrlQuad_setPattern) + nlassert((uint) wrapMode < CustomUVs); + _UMin = umin; + _UMax = umax; + _WrapMode = wrapMode; + } + + // ********************************************************************************* + void CCtrlQuad::setCustomUVs(const CUV uvs[4]) + { + H_AUTO(Rz_CCtrlQuad_setCustomUVs) + std::copy(uvs, uvs + 4, _CustomUVs ); + _WrapMode = CustomUVs; + } + + // ********************************************************************************* + bool CCtrlQuad::handleEvent(const NLGUI::CEventDescriptor &/* event */) + { + H_AUTO(Rz_CCtrlQuad_handleEvent) + return false; + } + + // ********************************************************************************* + bool CCtrlQuad::contains(const NLMISC::CVector2f &pos) const + { + H_AUTO(Rz_CCtrlQuad_contains) + static NLMISC::CPolygon2D poly; + poly.Vertices.resize(4); + poly.Vertices[0] = _Quad.V0; + poly.Vertices[1] = _Quad.V1; + poly.Vertices[2] = _Quad.V2; + poly.Vertices[3] = _Quad.V3; + return poly.contains(pos, false); + } + +} + + + diff --git a/code/ryzom/client/src/interface_v3/ctrl_quad.cpp b/code/ryzom/client/src/interface_v3/ctrl_quad.cpp deleted file mode 100644 index f1da0754b..000000000 --- a/code/ryzom/client/src/interface_v3/ctrl_quad.cpp +++ /dev/null @@ -1,435 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdpch.h" -#include "ctrl_quad.h" -#include "nel/gui/interface_group.h" -#include "interface_manager.h" - -using namespace NLMISC; - -// ********************************************************************************* -CCtrlQuad::CCtrlQuad() : CCtrlBase(TCtorParam()), _Color(CRGBA::White), - _Additif(false), - _Filtered(true), - _UMin(0.f), - _UMax(1.f), - _WrapMode(Repeat) -{ - setQuad(CQuad(CVector::Null, CVector::Null, CVector::Null, CVector::Null)); - // preset uvs for real quad - _RealQuad.Uv0.set(0.f, 0.f); - _RealQuad.Uv1.set(1.f, 0.f); - _RealQuad.Uv2.set(1.f, 1.f); - _RealQuad.Uv3.set(0.f, 1.f); -} - -// ********************************************************************************* -bool CCtrlQuad::parse(xmlNodePtr /* cur */, CInterfaceGroup * /* parentGroup */) -{ - nlassert(0); // NOT IMPLEMENTED (only created dynamically at this time) - return false; -} - -// ********************************************************************************* -void CCtrlQuad::updateCoords() -{ - H_AUTO(Rz_CCtrlQuad_updateCoords) - CViewBase::updateCoords(); - nlassert(_Parent); - // don't use _XReal && _YReal, because coords are given relative to parent - CVector delta((float) _Parent->getXReal(), (float) _Parent->getYReal(), 0.f); - _RealQuad.set(_Quad.V0 + delta, _Quad.V1 + delta, _Quad.V2 + delta, _Quad.V3 + delta); -} - -// ********************************************************************************* -void CCtrlQuad::draw() -{ - H_AUTO(Rz_CCtrlQuad_draw) - nlassert(_Parent); - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - CViewRenderer &rVR = *CViewRenderer::getInstance(); - - CRGBA col; - if(getModulateGlobalColor()) - { - col.modulateFromColor (_Color, CWidgetManager::getInstance()->getGlobalColorForContent()); - } - else - { - col= _Color; - col.A = (uint8)(((sint32)col.A*((sint32)CWidgetManager::getInstance()->getGlobalColorForContent().A+1))>>8); - } - - /*if (_InheritGCAlpha) - { - // search a parent container - CInterfaceGroup *gr = getParent(); - while (gr) - { - if (gr->isGroupContainer()) - { - CGroupContainer *gc = static_cast(gr); - col.A = (uint8)(((sint32)col.A*((sint32)gc->getCurrentContainerAlpha()+1))>>8); - break; - } - gr = gr->getParent(); - } - }*/ - if (_UMin == 0.f && _UMax == 1.f && _WrapMode != CustomUVs) - { - // no pattern applied, can draw the quad in a single piece - rVR.drawQuad(_RenderLayer, _RealQuad, _TextureId, col, _Additif, _Filtered); - } - else - { - NLMISC::CQuadUV quv; - if (_WrapMode == Repeat) - { - if (_UMax == _UMin) - { - (CQuad &) quv = _RealQuad; // copy CQuad part - float u = fmodf(_UMin, 1.f); - quv.Uv0.set(u, 0.f); - quv.Uv1.set(u, 0.f); - quv.Uv2.set(u, 1.f); - quv.Uv3.set(u, 1.f); - rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); - } - else - { - // reverse corners if needed to handle case where _UVMin < _UVmax - NLMISC::CQuad srcQuad; - float umin, umax; - if (_UMax < _UMin) - { - umin = _UMax; - umax = _UMin; - srcQuad.V0 = _RealQuad.V1; - srcQuad.V1 = _RealQuad.V0; - srcQuad.V2 = _RealQuad.V3; - srcQuad.V3 = _RealQuad.V2; - } - else - { - umin = _UMin; - umax = _UMax; - srcQuad = _RealQuad; - } - - - float unitRatio = 1.f / fabsf(umax - umin); // ratio of the real quad delta x in screen for du = 1 - // texture is stretched, mutiple parts needed - float ceilUMin = ceilf(umin); - float firstDeltaU = ceilUMin - umin; - if (firstDeltaU != 0.f) - { - - // start quad - quv.V0 = srcQuad.V0; - quv.V1 = blend(srcQuad.V0, srcQuad.V1, std::min(1.f, (firstDeltaU * unitRatio))); - quv.V2 = blend(srcQuad.V3, srcQuad.V2, std::min(1.f, (firstDeltaU * unitRatio))); - quv.V3 = srcQuad.V3; - float lastU = std::min(umax + 1.f - ceilUMin, 1.f); - quv.Uv0.set(1.f - firstDeltaU, 0.f); - quv.Uv1.set(lastU, 0.f); - quv.Uv2.set(lastU, 1.f); - quv.Uv3.set(1.f - firstDeltaU, 1.f); - rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); - - if (firstDeltaU * unitRatio >= 1.f) return; - } - - // TODO optim: reuse of previous uv & pos ... (prb is that they are not always computed) - - // intermediate quads - sint numQuads = (sint) (floorf(umax) - ceilf(umin)); - - for(sint k = 0; k < numQuads; ++k) - { - float deltaU = firstDeltaU + k; - // start quad - quv.V0 = blend(srcQuad.V0, srcQuad.V1, deltaU * unitRatio); - quv.V1 = blend(srcQuad.V0, srcQuad.V1, (deltaU + 1.f) * unitRatio); - quv.V2 = blend(srcQuad.V3, srcQuad.V2, (deltaU + 1.f) * unitRatio); - quv.V3 = blend(srcQuad.V3, srcQuad.V2, deltaU * unitRatio); - quv.Uv0.set(0.f, 0.f); - quv.Uv1.set(1.f, 0.f); - quv.Uv2.set(1.f, 1.f); - quv.Uv3.set(0.f, 1.f); - rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); - } - // end quad - float lastDeltaU = umax - floorf(umax); - if (lastDeltaU != 0.f) - { - - // start quad - quv.V0 = blend(srcQuad.V1, srcQuad.V0, lastDeltaU * unitRatio); - quv.V1 = srcQuad.V1; - quv.V2 = srcQuad.V2; - quv.V3 = blend(srcQuad.V2, srcQuad.V3, lastDeltaU * unitRatio); - quv.Uv0.set(0.f, 0.f); - quv.Uv1.set(lastDeltaU, 0.f); - quv.Uv2.set(lastDeltaU, 1.f); - quv.Uv3.set(0.f, 1.f); - rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); - } - } - - } - else if (_WrapMode == Clamp) - { - if (_UMin == _UMax) - { - (CQuad &) quv = _RealQuad; // copy CQuad part - // special case - float u = _UMin; - clamp(u, 0.f, 1.f); - quv.Uv0.set(u, 0.f); - quv.Uv1.set(u, 1.f); - quv.Uv2.set(u, 1.f); - quv.Uv3.set(u, 0.f); - rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); - } - else - { - NLMISC::CQuad srcQuad; - float umin, umax; - if (_UMax < _UMin) - { - umin = _UMax; - umax = _UMin; - srcQuad.V0 = _RealQuad.V1; - srcQuad.V1 = _RealQuad.V0; - srcQuad.V2 = _RealQuad.V3; - srcQuad.V3 = _RealQuad.V2; - } - else - { - umin = _UMin; - umax = _UMax; - srcQuad = _RealQuad; - } - float startRatio = - umin / (umax - umin); // start of unclamped u (actually (0.f - umin) / (umax - umin) ) - if (umin < 0.f) - { - quv.V0 = srcQuad.V0; - quv.V1 = blend(srcQuad.V0, srcQuad.V1, std::min(1.f ,startRatio)); - quv.V2 = blend(srcQuad.V3, srcQuad.V2, std::min(1.f ,startRatio)); - quv.V3 = srcQuad.V3; - // draw first clamped part - quv.Uv0.set(0.f, 0.f); - quv.Uv1.set(0.f, 0.f); - quv.Uv2.set(0.f, 1.f); - quv.Uv3.set(0.f, 1.f); - rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); - } - if (startRatio >= 1.f) return; - float endRatio = (1.f - umin) / (umax - umin); - if (endRatio > 0.f) - { - // draw middle part if visible - // TODO optim: reuse of previous uv & pos ... (prb is that they are not always computed) - quv.V0 = blend(srcQuad.V0, srcQuad.V1, std::max(0.f , startRatio)); - quv.V1 = blend(srcQuad.V0, srcQuad.V1, std::min(1.f , endRatio)); - quv.V2 = blend(srcQuad.V3, srcQuad.V2, std::min(1.f , endRatio)); - quv.V3 = blend(srcQuad.V3, srcQuad.V2, std::max(0.f , startRatio)); - // draw first clamped part - quv.Uv0.set(std::max(0.f, umin), 0.f); - quv.Uv1.set(std::min(1.f, umax), 0.f); - quv.Uv2.set(std::min(1.f, umax), 1.f); - quv.Uv3.set(std::max(0.f, umin), 1.f); - rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); - } - if (endRatio >= 1.f) return; - // draw end part - quv.V0 = blend(srcQuad.V0, srcQuad.V1, std::max(0.f , endRatio)); - quv.V1 = srcQuad.V1; - quv.V2 = srcQuad.V2; - quv.V3 = blend(srcQuad.V3, srcQuad.V2, std::max(0.f , endRatio)); - // draw end clamped part - quv.Uv0.set(1.f, 0.f); - quv.Uv1.set(1.f, 0.f); - quv.Uv2.set(1.f, 1.f); - quv.Uv3.set(1.f, 1.f); - rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); - } - } - else - { - nlassert(_WrapMode == CustomUVs); - quv.V0 = _RealQuad.V0; - quv.V1 = _RealQuad.V1; - quv.V2 = _RealQuad.V2; - quv.V3 = _RealQuad.V3; - quv.Uv0 = _CustomUVs[0]; - quv.Uv1 = _CustomUVs[1]; - quv.Uv2 = _CustomUVs[2]; - quv.Uv3 = _CustomUVs[3]; - rVR.drawQuad(_RenderLayer, quv, _TextureId, col, _Additif, _Filtered); - } - } -} - -// ********************************************************************************* -void CCtrlQuad::setAlpha(sint32 a) -{ - H_AUTO(Rz_CCtrlQuad_setAlpha) - _Color.A = (uint8) a; -} - -// ********************************************************************************* -void CCtrlQuad::setTexture(const std::string &texName) -{ - H_AUTO(Rz_CCtrlQuad_setTexture) -// CInterfaceManager *pIM = CInterfaceManager::getInstance(); -// CViewRenderer &rVR = *CViewRenderer::getInstance(); - _TextureId.setTexture(texName.c_str()); -} - -// ********************************************************************************* -std::string CCtrlQuad::getTexture() const -{ - H_AUTO(Rz_CCtrlQuad_getTexture) - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - CViewRenderer &rVR = *CViewRenderer::getInstance(); - return rVR.getTextureNameFromId (_TextureId); -} - -// ********************************************************************************* -void CCtrlQuad::setQuad(const CQuad &quad) -{ - H_AUTO(Rz_CCtrlQuad_setQuad) - float qXMin = minof(quad.V0.x, quad.V1.x, quad.V2.x, quad.V3.x); - float qXMax = maxof(quad.V0.x, quad.V1.x, quad.V2.x, quad.V3.x); - float qYMin = minof(quad.V0.y, quad.V1.y, quad.V2.y, quad.V3.y); - float qYMax = maxof(quad.V0.y, quad.V1.y, quad.V2.y, quad.V3.y); - setPosRef(Hotspot_BL); - setX((sint32) floorf(qXMin)); - setY((sint32) floorf(qYMin)); - setW((sint32) ceilf(qXMax) - getX()); - setH((sint32) ceilf(qYMax) - getY()); - _Quad = quad; -} - -// ********************************************************************************* -void CCtrlQuad::setQuad(const NLMISC::CVector &start, const NLMISC::CVector &end, float thickness) -{ - H_AUTO(Rz_CCtrlQuad_setQuad) - CVector right = end - start; - CVector up(-right.y, right.x, 0.f); - up = thickness * up.normed(); - setQuad(CQuad(start + up, end + up, end - up, start - up)); -} - -// ********************************************************************************* -void CCtrlQuad::setQuad(const NLMISC::CVector &pos, float radius, float angle /*=0.f*/) -{ - H_AUTO(Rz_CCtrlQuad_setQuad) - if (angle == 0.f) - { - setQuad(pos - radius * CVector::I, pos + radius * CVector::I, radius); - } - else - { - CVector right(radius * cosf(angle), radius * sinf(angle), 0.f); - setQuad(pos - right, pos + right, radius); - } -} - -// ********************************************************************************* -void CCtrlQuad::setQuad(const std::string &texName, const NLMISC::CVector &srcPos, float angle /*= 0.f*/, float offCenter /* = 0.f*/) -{ - H_AUTO(Rz_CCtrlQuad_setQuad) - NLMISC::CVector pos = srcPos; - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - CViewRenderer &rVR = *CViewRenderer::getInstance(); - sint32 w, h; - rVR.getTextureSizeFromId(rVR.getTextureIdFromName(texName), w, h); - if (angle == 0.f) - { - if (offCenter != 0.f) - { - pos.x += offCenter; - } - setQuad(pos - 0.5f * w * CVector::I, pos + 0.5f * w * CVector::I, 0.5f * h); - } - else - { - CVector unitRadius(cosf(angle), sinf(angle), 0.f); - CVector radius = 0.5f * w * unitRadius; - pos += offCenter * unitRadius; - setQuad(pos - radius, pos + radius, 0.5f * h); - } -} - -// ********************************************************************************* -void CCtrlQuad::setAdditif(bool additif) -{ - H_AUTO(Rz_CCtrlQuad_setAdditif) - _Additif = additif; -} - -// ********************************************************************************* -void CCtrlQuad::setFiltered(bool filtered) -{ - H_AUTO(Rz_CCtrlQuad_setFiltered) - _Filtered = filtered; -} - -// ********************************************************************************* -void CCtrlQuad::setPattern(float umin, float umax, TWrapMode wrapMode) -{ - H_AUTO(Rz_CCtrlQuad_setPattern) - nlassert((uint) wrapMode < CustomUVs); - _UMin = umin; - _UMax = umax; - _WrapMode = wrapMode; -} - -// ********************************************************************************* -void CCtrlQuad::setCustomUVs(const CUV uvs[4]) -{ - H_AUTO(Rz_CCtrlQuad_setCustomUVs) - std::copy(uvs, uvs + 4, _CustomUVs ); - _WrapMode = CustomUVs; -} - -// ********************************************************************************* -bool CCtrlQuad::handleEvent(const NLGUI::CEventDescriptor &/* event */) -{ - H_AUTO(Rz_CCtrlQuad_handleEvent) - return false; -} - -// ********************************************************************************* -bool CCtrlQuad::contains(const NLMISC::CVector2f &pos) const -{ - H_AUTO(Rz_CCtrlQuad_contains) - static NLMISC::CPolygon2D poly; - poly.Vertices.resize(4); - poly.Vertices[0] = _Quad.V0; - poly.Vertices[1] = _Quad.V1; - poly.Vertices[2] = _Quad.V2; - poly.Vertices[3] = _Quad.V3; - return poly.contains(pos, false); -} - - - - - diff --git a/code/ryzom/client/src/interface_v3/ctrl_quad.h b/code/ryzom/client/src/interface_v3/ctrl_quad.h deleted file mode 100644 index 2e4ec17ca..000000000 --- a/code/ryzom/client/src/interface_v3/ctrl_quad.h +++ /dev/null @@ -1,112 +0,0 @@ -// Ryzom - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - - -#ifndef RZ_CTRL_QUAD_H -#define RZ_CTRL_QUAD_H - -#include "nel/gui/ctrl_base.h" -#include "nel/gui/view_renderer.h" -#include "nel/misc/geom_ext.h" - -/** Display of an arbitrary textured quad in the UI. The applied texture is filtered. - * Unlike CViewBitmap, the texture is always scaled here, and this ui element coordinates - * are driven by the quad vertices coordinates (see setQuad). - * - * Derives from CCtrlBase for tooltipping support - * - * \author Nicolas Vizerie - * \author Nevrax France - * \date 12/2005 - */ -class CCtrlQuad : public CCtrlBase -{ -public: - enum TWrapMode { Repeat = 0, Clamp, CustomUVs, WrapModeCount }; - - - CCtrlQuad(); - - // from CInterfaceElement - bool parse(xmlNodePtr cur,CInterfaceGroup *parentGroup); - virtual void updateCoords(); - virtual void draw(); - virtual uint32 getMemory() { return (uint32)(sizeof(*this)+_Id.size()); } - - // from CViewBase - virtual sint32 getAlpha() const { return (sint32) _Color.A; } - virtual void setAlpha (sint32 a); - - // texture - void setTexture(const std::string &texName); - std::string getTexture () const; - - // color - void setColorRGBA(NLMISC::CRGBA col) { _Color = col; } - NLMISC::CRGBA getColorRGBA() const { return _Color; } - - /** Set a new quad relative to parent pos - * x,y, w, h & hotspot are updated to fit the bounding rect of the quad - */ - void setQuad(const NLMISC::CQuad &quad); - void setQuad(const NLMISC::CVector &start, const NLMISC::CVector &end, float thickness); - /** Fit the given texture size (no hotspot for now, always centered) - * NB : current texture is not modified. - */ - void setQuad(const std::string &texName, const NLMISC::CVector &pos, float angle = 0.f, float offCenter = 0.f); - void setQuad(const NLMISC::CVector &pos, float radius, float angle = 0.f); - const NLMISC::CQuad &getQuad() const { return _Quad; } - - void setAdditif(bool additif); - bool getAdditif() const { return _Additif; } - - void setFiltered(bool filtered); - bool getFiltered() const { return _Filtered; } - - void setPattern(float umin, float umax, TWrapMode wrapMode); - - /** Set uvs for each corners -> this will change the wrap mode to CustomUVs - * Use setPattern(0.f, 0.f, CCtrlQuad::Repeat) to return to previous behavior - */ - void setCustomUVs(const NLMISC::CUV uvs[4]); - - - // from CCtrlBase, no op by default - virtual bool handleEvent (const NLGUI::CEventDescriptor &event); - - // see if this control contains the given point (in parent coords) - bool contains(const NLMISC::CVector2f &pos) const; - - // no capturable by default (just tooltip capability wanted) - virtual bool isCapturable() const { return false; } - - -private: - NLMISC::CRGBA _Color; - NLMISC::CQuad _Quad; - NLMISC::CQuadUV _RealQuad; // absolute coords - float _ClampedUCorrection; - CViewRenderer::CTextureId _TextureId; /// Accelerator - bool _Additif; - bool _Filtered; - float _UMin; - float _UMax; - TWrapMode _WrapMode; - NLMISC::CUV _CustomUVs[4]; -}; - - -#endif diff --git a/code/ryzom/client/src/interface_v3/group_map.cpp b/code/ryzom/client/src/interface_v3/group_map.cpp index 01aabff64..68341375f 100644 --- a/code/ryzom/client/src/interface_v3/group_map.cpp +++ b/code/ryzom/client/src/interface_v3/group_map.cpp @@ -36,7 +36,7 @@ #include "people_interraction.h" // for MaxNumPeopleInTeam #include "../sheet_manager.h" // for MaxNumPeopleInTeam #include "../global.h" -#include "ctrl_quad.h" +#include "nel/gui/ctrl_quad.h" // #include "nel/misc/xml_auto_ptr.h" #include "game_share/mission_desc.h" diff --git a/code/ryzom/client/src/interface_v3/group_map.h b/code/ryzom/client/src/interface_v3/group_map.h index a276e5a5b..d2fa808b7 100644 --- a/code/ryzom/client/src/interface_v3/group_map.h +++ b/code/ryzom/client/src/interface_v3/group_map.h @@ -35,11 +35,18 @@ class CContinent; -namespace NLMISC{ -class CCDBNodeLeaf; + +namespace NLMISC +{ + class CCDBNodeLeaf; } + +namespace NLGUI +{ + class CCtrlQuad; +} + class CWorldSheet; -class CCtrlQuad; struct SMap; namespace NL3D diff --git a/code/ryzom/client/src/r2/displayer_visual_activity_sequence.cpp b/code/ryzom/client/src/r2/displayer_visual_activity_sequence.cpp index a15d4492a..40f1823e5 100644 --- a/code/ryzom/client/src/r2/displayer_visual_activity_sequence.cpp +++ b/code/ryzom/client/src/r2/displayer_visual_activity_sequence.cpp @@ -19,7 +19,7 @@ #include "displayer_visual_group.h" #include "r2_config.h" // -#include "../interface_v3/ctrl_quad.h" +#include "nel/gui/ctrl_quad.h" #include "../interface_v3/interface_manager.h" #include "nel/gui/view_renderer.h" diff --git a/code/ryzom/client/src/r2/displayer_visual_group.cpp b/code/ryzom/client/src/r2/displayer_visual_group.cpp index fed72c85a..d4daa2e67 100644 --- a/code/ryzom/client/src/r2/displayer_visual_group.cpp +++ b/code/ryzom/client/src/r2/displayer_visual_group.cpp @@ -34,7 +34,7 @@ #include "../misc.h" #include "../landscape_poly_drawer.h" #include "../interface_v3/ctrl_polygon.h" -#include "../interface_v3/ctrl_quad.h" +#include "nel/gui/ctrl_quad.h" #include "../time_client.h" // diff --git a/code/ryzom/client/src/r2/instance_map_deco.cpp b/code/ryzom/client/src/r2/instance_map_deco.cpp index 476326b19..c6b1b2dae 100644 --- a/code/ryzom/client/src/r2/instance_map_deco.cpp +++ b/code/ryzom/client/src/r2/instance_map_deco.cpp @@ -20,7 +20,7 @@ #include "r2_config.h" #include "tool.h" // -#include "../interface_v3/ctrl_quad.h" +#include "nel/gui/ctrl_quad.h" #include "../interface_v3/group_container.h" // #include "nel/misc/i18n.h" diff --git a/code/ryzom/client/src/r2/instance_map_deco.h b/code/ryzom/client/src/r2/instance_map_deco.h index 6f0f62977..074604dc7 100644 --- a/code/ryzom/client/src/r2/instance_map_deco.h +++ b/code/ryzom/client/src/r2/instance_map_deco.h @@ -21,8 +21,12 @@ #include "../interface_v3/group_map.h" #include "displayer_visual.h" +namespace NLGUI +{ + class CCtrlQuad; +} + class CGroupMap; -class CCtrlQuad; class CViewBitmap; namespace R2 diff --git a/code/ryzom/client/src/r2/prim_render.cpp b/code/ryzom/client/src/r2/prim_render.cpp index 9d6c16393..19b987e09 100644 --- a/code/ryzom/client/src/r2/prim_render.cpp +++ b/code/ryzom/client/src/r2/prim_render.cpp @@ -23,7 +23,7 @@ #include "nel/misc/time_nl.h" // #include "../interface_v3/view_bitmap.h" -#include "../interface_v3/ctrl_quad.h" +#include "nel/gui/ctrl_quad.h" #include "../interface_v3/ctrl_polygon.h" #include "../interface_v3/interface_manager.h" #include "nel/gui/view_renderer.h" diff --git a/code/ryzom/client/src/r2/tool_draw_prim.cpp b/code/ryzom/client/src/r2/tool_draw_prim.cpp index be0fdacf7..8bc8fdf99 100644 --- a/code/ryzom/client/src/r2/tool_draw_prim.cpp +++ b/code/ryzom/client/src/r2/tool_draw_prim.cpp @@ -32,7 +32,7 @@ #include "nel/misc/polygon.h" // // tmp tmp -#include "../interface_v3/ctrl_quad.h" +#include "nel/gui/ctrl_quad.h" using namespace NLMISC;