PDA

View Full Version : Exactly mapped textures



Cory Klein
03-28-2009, 12:53 PM
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?

Stuart McDonald
03-28-2009, 02:42 PM
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.

dletozeun
03-28-2009, 02:55 PM
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.

Ilian Dinev
03-28-2009, 03:33 PM
Stuart, glDrawPixels is as a good idea as using GDI's SetPixel() to blit a bitmap.

Cory Klein
03-28-2009, 08:05 PM
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?

Cory Klein
03-28-2009, 08:06 PM
And thanks, dletozeun, I will probably implement that. Either way, it will make the accurate drawing of my sprites much easier!

dletozeun
03-29-2009, 07:03 AM
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.