I have some bitmaps that I want to display exactly on the screen, mapping pixels in the bitmap exactly to pixels on the screen, no scaling, rotation, filtering, etc. This is partly because I want a clean look (exact reproduction of image) and part because of render speed. I am finding this difficult, because of a few problems. First, is the following part in my code:
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
It’s hard to get the size of a texture to be the exact right size on this scale instead of a pixel scale. If my image is 32x32 pixels, finding coordinates of the corners for the sprite vertices is difficult.
Since I know what my screen resolution will always be, can I solve that problem by just setting those to the actual screen resolution?
Second, is this:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
I have to have some sort of texture filter in order for the image to show at all right now, but running the bitmap through a filter defeats the whole purpose of not changing the image, right?
I think I should be able to do this because I know that I will never be resizing or rotating the images. Do I have to avoid the whole sprite vertex idea all together to do this?
Why use textures at all? You could just blit the screen. Something like…
// Copied from SIGRAPH 97 I think
static void window_pos( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
{
GLfloat fx, fy;
/* Push current matrix mode and viewport attributes */
glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT );
/* Setup projection parameters */
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glDepthRange( z, z );
glViewport( (int) x - 1, (int) y - 1, 2, 2 );
/* set the raster (window) position */
fx = x - (int) x;
fy = y - (int) y;
glRasterPos4f( fx, fy, 0.0, w );
/* restore matrices, viewport and matrix mode */
glPopMatrix();
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glPopAttrib();
}
void showScreen(unsigned char* pPixels, int x, int y, int w, int h)
{
window_pos(x,y,1,1);
glDrawPixels(w,h,GL_RGBA,GL_UNSIGNED_BYTE,pPixels);
}
WARNING! I am a noob, so there maybe all sorts things wrong with the above.
You can set the orthographic projection as:
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
// set a 2D orthographic projection
glOrtho(0, w, h, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
This way the upper left corner coordinates are (0,0) and the lower right one (w, h) where w and h are respectively the screen width and screen height.
This way it is easier to position your sprites at pixel precision.
Stuart, glDrawPixels is as a good idea as using GDI’s SetPixel() to blit a bitmap.
This sentence, grabbed from the last paragraph on the Bit Blit article on wikipedia, makes me wary of blitting:
“this makes blitting significantly slower than sprite manipulation”
Plus, I still don’t quite understand how the sprite gets from a png to on the screen, from using the code above. Do you have a link to the rest of the code, or even better, an explanation as to what it is doing?
And thanks, dletozeun, I will probably implement that. Either way, it will make the accurate drawing of my sprites much easier!
One correction: Remove the glPushMatrix call if you don’t call glPopMatrix after, otherwise you would have a stack overflow!
This is my mistake, copy and paste is evil.