Results 1 to 12 of 12

Thread: OpenGL image viewer, need some help on implementation

  1. #1
    Join Date
    Aug 2006
    Posts
    20
    Qt products
    Qt4
    Platforms
    Windows

    Default OpenGL image viewer, need some help on implementation

    Hi i'm currently working on an application for showing HDR-images and need some tips on how to implement zooming in the application.
    I have made a multi document interface with QtOpenGL widgets for displaying the images. in this widget I make a texture on a polygon the same size as the image.
    Question is when zooming is it best to scale the polygon or change the viewport or gluOrtho2D? Or am I doing this all wrong?
    I want the application to behave like for example photosshop so when I resize the window displaying the image the scale stays the same and in the middle of the window. Later on I also have to get the image coordinates from the mouseMove function so that I can display the raw color values of the image.

    Right now it looks like this:
    Qt Code:
    1. void GLWidget::resizeGL(int width, int height) {
    2.  
    3. glViewport( width / 2 - imageWith / 2,
    4. height / 2 - imageHeight / 2,
    5. imageWith,
    6. imageHeight );
    7. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. void GLWidget::paintGL()
    2. {
    3. ...........
    4.  
    5. glMatrixMode( GL_PROJECTION );
    6. glLoadIdentity();
    7. gluOrtho2D( 0, imageWith, 0, imageHeight);
    8. .................
    9. glMatrixMode( GL_MODELVIEW );
    10. glLoadIdentity();
    11. .................
    12. glBegin( GL_QUADS );
    13. glTexCoord2f( 0.0f, 0.0f );
    14. glVertex2f( offsetValues[0], offsetValues[1] );
    15.  
    16. glTexCoord2f( 1.0f, 0.0f );
    17. glVertex2f( (float)imageWith + offsetValues[0], offsetValues[1] );
    18.  
    19. glTexCoord2f( 1.0f, 1.0f );
    20. glVertex2f( (float)imageWith + offsetValues[0], (float)imageHeight + offsetValues[1] );
    21.  
    22. glTexCoord2f( 0.0f, 1.0f );
    23. glVertex2f( offsetValues[0], (float)imageHeight + offsetValues[1] );
    24.  
    25. glEnd();
    26.  
    27. }
    To copy to clipboard, switch view to plain text mode 

    Is there a simple way to do this? How would you do it?
    I'm quite new to qt and still have a lot to learn in the noble art of programming.
    Some help would be much appriciated.
    Thanks in advance.
    /Nils
    Last edited by Randulf; 9th May 2007 at 21:56.

  2. #2
    Join Date
    Feb 2007
    Posts
    49
    Thanks
    4
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: OpenGL image viewer, need some help on implementation

    First thing.

    ResizeGL method looks suspicouis, viewport depends of the image width and height, and doesn't make sense. Just use:

    Qt Code:
    1. void GLWidget::resizeGL(int width, int height) {
    2. glMatrixMode(GL_PROJECTION);
    3. glLoadIdentity();
    4. gluOrtho2D(0, width, 0, height);
    5. glViewport(0, 0, width, height);
    6. };
    To copy to clipboard, switch view to plain text mode 

    This way you get texture to pixel exact mapping. So if vertex coordinate is x, y it's (x, y) coordinate on the window (be careful y axis is inverted).

    For zooming you can scale, or change vertex coordinates (it's the same).

    But I will think about the part scaling staying the same and in the middle.

    What do you mean with "get the image coordinates from the mouseMove function so that I can display the raw color values of the image"?

    BTW, this is mostly OpenGL related.

  3. #3
    Join Date
    Feb 2007
    Posts
    49
    Thanks
    4
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: OpenGL image viewer, need some help on implementation

    Try this

    Qt Code:
    1. void GLWidget::resizeGL(int width, int height)
    2. {
    3. glViewport(0, 0, width, height);
    4. glMatrixMode(GL_PROJECTION);
    5. glLoadIdentity();
    6. gluOrtho2D(0.0, width, 0.0, height);
    7. }
    To copy to clipboard, switch view to plain text mode 


    Qt Code:
    1. void GLWidget::paintGL()
    2. {
    3. ................
    4. glMatrixMode(GL_MODELVIEW);
    5. glLoadIdentity();
    6. glTranslatef(width() / 2.0f, height() / 2.0f, 0.0f);
    7. glScalef(scaleFactor, scaleFactor, 0.0f);
    8. glTranslatef(-imageWidth / 2.0f, -imageHeight / 2.0f, 0.0f);
    9.  
    10. glBegin(GL_QUADS);
    11. glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
    12. glTexCoord2f(1.0f, 0.0f); glVertex2f(imageWidth, 0.0f);
    13. glTexCoord2f(1.0f, 1.0f); glVertex2f(imageWidth, imageHeight);
    14. glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, imageHeight);
    15. glEnd();
    16. }
    To copy to clipboard, switch view to plain text mode 

    You must know the basics of matrix and coordinate transformations if you want to understand above code.

  4. #4
    Join Date
    Aug 2006
    Posts
    20
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: OpenGL image viewer, need some help on implementation

    Ah, yes!!
    This is working perfectly. Thanks a lot!!!

    What do you mean with "get the image coordinates from the mouseMove function so that I can display the raw color values of the image"?
    Im going to have a widget with information about wich pixel the mouse pointer is over and what color values it has. Since I only get the window coordinates I have to translate them to image space. What I ment with raw valus is that I have two arrays with pixel valus, one with 32 bit HDR data and another with clamped values. Anyway that getting the valus from the array wont be a problem it just the translation that i'm unshure of.

    Thanks again for the help.

  5. #5
    Join Date
    Aug 2006
    Posts
    20
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: OpenGL image viewer, need some help on implementation

    Hi!
    Now I got everything working except from the translation from window coordinates to image.
    This is how i do it now:
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glTranslatef(this->size().width() / 2.0f, this->size().height() / 2.0f, 0.0f);
    glTranslatef(imageOffset.x(), -imageOffset.y(), 0.0f);
    glScalef(zoomFactor, zoomFactor, 0.0f);
    glTranslatef(-imageWidth / 2.0f, -imageHeight / 2.0f, 0.0f);
    Then in the mouse move method:
    void GLWidget::mouseMoveEvent(QMouseEvent *event)
    {
    QPoint pos = event->pos();
    QMatrix q,t1,t2,s,t3;
    t1.translate(this->size().width() / 2, this->size().height() / 2);
    t2.translate(imageOffset.x(), imageOffset.y());
    s.scale(zoomFactor, zoomFactor);
    t3.translate(- imageWidth / 2, - imageHeight / 2);
    q = t1*t2*s*t3;
    QMatrix qinv = q.inverted();
    QPoint im = qinv.map(pos);
    qDebug() << im;
    }
    This works fine when as long as I dont scale the image. I can move around the image in the window and it translates the coordinates.
    This is is supposed to be simple.

  6. #6
    Join Date
    Aug 2006
    Posts
    20
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: OpenGL image viewer, need some help on implementation

    Seems like I multiplied the matrices in the wrong order.
    Doing it the opposite way solved the problem.
    q = t3*s*t2*t1;

  7. #7
    Join Date
    Feb 2007
    Posts
    49
    Thanks
    4
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: OpenGL image viewer, need some help on implementation

    Well you have something like this transformations:

    M = T1 * T2 * S * T3

    You transform vertex with above transformations. Because projection is simple, with given window coordinate you want to know that position in object (untransformed) space, you need to untransform window coordinate to object space...

    Vwindow = M * V

    V = inverse(M) * Vwindow

    inverse(T1 * T2 * S * T3) = inverse(T3) * inverse(T2) * inverse(S) * inverse(T1)

    Because inverse of translation is just changing the sign, and inverse of scale is reciprocal

    inverse(M) = (-T3) * (-T2) * (1 / S) * (-T1)

    With this matrix you can transform window coordinate to object space (the image).

    It's easy to build this matrix by yourself.

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: OpenGL image viewer, need some help on implementation

    Is there a specific reason why you're doing it with OpenGL?

  9. #9
    Join Date
    Aug 2006
    Posts
    20
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: OpenGL image viewer, need some help on implementation

    Quote Originally Posted by wysota View Post
    Is there a specific reason why you're doing it with OpenGL?
    Not really. Main reason is that I have used OpenGL before but for 3D.
    Is QPainter easier to use?

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: OpenGL image viewer, need some help on implementation

    I think you'd have fewer problems with a painter approach. All the rendering problems (transformations, etc.) would vanish and getting cursor coordinates would be as easy as reading a variable from the mouse event.

    The most basic way to implement the viewer would be to use a QLabel with a pixmap. You can also embed it into a scroll area if you want scroll bars. Of course you can draw the image yourself using QPainter if you want more control over it (like easy scaling, etc.).

  11. #11
    Join Date
    Feb 2007
    Posts
    49
    Thanks
    4
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: OpenGL image viewer, need some help on implementation

    We talk about HDR images, which pixel is represented with 16 bit float, 32 bit float or 32 bit integer. QPixmap doesn't support this kind of format. OpenGL support textures in 32 bit float format (GF 6 up, Radeon 9800 up) or 16 bit float (GF2 up). Also, he can use shaders for image processing.

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: OpenGL image viewer, need some help on implementation

    Quote Originally Posted by minimoog View Post
    We talk about HDR images, which pixel is represented with 16 bit float, 32 bit float or 32 bit integer. QPixmap doesn't support this kind of format.
    Does your screen support it? Because if not, there is no point in doing something which you'll never see.

    Also, he can use shaders for image processing.
    And probe texels for colours when he wants to check the pixel value?

    Using shaders would make sense if he had 100 images per second to process, but not with an image viewer. At least that's my point of view.

Similar Threads

  1. Help needed handling image data
    By toratora in forum General Programming
    Replies: 2
    Last Post: 11th May 2007, 09:24
  2. Replies: 0
    Last Post: 4th May 2007, 10:44
  3. Requirement for versatile image viewer
    By deekayt in forum General Discussion
    Replies: 1
    Last Post: 27th October 2006, 14:28
  4. How and when to repaint a widget ?
    By yellowmat in forum Newbie
    Replies: 7
    Last Post: 3rd April 2006, 16:36
  5. Image Viewer
    By sumsin in forum Qt Programming
    Replies: 3
    Last Post: 14th March 2006, 13:29

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.