如何摆脱OpenGL圈中的红线

时间:2017-07-29 06:26:03

标签: opengl glm-math

以下是我的计划的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中的坐标,它确实使线条变小,但是当我增加圆的半径时,线条会再次出现。

2 个答案:

答案 0 :(得分:0)

下面

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)。

答案 1 :(得分:0)

您正在绘制GL_LINE_LOOP

请参阅Khronos小组OGL Primitive文档:

  

GL_LINE_LOOP:作为线条,除了第一个和最后一个顶点也用作线条。   因此,n个输入顶点得到n行。如果用户仅指定1个顶点,则忽略绘图命令。   第一个和最后一个顶点之间的线发生在序列中的所有前一行之后。

使用(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 );