aboutsummaryrefslogtreecommitdiff
path: root/xbmc/guilib/GUIFontTTFGL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/guilib/GUIFontTTFGL.cpp')
-rw-r--r--xbmc/guilib/GUIFontTTFGL.cpp118
1 files changed, 68 insertions, 50 deletions
diff --git a/xbmc/guilib/GUIFontTTFGL.cpp b/xbmc/guilib/GUIFontTTFGL.cpp
index 529078811e..3706883911 100644
--- a/xbmc/guilib/GUIFontTTFGL.cpp
+++ b/xbmc/guilib/GUIFontTTFGL.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2018 Team Kodi
+ * Copyright (C) 2005-2024 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
@@ -65,7 +65,18 @@ bool CGUIFontTTFGL::FirstBegin()
internalFormat = GL_R8;
else
internalFormat = GL_LUMINANCE;
+
renderSystem->EnableShader(ShaderMethodGL::SM_FONTS);
+ if (renderSystem->ScissorsCanEffectClipping())
+ {
+ m_scissorClip = true;
+ }
+ else
+ {
+ m_scissorClip = false;
+ renderSystem->ResetScissors();
+ renderSystem->EnableShader(ShaderMethodGL::SM_FONTS_SHADER_CLIP);
+ }
if (m_textureStatus == TEXTURE_REALLOCATED)
{
@@ -129,6 +140,9 @@ bool CGUIFontTTFGL::FirstBegin()
void CGUIFontTTFGL::LastEnd()
{
+ // static vertex arrays are not supported anymore
+ assert(m_vertex.empty());
+
CWinSystemBase* const winSystem = CServiceBroker::GetWinSystem();
if (!winSystem)
return;
@@ -138,7 +152,9 @@ void CGUIFontTTFGL::LastEnd()
GLint posLoc = renderSystem->ShaderGetPos();
GLint colLoc = renderSystem->ShaderGetCol();
GLint tex0Loc = renderSystem->ShaderGetCoord0();
- GLint modelLoc = renderSystem->ShaderGetModel();
+ GLint clipUniformLoc = renderSystem->ShaderGetClip();
+ GLint coordStepUniformLoc = renderSystem->ShaderGetCoordStep();
+ GLint matrixUniformLoc = renderSystem->ShaderGetMatrix();
CreateStaticVertexBuffers();
@@ -147,44 +163,6 @@ void CGUIFontTTFGL::LastEnd()
glEnableVertexAttribArray(colLoc);
glEnableVertexAttribArray(tex0Loc);
- if (!m_vertex.empty())
- {
-
- // Deal with vertices that had to use software clipping
- std::vector<SVertex> vecVertices(6 * (m_vertex.size() / 4));
- SVertex* vertices = &vecVertices[0];
- for (size_t i = 0; i < m_vertex.size(); i += 4)
- {
- *vertices++ = m_vertex[i];
- *vertices++ = m_vertex[i + 1];
- *vertices++ = m_vertex[i + 2];
-
- *vertices++ = m_vertex[i + 1];
- *vertices++ = m_vertex[i + 3];
- *vertices++ = m_vertex[i + 2];
- }
- vertices = &vecVertices[0];
-
- GLuint VertexVBO;
-
- glGenBuffers(1, &VertexVBO);
- glBindBuffer(GL_ARRAY_BUFFER, VertexVBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(SVertex) * vecVertices.size(), &vecVertices[0],
- GL_STATIC_DRAW);
-
- glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex),
- reinterpret_cast<const GLvoid*>(offsetof(SVertex, x)));
- glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex),
- reinterpret_cast<const GLvoid*>(offsetof(SVertex, r)));
- glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex),
- reinterpret_cast<const GLvoid*>(offsetof(SVertex, u)));
-
- glDrawArrays(GL_TRIANGLES, 0, vecVertices.size());
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glDeleteBuffers(1, &VertexVBO);
- }
-
if (!m_vertexTrans.empty())
{
// Deal with the vertices that can be hardware clipped and therefore translated
@@ -211,14 +189,55 @@ void CGUIFontTTFGL::LastEnd()
// skip empty clip
if (clip.IsEmpty())
continue;
+ }
+
+ if (m_scissorClip)
+ {
+ // clip using scissors
renderSystem->SetScissors(clip);
}
+ else
+ {
+ // clip using vertex shader
+ renderSystem->ResetScissors();
+
+ float x1 =
+ m_vertexTrans[i].m_clip.x1 - m_vertexTrans[i].m_translateX - m_vertexTrans[i].m_offsetX;
+ float y1 =
+ m_vertexTrans[i].m_clip.y1 - m_vertexTrans[i].m_translateY - m_vertexTrans[i].m_offsetY;
+ float x2 =
+ m_vertexTrans[i].m_clip.x2 - m_vertexTrans[i].m_translateX - m_vertexTrans[i].m_offsetX;
+ float y2 =
+ m_vertexTrans[i].m_clip.y2 - m_vertexTrans[i].m_translateY - m_vertexTrans[i].m_offsetY;
+
+ glUniform4f(clipUniformLoc, x1, y1, x2, y2);
+
+ // setup texture step
+ float stepX = context.GetGUIScaleX() / (static_cast<float>(m_textureWidth));
+ float stepY = context.GetGUIScaleY() / (static_cast<float>(m_textureHeight));
+ glUniform4f(coordStepUniformLoc, stepX, stepY, 1.0f, 1.0f);
+ }
- // Apply the translation to the currently active (top-of-stack) model view matrix
- glMatrixModview.Push();
- glMatrixModview.Get().Translatef(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY,
- m_vertexTrans[i].m_translateZ);
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glMatrixModview.Get());
+ // calculate the fractional offset to the ideal position
+ float fractX =
+ context.ScaleFinalXCoord(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY);
+ float fractY =
+ context.ScaleFinalYCoord(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY);
+ fractX = -fractX + std::round(fractX);
+ fractY = -fractY + std::round(fractY);
+
+ // proj * model * gui * scroll * translation * scaling * correction factor
+ CMatrixGL matrix = glMatrixProject.Get();
+ matrix.MultMatrixf(glMatrixModview.Get());
+ matrix.MultMatrixf(CMatrixGL(context.GetGUIMatrix()));
+ matrix.Translatef(m_vertexTrans[i].m_offsetX, m_vertexTrans[i].m_offsetY, 0.0f);
+ matrix.Translatef(m_vertexTrans[i].m_translateX, m_vertexTrans[i].m_translateY, 0.0f);
+ // the gui matrix messes with the scale. correct it here for now.
+ matrix.Scalef(context.GetGUIScaleX(), context.GetGUIScaleY(), 1.0f);
+ // the gui matrix doesn't align to exact pixel coords atm. correct it here for now.
+ matrix.Translatef(fractX, fractY, 0.0f);
+
+ glUniformMatrix4fv(matrixUniformLoc, 1, GL_FALSE, matrix);
// Bind the buffer to the OpenGL context's GL_ARRAY_BUFFER binding point
glBindBuffer(GL_ARRAY_BUFFER, m_vertexTrans[i].m_vertexBuffer->bufferHandle);
@@ -245,13 +264,12 @@ void CGUIFontTTFGL::LastEnd()
glDrawElements(GL_TRIANGLES, 6 * count, GL_UNSIGNED_SHORT, 0);
}
-
- glMatrixModview.Pop();
}
+
// Restore the original scissor rectangle
- renderSystem->SetScissors(scissor);
- // Restore the original model view matrix
- glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glMatrixModview.Get());
+ if (m_scissorClip)
+ renderSystem->SetScissors(scissor);
+
// Unbind GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);