Good way to view 2D images with an exact sizeing and viewing position

Hello,

I went through a few OpenGL tutorials, did a load of searches but can’t find a nice solution to my problem as most information on GL focuses on the use as a 3D platform. Here is what I try to do:

I want to display a two dimensional image in a OpenGL viewer to allow some GPU based live operations. The use case is a viewer for PTM style images (as I’m not allowed to post an URL, for further reference a search for PTM and Malzbender helps) where based on formula coefficients from read from multiple textures an image is calculated based on a light direction set by the user. This part is already working in an experimental viewer I wrote with a small Qt UI. What I want is a good way to set the viewing/projection parameters to get reliable scaling information as well as keep the current viewable area of the image when resizing.

To further demonstrate what already works here are some code snippets for better understanding. Most of the GL code is based on what I found in different tutorials I went through to learn the OpenGL basics:


...
// RTIglViewer is based on QGLWidget
void RTIglViewer::paintGL() {
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    float win_aspect_ratio = (float)width()/(float)height();
    gluPerspective(17/vscale, win_aspect_ratio, 1, 10);  // vsacle is a user-modifyable float for zoom initialy set to 1.0. Start value was set by trial and error for default window size

    float image_middle_height = (float)iheight/((float)iwidth*2);  // calculate image aspect ratio to set points of a Quad and the viewer direction correspondingly

    gluLookAt(0.5+vx, image_middle_height+vy, -2, // eye
              0.5+vx, image_middle_height+vy, 0, // center
              0, 1, 0); // up
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    ... // set uniform values with the virtual light positions

    glClear(GL_COLOR_BUFFER_BIT);

    glNormal3f(0.0, 0.0, 1.0);
    glBegin(GL_QUADS);
      glTexCoord2d(1, 1);
      glVertex3f(0.0, 0.0, 0.0);
      glTexCoord2d(1, 0);
      glVertex3f(0.0, image_aspect, 0);
      glTexCoord2d(0, 0);
      glVertex3f(1.0, image_aspect, 0);
      glTexCoord2d(0, 1);
      glVertex3f(1.0, 0.0, 0);
    glEnd();
}

When changing the viewer window size (not keeping the aspect ratio), the image size changes for example. I want to have a setup that shows the image with no border left and right, meaning the first pixel column has matches x=0.0 in GL-Space and the last column x=1.0. This should be kept while resizing. With this setup scale would be reliable and also I could display the user the exact zoom ratio/pixel mapping of texture resolution to viewer resolution.

Is the used projection view a good solution for this task? Would it be better to use some other viewing model for only a 2D image viewer maybe? Or is my approach good as a basic?

PS: Bonus charma points if anyone has a good hint where to find a good tutorial how to sneak in a rendering to a framebuffer (to get the image to the ram for further use) with an independent resolution. I need an easy solution to render the same setting just with a different resolution to easily get the image to a video output card (as in SDI TV referenc monitor output) or allow saving stills of the image after executing the shader.

To my opinion there’s no real interest in doing a perspective here since you are looking at a flat, 2D quad. I would go for a basic orthographic projection (with zmin=-1 and zmax=+1). So gluOrtho2D in this case.
You will then not need any gluLookAt anymore. Just draw a quad that fills the entire viewport.

For the scale, you might be interested by using the texture matrix.

Here is another link:
https://www.opengl.org/discussion_boards/showthread.php/123156-glMatrixMode(-GL_TEXTURE-)

To get back the image pixels you can simply get them by using glReadPixels with giving the viewport size to it.

I should also highlight that all of this is now considered as deprecated. If this is okay for you, there’s no problem in using these functionalities since they are still completely supported by most hardware. But for example, on MacOS you won’t be able to do that. This will be the same if you switch your GUI API to gtk-3…

Hey,

thank you for your reply.

[QUOTE=Silence;1283677]To my opinion there’s no real interest in doing a perspective here since you are looking at a flat, 2D quad. I would go for a basic orthographic projection (with zmin=-1 and zmax=+1). So gluOrtho2D in this case.
You will then not need any gluLookAt anymore. Just draw a quad that fills the entire viewport.[/QUOTE]
I already thought about switching to orthogonal view. Will do that next.

[QUOTE=Silence;1283677]For the scale, you might be interested by using the … (URL removed due to screwed board settings).

Here is another link:
… (URL removed due to screwed board settings)[/quote]
As the image aspect might not fill the entire viewport if the aspect ratio of viewer and image don’t fit this wouldn’t work as I want to loose the black border and fill the area if zooming in.

I already saw the glReadPixels function but I don’t get how to get an individual viewport for independent resolution and it looks like the only way to get data is at max 8 bit per channel? There has to be another way, isn’t there? Getting float or at least a 16 bit per color rendering for higher quality use.

What would be the new way than? As I said, I’d like a clean way (which in my view includes current tech, not deprecated). There is so much on the net regarding OpenGL that it makes finding the stuff I search not easy and almost everything is directed to 3D rendering task which of course is expected but isn’t OpenGL often used in some image processing applications also as graphic cards offer such fast processing speeds for images?

PS: Wth is this board software setup screwed so much. I get weird “Post denied. New posts are limited by number of URLs it may contain and checked if it doesn’t contain forbidden words.” (What does new posts mean and why can others post URLs?) I mean it took me some time as I just quoted Silence who posted an URL… This is weird.

You should do it first since you only manage images.

Then only adapt your projection to the image size.

If I understand you well, the previous answer should also answer this.
For your second point, your might be interested in reading this. Also, note that what will be displayed will be limited to 8 bytes per channel.

You then should target OpenGL 3.2 or higher, depending on your hardware capabilities. GL 3.2 looks far enough for what you want to do (but maybe I’m missing some newer extensions/features ?).
But be careful, several things you did here will have to be replaced (no more glu, no more GL matrices, no more glRotate…, no more glTexEnv… and no more glBegin…). All of these will have to be coded by yourself (matrix manipulations, projections, texture applications…).

[QUOTE=irieger;1283784]
PS: Wth is this board software setup screwed so much. I get weird “Post denied. New posts are limited by number of URLs it may contain and checked if it doesn’t contain forbidden words.” (What does new posts mean and why can others post URLs?) I mean it took me some time as I just quoted Silence who posted an URL… This is weird.[/QUOTE]

I don’t know. Maybe due to the fact that you are a new poster here.