| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- #include <OgreFontManager.h>
- #include <OgreHardwareBufferManager.h>
- #include <OgreMaterialManager.h>
- #include "core/Logger.h"
- #include "core/UiManager.h"
- #include "core/UiTextArea.h"
- UiTextArea::UiTextArea(const Ogre::String& name):
- UiWidget(name)
- {
- Initialise();
- }
- UiTextArea::UiTextArea(const Ogre::String& name, const Ogre::String& path_name, UiWidget* parent):
- UiWidget(name, path_name, parent)
- {
- Initialise();
- }
- UiTextArea::~UiTextArea()
- {
- DestroyVertexBuffer();
- }
- void
- UiTextArea::Initialise()
- {
- m_Font = nullptr;
- m_MaxLetters = 0;
- m_TextAlign = UiTextArea::LEFT;
- m_Text = "";
- m_TextNode = nullptr;
- m_SceneManager = Ogre::Root::getSingleton().getSceneManager("Scene");
- m_RenderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem();
- CreateVertexBuffer();
- }
- void
- UiTextArea::Update()
- {
- UiWidget::Update();
- }
- void
- UiTextArea::Render()
- {
- if(m_Visible == true)
- {
- if(m_RenderOp.vertexData->vertexCount != 0)
- {
- m_RenderSystem->_setWorldMatrix(Ogre::Matrix4::IDENTITY);
- m_RenderSystem->_setProjectionMatrix(Ogre::Matrix4::IDENTITY);
- m_RenderSystem->_setViewMatrix(Ogre::Matrix4::IDENTITY);
- m_SceneManager->_setPass(m_Material->getTechnique(0)->getPass(0), true, false);
- m_RenderSystem->setScissorTest(true, m_ScissorLeft, m_ScissorTop, m_ScissorRight, m_ScissorBottom);
- m_RenderSystem->_render(m_RenderOp);
- m_RenderSystem->setScissorTest(false);
- }
- }
- UiWidget::Render();
- }
- void
- UiTextArea::UpdateTransformation()
- {
- UiWidget::UpdateTransformation();
- UpdateGeometry();
- }
- void
- UiTextArea::SetTextAlign(const TextAlign align)
- {
- m_TextAlign = align;
- }
- void
- UiTextArea::SetText(const Ogre::UTFString& text)
- {
- m_Text = text;
- }
- void
- UiTextArea::SetText(TiXmlNode* text)
- {
- m_TextNode = text;
- }
- void
- UiTextArea::SetFont(const Ogre::String& font)
- {
- m_Font = UiManager::getSingleton().GetFont(font);
- if(m_Font == nullptr)
- {
- LOG_ERROR("Could not find font \"" + font + "\" for \"" + m_PathName + "\".");
- return;
- }
- m_Material = Ogre::MaterialManager::getSingleton().create("UiMaterials." + m_PathName, "General");
- Ogre::Pass* pass = m_Material->getTechnique(0)->getPass(0);
- pass->setVertexColourTracking(Ogre::TVC_AMBIENT);
- pass->setCullingMode(Ogre::CULL_NONE);
- pass->setDepthCheckEnabled(false);
- pass->setDepthWriteEnabled(false);
- pass->setLightingEnabled(false);
- pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
- pass->setAlphaRejectFunction(Ogre::CMPF_GREATER);
- pass->setAlphaRejectValue(0);
- Ogre::TextureUnitState* tex = pass->createTextureUnitState();
- tex->setTextureName(m_Font->GetImageName());
- tex->setNumMipmaps(-1);
- tex->setTextureFiltering(Ogre::TFO_NONE);
- }
- void
- UiTextArea::UpdateGeometry()
- {
- if(m_Font == nullptr)
- {
- LOG_ERROR("Font for \"" + m_PathName + "\" if not set.");
- return;
- }
- if(m_Text.size() > m_MaxLetters)
- {
- LOG_ERROR("Max number of text reached in \"" + m_PathName + "\". Can't render text \"" + m_Text + "\". Max number of letters is " + Ogre::StringConverter::toString(m_MaxLetters) + ".");
- return;
- }
- float length = 0;
- if(m_TextAlign != LEFT)
- {
- if(m_TextNode != nullptr)
- {
- length = GetTextLengthFromNode(m_TextNode);
- }
- else
- {
- length = GetTextLength(m_Text);
- }
- if(m_TextAlign == CENTER)
- {
- length /= 2;
- }
- }
- TextBlockData data;
- data.local_x1 = -m_FinalOrigin.x - length;
- data.local_y1 = -m_FinalOrigin.y;
- data.position = 0;
- TextStyle style;
- style.colour = m_Colour1;
- if(m_TextNode != nullptr)
- {
- SetTextGeometryFromNode(m_TextNode, data, style);
- }
- else
- {
- SetTextGeometry(m_Text, data, style);
- }
- }
- float
- UiTextArea::GetTextLengthFromNode(TiXmlNode* node) const
- {
- float length = 0;
- while(node != nullptr)
- {
- switch(node->Type())
- {
- case TiXmlNode::TINYXML_TEXT:
- {
- TiXmlText* childText = node->ToText();
- if(childText)
- {
- length += GetTextLength(childText->Value());
- }
- }
- break;
- case TiXmlNode::TINYXML_ELEMENT:
- {
- length +=GetTextLengthFromNode(node->FirstChild());
- }
- break;
- }
- node = node->NextSibling();
- }
- return length;
- }
- float
- UiTextArea::GetTextLength(const Ogre::UTFString& text) const
- {
- float length = 0;
- for(size_t i = 0; i < text.size(); ++i)
- {
- UiCharData char_data = m_Font->GetCharData(text[i]);
- length += (char_data.pre + char_data.width + char_data.post) * m_FinalScale.x * m_ScreenHeight / 720.0f;
- }
- return length;
- }
- void
- UiTextArea::SetTextGeometryFromNode(TiXmlNode* node, TextBlockData& data, const TextStyle& style)
- {
- while(node != nullptr)
- {
- switch(node->Type())
- {
- case TiXmlNode::TINYXML_TEXT:
- {
- TiXmlText* childText = node->ToText();
- if(childText)
- {
- SetTextGeometry(childText->Value(), data, style);
- }
- }
- break;
- case TiXmlNode::TINYXML_ELEMENT:
- {
- TextStyle style_child;
- style_child.colour = style.colour;
- Ogre::String name = node->ValueStr();
- if(name == "colour")
- {
- style_child.colour = Ogre::StringConverter::parseColourValue(node->ToElement()->Attribute("value"));
- }
- TiXmlNode* node_child = node->FirstChild();
- SetTextGeometryFromNode(node_child, data, style_child);
- }
- break;
- }
- node = node->NextSibling();
- }
- }
- void
- UiTextArea::SetTextGeometry(const Ogre::UTFString& text, TextBlockData& data, const TextStyle& style)
- {
- float* writeIterator = (float*) m_VertexBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL);
- writeIterator += data.position * 9 * 6;
- m_RenderOp.vertexData->vertexCount = data.position * 6;
- float local_x1 = data.local_x1;
- float local_y1 = data.local_y1;
- float x = m_FinalTranslate.x;
- float y = m_FinalTranslate.y;
- for(auto &c : text)
- {
- UiCharData char_data = m_Font->GetCharData(c);
- local_x1 += char_data.pre * m_FinalScale.x * m_ScreenHeight / 720.0f;
- float local_x2 = local_x1 + char_data.width * m_FinalScale.x * m_ScreenHeight / 720.0f;
- float local_y2 = local_y1 + char_data.height * m_FinalScale.y * m_ScreenHeight / 720.0f;
- int x1, y1, x2, y2, x3, y3, x4, y4;
- if(m_FinalRotation != 0)
- {
- float cos = Ogre::Math::Cos(Ogre::Radian(Ogre::Degree(m_FinalRotation)));
- float sin = Ogre::Math::Sin(Ogre::Radian(Ogre::Degree(m_FinalRotation)));
- x1 = static_cast<int>(local_x1 * cos - local_y1 * sin + x);
- y1 = static_cast<int>(local_x1 * sin + local_y1 * cos + y);
- x2 = static_cast<int>(local_x2 * cos - local_y1 * sin + x);
- y2 = static_cast<int>(local_x2 * sin + local_y1 * cos + y);
- x3 = static_cast<int>(local_x2 * cos - local_y2 * sin + x);
- y3 = static_cast<int>(local_x2 * sin + local_y2 * cos + y);
- x4 = static_cast<int>(local_x1 * cos - local_y2 * sin + x);
- y4 = static_cast<int>(local_x1 * sin + local_y2 * cos + y);
- }
- else
- {
- x1 = static_cast<int>(local_x1 + x);
- y1 = static_cast<int>(local_y1 + y);
- x2 = static_cast<int>(local_x2 + x);
- y2 = static_cast<int>(local_y1 + y);
- x3 = static_cast<int>(local_x2 + x);
- y3 = static_cast<int>(local_y2 + y);
- x4 = static_cast<int>(local_x1 + x);
- y4 = static_cast<int>(local_y2 + y);
- }
- local_x1 += (char_data.width + char_data.post) * m_FinalScale.x * m_ScreenHeight / 720.0f;
- float width = static_cast<float>(m_Font->GetImageWidth());
- float height = static_cast<float>(m_Font->GetImageHeight());
- Ogre::Vector3 coords[4] = {
- Ogre::Vector3((x1 / m_ScreenWidth) * 2 - 1, -((y1 / m_ScreenHeight) * 2 - 1), m_FinalZ),
- Ogre::Vector3((x2 / m_ScreenWidth) * 2 - 1, -((y2 / m_ScreenHeight) * 2 - 1), m_FinalZ),
- Ogre::Vector3((x3 / m_ScreenWidth) * 2 - 1, -((y3 / m_ScreenHeight) * 2 - 1), m_FinalZ),
- Ogre::Vector3((x4 / m_ScreenWidth) * 2 - 1, -((y4 / m_ScreenHeight) * 2 - 1), m_FinalZ)
- };
- auto texture = Ogre::FloatRect(
- (float)char_data.x / width, // left
- (float)char_data.y / height, // top
- (float)(char_data.x + char_data.width) / width, // right
- (float)(char_data.y + char_data.height) / height // bottom
- );
- Ogre::ColourValue colour = style.colour;
- // draw two triangles with a colour and texture.
- WriteGlyph(writeIterator, coords, colour, texture);
- m_RenderOp.vertexData->vertexCount += 6;
- data.position += 1;
- }
- m_VertexBuffer->unlock();
- data.local_x1 = local_x1;
- data.local_y1 = local_y1;
- }
- void
- UiTextArea::CreateVertexBuffer()
- {
- m_MaxLetters = 1024;
- m_RenderOp.vertexData = new Ogre::VertexData;
- m_RenderOp.vertexData->vertexStart = 0;
- Ogre::VertexDeclaration* vDecl = m_RenderOp.vertexData->vertexDeclaration;
- size_t offset = 0;
- vDecl->addElement(0, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
- offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
- vDecl->addElement(0, offset, Ogre::VET_FLOAT4, Ogre::VES_DIFFUSE);
- offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT4);
- vDecl->addElement(0, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES);
- m_VertexBuffer = Ogre::HardwareBufferManager::getSingletonPtr()->createVertexBuffer(vDecl->getVertexSize(0), m_MaxLetters * 6, Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY, false);
- m_RenderOp.vertexData->vertexBufferBinding->setBinding(0, m_VertexBuffer);
- m_RenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
- m_RenderOp.useIndexes = false;
- }
- void
- UiTextArea::DestroyVertexBuffer()
- {
- delete m_RenderOp.vertexData;
- m_RenderOp.vertexData = 0;
- m_VertexBuffer.setNull();
- m_MaxLetters = 0;
- }
|