summaryrefslogtreecommitdiff
path: root/indra/llrender/llfontvertexbuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender/llfontvertexbuffer.cpp')
-rw-r--r--indra/llrender/llfontvertexbuffer.cpp157
1 files changed, 157 insertions, 0 deletions
diff --git a/indra/llrender/llfontvertexbuffer.cpp b/indra/llrender/llfontvertexbuffer.cpp
new file mode 100644
index 0000000000..3ff0771795
--- /dev/null
+++ b/indra/llrender/llfontvertexbuffer.cpp
@@ -0,0 +1,157 @@
+/**
+ * @file llfontvertexbuffer.cpp
+ * @brief Buffer storage for font rendering.
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llfontvertexbuffer.h"
+
+#include "llvertexbuffer.h"
+
+
+LLFontVertexBuffer::LLFontVertexBuffer(bool track_changes)
+: mTrackStringChanges(track_changes)
+{
+}
+
+LLFontVertexBuffer::~LLFontVertexBuffer()
+{
+ reset();
+}
+
+void LLFontVertexBuffer::reset()
+{
+ mBufferList.clear();
+}
+
+S32 LLFontVertexBuffer::render(
+ const LLFontGL* fontp,
+ const LLWString& text,
+ S32 begin_offset,
+ F32 x, F32 y,
+ const LLColor4& color,
+ LLFontGL::HAlign halign, LLFontGL::VAlign valign,
+ U8 style, LLFontGL::ShadowType shadow,
+ S32 max_chars , S32 max_pixels,
+ F32* right_x,
+ bool use_ellipses,
+ bool use_color )
+{
+ if (mBufferList.empty())
+ {
+ genBuffers(fontp, text, begin_offset, x, y, color, halign, valign,
+ style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color);
+ }
+ else if (mLastX != x || mLastY != y || mLastColor != color) // always track position and alphs
+ {
+ genBuffers(fontp, text, begin_offset, x, y, color, halign, valign,
+ style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color);
+ }
+ else if (true //mTrackStringChanges
+ && (mLastOffset != begin_offset
+ || mLastMaxChars != max_chars
+ || mLastMaxPixels != max_pixels
+ || mLastStringHash != sStringHasher._Do_hash(text))) // todo, track all parameters?
+ {
+ genBuffers(fontp, text, begin_offset, x, y, color, halign, valign,
+ style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color);
+ }
+ else
+ {
+
+ gGL.flush(); // deliberately empty pending verts
+ gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+ gGL.pushUIMatrix();
+
+ gGL.loadUIIdentity();
+
+ // Depth translation, so that floating text appears 'in-world'
+ // and is correctly occluded.
+ gGL.translatef(0.f, 0.f, LLFontGL::sCurDepth);
+
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ for (auto &buf_data : mBufferList)
+ {
+ if (buf_data.mImage)
+ {
+ gGL.getTexUnit(0)->bind(buf_data.mImage);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ buf_data.mBuffer->setBuffer();
+
+ if (LLRender::sGLCoreProfile && buf_data.mMode == LLRender::QUADS)
+ {
+ buf_data.mBuffer->drawArrays(LLRender::TRIANGLES, 0, buf_data.mCount);
+ }
+ else
+ {
+ buf_data.mBuffer->drawArrays(buf_data.mMode, 0, buf_data.mCount);
+ }
+ }
+ if (right_x)
+ {
+ *right_x = mLastRightX;
+ }
+
+ gGL.popUIMatrix();
+ }
+ return mChars;
+}
+
+void LLFontVertexBuffer::genBuffers(
+ const LLFontGL* fontp,
+ const LLWString& text,
+ S32 begin_offset,
+ F32 x, F32 y,
+ const LLColor4& color,
+ LLFontGL::HAlign halign, LLFontGL::VAlign valign,
+ U8 style, LLFontGL::ShadowType shadow,
+ S32 max_chars, S32 max_pixels,
+ F32* right_x,
+ bool use_ellipses,
+ bool use_color)
+{
+ mBufferList.clear();
+ mChars = fontp->render(text, begin_offset, x, y, color, halign, valign,
+ style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color, &mBufferList);
+
+ mLastOffset = begin_offset;
+ mLastMaxChars = max_chars;
+ mLastMaxPixels = max_pixels;
+ mLastStringHash = sStringHasher._Do_hash(text);
+ mLastX = x;
+ mLastY = y;
+ mLastColor = color;
+
+ if (right_x)
+ {
+ mLastRightX = *right_x;
+ }
+}
+