如何使用Qt里的QOpenGLWidget显示一张图片(QImage)



  • glwidget.cpp如下:

    GLWidget::GLWidget(QWidget *parent)
    : QOpenGLWidget(parent)
    {
    elapsed = 0;
    setFixedSize(200, 400);
    pixmap.load("1.jpg");
    image.load("1.jpg");
    // tex = QGLWidget::convertToGLFormat(image);
    // textures = new QOpenGLTexture(image);
    }

    void GLWidget::initializeGL()
    {
    initializeOpenGLFunctions();
    glClear(GL_COLOR_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);

     QImage t = (image.convertToFormat(QImage::Format_RGBA8888)).mirrored();
    
     glGenTextures(1, &texture);
     glBindTexture(GL_TEXTURE_2D, texture);
     glTexImage2D(GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.constBits());
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glBindTexture( GL_TEXTURE_2D, 0);
    
    
    QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
    const char *vsrc =
        "#version 130\n"
        "in vec2 in_Vertex;\n"
        "in vec2 vertTexCoord;\n"
        "out vec2 fragTexCoord;\n"
        "void main(void)\n"
        "{\n"
        "    gl_Position = vec4(in_Vertex, 0.0, 1.0);\n"
        "    fragTexCoord = vertTexCoord;\n"
        "}\n";
    vshader->compileSourceCode(vsrc);
    
    QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
    const char *fsrc =
            "#version 130\n"
            "uniform sampler2D tex;\n"
            "in vec2 fragTexCoord;\n"
            "void main(void)\n"
            "{\n"
            "    gl_FragColor = texture2D(tex,fragTexCoord);\n"
            "}\n";
    fshader->compileSourceCode(fsrc);
    
    program = new QOpenGLShaderProgram;
    program->addShader(vshader);
    program->addShader(fshader);
    
    program->link();
    program->bind();
    program->setUniformValue("tex", texture);
    

    }

    void GLWidget::resizeGL(int w, int h)
    {
    glViewport(0,0,w,h);
    }

    void GLWidget::paintGL()
    {
    makeCurrent();
    glClear(GL_COLOR_BUFFER_BIT);
    program->bind();
    {
    float vertices[] = {-1.0,-1.0, 1.0,-1.0, 1.0,1.0, -1.0,1.0};
    float coordTexture[] = {0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0};

        GLint vertexLocation = glGetAttribLocation(program->programId(), "in_Vertex" );
        GLint texcoordLocation = glGetAttribLocation(program->programId(), "vertTexCoord" );
    
        glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices);
        glEnableVertexAttribArray(0);
    
        glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, 0, coordTexture);
        glEnableVertexAttribArray(2);
    
        glBindTexture(GL_TEXTURE_2D, texture);
        glDrawArrays(GL_QUADS, 0, 4);
        glBindTexture(GL_TEXTURE_2D, 0);
    
        glDisableVertexAttribArray(2);
        glDisableVertexAttribArray(0);
    }
    program->release();
    glClearColor(0.4f, 0.1f, 0.1f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, textureId);
    
    glBegin(GL_QUADS);
    glTexCoord2f(0,0); glVertex3f(-1, -1, -1);
    glTexCoord2f(1,0); glVertex3f(1, -1, -1);
    glTexCoord2f(1,1); glVertex3f(1, 1, -1);
    glTexCoord2f(0,1); glVertex3f(-1, 1, -1);
    glEnd();
    
    glDisable(GL_TEXTURE_2D);
    

    }



  • 我在main.cpp里设置了Qt::AA_UserSoftwareOpenGL



  • @flowerlove如何使用Qt里的QOpenGLWidget显示一张图片(QImage) 中说:

    AA_UserSoftwareOpenGL

    为什么不能使用OpenGL加速来做呢?在三维场景中显示图片其实比正常Widget显示图片要复杂呢。不过还是可以使用纹理的方式来做。怎么说呢,还是多尝试一下。



  • @flowerlove如何使用Qt里的QOpenGLWidget显示一张图片(QImage) 中说:

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.constBits());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBindTexture( GL_TEXTURE_2D, 0);

    现在有QOpenGLTexture这个很方便的类可以使用了,不用那么麻烦了。



  • @flowerlove 另外,为什么不用Qt Quick来实现这样的功能呢?QOpenGLWidget也是可以的啊。看看Cube OpenGL ES 2 Example,这个也是利用了图片来绘制骰子的。



  • 我用的就是QOpenGLWidget。主要是项目里用的是widget,暂时没打算移到quick上



  • @jiangcaiyang 就是打算用opengl呢。我设置这个AA_UserSoftwareOpenGL的目的是,使用这个参数或ES的话,全屏创建opengl窗口不会产生刷新闪屏。这是我之前在论坛里问过的问题。但是我发现换了高版本的qt再加上设置这个参数,之前的刷新问题就没有了



  • @jiangcaiyang 采阳有使用QOpenGLTexture绘图的例子吗?想参考下



  • @flowerlove 有的,我翻出github上的一个例子给你看看吧。链接地址:alien:




登录后回复
 

与 萌梦社区 的连接断开,我们正在尝试重连,请耐心等待