I need to draw a smooth line in OpenGL and here is what I have done:
glEnable( GL_LINE_SMOOTH );
glEnable( GL_POLYGON_SMOOTH );
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
glBegin( GL_LINE_STRIP );
for( UINT uiPoint = 0; uiPoint < iNumPoints; ++uiPoint )
{
const Coord &Node = vecPoints[uiPoint];
glVertex3f( Node.x, Node.y, Node.z );
}
glEnd();
What else I can do?
You can generate thin, screen-oriented polygons instead, and set the fragment's alpha according to the distance to the line.
Example :
a (0,1) b (0,1)
+--------------------------------------+
A | | B
----+--------------------------------------+----
| |
+--------------------------------------+
d (0,0) c (0,0)
Suppose you want to draw segment [AB].
- Draw polygon abcd instead
- Map the UVs (the (0,0) , (0,1))
- bind a 8x1 black and white texture that is white only on the center
- render with a fragment shader that set gl_FragColor.a from the texture
(more or less the technique used in ShaderX5)
But do this only if you can't use MSAA.
You also need to turn on blending for line smoothing to work. Try:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
and then drawing lines. It may also help to set the line width to a non-integral width.
As others have mentioned, this won't smooth polygon edges, but it will create antialiased lines.
GL_POLYGON_SMOOTH by itself does you no good. You need to force antialiasing when OpenGL context is created. What do you use to create OpenGL window? See if it supports antialiasing among its parameters. Or you could force antialiasing for all OpenGL programs with Nvidia or ATI tools... It all depends on your setup.
As another answer mentioned, enabling antialiasing helps - how to enable this depends on your context creation, but this info will hopefully be of use for GLFW users.
If using GLFW 2:
glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4);
If using GLFW 3:
glfwWindowHint(GLFW_SAMPLES, 4);
...or whatever number of antialiasing samples you prefer. The above hints need to be set before opening the GLFW window.
There is no guarantee the GL_LINE_SMOOTH
or GL_POLYGON_SMOOTH
will do anything.
Although they look like core functionality my experience is that lots of hardware doesn't implement these - the ones that do don't implement it consistently, and if they do implement it the performance hit can be considerable. if you look at the OpenGL specification documents - these provide excellent reference for the whole library, however you won't find any mention of these in there because they aren't part of the spec. You can confirm this to some degree by looking at the spec for glEnable: khronos.org/opengles/sdk/docs/man/xhtml/glEnable.xml
Nanovg is a 2D drawing package that renders to OpenGL. I have used it alongside regular OpenGL to do filled and stroked 2D paths and lines. https://github.com/memononen/nanovg