How to use OpenGL draw instance dashed curve

I am writing a 2D CAD project in Opengl. I need to display a large number of curves, so I have instantiated the small segments of straight lines interpolated from the curves. Based on this, how should I achieve the dased line effect.

#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <thread>


#include <iostream>

#include "Shader.h"
#include <vector>
#include <random>
#include <time.h>

void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods);
void processInput(GLFWwindow* window);

// settings
const unsigned int SCR_WIDTH = 1600;
const unsigned int SCR_HEIGHT = 1000;

float ZOOM_PARAM = 1;

float TARGET_GEO_X = 0;
float TARGET_GEO_Y = 0;

// timing
float deltaTime = 0.0f;	// time between current frame and last frame
float lastFrame = 0.0f;

glm::mat4 projection;

std::vector<glm::vec2> pointData;
std::vector<glm::vec4> colorData;

std::vector<float> widthData;

int num = 1e6; //100w


void updateData() {
    pointData.clear();

    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_real_distribution<float> dist(-200.0f, 200.0f);

    std::uniform_real_distribution<float> width_random(1.0f, 20.0f);

    for (int i = 0; i < num; i++) {
        float p0 = dist(mt);
        float p1 = dist(mt);
        float p2 = dist(mt);
        float p3 = dist(mt);
        float width = width_random(mt);
        pointData.push_back(glm::vec2(p0, p1));
        pointData.push_back(glm::vec2(p2, p3));
        widthData.push_back(width);
    }
}

void updateColor() {
    colorData.clear();

    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_real_distribution<float> color(0.0f, 1.0f);

    for (int i = 0; i < num; i++) {
        float p0 = color(mt);
        float p1 = color(mt);
        float p2 = color(mt);
        float p3 = color(mt);
        colorData.push_back(glm::vec4(p0, p1, p2, p3));
    }

}


int main()
{
    // glfw: initialize and configure
    // ------------------------------
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

#ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

    // glfw window creation
    // --------------------
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetMouseButtonCallback(window, mouse_button_callback);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    // glad: load all OpenGL function pointers
    // ---------------------------------------
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    std::vector<glm::vec2> posData = {
    glm::vec2(0, -0.5),
    glm::vec2(1, -0.5),
    glm::vec2(1, 0.5),
    glm::vec2(0, -0.5),
    glm::vec2(1, 0.5),
    glm::vec2(0, 0.5),

    glm::vec2(1, -0.5),
    glm::vec2(2, -0.5),
    glm::vec2(2, 0.5),
    glm::vec2(1, -0.5),
    glm::vec2(2, 0.5),
    glm::vec2(1, 0.5),

    glm::vec2(-1, -0.5),
    glm::vec2(0, -0.5),
    glm::vec2(0, 0.5),
    glm::vec2(-1, -0.5),
    glm::vec2(0, 0.5),
    glm::vec2(-1, 0.5),
    };

    updateData();
    updateColor();

    GLuint VAO, VBO;
    GLuint insVBO;
    GLuint colorVBO;
    GLuint widthVBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &insVBO);
    glGenBuffers(1, &colorVBO);
    glGenBuffers(1, &widthVBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * posData.size(), &posData[0], GL_STATIC_DRAW);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);


    glBindBuffer(GL_ARRAY_BUFFER, insVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * pointData.size(), &pointData[0], GL_STATIC_DRAW);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(1);
    glVertexAttribDivisor(1, 1);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
    glEnableVertexAttribArray(2);
    glVertexAttribDivisor(2, 1);

    glBindBuffer(GL_ARRAY_BUFFER, colorVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec4) * colorData.size(), &colorData[0], GL_STATIC_DRAW);
    glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(3);
    glVertexAttribDivisor(3, 1);

    glBindBuffer(GL_ARRAY_BUFFER, widthVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * widthData.size(), &widthData[0], GL_STATIC_DRAW);
    glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, 1 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(4);
    glVertexAttribDivisor(4, 1);


    std::shared_ptr<Shader> baseShader = std::make_shared<Shader>("ins4.vs", "ins4.fs");

    // render loop
    // -----------
    while (!glfwWindowShouldClose(window))
    {
        float currentFrame = static_cast<float>(glfwGetTime());
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;


        // input
        // -----
        processInput(window);

        projection = glm::ortho(
            TARGET_GEO_X - ((float)SCR_WIDTH) * ZOOM_PARAM / 2,
            TARGET_GEO_X + ((float)SCR_WIDTH) * ZOOM_PARAM / 2,
            TARGET_GEO_Y - ((float)SCR_HEIGHT) * ZOOM_PARAM / 2,
            TARGET_GEO_Y + ((float)SCR_HEIGHT) * ZOOM_PARAM / 2,
            -1.0f, 1.0f
        );

        // render
        // ------
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        baseShader->use();
        glm::mat4 model;
        float scaleDeta = 1;
        model = glm::scale(model, glm::vec3(scaleDeta, scaleDeta, scaleDeta));

        baseShader->setMat4("model", model);
        baseShader->setMat4("projection", projection);

        glBindVertexArray(VAO);
        glDrawArraysInstanced(GL_TRIANGLES, 0, 18, pointData.size() / 2);



        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // glfw: terminate, clearing all previously allocated GLFW resources.
    // ------------------------------------------------------------------
    glfwTerminate();
    return 0;
}

