Skip to content

Commit

Permalink
OpenGL: Improved GLSL rendering of rounded rectangles
Browse files Browse the repository at this point in the history
- better (correct) line sizing for thicker lines.
- only operate on the alpha channel, which avoids some minor rendering
oddities on the outside edge of rendered curves.
  • Loading branch information
Mark Kendall committed Mar 12, 2011
1 parent 3d3c055 commit 460766d
Showing 1 changed file with 20 additions and 22 deletions.
42 changes: 20 additions & 22 deletions mythtv/libs/libmythui/mythrender_opengl2.cpp
Expand Up @@ -78,7 +78,7 @@ static const QString kCircleFragmentShader =
"{\n"
" float dis = distance(v_position.xy, u_parameters[0].xy);\n"
" float mult = smoothstep(u_parameters[0].z, u_parameters[0].w, dis);\n"
" gl_FragColor = v_color * mult;\n"
" gl_FragColor = v_color * vec4(1.0, 1.0, 1.0, mult);\n"
"}\n";

static const QString kCircleEdgeFragmentShader =
Expand All @@ -91,36 +91,34 @@ static const QString kCircleEdgeFragmentShader =
" float dis = distance(v_position.xy, u_parameters[0].xy);\n"
" float rad = u_parameters[0].z;\n"
" float wid = u_parameters[0].w;\n"
" float mult = smoothstep(rad + wid, rad, dis) * smoothstep(rad - wid, rad, dis);\n"
" gl_FragColor = v_color * mult;\n"
" float mult = smoothstep(rad + wid, rad + (wid - 1.0), dis) * smoothstep(rad - (wid + 1.0), rad - wid, dis);\n"
" gl_FragColor = v_color * vec4(1.0, 1.0, 1.0, mult);\n"
"}\n";

static const QString kVertLineFragmentShader =
"GLSL_DEFINES"
"#define Y u_parameters[0].y\n"
"varying vec4 v_color;\n"
"varying vec2 v_position;\n"
"uniform mat4 u_parameters;\n"
"void main(void)\n"
"{\n"
" float dis = abs(u_parameters[0].x - v_position.x);\n"
" float wid = Y * 2.0;\n"
" float mult = smoothstep(Y + wid, Y, dis) * smoothstep(Y - wid, Y, dis);\n"
" gl_FragColor = v_color * mult;\n"
" float y = u_parameters[0].y * 2.0;\n"
" float mult = smoothstep(y, y - 0.1, dis) * smoothstep(-0.1, 0.0, dis);\n"
" gl_FragColor = v_color * vec4(1.0, 1.0, 1.0, mult);\n"
"}\n";

static const QString kHorizLineFragmentShader =
"GLSL_DEFINES"
"#define X u_parameters[0].y\n"
"varying vec4 v_color;\n"
"varying vec2 v_position;\n"
"uniform mat4 u_parameters;\n"
"void main(void)\n"
"{\n"
" float dis = abs(u_parameters[0].x - v_position.y);\n"
" float wid = X * 2.0;\n"
" float mult = smoothstep(X + wid, X, dis) * smoothstep(X - wid, X, dis);\n"
" gl_FragColor = v_color * mult;\n"
" float x = u_parameters[0].y * 2.0;\n"
" float mult = smoothstep(x, x - 0.1, dis) * smoothstep(-0.1, 0.0, dis);\n"
" gl_FragColor = v_color * vec4(1.0, 1.0, 1.0, mult);\n"
"}\n";

class MythGLShaderObject
Expand Down Expand Up @@ -519,7 +517,7 @@ void MythRenderOpenGL2::DrawRoundRectPriv(const QRect &area, int cornerRadius,

// Set the radius
m_parameters[0][2] = rad;
m_parameters[0][3] = rad - 1; // ??
m_parameters[0][3] = rad - 1.0;

// Enable the Circle shader
SetShaderParams(elip, &m_projection[0][0], "u_projection");
Expand Down Expand Up @@ -605,8 +603,8 @@ void MythRenderOpenGL2::DrawRoundRectPriv(const QRect &area, int cornerRadius,
(linePen.color().alpha() / 255.0) * (alpha / 255.0));

// Set the radius and width
m_parameters[0][2] = rad - linePen.width();
m_parameters[0][3] = 2 * linePen.width();
m_parameters[0][2] = rad - linePen.width() / 2.0 + 0.5;
m_parameters[0][3] = linePen.width() / 2.0 + 0.25;

// Enable the edge shader
SetShaderParams(edge, &m_projection[0][0], "u_projection");
Expand Down Expand Up @@ -653,12 +651,12 @@ void MythRenderOpenGL2::DrawRoundRectPriv(const QRect &area, int cornerRadius,

// Vertical lines
SetShaderParams(vline, &m_projection[0][0], "u_projection");
m_parameters[0][1] = linePen.width();
m_parameters[0][1] = linePen.width() / 2.0;
QRect vl(area.left(), area.top() + rad,
2 * linePen.width(), area.height() - dia);
linePen.width(), area.height() - dia);

// Draw the left line segment
m_parameters[0][0] = vl.left();
m_parameters[0][0] = vl.left() + linePen.width();
SetShaderParams(vline, &m_parameters[0][0], "u_parameters");
GetCachedVBO(GL_TRIANGLE_STRIP, vl);
m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
Expand All @@ -667,7 +665,7 @@ void MythRenderOpenGL2::DrawRoundRectPriv(const QRect &area, int cornerRadius,
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Draw the right line segment
vl.translate(area.width() - 2 * linePen.width(), 0);
vl.translate(area.width() - linePen.width(), 0);
m_parameters[0][0] = vl.left();
SetShaderParams(vline, &m_parameters[0][0], "u_parameters");
GetCachedVBO(GL_TRIANGLE_STRIP, vl);
Expand All @@ -676,13 +674,13 @@ void MythRenderOpenGL2::DrawRoundRectPriv(const QRect &area, int cornerRadius,
(const void *) kVertexOffset);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Vertical lines
// Horizontal lines
SetShaderParams(hline, &m_projection[0][0], "u_projection");
QRect hl(area.left() + rad, area.top(),
area.width() - dia, 2 * linePen.width());
area.width() - dia, linePen.width());

// Draw the top line segment
m_parameters[0][0] = hl.top();
m_parameters[0][0] = hl.top() + linePen.width();
SetShaderParams(hline, &m_parameters[0][0], "u_parameters");
GetCachedVBO(GL_TRIANGLE_STRIP, hl);
m_glVertexAttribPointer(VERTEX_INDEX, VERTEX_SIZE, GL_FLOAT, GL_FALSE,
Expand All @@ -691,7 +689,7 @@ void MythRenderOpenGL2::DrawRoundRectPriv(const QRect &area, int cornerRadius,
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Draw the bottom line segment
hl.translate(0, area.height() - 2 * linePen.width());
hl.translate(0, area.height() - linePen.width());
m_parameters[0][0] = hl.top();
SetShaderParams(hline, &m_parameters[0][0], "u_parameters");
GetCachedVBO(GL_TRIANGLE_STRIP, hl);
Expand Down

0 comments on commit 460766d

Please sign in to comment.