1

How to calculate a thickness as a fixed width like OpenGL does?

Drawing lines with OpenGL using GL_LINES is projection independent (if I can call it like this). I'd like to achieve the same effect with GL_TRIANGLE_FAN.

I've got the following setup of vertices in pseudocode

void DrawLine(const std::pair<float, float>& a, const std::pair<float, float>& b, float thickness)
{
    const auto [ax, ay] = a;
    const auto [bx, by] = b;
    const auto [dx, dy] = std::make_pair(bx - ax, by - ay);

    auto [normal1x, normal1y] = Normalize(std::make_pair(-dy, dx));
    auto [normal2x, normal2y] = Normalize(std::make_pair(dy, -dx));

    normal1x *= thickness; normal1y *= thickness;
    normal2x *= thickness; normal2y *= thickness;

    vertices.emplace_back({ ax + normal1x, ay + normal1y });
    vertices.emplace_back({ ax + normal2x, ay + normal2y });
    vertices.emplace_back({ bx + normal2x, by + normal2y });
    vertices.emplace_back({ bx + normal1x, by + normal1y });

    glNamedBufferData(vertexBufferObject, sizeof(float) * 2 * vertices.size(), vertices.data(), GL_STREAM_DRAW);
    glDrawArrays(GL_TRIANGLE_FAN, 0, vertices.size());
}

it draws a nice line, but it is not fixed-width.

How can I calculate the fixed width for a line?

BrodaJarek3
  • 311
  • 1
  • 9
  • on a side-note: why are you enclosing `{ ax + normal1x, ay + normal1y }` in curly braces? you can just do `emplace_back(ax + normal1x, ay + normal1y)` ( assuming vertices is a `vector` – Yamahari Oct 14 '20 at 18:39
  • TBH, I do not know. It is done a different way in the original code anyways. – BrodaJarek3 Oct 14 '20 at 18:40
  • I suggest posting a screenshot of your current output. I 'ran the code' in my head and it seemed fine, so maybe seeing the actual output would help. – nmr Oct 14 '20 at 18:42
  • @nmr because it works fine. But when you use projection, let's say perspective, and your scene is far, far away, the line'd be invisible. And when you use `GL_LINES` it does not matter how far the camera is, because OpenGL uses a fixed width for lines. I want to have the same fixed width functionality with my code. I'd have to record a video to better interpret my words. – BrodaJarek3 Oct 14 '20 at 18:47
  • Oh, well this isn't an answer to your question, but FWIW you're doing a world space perturbation of the vertices, and you want to be doing a screen space perturbation based on the projected (to screen space) vertices. Easy to do in a vertex shader, not sure if you have one given you're using immediate mode OpenGL – nmr Oct 14 '20 at 18:52
  • Yep, I've got a shader, but every geometry is batched and draw with one draw call, so I cannot do it in shader, because I'd affect other things. – BrodaJarek3 Oct 14 '20 at 18:57
  • @BrodaJarek3 The line width depends on the projection. – Rabbid76 Oct 14 '20 at 18:59
  • @Rabbid76 projection? How projection affects the line width? Projection usually is just a static matrix, I think, maybe values change on a viewport resize. Or by saying projection you mean model, view and projection? – BrodaJarek3 Oct 14 '20 at 20:15
  • Offensive? What do you mean? I am not sure how to describe how I want it to be like. I'd love it to work similar way as just regular `GL_LINES` draws lines. When a camera goes far away the line width stays almost (it is a bit more thick) the same as it was very close. And with drawing the line "my" way, when the camera goes far away line gets smaller and smaller and I do not like it. I'd much more prefer "my" line to work like regular opengl does it. – BrodaJarek3 Oct 14 '20 at 20:23
  • @BrodaJarek3 Yes, I know `GL_LINES` draw a line with a thickness in pixels units. If you draw a triangle primitive, then the thickness depends on the vertex coordinates. In common the vertex coordinates are transformed by matrices (mode, view, projection). The projection matrix defines the viewing volume, it scales the region, which should be shown on the viewport to normalized device space. Hence the projected size of the object (length and thickness) depends on the projection. – Rabbid76 Oct 14 '20 at 20:24
  • @BrodaJarek3 See [OpenGL Line Width](https://stackoverflow.com/questions/3484260/opengl-line-width/59688394#59688394) – Rabbid76 Oct 14 '20 at 20:27
  • @BrodaJarek3 *"When a camera goes far away the line width stays almost (it is a bit more thick) the same as it was very close"* - exactly, that is what I mean by *"The line width depends on the projection."*. At perspective projection, the line width depends on the "depth" (distance to the camera) of the line. I recommend to use orthographic projection when you draw lines. If this is not possible, you have to compensate the perspective effect when you compute the vertex coordinates. – Rabbid76 Oct 14 '20 at 20:37
  • Hmmm.. I do not exactly understand. So, what I think I want, is to have the line width in screen space. To achieve this effect I have to have vertices also in screen space? So I have to multiply my vertices with an inverse view and inverse projection? – BrodaJarek3 Oct 14 '20 at 23:30

0 Answers0