簡體   English   中英

GL_TRIANGLE_FAN畫一個圓

[英]GL_TRIANGLE_FAN to draw a circle

我正在使用GL_TRIANGLE_FAN畫一個圓。 當我使用其他Triangle類型的原語時,會得到一些三角形,但是當我使用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();
}

代碼中的主要問題是索引值使用的類型錯誤:

std::vector<GLuint64> indeces;

GLuint64不是有效的索引類型,並且它肯定與draw命令中指定的索引類型不匹配:

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

將所有出現的GLuint64替換為正確的類型GLuint ,您應該開始看到一些東西。

如果使用錯誤的類型來繪制索引緩沖區的內存布局,則在使用GL_TRIANGLE_FAN進行繪制時根本看不到任何東西的原因變得更加清楚。 如果您編寫一個由64位值組成的序列,然后將其解釋為32位值,則每個第二個值將被讀取為值0。

使用GL_TRIANGLE_FAN ,所有三角形均由第一個索引(您將其設置為0)和數組中的兩個順序索引組成。 在第二個索引讀取為0的情況下,這意味着每個三角形都有兩個值為0的索引。這又意味着所有三角形均退化,並且不會點亮任何像素。

圓圖繪制代碼也將需要一些改進。 現在,您正在從0到720度循環播放,它將繞圓旋轉兩次。 同樣,22/7是pi的非常近似值。 您可能想使用數學頭文件中更精確的常量定義。

雖然這不是正確性問題,但我也將避免對頂點屬性使用雙精度值。 OpenGL實現在內部使用浮點數。 如果將屬性指定為double,則將僅使用額外的內存,並增加開銷以將值從double轉換為float。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM