Hello fellow OpenGL experts, enthusiasts, and confused folk such as me.
I’ve looked for three days online and I found a lot of useful and related information, but I can’t find the answer to my problem.
I’m using glDrawPixels() with some success to display a bitmap image. The problem is that I can’t control the placement of the image do the degree that I desire.
I’m dealing only with 2D. The images I’m using are quite large so I don’t think I want to draw a texture on a quad. Every time I need to change the image it’s the difference between copying to the texture memory or copying to the frame buffer using glDrawPixels(). I don’t see much difference between them and I’m pretty happy with the performace of glDrawPixels() at this point. (Or I was until I came across this problem)
I use glPixelZoom() to set the zoom factor, then copy to the screen from the bitmap in memory using glDrawPixels().
It works fine except that I want to control the placement of the image down to screen pixel precision and I can’t seem to do it.
For example, if the zoom factor is 16, each image pixel will be 16x16 screen pixels. As it is, glDrawPixels() starts drawing on the image pixel boundary in the lower-left corner. But there are times when I want to draw, say, only 3/4 of the pixel in the x-dimension. In this case I want to “skip over” the left-most 4 screen pixels and draw only 12 screen pixels for image pixels along the left edge of the screen.
Here’s a bare-bones version of what I’m doing:
// Set "copy from" location in the image glPixelStorei( GL_UNPACK_SKIP_ROWS, imageY ) ; glPixelStorei( GL_UNPACK_SKIP_PIXELS, imageX ) ; glPixelStorei( GL_UNPACK_ROW_LENGTH, bitmapWidth ) ; // Set zoom factor glPixelZoom( zoomFactor, zoomFactor ) ; // Set "draw to" location in frame buffer glRasterPos2i( drawX, drawY ) ; // Draw it glDrawPixels( imageWidth, // width of displayed region imageHeight, // height GL_BGR_EXT, // format (24-bit BGR DIB) GL_UNSIGNED_BYTE, // source array type (GLvoid*)lpBitmap ) ; // pointer to image
This works as long as I don’t need to begin drawing in the middle of a pixel. I should mention that the image can start in the middle of the window also. (For example, if the user zooms out so far that the entire image is visible in the window) This means my problem only occurs when part of the bitmap is “outside” of the window to the left or bottom.
I tried setting the raster position outside the window. This resulted in an invalid raster position and nothing was drawn. Before the call to glDrawPixels() I tried using this hack I found online:
// Set raster position to lower-left corner (valid raster position) glRasterPos2i( 0, 0 ) ; // Move to "draw to" location glBitmap( 0, 0, 0.0f, 0.0f, (GLfloat)drawX, (GLfloat)drawY, NULL ) ;
The hack effectively starts drawing outside of the window. But it isn’t working for me.
The following is how I set up my viewport and perspective, since it may be related.
void OpenGLWindow::OnSize(UINT nType, int cx, int cy) ... // Set viewport glViewport( 0, 0, (GLsizei) cx, (GLsizei) cy ) ; // Set up 2D orthographic projection glMatrixMode( GL_PROJECTION ) ; glLoadIdentity(); gluOrtho2D( 0.0f, (GLdouble) cx, 0.0f, (GLdouble) cy ) ; // Set up Modelview matrix glMatrixMode( GL_MODELVIEW ) ; glLoadIdentity() ; ... }
So here are my questions:
-
How can I start drawing in the middle of a pixel, or alternatively, draw whole pixels but start drawing outside the window.
-
Can I use the glBitmap() trick? Why won’t it work for me?
-
Does the raster position after the glBitmap() call need to be valid also? If so, can I extend my “valid raster space” past the boundaries of the window?
Wow… I just re-read this. Sorry it’s so long. I hope it doesn’t scare anyone away, I just wanted to be thorough in explaining the problem.
Thanks in advance,
-tom
[This message has been edited by kanet77 (edited 03-19-2003).]