0

glLineWidth guarantees to support only width 1. On Windows, it's limited to width 10. To overcome this limitation, the common suggestion is to "simply" render a rectangle instead.

Since this seems like a basic requirement (render 2D/3D lines of arbitrary width, mesh wireframe, etc.), I was wondering if anyone has a code snippet for it.

It would work similar to what the legacy OpenGL offers. Input: two 3D points and width. Output: It would render a 3D line that faces the camera with width in pixels.

Emphasis:

  • It needs to face the camera.
  • The width is in screen pixels.

Since it's a 3D (flat) line, these properties aren't defined properly. So, I guess it would be something like "as much as possible" and "on average" (whatever that means). This is probably why glLineWidth is limited.

Zohar Levi
  • 614
  • 6
  • 16
  • Thats' more a mathematical problem. You need to find 4 points, to make rectangle from a line. It's also a problem you should at least try to solve on your own first. And why do you assume the flat lines would not be defined properly in 3D? You gave a very specific definition of the rectangle you want to get. – Lukas-T Dec 30 '19 at 09:05
  • You could probably use a geometry shader to generate the right rectangle in screen space. – user253751 Dec 30 '19 at 13:43
  • Sadly that is not an easy task. Of course it is easy to generate rectangles for each line (possibly in a [Geometry Shader](https://www.khronos.org/opengl/wiki/Geometry_Shader)). But what is with the transitions between line segments, along a polygon. Assembling rectangles would look weird. You have to create a geometry with miters between the line segments. Possibly the `GL_LINE_STRIP_ADJACENCY` [`Primitive`](https://www.khronos.org/opengl/wiki/Primitive) will help. – Rabbid76 Dec 30 '19 at 15:27
  • If your goal is to render mesh wireframes, then there's a way to do that through a fragment shader (discard interior fragments based on their non-perspective barycentric coordinates, otherwise fill with color). granted, it's not quite equivalent, but might be much simpler and faster than generating a ton of thin rectangles. – Yakov Galka Jan 02 '20 at 06:29

1 Answers1

0

Something basic that doesn't answer the nuances, which is enough for me at the moment (for now, only 2D lines, for given world thickness):

GLUquadricObj *pQuadric = gluNewQuadric();
glPushMatrix();
// flatten y to make a rectangle
glm::dmat4 S = glm::scale( glm::dvec3(1., 0.001 / radius, 1.) );
// translate
glm::dmat4 T = glm::translate( toPoint<glm::dvec3>(p0) );
// rotate
glm::dvec3 xaxis(1, 0, 0);
glm::dmat4 R1 = glm::rotate( -M_PI / 2, xaxis );
glm::dvec3 u( toPoint<glm::dvec3>(p1 - p0) );
u = glm::normalize( u );
glm::dvec3 yaxis(0, 1, 0);
glm::dmat4 R2 = glm::orientation(u, yaxis);
// combine transforms
glm::dmat4 A = T * R2 * R1 * S;
glMultMatrixd( (double*)&A[0] );
glGetDoublev(GL_MODELVIEW_MATRIX, (double*)&A[0]);
gluCylinder(pQuadric, radius, radius, height, 4, 1);
glPopMatrix();
gluDeleteQuadric(pQuadric);
Zohar Levi
  • 614
  • 6
  • 16