Lighthouse3d.com >> GLUT Tutorial >> Fonts >> Bitmap Fonts and Orthogonal Projections

一般用法下,位图字体只能以二维的形式显示信息给用户.例如,一个简单的例子,我们想显示应用程序每秒的帧数.这些信息可以驻留在同一个位置,即使用户移动镜头.除此之外,用二维的正交投影比透视投影更容易计算这些位置,因为我们可以指定用像素表示该位置.

实现的基本模式是以之前的方式绘制世界,用透视投影,然后切换到正交投影来绘制文本.执行完最后一步之后我们要恢复到原来的视角,这样下一帧就会正确显示.

接下来我们演示一个渲染函数的模板来大道该效果:

void renderScene() {

// do everything we need to render the world as usual
... setOrthographicProjection(); glPushMatrix();
glLoadIdentity();
renderBitmapString(,,GLUT_BITMAP_HELVETICA_18,"Lighthouse3D");
glPopMatrix(); restorePerspectiveProjection(); glutSwapBuffers();
}

上面有两个新函数: setOrthograpicProjection and restorePerspectiveProjection.第一个函数始于转换矩阵模式到GL_PROJECTION,意味着我们在镜头下工作.然后我们保存之前的设置,在这个例子中是引用自其它某处定义好的透视投影.然后我们用glLoadIdentity函数重置矩阵,并用gluOrtho函数定义一个正交投影.

该函数的参数是表示从x到y轴的范围.然后转换沿着y轴滑动,正值是向下,翻译成原型是到左上角.这样使输出文本到屏幕坐标更简单.

变量w和h在其它地方计算好(见之前changeSize函数).

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(, w, , h); // invert the y axis, down is positive
glScalef(, -, ); // mover the origin from the bottom left corner
// to the upper left corner
glTranslatef(, -h, ); // switch back to modelview mode
glMatrixMode(GL_MODELVIEW);
}

一个演示正交投影的快速方法如下.方法是设置投影而无需测量和翻译.

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(, w, h, ); // switch back to modelview mode
glMatrixMode(GL_MODELVIEW);
}

该函数非常简单.当我们在设置正交投影前保存透视投影的设置的时候,我们需要做的只是更改矩阵模式到GL_PROJECTION,然后弹出矩阵.然后恢复设置,最后更改矩阵模式回GL_MODELVIEW.

void restorePerspectiveProjection() {

    glMatrixMode(GL_PROJECTION);
// restore previous projection matrix
glPopMatrix(); // get back to modelview mode
glMatrixMode(GL_MODELVIEW);
}

上面这个renderBitmapString函数,上一节介绍过,会连续写入字符,不包含额外的空间,除了文本本身带有空格字符外.为了添加额外的空间,我们必须保持跟踪当然的栅格位置,这样才可以添加额外的空间到x坐标.至少有两种不同的方法来保持跟踪栅格位置.一种是在绘制完一张位图之后计算当前的栅格位置.另一种是专注于请求OpenGL的关于当前栅格位置的状态机器.

第一种方法需要我们知道字符的维度.最大的高度一直保持为一个特殊字体的常量,在多数字体中宽度是可以任意变更的.幸运的是GLUT提供了一个函数来返回字宽.glutBitmapWidth原型如下:

int glutBitmapWidth(void *font, int character);

font - GLUT中的预定义字体之一,见上一节中列出的可选值

character - 我们想要知道字宽的字符

所以,例如我们需要一个函数来写入一个固定每个字符所占像素量的字符串,我们可以如下实现:

void renderSpacedBitmapString(

            float x,
float y,
int spacing,
void *font,
char *string) { char *c;
int x1=x; for (c=string; *c != '\0'; c++) { glRasterPos2f(x1,y);
glutBitmapCharacter(font, *c);
x1 = x1 + glutBitmapWidth(font,*c) + spacing;
}
}

如果我们想要绘制垂直的文本,可以如下实现:

void renderVerticalBitmapString(

            float x,
float y,
int bitmapHeight,
void *font,
char *string) { char *c;
int i; for (c=string,i=; *c != '\0'; i++,c++) { glRasterPos2f(x, y+bitmapHeight*i);
glutBitmapCharacter(font, *c);
}
}

变量bitmapHeight可以很容易计算得出,因为我们知道每个字体的最大高度,就是字体名的最后那串数字.例如GLUT_BITMAP_TIMES_ROMAN_10是占10个像素的高度.

最后一件事是,GLUT提供了另外一个函数来处理位图字体,就是glutBitMapLength函数,它可以以像素为单位计算一个字符串的长度.函数的返回值是字符串中字符的宽度总和.原型如下:

