2017-07-29 4 views
1

Voici le output de mon programme.Comment se débarrasser de la ligne rouge dans mon cercle OpenGL

Voici mon code

#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); 
} 

Je veux me débarrasser de la ligne rouge qui sort de l'axe. Je veux juste un cercle creux. J'utilise GL_LINE_LOOP pour dessiner mes tableaux. Est-ce que j'utilise la mauvaise primitive? J'ai essayé d'ajuster les coordonnées dans g_vertices et cela réduit la ligne, mais quand j'augmente le rayon du cercle, la ligne réapparaît.

+0

["Les questions qui cherchent l'aide au débogage ... doivent inclure ...le plus court code nécessaire pour le reproduire ** dans la question elle-même. ** "" (https://stackoverflow.com/help/on-topic) – ybungalobill

Répondre

0

Vous dessinez un GL_LINE_LOOP:

voir le groupe Khronos OGL Primitive documentation:

GL_LINE_LOOP: Comme bandes de ligne, sauf que les premiers et derniers sommets sont également utilisés comme une ligne. Ainsi, vous obtenez n lignes pour n sommets d'entrée. Si l'utilisateur ne spécifie qu'un seul sommet, la commande de dessin est ignorée. La ligne entre le premier et le dernier sommet se produit après toutes les lignes précédentes de la séquence.

Vous initilize la première et la deuxième position de sommet avec (0, 0, 0):

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

Et puis vous ajoutez les sommets du cercle, parce que votre boucle commence comme l'indice commence à index 2:

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

Ce que vous dessinez est une ligne allant du centre au premier point du cercle. Ensuite, vous dessinez le cercle. Enfin, la dernière position de sommet (sur le cercle) est connectée à la première, qui est le point central du cercle.

Vous devez ignorer les 2 sommets au début de la liste. Vous ne devez pas initialiser les deux premiers sommets et vous pouvez commencer la boucle à 0. Voir le code ci-dessus:

Définitions et variables globales:

#define MAX_SLICES 32 
#define MAX_VERTICES MAX_SLICES*3 

GLfloat g_vertices_circle[MAX_VERTICES]; 
GLuint g_slices = MAX_SLICES; 

Créer la position de sommet et attribut tableau couleur

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; 
} 

Mettre en place l'objet vertex buffer:

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

Et enfin le dessin:

glDrawArrays(GL_LINE_LOOP, 0, g_slices); 
+0

J'ai étendu ma réponse – Rabbid76

0

Ici

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

Et ici:

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

Vertex 0 est toujours (0, 0, 0).