All pastes #1856161 Raw Edit

Something

public diff v1 · immutable
#1856161 ·published 2010-04-03 23:17 UTC
rendered paste body
diff --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();