int glutBitmapLength(void *font, char *string);

font -  GLUT中的预定义字体之一,见上一节中列出的可选值

string - 我们想要知道字宽的字符串

[译]GLUT教程 - 位图和正交投影视图的更多相关文章

  1. [译]GLUT教程 - 位图字体

    Lighthouse3d.com >> GLUT Tutorial >> Fonts >> Bitmap Fonts 位图字体一般是二维字体.虽然我们会把它放到三维 ...

  2. [译]GLUT教程(目录)

    http://www.lighthouse3d.com/tutorials/glut-tutorial/ GLUT是OpenGL Utility Toolkit的意思.作者Mark J. Kilgar ...

  3. [译]GLUT教程 - 整合代码5

    Lighthouse3d.com >> GLUT Tutorial >> Extras >> The Code So Far V 该代码与位图字体的代码类似.区别是 ...

  4. [译]GLUT教程 - 渲染到子窗体

    Lighthouse3d.com >> GLUT Tutorial >> Subwindows >> Rendering to Subwindows 先回顾一下之前 ...

  5. [译]GLUT教程 - 整合代码6

    Lighthouse3d.com >> GLUT Tutorial >> Extras >> The Code So Far VI 下面代码以窗体模式启动.你可以在 ...

  6. [译]GLUT教程 - 游戏模式

    Lighthouse3d.com >> GLUT Tutorial >> Extras >> Game Mode 根据GLUT官网的说明,GLUT的游戏模式是为开启 ...

  7. [译]GLUT教程 - 笔划字体

    Lighthouse3d.com >> GLUT Tutorial >> Fonts >> Stroke Fonts 笔划字体是用线条生成的.跟位图字体相反,笔划字 ...

  8. [译]GLUT教程 - 整合代码4

    Lighthouse3d.com >> GLUT Tutorial >> Pop-up Menus >> The Code So Far IV 以下代码使用了位图字 ...

  9. [译]GLUT教程 - glutPostRedisplay函数

    Lighthouse3d.com >> GLUT Tutorial >> Avoiding the Idle Func >> glutPostRedisplay 直 ...

随机推荐

  1. java.sql.SQLException: Access denied for user 'roo'@'localhost' (using password: YES)

    初学mysql,安装了mysql8.0.11,激动的用jdbc连接数据库,出现error,折腾了三天依旧无解,最后无奈装了比较稳定的mysql5.5,问题得以解决,很迷,但只要error没了就开心. ...

  2. 最基础的java

    一.Window中常见的dos命令 在哪里操作dos命令: Win7 ---> 开始  ---->所有程序--->附件---->命令提示符 Win7-->  开始  -- ...

  3. [POI2007]Tourist Attractions

    题目大意: 给你一个$n(n\leq 2\times 10^4)$个点,$m(m\leq 2\times 10^5)$条边的带边权的连通图.其中有$k(k\leq 20)$个关键点.关键点之间有$g$ ...

  4. php的一些语法

    命名空间: 一个类为App/Http/Controllers/Controller,则该类的命名空间为App/Http/Controllers,可以通过use关键字导入该类,也可以导入命名空间,但是该 ...

  5. Spcomm 属性详解

    http://wenku.baidu.com/link?url=w53wCrhi_E33atqp0joeG029YO3H2z4Xy101oGbKqhG9bfWJQHSmcMi4q7l6xrS424St ...

  6. Ubuntu system zabbix-server-3.x install documentation

    Installing repository configuration package wget http://repo.zabbix.com/zabbix/3.0/ubuntu/pool/main/ ...

  7. Tomcat:Java Web服务器配置详解

    一.Tomcat概述 1.tomcat简介 tomcat是基于JDK的web服务器,其能运行Servlet和JSP规范总.Tomcat 5支持最新的Servlet 2.4 和JSP 2.0规范.实际上 ...

  8. vertex buffer 数据结构 如何读vb的memory pool

    vertex attribute (declaration)    vertex stream (memory pool) 这两部分 通过attribute 里面对memory的描述把两部分 vbo ...

  9. 【重点突破】—— 百度地图在React单页面应用中的使用

    前言:百度地图是网页中使用地图的常用第三方工具,这里结合React项目中学到的应用场景总结一些使用要点. 一.在网页中嵌入百度地图 搜百度地图开放平台,注册百度开发者账号 控制台:查看应用.创建应用( ...

  10. 联想Y430P CentOS 7.3 无线网络的配置

    # uname -a # 查看内核/操作系统/CPU信息的Linux系统信息命令 [root@www ~]# uname -a Linux www SMP Tue Nov :: UTC x86_64 ...