Черное окно при рендеринге obj файла в opengl - PullRequest
0 голосов
/ 16 октября 2018

Я использовал opengl в qt5 на Ubuntu 18.4, я хотел загрузить простой куб (сохранить в файле .obj) и отобразить его.Я следовал этому руководству здесь http://www.opengl -tutorial.org / beginners-tutorials / tutorial-7-model-loading / , но у меня наконец появилось черное окно.Вот мой код, большое спасибо:

myopengl.hpp

class MyOpenGL : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
MyOpenGL(const QString& obj_file);

protected:
    virtual void initializeGL() Q_DECL_OVERRIDE;
    virtual void paintGL() Q_DECL_OVERRIDE;
    virtual void resizeGL(int width, int height) Q_DECL_OVERRIDE;
    void CheckGLerror();

private:
    std::vector< glm::vec3 > vertices;
    std::vector< glm::vec2 > uvs;
    std::vector< glm::vec3 > normals;

/*  Render data  */
    GLuint VAO, VBO, EBO;
};

myopengl.cpp

MyOpenGL ::MyOpenGL (const QString& obj_file) :
VAO(0),
VBO(0),
EBO(0)
{
    std::vector< unsigned int > vertex_indices, uv_indices, normal_indices;
    std::vector< glm::vec3 > temp_vertices;
    std::vector< glm::vec2 > temp_uvs;
    std::vector< glm::vec3 > temp_normals;

//parse obj file
QFile file(obj_file);
file.open(QFile::ReadOnly | QFile::Text);
QTextStream in(&file);
while(!in.atEnd()) {
    QString line = in.readLine();
    QStringList list = line.replace(",","").split(' ', QString::SkipEmptyParts);
    if (list.size() >= 3) {
        if (list.at(0) == "v") {  //veertex
            bool ok1, ok2, ok3;
            float v1 = list.at(1).toFloat(&ok1);
            float v2 = list.at(2).toFloat(&ok2);
            float v3 = list.at(3).toFloat(&ok3);
            if (ok1 && ok2 && ok3) {
                glm::vec3 vertex;
                vertex.x = v1;
                vertex.y = v2;
                vertex.z = v3;
                temp_vertices.push_back(vertex);
            }
        } else if (list.at(0) == "vn") {
            bool ok1, ok2, ok3;
            float v1 = list.at(1).toFloat(&ok1);
            float v2 = list.at(2).toFloat(&ok2);
            float v3 = list.at(3).toFloat(&ok3);
            if (ok1 && ok2 && ok3) {
                glm::vec3 normal;
                normal.x = v1;
                normal.y = v2;
                normal.z = v3;
                temp_normals.push_back(normal);
            }
        } else if (list.at(0) == "vt") {
            bool ok1, ok2;
            float v1 = list.at(1).toFloat(&ok1);
            float v2 = list.at(2).toFloat(&ok2);
            if (ok1 && ok2) {
                glm::vec2 uv;
                uv.x = v1;
                uv.y = v2;
                temp_uvs.push_back(uv);
            }
        } else if (list.at(0) == "f") {
            bool f_ok1, f_ok2, f_ok3;
            bool t_ok1, t_ok2, t_ok3;
            bool n_ok1, n_ok2, n_ok3;
            unsigned int v_index1, v_index2, v_index3;
            unsigned int t_index1, t_index2, t_index3;
            unsigned int n_index1, n_index2, n_index3;
            QStringList f_list = list.at(1).split('/');
            if (f_list.size() >= 3) {
                v_index1 = f_list.at(0).toUInt(&f_ok1);
                if (f_ok1) {
                    v_index1 -= 1;
                }
                t_index1 = f_list.at(1).toUInt(&t_ok1);
                if (t_ok1) {
                    t_index1 -= 1;
                }
                n_index1 = f_list.at(2).toUInt(&n_ok1);
                if (n_ok1) {
                    n_index1 -= 1;
                }
            }
            f_list = list.at(2).split('/');
            if (f_list.size() >= 3) {
                v_index2 = f_list.at(0).toUInt(&f_ok2);
                if (f_ok2) {
                    v_index2 -= 1;
                }
                t_index2 = f_list.at(1).toUInt(&t_ok2);
                if (t_ok2) {
                    t_index2 -= 1;
                }
                n_index2 = f_list.at(2).toUInt(&n_ok2);
                if (n_ok2) {
                    n_index2 -= 1;
                }
            }
            f_list = list.at(3).split('/');
            if (f_list.size() >= 3) {
                v_index3 = f_list.at(0).toUInt(&f_ok3);
                if (f_ok3) {
                    v_index3 -= 1;
                }
                t_index3 = f_list.at(1).toUInt(&t_ok3);
                if (t_ok3) {
                    t_index3 -= 1;
                }
                n_index3 = f_list.at(2).toUInt(&n_ok3);
                if (n_ok3) {
                    n_index3 -= 1;
                }
            }
            if (f_ok1 && f_ok2 && f_ok3 && n_ok1 && n_ok2 && n_ok3
                    && t_ok1 && t_ok2 && t_ok3) {
                vertex_indices.push_back(v_index1);
                vertex_indices.push_back(v_index2);
                vertex_indices.push_back(v_index3);

                uv_indices.push_back(t_index1);
                uv_indices.push_back(t_index2);
                uv_indices.push_back(t_index3);

                normal_indices.push_back(n_index1);
                normal_indices.push_back(n_index2);
                normal_indices.push_back(n_index3);
            }
        }

    }
}
file.close();

for (unsigned int i = 0; i < vertex_indices.size(); ++i) {
    glm::vec3 vertex = temp_vertices.at(vertex_indices.at(i));
    vertices.push_back(vertex);
}
for (unsigned int i = 0; i < uv_indices.size(); ++i) {
    glm::vec2 uv = temp_uvs.at(uv_indices.at(i));
    uvs.push_back(uv);
}
for (unsigned int i = 0; i < normal_indices.size(); ++i) {
    glm::vec3 normal = temp_normals.at(normal_indices.at(i));
    normals.push_back(normal);
}
}

