Нарисуй куб и пирамиду - PullRequest
       0

Нарисуй куб и пирамиду

0 голосов
/ 13 февраля 2019

Я изучаю OpenGL и использую Qt 5.12.Мне сейчас нужно нарисовать куб и пирамиду с треугольниками.

Я думаю, что класс вершин и структура треугольника в порядке, но, к сожалению, не все треугольники отображаются правильно.Я все еще новичок в OpenGL, поэтому, возможно, мне что-то не хватает в разделе привязки VBO / VAO, но я не могу понять, что.

Я создал класс myVertex с 6 числами с плавающей запятой: 3 для позиции и3 для цвета:

class myVertex{
public:
    GLfloat _x;
    GLfloat _y;
    GLfloat _z;
    GLfloat _r;
    GLfloat _g;
    GLfloat _b;

    myVertex(GLfloat x, GLfloat y, GLfloat z, GLfloat r, GLfloat g, GLfloat b){
        _x=x;
        _y=y;
        _z=z;
        _r=r;
        _g=g;
        _b=b;

    }
};

Затем я определил структуру для треугольников:

struct triangle {
    myVertex a;
    myVertex b;
    myVertex c;
};

В MainView :: initializeGL () я определяю цвет и положение в 3D каждой вершины, а затемЯ строю треугольники:

// Cube
    myVertex CUBE_LEFT_FRONT_DOWN  = myVertex(-1.0f,-1.0f,-1.0f,1.0f,0.0f,0.0f);
    myVertex CUBE_RIGHT_FRONT_DOWN = myVertex( 1.0f,-1.0f,-1.0f,0.0f,1.0f,0.0f);
    myVertex CUBE_LEFT_BACK_DOWN   = myVertex(-1.0f, 1.0f,-1.0f,0.0f,0.0f,1.0f);
    myVertex CUBE_RIGHT_BACK_DOWN  = myVertex( 1.0f, 1.0f,-1.0f,1.0f,1.0f,0.0f);
    myVertex CUBE_LEFT_FRONT_UP    = myVertex(-1.0f,-1.0f, 1.0f,1.0f,0.0f,1.0f);
    myVertex CUBE_RIGHT_FRONT_UP   = myVertex( 1.0f,-1.0f, 1.0f,0.0f,1.0f,1.0f);
    myVertex CUBE_LEFT_BACK_UP     = myVertex(-1.0f, 1.0f, 1.0f,0.2f,0.5f,0.7f);
    myVertex CUBE_RIGHT_BACK_UP    = myVertex( 1.0f, 1.0f, 1.0f,0.7f,0.2f,0.5f);


    // Every face is made of 2 triangles
    triangle left1  = {CUBE_LEFT_BACK_DOWN,  CUBE_LEFT_FRONT_DOWN,  CUBE_LEFT_BACK_UP};
    triangle left2  = {CUBE_LEFT_FRONT_UP,   CUBE_LEFT_FRONT_DOWN,  CUBE_LEFT_BACK_UP};
    triangle right1 = {CUBE_RIGHT_BACK_DOWN, CUBE_RIGHT_BACK_UP,    CUBE_RIGHT_FRONT_DOWN};
    triangle right2 = {CUBE_RIGHT_FRONT_UP,  CUBE_RIGHT_BACK_UP,    CUBE_RIGHT_FRONT_DOWN};
    triangle back1  = {CUBE_LEFT_BACK_DOWN,  CUBE_RIGHT_BACK_DOWN,  CUBE_LEFT_BACK_UP};
    triangle back2  = {CUBE_RIGHT_BACK_UP,   CUBE_RIGHT_BACK_DOWN,  CUBE_LEFT_BACK_UP};
    triangle front1 = {CUBE_LEFT_FRONT_DOWN, CUBE_RIGHT_FRONT_DOWN, CUBE_LEFT_FRONT_UP};
    triangle front2 = {CUBE_RIGHT_FRONT_UP,  CUBE_RIGHT_FRONT_DOWN, CUBE_LEFT_FRONT_UP};
    triangle down1  = {CUBE_LEFT_FRONT_DOWN, CUBE_RIGHT_FRONT_DOWN, CUBE_LEFT_BACK_DOWN};
    triangle down2  = {CUBE_RIGHT_BACK_DOWN, CUBE_RIGHT_FRONT_DOWN, CUBE_LEFT_BACK_DOWN};
    triangle up1    = {CUBE_RIGHT_BACK_UP,   CUBE_RIGHT_FRONT_UP,   CUBE_LEFT_BACK_UP};
    triangle up2    = {CUBE_LEFT_FRONT_UP,   CUBE_RIGHT_FRONT_UP,   CUBE_LEFT_BACK_UP};

    triangle cube[] = {left1, left2, right1, right2, back1, back2, front1, front2, down1, down2, up1, up2};


