2015-09-18 214 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個指數。 –