void MyOpenGL::initializeGL()
{
    initializeOpenGLFunctions();
    glClearColor(0.0,0.0,0.0,1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);
    glEnable(GL_LIGHT0);

    glewExperimental = GL_TRUE;
    GLenum status = glewInit();
    if (status != GLEW_OK)
    {
        glfwTerminate();
        std::system("pause");
        return;
    }
    glGenVertexArrays(1, &this->VAO);
    glBindVertexArray(this->VAO);
    glGenBuffers(1, &this->VBO);
    glBindBuffer(GL_ARRAY_BUFFER, this->VBO);
    glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(glm::vec3), &this->vertices[0], GL_STATIC_DRAW);
    glBindVertexArray(0);
}

void MyOpenGL::resizeGL(int width, int height)
{
    glViewport(0,0,width,height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-width/2,width/2,-height/2,height/2,-1,1);
    glMatrixMode(GL_MODELVIEW);
}

void MyOpenGL::paintGL()
{
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, this->VBO);
    glDrawArrays(GL_TRIANGLES, 0, vertices.size());
    glDisableVertexAttribArray(0);

}

1 Ответ

0 голосов
/ 16 октября 2018

Вы должны определить массив общих данных атрибутов вершин с помощью glVertexAttribPointer.

Обратите внимание, что объект буфера вершин является только хранилищем данных вершин.Но вы должны указать, как их «использовать».Спецификация и состояния атрибутов вершины хранятся в объекте массива вершин .Достаточно связать объект массива вершин, когда вы хотите нарисовать сетку:

спецификация :

glBindVertexArray(this->VAO);
glBindBuffer(GL_ARRAY_BUFFER, this->VBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

draw :

glBindVertexArray(this->VAO);
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
glBindVertexArray(0);

Расширение:

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

Если у вас нет шейдера, тогда вам нужно использовать Fixed Function Pipeline и для определения атрибутов фиксированных функций,на glVertexPointer соответственно glEnableClientState( GL_VERTEX_ARRAY ).
Но поскольку вы используете только один атрибут, координату вершины с индексом атрибута 0, вы все равно можете определить атрибут с помощью glVertexAttribPointerи glEnableVertexAttribArray.
См. Каковы местоположения атрибутов для конвейера с фиксированными функциями в профиле ядра OpenGL 4.0 ++?

Обратите внимание, в этом случае вы должны использовать совместимость OpenGL Context .

...