// Pyramid
    myVertex PYR_LEFT_FRONT  = myVertex(-1.0f,-1.0f,-1.0f,0.0f,1.0f,0.0f);
    myVertex PYR_RIGHT_FRONT = myVertex( 1.0f,-1.0f,-1.0f,0.0f,0.0f,1.0f);
    myVertex PYR_LEFT_BACK   = myVertex(-1.0f, 1.0f,-1.0f,1.0f,0.0f,0.0f);
    myVertex PYR_RIGHT_BACK  = myVertex( 1.0f, 1.0f,-1.0f,0.5f,0.8f,0.0f);
    myVertex PYR_TOP         = myVertex( 0.0f, 0.0f, 1.0f,0.3f,0.1f,0.4f);


// Base need 2 triangles
    triangle leftside  = {PYR_LEFT_FRONT,  PYR_LEFT_BACK,   PYR_TOP};
    triangle rightside = {PYR_RIGHT_FRONT, PYR_RIGHT_BACK,  PYR_TOP};
    triangle frontside = {PYR_LEFT_FRONT,  PYR_RIGHT_FRONT, PYR_TOP};
    triangle backside  = {PYR_LEFT_BACK,   PYR_RIGHT_BACK,  PYR_TOP};
    triangle base1     = {PYR_LEFT_FRONT,  PYR_LEFT_BACK,   PYR_RIGHT_FRONT};
    triangle base2     = {PYR_RIGHT_BACK,  PYR_LEFT_BACK,   PYR_RIGHT_FRONT};

    triangle pyramid[] = {leftside, rightside, frontside, backside, base1, base2};

Теперь я определяю VBO и VAO, включаю атрибуты и т. Д .:

GLuint cubeVBO;
GLuint cubeVAO;
GLuint pyrVBO;
GLuint pyrVAO;

glGenBuffers(1, &cubeVBO);
glGenVertexArrays(1, &cubeVAO);
glBindVertexArray(cubeVAO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube), cube, GL_STATIC_DRAW);

glGenBuffers(1, &pyrVBO);
glGenVertexArrays(1, &pyrVAO);
glBindVertexArray(pyrVAO);
glBindBuffer(GL_ARRAY_BUFFER, pyrVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(pyramid), pyramid, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(myVertex),(void *)0);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(myVertex),(void *)(3*sizeof(GLfloat)));

И, наконец, рисую на экране:

MainView::paintGL() {

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    shaderProgram.bind();

    glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
    glDrawArrays(GL_TRIANGLES,0,36);
    glBindBuffer(GL_ARRAY_BUFFER, pyrVBO);
    glDrawArrays(GL_TRIANGLES,0,18);


    shaderProgram.release();
}

Я ожидал увидеть такую ​​фигуру: Ожидается

Но сейчас я вижу это: Мой результат

Я просмотрел кодмного раз, но я не могу понять, что происходит не так.

1 Ответ

0 голосов
/ 13 февраля 2019

Если объект буфера массива с ненулевым именем связан, то последний параметр glVertexAttribPointer обрабатывается как смещение байта в хранилище данных объекта буфера.
Определение универсальногоДанные атрибута вершины и имя указанного буфера заносятся в Объект массива вершин вектор состояния.

Перед определением массива общих данных атрибута вершины, с помощью вызова glVertexAttribPointer, объект массива вершин, в который должна быть сохранена спецификация вершин, должен быть связан.Надлежащий буферный объект тоже должен быть связан:

// vertex array buffer for cube
GLuint cubeVBO;
glGenBuffers(1, &cubeVBO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube), cube, GL_STATIC_DRAW);

// vertex array buffer for pyramid
GLuint pyrVBO;
glGenBuffers(1, &pyrVBO);
glBindBuffer(GL_ARRAY_BUFFER, pyrVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(pyramid), pyramid, GL_STATIC_DRAW);
// vertex array object for cube
GLuint cubeVAO;
glGenVertexArrays(1, &cubeVAO);
glBindVertexArray(cubeVAO);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(myVertex),(void *)0);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(myVertex),(void *)(3*sizeof(GLfloat)));

// vertex array object for pyramid
GLuint pyrVAO;
glGenVertexArrays(1, &pyrVAO);
glBindVertexArray(pyrVAO);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

glBindBuffer(GL_ARRAY_BUFFER, pyrVBO);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(myVertex),(void *)0);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(myVertex),(void *)(3*sizeof(GLfloat)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...