void processInput(GLFWwindow* window)
{
    float speed = static_cast<float>(deltaTime);
    //std::cout << deltaTime << std::endl;

    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);

    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
        TARGET_GEO_Y += 10;
    }

    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
        TARGET_GEO_Y -= 10;
    }

    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
        TARGET_GEO_X -= 10;
    }

    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
        TARGET_GEO_X += 10;
    }

    if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) {
        std::cout << "update start .." << std::endl;
        clock_t start, end;
        start = clock();
        updateData();
        end = clock();
        std::cout << 1.0 * (end - start) / 1000 << " s" << std::endl;
    }

}

// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    // make sure the viewport matches the new window dimensions; note that width and 
    // height will be significantly larger than specified on retina displays.
    glViewport(0, 0, width, height);
}

void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
    if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
        std::cout << "mouse press ! " << std::endl;
    }
}
#version 330 core
layout (location = 0) in vec2 position;
layout (location = 1) in vec2 startPos;
layout (location = 2) in vec2 endPos;
layout (location = 3) in vec4 color;
layout (location = 4) in float width;

uniform mat4 model;
uniform mat4 projection;

out vec4 outColor;
out vec2 outPosition;
out vec2 center1;
out vec2 center2;
out float radius;
flat out int needJudgeInCircle;

void main()
{
    int rec_i  = gl_VertexID / 6;

    float len = length(endPos - startPos);
    vec2 xBasis = normalize(endPos - startPos);
    vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x));
    vec2 point;

    if(rec_i == 0){
        point = startPos + xBasis * position.x * len + yBasis * width * position.y;
        needJudgeInCircle = 0;
    }
    else if(rec_i == 1){
        point = startPos + xBasis * ((position.x - 1) * width + len) + yBasis * width * position.y;
        needJudgeInCircle = 1;
    }
    else if(rec_i == 2){
        point = startPos + xBasis * position.x * width + yBasis * width * position.y;
        needJudgeInCircle = 1;
    }

    gl_Position = projection * model * vec4(point, 0.0, 1.0);

    outColor = color;
    outPosition = point;
    center1 = startPos;
    center2 = endPos;
    radius = width / 2;

}
#version 330 core
out vec4 FragColor;

in vec4 outColor;
in vec2 outPosition;
in vec2 center1;
in vec2 center2;
in float radius;
flat in int needJudgeInCircle;


void main()
{

    if(needJudgeInCircle == 1){
        float dis1 = length(outPosition - center1);
        float dis2 = length(outPosition - center2);
        if(dis1 > radius && dis2 > radius)
            discard;
    }
    FragColor = outColor;
}