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.