Actually I make sure the size of the label bitmap is equal to the texture quad, below is the complete function of the label drawing, I’m using Objectie-C/Cocoa so the “AABitmapData” object is made somewhere else, but I think is pretty straight forward to see what I do, remember, this function is call after I render the 3D model.
typedef struct SignTextureData
{
GLuint width, height, textureName;
double distance;
AAPoint point;
} SignTextureData;
int qsortSignTextureData(const void *e1, const void *e2)
{
return ((const SignTextureData *)e2)->distance - ((const SignTextureData *)e1)->distance;
}
- (void)renderSigns
{
NSArray *bitmapsArray, *coordinatesArray;
NSEnumerator *bitmapsArrayEnumerator, *coordinatesArrayEnumerator;
AABitmapData *bmp, *tmpBmp;
AAPoint pt3D, pt2D, cameraCenter;
GLdouble mvmatrix[16], projmatrix[16];
GLint viewport[4];
GLuint i, w, h, *data;
BOOL orderSigns = YES;
// check to make the textures
if (_signTextureQuantity == 0)
{
// create signs bitmaps and the arrays with them
[_modelSigns renderSigns];
bitmapsArray = [_modelSigns partSignBitmapsArray];
bitmapsArrayEnumerator = [bitmapsArray objectEnumerator];
coordinatesArray = [_modelSigns partSignCoordinatesArray];
coordinatesArrayEnumerator = [coordinatesArray objectEnumerator];
// allocate textures
_signTextureQuantity = [bitmapsArray count];
_signTextures = (SignTextureData *) malloc(sizeof(SignTextureData) * _signTextureQuantity);
for (i=0; i < _signTextureQuantity; i++) glGenTextures(1, &_signTextures[i].textureName);
// make the textures
for (i=0; i < _signTextureQuantity; i++)
{
glBindTexture(GL_TEXTURE_2D, _signTextures[i].textureName);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
bmp = [bitmapsArrayEnumerator nextObject];
w = nextPowerOfTwo([bmp width]);
h = nextPowerOfTwo([bmp height]);
tmpBmp = [[AABitmapData alloc] initWithWidth:w height:h];
[tmpBmp setIsMonochrome:NO];
[bmp maskedBlit: tmpBmp x: (w - [bmp width])/2 y: (h - [bmp height])/2];
[tmpBmp reset];
data = [tmpBmp drawingBytes];
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
_signTextures[i].width = w;
_signTextures[i].height = h;
_signTextures[i].point = [[coordinatesArrayEnumerator nextObject] cartesianPointValue];
[tmpBmp release];
}
// release signs bitmaps arrays
[_modelSigns releaseStoredArrays];
}
// setup 2D view
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, viewport[2], 0, viewport[3]);
// order signs
if (orderSigns)
{
cameraCenter.x = mvmatrix[3];
cameraCenter.y = mvmatrix[7];
cameraCenter.z = mvmatrix[11];
for (i=0; i < _signTextureQuantity; i++)
_signTextures[i].distance = AAPointDistance(cameraCenter, _signTextures[i].point);
qsort(_signTextures, _signTextureQuantity, sizeof(SignTextureData), qsortSignTextureData);
}
// render the textures
glEnable(GL_TEXTURE_2D);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5);
glShadeModel(GL_FLAT);
glDisable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
for (i=0; i < _signTextureQuantity; i++)
{
glBindTexture(GL_TEXTURE_2D, _signTextures[i].textureName);
pt3D = _signTextures[i].point;
gluProject(pt3D.x, pt3D.y, pt3D.z, mvmatrix, projmatrix, viewport, &pt2D.x, &pt2D.y, &pt2D.z);
w = _signTextures[i].width / 2;
h = _signTextures[i].height / 2;
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex3d(pt2D.x - w, pt2D.y - h, pt2D.z);
glTexCoord2f(1.0f, 0.0f);
glVertex3d(pt2D.x + w - 1, pt2D.y - h, pt2D.z);
glTexCoord2f(1.0f, 1.0f);
glVertex3d(pt2D.x + w - 1, pt2D.y + h - 1, pt2D.z);
glTexCoord2f(0.0f, 1.0f);
glVertex3d(pt2D.x - w, pt2D.y + h - 1, pt2D.z);
glEnd();
}
glDisable(GL_TEXTURE_2D);
glDisable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
// restore 3D view
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
hope whit this you get the idea, thanks!!
EDIT: btw, the sort I did does not work properly…