PetrasVestartasEPFL
PetrasVestartasEPFL

Reputation: 576

OpenGL line width geometry shader

I am trying to implement geometry shader for line thickness using OpenGL 4.3.

I followed accepted answer and other given solutions of stackoverflow, but it is wrong according to the screenshot. Is there any proper way how can I get a normal of a screen? It seems correct in the first frame but the moment I move my mouse, the camera changes and offset direction is not correct. The shader is updated by camera matrix in while loop.

GLSL Geometry shader to replace glLineWidth

Vertex shader

#version 330 core
layout (location = 0) in vec3 aPos;
uniform mat4 projection_view_model;

void main()
{
    gl_Position = projection_view_model * vec4(aPos, 1.0); 
}

Fragment shader

#version 330 core
//resources:
//https://stackoverflow.com/questions/6017176/gllinestipple-deprecated-in-opengl-3-1
out vec4 FragColor;


uniform vec4 uniform_fragment_color;

void main()
{
       FragColor = uniform_fragment_color;
}

Geometry shader

#version 330 core
layout (lines) in;
layout(triangle_strip, max_vertices = 4) out;

uniform float u_thickness ;
uniform   vec2    u_viewportSize ;

in gl_PerVertex
{
  vec4 gl_Position;
  //float gl_PointSize;
  //float gl_ClipDistance[];
} gl_in[];

void main() {   


 //https://stackoverflow.com/questions/54686818/glsl-geometry-shader-to-replace-gllinewidth


   vec4 p1 = gl_in[0].gl_Position;
    vec4 p2 = gl_in[1].gl_Position;

    vec2 dir    = normalize((p2.xy - p1.xy) * u_viewportSize);
    vec2 offset = vec2(-dir.y, dir.x) * u_thickness*100 / u_viewportSize;

    gl_Position = p1 + vec4(offset.xy * p1.w, 0.0, 0.0);
    EmitVertex();
    gl_Position = p1 - vec4(offset.xy * p1.w, 0.0, 0.0);
    EmitVertex();
    gl_Position = p2 + vec4(offset.xy * p2.w, 0.0, 0.0);
    EmitVertex();
    gl_Position = p2 - vec4(offset.xy * p2.w, 0.0, 0.0);
    EmitVertex();

    EndPrimitive();
}

Upvotes: 1

Views: 823

Answers (1)

Rabbid76
Rabbid76

Reputation: 210877

To get the direction of the line in normalized device space, the x and y components of the clip space coordinated must be divided by the w component (perspective divide):

vec2 dir = normalize((p2.xy - p1.xy) * u_viewportSize);

vec2 dir = normalize((p2.xy / p2.w - p1.xy / p1.w) * u_viewportSize);

Upvotes: 1

Related Questions