如何摆脱 OpenGL 圆圈中的红线

How do I get rid of the red line in my OpenGL circle

这是我程序的output。

这是我的代码

 #include <cstdio>      // for C++ i/o
#include <iostream>
using namespace std;    // to avoid having to use std::

#define GLEW_STATIC     // include GLEW as a static library
#include <GLEW/glew.h>  // include GLEW
#include <GLFW/glfw3.h> // include GLFW (which includes the OpenGL header)
#include <glm/glm.hpp>  // include GLM (ideally should only use the GLM headers that are actually used)
using namespace glm;    // to avoid having to use glm::

#include "shader.h"

#define PI 3.14159265
#define MAX_SLICES 32
#define MIN_SLICES 8
#define MAX_VERTICES (MAX_SLICES+2)*3   // a triangle fan should have a minimum of 3 vertices
#define CIRCLE_RADIUS 0.5
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600

// global variables
GLfloat g_vertices[MAX_VERTICES] = {
    0.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 0.0f
};

GLuint g_slices = MAX_SLICES;   // number of circle slices

GLuint g_VBO = 0;               // identifiers
GLuint g_VAO = 0;           
GLuint g_shaderProgramID = 0;       

void generate_circle()
{
    float angle = PI*2 / static_cast<float>(g_slices);  // used to generate x and y coordinates
    float scale_factor = static_cast<float>(WINDOW_HEIGHT) / WINDOW_WIDTH;  // scale to make it a circle instead of an elipse
    int index = 0;  // vertex index

    g_vertices[3] = CIRCLE_RADIUS * scale_factor;   // set x coordinate of vertex 1

    // generate vertex coordinates for triangle fan
    for (int i = 2; i < g_slices+2; i++)
    {
        // multiply by 3 because a vertex has x, y, z coordinates
        index = i * 3;

        g_vertices[index] = CIRCLE_RADIUS * cos(angle) * scale_factor;
        g_vertices[index + 1] = CIRCLE_RADIUS * sin(angle);
        g_vertices[index + 2] = 0.0f;

        // update to next angle
        angle += PI*2 / static_cast<float>(g_slices);
    }
}

static void init()
{
    glClearColor(0.0, 0.0, 0.0, 1.0);   // set clear background colour

    // create and compile our GLSL program from the shader files
    g_shaderProgramID = loadShaders("SimpleVS.vert", "SimpleFS.frag");

    // generate vertices of triangle fan
    generate_circle();

    // create VBO and buffer the data
    glGenBuffers(1, &g_VBO);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*(g_slices + 2), g_vertices, GL_STATIC_DRAW);

    // create VAO and specify VBO data
    glGenVertexArrays(1, &g_VAO);
    glBindVertexArray(g_VAO);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);  // specify the form of the data

    glEnableVertexAttribArray(0);   // enable vertex attributes
}

// function used to render the scene
static void render_scene()
{
    glClear(GL_COLOR_BUFFER_BIT);   // clear colour buffer

    glUseProgram(g_shaderProgramID);    // use the shaders associated with the shader program

    glBindVertexArray(g_VAO);           // make VAO active
    glDrawArrays(GL_LINE_LOOP, 0, g_slices+2);  // display the vertices based on the primitive type

    glFlush();  // flush the pipeline
}

int main(void)
{
    GLFWwindow* window = NULL;  // pointer to a GLFW window handle

    glfwSetErrorCallback(error_callback);   // set error callback function

    // initialise GLFW
    if(!glfwInit()) 
    {
        // if failed to initialise GLFW
        exit(EXIT_FAILURE);
    }

    // minimum OpenGL version 3.3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

    // create a window and its OpenGL context
    window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "DemoCode", NULL, NULL);

    // if failed to create window
    if(window == NULL)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    glfwMakeContextCurrent(window); // set window context as the current context
    glfwSwapInterval(1);            // swap buffer interval

    // initialise GLEW
    if(glewInit() != GLEW_OK) 
    {
        // if failed to initialise GLEW
        cerr << "GLEW initialisation failed" << endl;
        exit(EXIT_FAILURE);
    }

    // set key callback function
    glfwSetKeyCallback(window, key_callback);

    // initialise rendering states
    init();

    // the rendering loop
    while(!glfwWindowShouldClose(window))
    {
        render_scene();             // render the scene

        glfwSwapBuffers(window);    // swap buffers
        glfwPollEvents();           // poll for events
    }

    // clean up
    glDeleteProgram(g_shaderProgramID);
    glDeleteBuffers(1, &g_VBO);
    glDeleteVertexArrays(1, &g_VAO);

    // close the window and terminate GLFW
    glfwDestroyWindow(window);
    glfwTerminate();

    exit(EXIT_SUCCESS);
}

我想摆脱从轴出来的红线。我只想要一个空心圆。 我正在使用 GL_LINE_LOOP 绘制数组。我使用了错误的原语吗? 我试过调整g_vertices中的坐标,它确实使线变小了,但是当我增加圆的半径时,线又出现了。

这里

GLfloat g_vertices[MAX_VERTICES] = {
    0.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 0.0f
};

这里:

g_vertices[3] = CIRCLE_RADIUS * scale_factor;   // set x coordinate of vertex 1

// generate vertex coordinates for triangle fan
for (int i = 2; i < g_slices+2; i++)

顶点 0 始终为 (0, 0, 0)。

您正在绘制 GL_LINE_LOOP:

查看 Khronos 组 OGL Primitive 文档:

GL_LINE_LOOP: As line strips, except that the first and last vertices are also used as a line. Thus, you get n lines for n input vertices. If the user only specifies 1 vertex, the drawing command is ignored. The line between the first and last vertices happens after all of the previous lines in the sequence.

你用 (0, 0, 0):

初始化第一个和第二个顶点位置
GLfloat g_vertices[MAX_VERTICES] = {
    0.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 0.0f
};

然后添加圆的顶点,因为循环从索引 2 开始:

for (int i = 2; i < g_slices+2; i++)
{
  ......
}

你画的是从圆心到圆上第一个点的线。 然后画圆。最后一个顶点位置(在圆上)连接到第一个顶点位置,即圆的中心点。

您必须跳过列表开头的 2 个顶点。您不必初始化前两个顶点,您可以从 0 开始循环。 见上面的代码:

定义和全局变量:

#define MAX_SLICES 32
#define MAX_VERTICES MAX_SLICES*3 

GLfloat g_vertices_circle[MAX_VERTICES];
GLuint g_slices = MAX_SLICES; 

创建顶点位置和颜色属性数组

for (int i = 0; i < g_slices; i++)
{
    float angle = (float)PI * 2.0f * (float)i / float(g_slices); 
    int   index = i * 3;

    g_vertices_circle[index] = CIRCLE_RADIUS * cos(angle) * scale_factor;
    g_vertices_circle[index + 1] = CIRCLE_RADIUS * sin(angle);
    g_vertices_circle[index + 2] = 0.0f;
}

设置顶点缓冲区对象:

glGenBuffers(1, &g_VBO);
glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * g_slices, g_vertices, GL_STATIC_DRAW);

最后是绘图:

glDrawArrays( GL_LINE_LOOP, 0, g_slices );