diff options
Diffstat (limited to 'xbmc/guilib/GUIFontTTFGLES.cpp')
-rw-r--r-- | xbmc/guilib/GUIFontTTFGLES.cpp | 102 |
1 files changed, 64 insertions, 38 deletions
diff --git a/xbmc/guilib/GUIFontTTFGLES.cpp b/xbmc/guilib/GUIFontTTFGLES.cpp index c00a601319..67cceae441 100644 --- a/xbmc/guilib/GUIFontTTFGLES.cpp +++ b/xbmc/guilib/GUIFontTTFGLES.cpp @@ -62,6 +62,17 @@ bool CGUIFontTTFGLES::FirstBegin() GLenum pixformat = GL_ALPHA; // deprecated GLenum internalFormat = GL_ALPHA; + if (renderSystem->ScissorsCanEffectClipping()) + { + m_scissorClip = true; + } + else + { + m_scissorClip = false; + renderSystem->ResetScissors(); + renderSystem->EnableGUIShader(ShaderMethodGLES::SM_FONTS_SHADER_CLIP); + } + if (m_textureStatus == TEXTURE_REALLOCATED) { if (glIsTexture(m_nTexture)) @@ -124,6 +135,9 @@ bool CGUIFontTTFGLES::FirstBegin() void CGUIFontTTFGLES::LastEnd() { + // static vertex arrays are not supported anymore + assert(m_vertex.empty()); + CWinSystemBase* const winSystem = CServiceBroker::GetWinSystem(); if (!winSystem) return; @@ -134,7 +148,9 @@ void CGUIFontTTFGLES::LastEnd() GLint posLoc = renderSystem->GUIShaderGetPos(); GLint colLoc = renderSystem->GUIShaderGetCol(); GLint tex0Loc = renderSystem->GUIShaderGetCoord0(); - GLint modelLoc = renderSystem->GUIShaderGetModel(); + GLint clipUniformLoc = renderSystem->GUIShaderGetClip(); + GLint coordStepUniformLoc = renderSystem->GUIShaderGetCoordStep(); + GLint matrixUniformLoc = renderSystem->GUIShaderGetMatrix(); CreateStaticVertexBuffers(); @@ -143,35 +159,6 @@ void CGUIFontTTFGLES::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]; - - glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, sizeof(SVertex), - reinterpret_cast<char*>(vertices) + offsetof(SVertex, x)); - glVertexAttribPointer(colLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(SVertex), - reinterpret_cast<char*>(vertices) + offsetof(SVertex, r)); - glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, GL_FALSE, sizeof(SVertex), - reinterpret_cast<char*>(vertices) + offsetof(SVertex, u)); - - glDrawArrays(GL_TRIANGLES, 0, vecVertices.size()); - } - if (!m_vertexTrans.empty()) { // Deal with the vertices that can be hardware clipped and therefore translated @@ -198,14 +185,54 @@ void CGUIFontTTFGLES::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); @@ -236,9 +263,8 @@ void CGUIFontTTFGLES::LastEnd() 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); |