rendered paste bodydiff --git a/guilib/GUIFontTTF.cpp b/guilib/GUIFontTTF.cppindex 1a911c6..d0a00c4 100644--- a/guilib/GUIFontTTF.cpp+++ b/guilib/GUIFontTTF.cpp@@ -28,6 +28,7 @@ #include "MathUtils.h" #include "utils/log.h" #include "WindowingFactory.h"+#include "Shader.h" #include <math.h> @@ -117,6 +118,119 @@ private: CFreeTypeLibrary g_freeTypeLibrary; // our freetype library +static void glGetViewportScale(GLfloat* Rx, GLfloat* Ry)+{+ GLfloat viewport[4];+ glGetFloatv(GL_VIEWPORT, viewport);+ Rx[0] = 0.5f * (viewport[2] - viewport[0]); // X Scale+ Rx[1] = 0.5f * (viewport[2] + viewport[0]); // X Offset+ Rx[2] = - Rx[1]; // - X Offset+ Rx[3] = 1.0f / Rx[0]; // 1.0 / X Scale++ Ry[0] = 0.5f * (viewport[3] - viewport[1]); // Y Scale+ Ry[1] = 0.5f * (viewport[3] + viewport[1]); // Y Offset+ Ry[2] = - Ry[1]; // - Y Offset+ Ry[3] = 1.0f / Ry[0]; // 1.0 / Y Scale+}++#ifdef HAS_SDL_OPENGL+class CTTFShaderGLSL+ : public Shaders::CGLSLShaderProgram+{+public:+ CTTFShaderGLSL()+ {+ SetVertexShaderSource(+ "uniform vec4 Rx;"+ "uniform vec4 Ry;"+ "float round(in float a)"+ "{"+ " return(sign(a)*floor(abs(a) + 0.5));"+ "}"+ "float correct(in float a, in vec4 R)"+ "{"+ " return ( round(a * R[0] + R[1]) + R[2]) * R[3];"+ "}"+ "void main()"+ "{"+ " gl_FrontColor = gl_Color;"+ " gl_TexCoord[0] = gl_MultiTexCoord0;"+ " gl_Position = ftransform();"+ " gl_Position /= gl_Position.w;"+ " gl_Position.x = correct(gl_Position.x, Rx);"+ " gl_Position.y = correct(gl_Position.y, Ry);"+ "}"+ );+ }+ void OnCompiledAndLinked()+ {+ m_HandleRx = glGetUniformLocation(ProgramHandle(), "Rx");+ m_HandleRy = glGetUniformLocation(ProgramHandle(), "Ry");+ }++ bool OnEnabled()+ {+ GLfloat Rx[4], Ry[4];+ glGetViewportScale(Rx, Ry);+ glUniform4fv(m_HandleRx, 1, Rx);+ glUniform4fv(m_HandleRy, 1, Ry);+ return true;+ }+ GLint m_HandleRx;+ GLint m_HandleRy;+};++class CTTFShaderARB+ : public Shaders::CARBShaderProgram+{+public:+ CTTFShaderARB()+ {+ SetVertexShaderSource(+ "!!ARBvp1.0\n"+ "PARAM c[7] = { { 0.5 },\n"+ " program.local[1..2],\n"+ " state.matrix.mvp };\n"+ "TEMP R0;\n"+ "TEMP R1;\n"+ "DP4 R0.x, vertex.position, c[6];\n"+ "MOV R0.w, R0.x;\n"+ "RCP R1.x, R0.x;\n"+ "DP4 R0.z, vertex.position, c[5];\n"+ "DP4 R0.y, vertex.position, c[4];\n"+ "DP4 R0.x, vertex.position, c[3];\n"+ "MUL R0, R0, R1.x;\n"+ "MAD R0.y, R0, c[2].x, c[2];\n"+ "MAD R0.x, R0, c[1], c[1].y;\n"+ "ADD R0.y, R0, c[0].x;\n"+ "ADD R0.x, R0, c[0];\n"+ "FLR R0.y, R0;\n"+ "FLR R0.x, R0;\n"+ "ADD R0.y, R0, c[2].z;\n"+ "ADD R0.x, R0, c[1].z;\n"+ "MUL result.position.y, R0, c[2].w;\n"+ "MUL result.position.x, R0, c[1].w;\n"+ "MOV result.position.zw, R0;\n"+ "MOV result.color, vertex.color;\n"+ "MOV result.texcoord[0], vertex.texcoord[0];\n"+ "END\n"+ );+ }++ bool OnEnabled()+ {+ GLfloat Rx[4], Ry[4];+ glGetViewportScale(Rx, Ry);+ glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 1, Rx);+ glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, 2, Ry);+ VerifyGLState();+ return true;+ }+};++static class Shaders::CShaderProgram* m_Shader = NULL;+#endif+ CGUIFontTTFBase::CGUIFontTTFBase(const CStdString& strFileName) { m_texture = NULL;@@ -275,6 +399,21 @@ bool CGUIFontTTF::Load(const CStdString& strFilename, float height, float aspect Character *ellipse = GetCharacter(L'.'); if (ellipse) m_ellipsesWidth = ellipse->advance; +#ifdef HAS_SDL_OPENGL+ if(m_Shader == NULL && (GLEW_ARB_shading_language_100 || GLEW_ARB_vertex_program))+ {+ if(GLEW_ARB_shading_language_100)+ m_Shader = new CTTFShaderGLSL();+ else if(GLEW_ARB_vertex_program)+ m_Shader = new CTTFShaderARB();++ if(m_Shader->CompileAndLink())+ CLog::Log(LOGERROR, "%s - compiled font rounding shader", __FUNCTION__);+ else+ CLog::Log(LOGERROR, "%s - failed to compile rounding shader", __FUNCTION__);+ }+#endif+ return true; } @@ -627,13 +756,35 @@ void CGUIFontTTF::RenderCharacter(float posX, float posY, const Character *ch, D g_graphicsContext.ClipRect(vertex, texture); // transform our positions - note, no scaling due to GUI calibration/resolution occurs- float x[4];-+ float x[4], y[4], z[4];+ if(m_hwtransform)+ {+ // if shader is okey, we use hardware transforms+ x[0] = x[3] = vertex.x1;+ x[1] = x[2] = vertex.x2;+ y[0] = y[1] = vertex.y1;+ y[2] = y[3] = vertex.y2;+ z[0] = z[1] = z[2] = z[3] = 0.0;+ }+ else+ { x[0] = g_graphicsContext.ScaleFinalXCoord(vertex.x1, vertex.y1); x[1] = g_graphicsContext.ScaleFinalXCoord(vertex.x2, vertex.y1); x[2] = g_graphicsContext.ScaleFinalXCoord(vertex.x2, vertex.y2); x[3] = g_graphicsContext.ScaleFinalXCoord(vertex.x1, vertex.y2); + y[0] = g_graphicsContext.ScaleFinalYCoord(vertex.x1, vertex.y1);+ y[1] = g_graphicsContext.ScaleFinalYCoord(vertex.x2, vertex.y1);+ y[2] = g_graphicsContext.ScaleFinalYCoord(vertex.x2, vertex.y2);+ y[3] = g_graphicsContext.ScaleFinalYCoord(vertex.x1, vertex.y2);++#ifndef HAS_SDL_2D+ z[0] = g_graphicsContext.ScaleFinalZCoord(vertex.x1, vertex.y1);+ z[1] = g_graphicsContext.ScaleFinalZCoord(vertex.x2, vertex.y1);+ z[2] = g_graphicsContext.ScaleFinalZCoord(vertex.x2, vertex.y2);+ z[3] = g_graphicsContext.ScaleFinalZCoord(vertex.x1, vertex.y2);+#endif+ if (roundX) { // We only round the "left" side of the character, and then use the direction of rounding to@@ -655,15 +806,12 @@ void CGUIFontTTF::RenderCharacter(float posX, float posY, const Character *ch, D x[3] = rx3; } - float y1 = (float)MathUtils::round_int(g_graphicsContext.ScaleFinalYCoord(vertex.x1, vertex.y1));- float y2 = (float)MathUtils::round_int(g_graphicsContext.ScaleFinalYCoord(vertex.x2, vertex.y1));- float y3 = (float)MathUtils::round_int(g_graphicsContext.ScaleFinalYCoord(vertex.x2, vertex.y2));- float y4 = (float)MathUtils::round_int(g_graphicsContext.ScaleFinalYCoord(vertex.x1, vertex.y2));-+ for(int i=0; i<4; i++)+ {+ y[i] = ROUND_TO_PIXEL(y[i]);- float z1 = (float)MathUtils::round_int(g_graphicsContext.ScaleFinalZCoord(vertex.x1, vertex.y1));- float z2 = (float)MathUtils::round_int(g_graphicsContext.ScaleFinalZCoord(vertex.x2, vertex.y1));- float z3 = (float)MathUtils::round_int(g_graphicsContext.ScaleFinalZCoord(vertex.x2, vertex.y2));- float z4 = (float)MathUtils::round_int(g_graphicsContext.ScaleFinalZCoord(vertex.x1, vertex.y2));+ z[i] = ROUND_TO_PIXEL(z[i]);+ }+ } // tex coords converted to 0..1 range float tl = texture.x1 * m_textureScaleX;@@ -687,32 +835,24 @@ struct CUSTOMVERTEX { v[i].g = GET_G(color); v[i].b = GET_B(color); v[i].a = GET_A(color);++ v[i].x = x[i];+ v[i].y = y[i];+ v[i].z = z[i]; } #ifdef HAS_GL v[0].u = tl; v[0].v = tt;- v[0].x = x[0];- v[0].y = y1;- v[0].z = z1; v[1].u = tr; v[1].v = tt;- v[1].x = x[1];- v[1].y = y2;- v[1].z = z2; v[2].u = tr; v[2].v = tb;- v[2].x = x[2];- v[2].y = y3;- v[2].z = z3; v[3].u = tl; v[3].v = tb;- v[3].x = x[3];- v[3].y = y4;- v[3].z = z4; #else // GLES uses triangle strips, not quads, so have to rearrange the vertex order v[0].u = tl;diff --git a/guilib/GUIFontTTFGL.h b/guilib/GUIFontTTFGL.cppindex 0058fd7..2e9826e 100644--- a/guilib/GUIFontTTFGL.cpp+++ b/guilib/GUIFontTTFGL.cpp@@ -59,6 +59,8 @@ void CGUIFontTTFGL::Begin() { if (m_nestedBeginCount == 0) {+ m_hwtransform = g_graphicsContext.ApplyHardwareTransform();+ if (!m_bTextureLoaded) { // Have OpenGL generate a texture object handle for us@@ -98,6 +100,10 @@ void CGUIFontTTFGL::Begin() glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); VerifyGLState();+ + if(m_Shader && m_Shader->OK())+ m_Shader->Enable();+ #else g_Windowing.EnableGUIShader(SM_FONTS); #endif@@ -127,6 +133,9 @@ void CGUIFontTTF::End() glEnableClientState(GL_TEXTURE_COORD_ARRAY); glDrawArrays(GL_QUADS, 0, m_vertex_count); glPopClientAttrib();++ if(m_Shader && m_Shader->OK())+ m_Shader->Disable(); #else GLint posLoc = g_Windowing.GUIShaderGetPos(); GLint colLoc = g_Windowing.GUIShaderGetCol();@@ -154,6 +163,12 @@ void CGUIFontTTFGL::End() g_Windowing.DisableGUIShader(); #endif++ if(m_hwtransform)+ {+ g_graphicsContext.RestoreHardwareTransform();+ m_hwtransform = false;+ } } CBaseTexture* CGUIFontTTFGL::ReallocTexture(unsigned int& newHeight)diff --git a/guilib/GUIFontTTF.h b/guilib/GUIFontTTF.hindex 0058fd7..2e9826e 100644--- a/guilib/GUIFontTTF.h+++ b/guilib/GUIFontTTF.h@@ -157,6 +157,7 @@ protected: CStdString m_strFileName; private:+ bool m_hwtransform; int m_referenceCount; }; diff --git a/guilib/GUITexture.cpp b/guilib/GUITexture.cppindex 50e5551..7786a69 100644--- a/guilib/GUITexture.cpp+++ b/guilib/GUITexture.cpp@@ -82,6 +82,7 @@ CGUITextureBase::CGUITextureBase(float posX, float posY, float width, float heig m_allocateDynamically = false; m_isAllocated = NO; m_invalid = true;+ m_hwtransform = false; } CGUITextureBase::CGUITextureBase(const CGUITextureBase &right)@@ -247,7 +248,24 @@ void CGUITextureBase::Render(float left, float top, float right, float bottom, f float x[4], y[4], z[4]; #define ROUND_TO_PIXEL(x) (float)(MathUtils::round_int(x))+ if(m_hwtransform)+ {+ x[0] = vertex.x1;+ y[0] = vertex.y1;++ x[1] = vertex.x2;+ y[1] = vertex.y1;++ x[2] = vertex.x2;+ y[2] = vertex.y2;++ x[3] = vertex.x1;+ y[3] = vertex.y2; + z[0] = z[1] = z[2] = z[3] = 0;+ }+ else+ { x[0] = ROUND_TO_PIXEL(g_graphicsContext.ScaleFinalXCoord(vertex.x1, vertex.y1)); y[0] = ROUND_TO_PIXEL(g_graphicsContext.ScaleFinalYCoord(vertex.x1, vertex.y1)); z[0] = ROUND_TO_PIXEL(g_graphicsContext.ScaleFinalZCoord(vertex.x1, vertex.y1));@@ -263,6 +281,7 @@ void CGUITextureBase::Render(float left, float top, float right, float bottom, f if (y[2] == y[0]) y[2] += 1.0f; if (x[2] == x[0]) x[2] += 1.0f; if (y[3] == y[1]) y[3] += 1.0f; if (x[3] == x[1]) x[3] += 1.0f;+ } #define MIX_ALPHA(a,c) (((a * (c >> 24)) / 255) << 24) | (c & 0x00ffffff) diff --git a/guilib/GUITexture.h b/guilib/GUITexture.hindex e979f4f..049517b 100644--- a/guilib/GUITexture.h+++ b/guilib/GUITexture.h@@ -144,6 +144,7 @@ protected: CRect m_vertex; // vertex coords to render bool m_invalid; // if true, we need to recalculate+ bool m_hwtransform; unsigned char m_alpha; diff --git a/guilib/GUITextureGL.cpp b/guilib/GUITextureGL.cppindex 074521f..4db8afb 100644--- a/guilib/GUITextureGL.cpp+++ b/guilib/GUITextureGL.cpp@@ -68,24 +68,31 @@ void CGUITexture::Begin() glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); VerifyGLState(); }- //glDisable(GL_TEXTURE_2D); // uncomment these 2 lines to switch to wireframe rendering- //glBegin(GL_LINE_LOOP);- glBegin(GL_QUADS);+ m_hwtransform = g_graphicsContext.ApplyHardwareTransform(); } void CGUITextureGL::End() {- glEnd(); if (m_diffuse.size()) { glDisable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE0_ARB); } glDisable(GL_TEXTURE_2D);++ if(m_hwtransform)+ {+ g_graphicsContext.RestoreHardwareTransform();+ m_hwtransform = false;+ } } void CGUITextureGL::Draw(float *x, float *y, float *z, const CRect &texture, const CRect &diffuse, color_t color, int orientation) {+ //glDisable(GL_TEXTURE_2D); // uncomment these 2 lines to switch to wireframe rendering+ //glBegin(GL_LINE_LOOP);+ glBegin(GL_QUADS);+ GLubyte a = (GLubyte)GET_A(color); GLubyte r = (GLubyte)GET_R(color); GLubyte g = (GLubyte)GET_G(color);@@ -134,6 +141,8 @@ void CGUITexture::Draw(float *x, float *y, float *z, const CRect &texture, const glMultiTexCoord2fARB(GL_TEXTURE1_ARB, diffuse.x1, diffuse.y2); } glVertex3f(x[3], y[3], z[3]);++ glEnd(); } void CGUITextureGL::DrawQuad(const CRect &rect, color_t color, CBaseTexture *texture, const CRect *texCoords)diff --git a/guilib/GraphicContext.cpp b/guilib/GraphicContext.cppindex 646a39e..e4d3d3f 100644--- a/guilib/GraphicContext.cpp+++ b/guilib/GraphicContext.cpp@@ -749,9 +749,9 @@ void CGraphicContext::Flip() g_Windowing.PresentRender(); } -void CGraphicContext::ApplyHardwareTransform()+bool CGraphicContext::ApplyHardwareTransform() {- g_Windowing.ApplyHardwareTransform(m_finalTransform);+ return g_Windowing.ApplyHardwareTransform(m_finalTransform); } void CGraphicContext::RestoreHardwareTransform()diff --git a/guilib/GraphicContext.h b/guilib/GraphicContext.hindex 782d1a3..72ade75 100644--- a/guilib/GraphicContext.h+++ b/guilib/GraphicContext.h@@ -128,7 +128,7 @@ public: void RestoreCameraPosition(); bool SetClipRegion(float x, float y, float w, float h); void RestoreClipRegion();- void ApplyHardwareTransform();+ bool ApplyHardwareTransform(); void RestoreHardwareTransform(); void ClipRect(CRect &vertex, CRect &texture, CRect *diffuse = NULL); void ClipToViewWindow();