Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. OpenGL and QT, crash at glDrawElements

OpenGL and QT, crash at glDrawElements

Scheduled Pinned Locked Moved Unsolved General and Desktop
openglsegfault
9 Posts 2 Posters 7.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • DaOnlyOwnerD Offline
    DaOnlyOwnerD Offline
    DaOnlyOwner
    wrote on last edited by DaOnlyOwner
    #1

    Hi guys,
    I am new here and new to OpenGL ;)

    So I was trying to make something to appear on my screen, but unfortunately it always crashes at glDrawElements.
    I am glad if somebody could help. Here is the code:

    //Initialization 
    void Mesh::initialize()
    {
        this->initializeOpenGLFunctions();
    
        vao = new QOpenGLVertexArrayObject();
        vbo = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
        ebo = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
    
        vao->create();
        vbo->create();
        ebo->create();
    
        vao->bind();
    
            vbo->bind();
            vbo->setUsagePattern(QOpenGLBuffer::StaticDraw);
            vbo->allocate(vertices.data(),vertices.size() * sizeof(Vertex)); 
    
    
            ebo->bind(); 
            ebo->setUsagePattern(QOpenGLBuffer::StaticDraw);
            ebo->allocate(indices.data(),indices.size()*sizeof(GLuint)); 
    
    
            //Vertex position
    
            program->enableAttributeArray(0);
            program->setAttributeBuffer(0,GL_FLOAT,0,sizeof(Vertex));
    
            program->enableAttributeArray(1); 
            program->setAttributeBuffer(1,GL_FLOAT,offsetof(Vertex,Normal),3,sizeof(Vertex)); 
    
            glEnableVertexAttribArray(2);
            program->setAttributeBuffer(2,GL_FLOAT,offsetof(Vertex,TextCoords),2,sizeof(Vertex));
    
        vao->release();
    
    }
    

    It always crashes here:

    void Mesh::DrawMesh()
    {
        vao->bind();
        qDebug() << vertices.size();
        glDrawElements(GL_TRIANGLES, indices.size(),GL_UNSIGNED_INT,0);
        vao->release();
    }
    

    Note: When I call vao->isCreated() it returns false even tough I made sure (100%) that initialize() is called BEFORE DrawMesh.

    Here is my Vertex struct:

    struct Vertex
    {
        QVector3D Position;
        QVector3D Normal;
        QVector2D TextCoords;
    };
    

    This is my vertex shader:

    #version 330 core
    
    layout(location=0) in vec3 position;
    layout(location=1) in vec3 normal;
    layout(location=2) in vec2 textCoords;
    
    uniform mat4 MVP;
    
    out vec4 color;
    
    void main(void)
    {
        gl_Position= MVP*vec4(position,1);
        color = vec4(1,1,1,1);
    }
    
    

    Can somebody help me? I'm really stuck here. Also I don't know if I can pass an array of QVector3D like that to the graphicscard...

    Thank you really for your help. ;)

    1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on last edited by A Former User
      #2

      Hi, welcome to the Qt forum! Seems like you forgot to create an OpenGL context and make it current, see: http://doc.qt.io/qt-5/qopenglfunctions.html#details

      Edit: There is also a minimal example: http://doc.qt.io/qt-5/qtgui-openglwindow-example.html

      DaOnlyOwnerD 1 Reply Last reply
      0
      • ? A Former User

        Hi, welcome to the Qt forum! Seems like you forgot to create an OpenGL context and make it current, see: http://doc.qt.io/qt-5/qopenglfunctions.html#details

        Edit: There is also a minimal example: http://doc.qt.io/qt-5/qtgui-openglwindow-example.html

        DaOnlyOwnerD Offline
        DaOnlyOwnerD Offline
        DaOnlyOwner
        wrote on last edited by
        #3

        @Wieland Thanks for the reply Wieland.
        Inside paintGL I loop through a list of meshes and call the DrawMesh() method on all of them. I use a QOpenGLWidget for that.
        So is manually creating a context still the recommended way to go?
        Thanks you ;)

        1 Reply Last reply
        0
        • ? Offline
          ? Offline
          A Former User
          wrote on last edited by A Former User
          #4

          @DaOnlyOwner said:

          void Mesh::initialize()

          That should be void Mesh::initializeGL(), in other words override void QOpenGLWidget::initializeGL(). Otherwise the function won't automatically use the correct OpenGL context. May I please see your Mesh header file?

          DaOnlyOwnerD 1 Reply Last reply
          0
          • ? A Former User

            @DaOnlyOwner said:

            void Mesh::initialize()

            That should be void Mesh::initializeGL(), in other words override void QOpenGLWidget::initializeGL(). Otherwise the function won't automatically use the correct OpenGL context. May I please see your Mesh header file?

            DaOnlyOwnerD Offline
            DaOnlyOwnerD Offline
            DaOnlyOwner
            wrote on last edited by
            #5

            @Wieland Of course,

            class Mesh : public QOpenGLFunctions_3_3_Core
            {
            public:
                Mesh(const Mesh& mesh)
                {
                    this->vertices = mesh.vertices;
                    this->indices = mesh.indices;
                    this->program = mesh.program;
                    initialize();
                }
            
                Mesh(){}
                ~Mesh()
                {
            
                    vao->destroy();
                    vbo->destroy();
                    ebo->destroy();
            
                }
            
                QVector<Vertex> vertices;
                QVector<GLuint> indices;
                QOpenGLShaderProgram* program;
            
                Mesh(const QVector<Vertex> &vertices, const QVector<GLuint> &indices, QOpenGLShaderProgram* program);
                void DrawMesh();
            
            private:
            
                QOpenGLVertexArrayObject* vao;
                QOpenGLBuffer* vbo;
                QOpenGLBuffer* ebo;
            
                void initialize();
            
            };
            

            The code of my QOpenGLWidget:

            void RenderingWindow::initializeGL()
            {
                this->initializeOpenGLFunctions();    
                program->create();
                program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/testvert.vert" );
                program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/testfrag.frag");
                program->link();
            
                Camera::instance().LookAt(0,0,5, 0,0,0 ,0,1,0);
            }
            
            void RenderingWindow::resizeGL(int w, int h)
            {
                Camera::instance().Perspective(60,w/h,0,10000);
            }
            
            void RenderingWindow::paintGL()
            {
                program->bind();
                    program->setUniformValue("MVP",Camera::instance().GetMVP());
                    model.Draw();
                program->release();
            }
            
            void RenderingWindow::LoadModel()
            {
                QString filename = QFileDialog::getOpenFileName(this,"Choose Model file",QString(),"Model files (*.fbx *.obj)");
                model.LoadModel(*this, filename, program);
            }
            
            

            model.Draw() goes through all the meshes currently attached to this model and draws them.

            1 Reply Last reply
            0
            • ? Offline
              ? Offline
              A Former User
              wrote on last edited by A Former User
              #6

              Mesh(const Mesh& mesh) calls void Mesh::initialize(). Who calls Mesh(const Mesh& mesh)? The constructor must be called from within the correct OpenGL context.

              DaOnlyOwnerD 1 Reply Last reply
              0
              • ? A Former User

                Mesh(const Mesh& mesh) calls void Mesh::initialize(). Who calls Mesh(const Mesh& mesh)? The constructor must be called from within the correct OpenGL context.

                DaOnlyOwnerD Offline
                DaOnlyOwnerD Offline
                DaOnlyOwner
                wrote on last edited by
                #7

                @Wieland I think it's called when storing the Meshes inside a QVector. So the constructor is called somewhere in LoadModel().

                1 Reply Last reply
                0
                • ? Offline
                  ? Offline
                  A Former User
                  wrote on last edited by
                  #8

                  Ok. Then call makeCurrent() in void RenderingWindow::LoadModel().

                  DaOnlyOwnerD 1 Reply Last reply
                  0
                  • ? A Former User

                    Ok. Then call makeCurrent() in void RenderingWindow::LoadModel().

                    DaOnlyOwnerD Offline
                    DaOnlyOwnerD Offline
                    DaOnlyOwner
                    wrote on last edited by DaOnlyOwner
                    #9

                    @Wieland somehow It's still not working.
                    The reason why I have to call initialize() inside the copyConstructor is, that you can't copy QOpenGLVertexArrayObject..

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved