如何在OpenGl中绘制线条?

Abu*_*suf 7 opengl line

我想在opengl中画一条线.

 glBegin(GL_LINES);
    glVertex2f(.25,0.25);
    glVertex2f(.75,.75);
glEnd();
Run Code Online (Sandbox Code Playgroud)

这段代码画线,但如果我想从坐标(10,10)到坐标(20,20)画一条线,我该怎么办?

这意味着什么(.25,.25)和(.75,.75)?

n1x*_*xx1 23

(.25,.25)和(.75,.75)是线的起点和终点.

从(10,10)到(20,20)画一条线:

glBegin(GL_LINES);
    glVertex2f(10, 10);
    glVertex2f(20, 20);
glEnd();
Run Code Online (Sandbox Code Playgroud)

  • 这是不推荐使用的 (22认同)
  • ...什么是“新黑色” (7认同)

jac*_*111 15

使用 OpenGL2 :

中的每个点值glVertex2f都在 -1 和 1 之间,左下角是 (-1, -1),右上角是 (1,1),中心是 (0, 0)。

将绝对点映射到归一化空间:

  • 除以x窗口宽度 ,w以获得 0 到 1 范围内的点。

  • 乘以 2 得到 0 到 2 的范围。

  • 减去 1 以获得所需的 -1 到 1 范围。

  • yvalue 和 windows height重复h

例如:

double x1 = 10;
double y1 = 10;
double x2 = 20;
double y2 = 20;

x1 = 2*x1 / w - 1;
y1 = 2*y1 / h - 1;

x2 = 2*x2 / w - 1;
y2 = 2*y2 / h - 1;

glBegin(GL_LINES);
    glVertex2f(x1, y1);
    glVertex2f(x2, y2);
glEnd();
Run Code Online (Sandbox Code Playgroud)

使用 OpenGL3+ : 使用可编程管道绘制一条线稍微复杂一些。您可以创建一个Line类,该类将获取两个点并将它们发送到 GPU,然后使用简单的着色器程序绘制它们。所有设置都可以在构造函数中完成,并且可以通过一些访问函数进行修改:

class Line {
    int shaderProgram;
    unsigned int VBO, VAO;
    vector<float> vertices;
    vec3 startPoint;
    vec3 endPoint;
    mat4 MVP;
    vec3 lineColor;
public:
    Line(vec3 start, vec3 end) {

        startPoint = start;
        endPoint = end;
        lineColor = vec3(1,1,1);

        const char *vertexShaderSource = "#version 330 core\n"
            "layout (location = 0) in vec3 aPos;\n"
            "uniform mat4 MVP;\n"
            "void main()\n"
            "{\n"
            "   gl_Position = MVP * vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
            "}\0";
        const char *fragmentShaderSource = "#version 330 core\n"
            "out vec4 FragColor;\n"
            "uniform vec3 color;\n"
            "void main()\n"
            "{\n"
            "   FragColor = vec4(color, 1.0f);\n"
            "}\n\0";

        // vertex shader
        int vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
        glCompileShader(vertexShader);
        // check for shader compile errors

        // fragment shader
        int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
        glCompileShader(fragmentShader);
        // check for shader compile errors

        // link shaders
        shaderProgram = glCreateProgram();
        glAttachShader(shaderProgram, vertexShader);
        glAttachShader(shaderProgram, fragmentShader);
        glLinkProgram(shaderProgram);
        // check for linking errors

        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);

        vertices = {
             start.x, start.y, start.z,
             end.x, end.y, end.z,

        };
        
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        glBindVertexArray(VAO);

        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices.data(), GL_STATIC_DRAW);

        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(0);

        glBindBuffer(GL_ARRAY_BUFFER, 0); 
        glBindVertexArray(0); 

    }

    int setMVP(mat4 mvp) {
        MVP = mvp;
    }

    int setColor(vec3 color) {
        lineColor = color;
    }

    int draw() {
        glUseProgram(shaderProgram);
        glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "MVP"), 1, GL_FALSE, &MVP[0][0]);
        glUniform3fv(glGetUniformLocation(shaderProgram, "color"), 1, &lineColor[0]);

        glBindVertexArray(VAO);
        glDrawArrays(GL_LINES, 0, 2);
        return 0;
    }

    ~Line() {

        glDeleteVertexArrays(1, &VAO);
        glDeleteBuffers(1, &VBO);
        glDeleteProgram(shaderProgram);
    }
};
Run Code Online (Sandbox Code Playgroud)

初始化一些3D线与Line line(vec3 ..., vec3 ...),设置模型-视图-投影矩阵line.setMVP(projection * view * model)line.draw()和旋转相机会产生这样的:

xyz 轴

示例代码

注意:如果你只需要二维线,你只需要指定 vec3 端点坐标,z 值设置为 0,并从setMVP调用中删除投影矩阵,并将相机位置设置为 (0,0,0) . 这同样适用于上面为 OpenGL2 解释的绘制 2D 线,因此需要将坐标发送到 NDC 空间中的 OpenGL。