Reputation: 454
I'm working on font generation solution and facing texture problem. I'm creating texture atlas dynamically and then mapping every letter by their texture coordinates.
Here's result of mapping "t" letter: (generated texture is on top and what I draw is on bottom)
It seem that the issue is that size of the primitive and texture region is not matching that's why openGL trying to resize it. I'm using GL_NEAREST on both Min and Mag when loading / rendering texture
Here's the render code:
glBegin(GL_TRIANGLE_STRIP);
float twidth = 7.f / 512.f;
float theight = 11.f / 512.f;
float width = 7.f;
float height = 11.f;
float w = width / 2.f;
float h = height / 2.f;
float x = 100;
float y = 100;
float tx = 135.f / 512.f;
float ty = 0;
glTexCoord2f(tx, ty);
glVertex2f(x - w, y-h);
glTexCoord2f(tx + twidth, ty);
glVertex2f(x + w, y-h);
glTexCoord2f(tx, ty + theight);
glVertex2f(x - w, y+h);
glTexCoord2f(tx + twidth, ty + theight);
glVertex2f(x + w, y+h);
glEnd();
Here's initialization code:
glViewport(0,0,width,height);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
// Set up the GL state.
glClearColor(1, 1, 1, 1);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
//glDisable(GL_BLEND);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Texture loading code:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 512, 512,
0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, &texBinary[0]);
Upvotes: 1
Views: 759
Reputation: 162164
Your problem stems from a common misconception how OpenGL treats texture coordinates.
The texture coordinates 0 and 1 are not on pixel centers!
Textures are actually multidimensional samplers and the texture data provides the support for the sampler interpolation. Now the way this sampling works puts some constraints on the texture coordinate mapping. One boundary condition is, that support points should be equidistant along dimensions. Now remember that OpenGL supports texture wrapping.
Your image is basically a raster, a grid of quadrats, called pixels. Say you got 8 pixels in a row
|0|1|2|3|4|5|6|7|
The texture coordinates are
|0|1|2|3|4|5|6|7|
^ ^
0.0 1.0
This is the well known fence post problem. Your pixel centers are actually at texture coordinates
(0/8 + 1/8)/2, (1/8 + 2/8)/2, …, (7/8 + 8/8)/2
or more general at
(2i + 1)/2N
However in the case of text rendering you seldomly want to filter your textures; if you minify rasterized glyphs the result will look to weak, magnifying rasterized glyphs loose crispnes or get aliased.
Texture rectangles are perfectly suited for this case, if you want to use the fixed function pipeline. In later OpenGL versions that mandate the use of shaders (3 and upwards) there is a special texture sampling function that accepts absolute texel indices instead of a sampler interpolation coordinate. Either of them is perfectly suited for the task.
And should you use Vector Textures or Distance Maps, then the way you sample glyps is completely different anyway.
Upvotes: 3