2015-09-18 256 views
0

我正在用GL_TRIANGLE_FAN画一个圆圈。当我使用其他三角形基元时,我得到了一些三角形,但是当我使用GL_TRIANGLE_FAN时,我产生了一个空白屏幕。我对此很陌生,而且我没有弄清楚我错了什么。GL_TRIANGLE_FAN画一个圆圈

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

回答

1

在你的代码的主要问题是,你使用了错误类型的索引值:

std::vector<GLuint64> indeces; 

GLuint64不是有效的索引类型,它当然不匹配指数

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

与正确的类型,这是GLuint更换的GLuint64所有出现,你应该ST:绘图命令中的某类型艺术看到的东西。

如果您使用错误的类型描绘索引缓冲区的内存布局,使用GL_TRIANGLE_FAN进行绘图时,您看不到任何内容的原因将变得更加清晰。如果您编写一个64位值的序列,然后将其解释为32位值,则每个第二个值将被读为值0.

对于GL_TRIANGLE_FAN,所有三角形都是从您设置的第一个索引到0)和数组中的两个连续索引。每读取第二个索引为0,这意味着每个三角形都有两个值为0的索引。这又意味着所有三角形都是退化的,并且不会点亮任何像素。

圆形绘图代码也需要一些改进。现在你正在从0到720度循环,这将绕着圆圈两次。另外,22/7是pi的非常粗略的近似值。您可能希望从数学头文件中使用更精确的常量定义。

虽然这不是一个正确性问题,但我也会避免对顶点属性使用双值。 OpenGL实现内部使用浮动。如果将属性指定为双精度,则只会使用额外内存,并添加开销以将值从double转换为float。

+0

谢谢,这工作,从GLuint64更改为GLuint ...我用GLuint64实现了缓冲区,并按我的需要正确工作。什么可能是当时正确工作的原因。我在它的帮助下画了点。那时我必须存储300 * 16个指数。 –