博客转自:http://www.lighthouse3d.com/tutorials/glut-tutorial/bitmap-fonts-and-orthogonal-projections/
位图字体的通常使用是在2维空间给用户提供信息。例如,一个简单的例子就是当我们想去显示应用程序的帧率的时候。显示信息应当出现在屏幕上的固定位置,即使在用户移动相机视野时候。利用正交投影很容易计算位图字体的位置,而不是依靠透视投影,因为我们可以阐明像素的位置。
基本的概略流程就是在透视投影模式下去绘制世界,之后,切换到正交投影去绘制字体,之后在切换回透视投影模式即可。接下俩的模板就是一个渲染函数去实现这个效果。
void renderScene() { // do everything we need to render the world as usual ... setOrthographicProjection(); glPushMatrix(); glLoadIdentity(); renderBitmapString(5,30,GLUT_BITMAP_HELVETICA_18,"Lighthouse3D"); glPopMatrix(); restorePerspectiveProjection(); glutSwapBuffers(); }
这两个函数 setOrthograpicProjection 和 restorePerspectiveProjection 在下面呈现。第一个函数 改变矩阵模式到 GL_PROJECTION,意味着我们正在相机上工作。之后,我们并保存先前的透视投影设置,方便绘制字体后可以恢复。之后设置 GL_PROJECTION 矩阵为单位矩阵,利用gluOrtho声明正交投影。
这个函数的参数表明x和y的范围,围绕Y周反转之后平移操作。平移中的负值是向下,其实就是平移原点到左上角。这种方式使在屏幕坐标上写字符很容易。
The variables w and h we’re computed elsewhere (see the changeSize function in the source code).
void setOrthographicProjection() { // switch to projection mode glMatrixMode(GL_PROJECTION); // save previous matrix which contains the //settings for the perspective projection glPushMatrix(); // reset matrix glLoadIdentity(); // set a 2D orthographic projection gluOrtho2D(0, w, 0, h); // invert the y axis, down is positive glScalef(1, -1, 1); // mover the origin from the bottom left corner // to the upper left corner glTranslatef(0, -h, 0); // switch back to modelview mode glMatrixMode(GL_MODELVIEW); }
A faster way to perform the ortho projection is as follows. The idea is to set the projection in such a way that no scale and translation are required.
void setOrthographicProjection() { // switch to projection mode glMatrixMode(GL_PROJECTION); // save previous matrix which contains the //settings for the perspective projection glPushMatrix(); // reset matrix glLoadIdentity(); // set a 2D orthographic projection gluOrtho2D(0, w, h, 0); // switch back to modelview mode glMatrixMode(GL_MODELVIEW); }
This function is very simple. Since we saved the settings of the perspective projection before we set the orthographic projection, all we have to do is to change the matrix mode to GL_PROJECTION, pop the matrix, i.e. restore the settings, and finally change the matrix mode again to GL_MODELVIEW.
void restorePerspectiveProjection() { glMatrixMode(GL_PROJECTION); // restore previous projection matrix glPopMatrix(); // get back to modelview mode glMatrixMode(GL_MODELVIEW); }
The function above, renderBitmapString, as presented in the previous section will write the characters continuously, without extra spacing, except where a space character appears in the text. In order to add extra spacing we must keep track of where the current raster position is so that we can add the extra spacing to the x coordinate, for example. There are at least two different approaches to keep track of the raster position; one is to compute the current raster position after drawing a bitmap. The second option involves asking the OpenGL state machine what is the current raster position.
The first approach requires that we know the dimensions of the character. While the maximum height is always constant for a particular font, the width may vary in some fonts. Fortunately GLUT provides a function that returns the width of a character. The function is glutBitmapWidth and the syntax is as follows:
int glutBitmapWidth(void *font, int character); Parameters: font – one of the pre defined fonts in GLUT, see the previous section for the possible values. character – the character which we want to know the width
So for instance if we want a function that writes a string with a certain amount of pixels between each character we can write:
void renderSpacedBitmapString( float x, float y, int spacing, void *font, char *string) { char *c; int x1=x; for (c=string; *c != '