简体   繁体   English

GL_TRIANGLE_FAN画一个圆

[英]GL_TRIANGLE_FAN to draw a circle

I am using GL_TRIANGLE_FAN to draw a circle. 我正在使用GL_TRIANGLE_FAN画一个圆。 When I use other Triangle primitives, I get some triangles, but when I use GL_TRIANGLE_FAN, I ge a blank screen. 当我使用其他Triangle类型的原语时,会得到一些三角形,但是当我使用GL_TRIANGLE_FAN时,会出现空白屏幕。 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: GLuint64不是有效的索引类型,并且它肯定与draw命令中指定的索引类型不匹配:

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. 将所有出现的GLuint64替换为正确的类型GLuint ,您应该开始看到一些东西。

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. 如果使用错误的类型来绘制索引缓冲区的内存布局,则在使用GL_TRIANGLE_FAN进行绘制时根本看不到任何东西的原因变得更加清楚。 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. 如果您编写一个由64位值组成的序列,然后将其解释为32位值,则每个第二个值将被读取为值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. 使用GL_TRIANGLE_FAN ,所有三角形均由第一个索引(您将其设置为0)和数组中的两个顺序索引组成。 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. 在第二个索引读取为0的情况下,这意味着每个三角形都有两个值为0的索引。这又意味着所有三角形均退化,并且不会点亮任何像素。

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. 现在,您正在从0到720度循环播放,它将绕圆旋转两次。 Also, 22/7 is a very rough approximation of pi. 同样,22/7是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. OpenGL实现在内部使用浮点数。 If you specify the attributes as doubles, you will only use extra memory, and add overhead to convert the values from double to float. 如果将属性指定为double,则将仅使用额外的内存,并增加开销以将值从double转换为float。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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