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. [Solved]A class inherited from QGLwidget to display an image (the image can not be displaed)

[Solved]A class inherited from QGLwidget to display an image (the image can not be displaed)

Scheduled Pinned Locked Moved General and Desktop
6 Posts 3 Posters 4.2k Views 1 Watching
  • 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.
  • M Offline
    M Offline
    mybiandou
    wrote on last edited by
    #1

    Hello, everyone.

    I am trying to write a class inherited from QGLWidget to display an image using openGL with basic pan & zoom etc. functions.
    (I have realized one before, but I am trying to write a more clear one.)
    Can anyone help me out of the problem?
    The following includes all source code. Thank you in advance.
    @
    #include <QtOpenGL>
    class FrameGLWidget : public QGLWidget
    {
    public:
    FrameGLWidget(QWidget *parent);
    ~FrameGLWidget();
    protected:
    void initializeGL();
    void paintGL();
    void resizeGL(int w, int h);

    public:
    void loadImage(QImage &img);
    void loadImage(const QString &filename);

    void setBackgroundColor(QColor color);
    

    private:
    void showImage();
    void showTitlePage();

    private:
    QColor bg_color; //background color
    float XPan_Ratio,YPan_Ratio,Zoom_Ratio;
    int width_img,height_img; //image size

    bool bImageConnected;
    bool bGridEnabled;
    bool bTextureCreated;
    
    GLuint texture;
    

    };

    @

    @
    #include "FrameGLWidget.h"
    FrameGLWidget::FrameGLWidget(QWidget *parent) :
    QGLWidget(parent)
    {
    setWindowTitle(tr("FrameGLWidget"));
    bImageConnected=false;
    bTextureCreated=false;
    bGridEnabled=false;

    XPan_Ratio=0.0f;
    YPan_Ratio=0.0f;
    Zoom_Ratio=1.0f;
    

    }

    FrameGLWidget::~FrameGLWidget()
    {
    if(bTextureCreated)
    glDeleteTextures(1,&texture);
    }

    void FrameGLWidget::initializeGL()
    {
    glDisable(GL_DEPTH_TEST); //disable for 2D painting
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    }

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

    void FrameGLWidget::paintGL()
    {
    qglClearColor(bg_color);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    //set the window background color
    if(!bImageConnected)
    showTitlePage();
    else
    showImage();
    }

    void FrameGLWidget::showImage()
    {
    float ox,oy;
    float x1,y1,x2,y2,x3,y3,x4,y4;
    float rw,rh;

    //rw=w_h_ratio_image/w_h_ratio_window;
    rw=1.0f;rh=1.0f;
    
    ox=XPan_Ratio*(1.0+Zoom_Ratio*rw); oy=YPan_Ratio*(1.0+Zoom_Ratio*rh);
    x1=ox-Zoom_Ratio*rw; y1=oy-Zoom_Ratio*rh;
    x2=ox+Zoom_Ratio*rw; y2=oy-Zoom_Ratio*rh;
    x3=ox+Zoom_Ratio*rw; y3=oy+Zoom_Ratio*rh;
    x4=ox-Zoom_Ratio*rw; y4=oy+Zoom_Ratio*rh;
    y3=0.0;y4=0.0;
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0,0,this->width(),this->height());
    
    glEnable(GL_TEXTURE_2D);
    
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    
    glBegin( GL_QUADS );
    glTexCoord2d(0.0,0.0); glVertex2d(x1,y1);
    glTexCoord2d(1.0,0.0); glVertex2d(x2,y2);
    glTexCoord2d(1.0,1.0); glVertex2d(x3,y3);
    glTexCoord2d(0.0,1.0); glVertex2d(x4,y4);
    glEnd();
    
    glDrawBuffer(GL_BACK);
    

    }

    void FrameGLWidget::loadImage(QImage &img)
    {
    width_img=img.width();
    height_img=img.height();

    /* Create texture object */
    if(!bTextureCreated)
    {
        glGenTextures(1, &texture);
        bTextureCreated=true;
    }
    
    /* Now upload pixels */
    if(img.format()!=QImage::Format_RGB32)
        img=img.convertToFormat(QImage::Format_RGB32);
    qDebug()<<"Color count:"<<img.colorCount();
    qDebug()<<"Depth:"<<img.depth();
    qDebug()<<"Format"<<img.format();
    qDebug()<<"Has Alpha channel:"<<img.hasAlphaChannel();
    
    QImage tex_image;
    tex_image = QGLWidget::convertToGLFormat(img);
    
    //make sure its not null
    if(tex_image.isNull())
    {
        QMessageBox::warning(this, tr("Error"),
                             tr("failed to transform image to opengl format."));
        return ;
    }
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
                 tex_image.width(), tex_image.height(), 0,
                 GL_RGB, GL_UNSIGNED_BYTE, tex_image.bits());
    
    bImageConnected=true;
    
    // Update scene
    updateGL();
    return;
    

    }

    void FrameGLWidget::loadImage(const QString &filename)
    {
    QImage img;
    img.load(filename);
    if(img.isNull())
    {
    QMessageBox::warning(this, tr("Error"),
    tr("Can not open specified file <%1>").arg(filename),
    QMessageBox::Ok);
    return;
    }
    else
    {
    loadImage(img);
    return ;
    }
    }

    void FrameGLWidget::setBackgroundColor(QColor color)
    {
    bg_color=color;
    }

    void FrameGLWidget::showTitlePage()
    {
    QFont serifFont("Times", 30, QFont::Bold);
    setFont(serifFont);
    QString text=tr("NO IMAGE");
    QFontMetrics metrics = QFontMetrics(font());
    int border = qMax(4, metrics.leading());
    QRect rect = metrics.boundingRect(0, 0, width() - 2*border, int(height()*0.125),
    Qt::AlignCenter | Qt::TextWordWrap, text);
    renderText((width() - rect.width())/2,(height()-rect.height())/2,text);
    }

    @

    @

    #include <QtWidgets/QApplication>
    #include <QtWidgets/QMessageBox>
    #include "FrameGLWidget.h"

    int main(int argc, char **argv)
    {
    QApplication app(argc, argv);
    if (!QGLFormat::hasOpenGL() || !QGLFramebufferObject::hasOpenGLFramebufferObjects()) {
    QMessageBox::information(0, "Warning",
    "This system does not support OpenGL/framebuffer objects.");
    return -1;
    }

    FrameGLWidget frameGL(0);
    frameGL.resize(640, 480);
    frameGL.setBackgroundColor(Qt::darkGreen);
    frameGL.loadImage("test.jpg");
    frameGL.show();
    return app.exec(&#41;;
    

    }
    @

    1 Reply Last reply
    0
    • V Offline
      V Offline
      Vaquita Tim
      wrote on last edited by
      #2

      Well, I think you want to debug this a bit first, and find out where the problem is before posting...

      Just a stab in the dark, but maybe double-check
      @glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ...@
      since my code has
      @glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ...@

      1 Reply Last reply
      0
      • M Offline
        M Offline
        mybiandou
        wrote on last edited by
        #3

        Thanks for your hint.
        But I think that is not the cause of my problem.
        I copy the piece of code from my old project, which runs without problem.
        As you say, I try to debug it further.
        Thank you.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mybiandou
          wrote on last edited by
          #4

          I tried to convert image format to QImage::Format_RGB32 and then call the following glTexImage2D with GL_RGB format. But it also failed.

          Can anyone help me out? Thank you.

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mybiandou
            wrote on last edited by
            #5

            I have solved the problem.
            In the main program, I try to load the image file and construct texture before QGLwidget window shows. In fact , the opengl context will not be constructed until the QGLwidget shows is called (and then initializeGL is called). I just change the order
            from
            @
            frameGL.loadImage("test.jpg");
            frameGL.show();
            @

            to
            @
            frameGL.show();
            frameGL.loadImage("test.jpg");
            @

            And then it works fine.

            1 Reply Last reply
            0
            • P Offline
              P Offline
              Pistolero99
              wrote on last edited by
              #6

              It's strange. I use your code without modification and it shows the image only in the lower half part of the window.
              I mean, the jpg image's height is halved (its width is unmodified) and the image is drawn starting from the position (0, height/2).
              Do you see an explanation ?

              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