简体   繁体   中英

GL_TRIANGLE_FAN to draw a circle

I am using GL_TRIANGLE_FAN to draw a circle. When I use other Triangle primitives, I get some triangles, but when I use GL_TRIANGLE_FAN, I ge a blank screen. I am new to this, and I am not getting where I am going wrong.

#include <string>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
//Include GLEW  
#include <GL/glew.h>  
//Include GLFW  
#include <glfw3.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <math.h>

int width;
int height;

float r;
float theta;

GLuint vboHandle[1];
GLuint indexVBO;

struct vertex
{
    double x, y;
    double u, v;
    double r, g, b;
}temp;

std::vector<vertex> vertices;
std::vector<GLuint64> indeces;

void initNormal(){
    float a=0;
    int value1 = 1;
    double radius = 0.3;
    double centerX = 0;
    double centerY = 0;
    double theta = 0;
//u,v,r,g,b are dummy for now
    temp.x = 0;
    temp.y = 0;
    temp.u = a;
    temp.v = a;
    temp.r = a;
    temp.g = a;
    temp.b = a;

    vertices.push_back(temp);
    indeces.push_back(0);

    for (int i = 1; i <= 72; i++){
        a = a+0.10;
        temp.x = radius*cos(((22 / 7.0) / 180.0)*theta);
        temp.y = radius*sin(((22 / 7.0) / 180.0)*theta);
        temp.u = a;
        temp.v = a;//value1 / (i * 2);
        temp.r = a;//value1 / i;
        temp.g = a; //value1 / (i * 2);
        temp.b = a;//value1 / i;
        std::ofstream ofs;

        vertices.push_back(temp);
        indeces.push_back(i);
        theta = theta + 10;

    }
}

void initVbo(){

    GLenum err = glewInit();

    if (err != GLEW_OK) {
        fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
        //return -1;
    }
    glPointSize(10);

    glGenBuffers(1, &vboHandle[0]);   // create a VBO handle
    glBindBuffer(GL_ARRAY_BUFFER, vboHandle[0]);   // bind the handle to the current VBO 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex)* vertices.size(), &vertices[0], GL_DYNAMIC_DRAW); // allocate space and copy the data over
    glBindBuffer(GL_ARRAY_BUFFER, 0);   // clean up 

    glGenBuffers(1, &indexVBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint64)*indeces.size(), &indeces[0], GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);  //clean up 
}


void display(){
    glClearColor(0, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    glColor4f(1, 1, 1, 1);

    glEnableClientState(GL_VERTEX_ARRAY);
    glBindBuffer(GL_ARRAY_BUFFER, vboHandle[0]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
    glVertexPointer(2, GL_DOUBLE, sizeof(vertex), 0);
    glDrawElements(GL_TRIANGLES, indeces.size(), GL_UNSIGNED_INT, (char*)NULL + 0);//2 indeces needed to make one line  
    glFlush();

}


void initializeGlut(int argc, char** argv){

    std::cout << "entered";
    glutInit(&argc, argv);
    width = 800;
    height = 800;
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowSize(width, height);
    glutCreateWindow("Bhavya's Program");
    glutDisplayFunc(display);
}

void main(int argc, char** argv){
    initializeGlut(argc, argv);
    initNormal();
    initVbo();
    //glutReshapeFunc(reshape);
    glutMainLoop();
}

The main problem in your code is that you're using the wrong type for the index values:

std::vector<GLuint64> indeces;

GLuint64 is not a valid index type, and it certainly does not match the index type specified in the draw command:

glDrawElements(GL_TRIANGLES, indeces.size(), GL_UNSIGNED_INT, ...);

Replace all occurrences of GLuint64 with the correct type, which is GLuint , and you should start seeing something.

The reason you're not seeing anything at all when drawing with GL_TRIANGLE_FAN becomes clearer if you picture the memory layout of the index buffer with the wrong type. If you write a sequence of 64-bit values, which are then interpreted as 32-bit values, every second value will be read as value 0.

With GL_TRIANGLE_FAN , all triangles are formed from the first index (which you set to 0) and two sequential indices from the array. With every second index read as 0, this means that every triangle has two indices of value 0. Which in turn means that all triangles are degenerate, and will not light up any pixels.

The circle drawing code will need some improvement as well. Right now you're looping from 0 to 720 degrees, which will go around the circle twice. Also, 22/7 is a very rough approximation of pi. You may want to use a more precise constant definition from a math header file instead.

While it's not a correctness problem, I would also avoid using double values for vertex attributes. OpenGL implementations internally uses floats. If you specify the attributes as doubles, you will only use extra memory, and add overhead to convert the values from double to float.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM