OpenGL总结14-字符与文字输出

字符基础

字符图元基础(根据计算机图形学进行简单的总结):

字样:一组字符的完整设计风格
字体:一组按照特定尺寸和格式的目标字符样式

衬线字体:易于阅读
无衬线字体:易于识别
单一宽度字体:每个字符大小是相同的,不受字符本身的大小影响
比例字体:每个字符的大小根据自身的大小决定

字体的表示有两种方式(OpenGL本身不提供字符支持,通过调用window的接口实现):

  1. 位图字体:与光栅化类似(也叫光栅化字体),在网格上用一个一个像素块拼出一个字符形状,位图字体比较简单,显示时方便,但是位图字体对于缩放等操作并不具备很好的支持,因为要调整像素的位置,同时因为字体存储在高速内存中,所以很占地方,尤其是字体需要更多像素点的时候,并且显示效果也不是特别的好(锯齿严重,OpenGL中一般用位图字体显示不需要缩放和旋转的内容)。
  2. 轮廓字体:利用点和曲线形成字体(跟写字差不多,定好点,然后连线),轮廓字体对于缩放等操作有较好的支持(因为只要控制点和线的位置就可以实现,不易不会产生变形,类似矢量图),显示效果较好同时不需要过多的内存,但是需要存入帧缓存中(需要计算比较耗时,时间换空间)。

因为OpenGL本身不提供文字的绘制,所以需要调用window的接口,但是有些字符我们可以自己生成,然后保存在字库中进行调用。(不存在需要的字符的时候)

OpenGL显示列表

将绘制对象的一系列语句保存成一个具有名字的列表,这样每次绘制可以直接调用这个名字就可以进行绘制,这样可以避免每次都要进行命令的传递,可以节省时间,调用也变的简单,还可以重复利用。

创建列表

glNewList(id,mode);

glEndList();

这两个语句之间的所有语句将会形成列表,也就是可以当作一个统一的对象进行调用。
参数:

  1. id:列表名
  2. mode:执行模式,GL_COMPILE和GL_COMPILE_AND_EXECUTE,日后执行则选择第一个,如果现在就需要执行,选第二个,两种模式都会将这个对象进行保存,直到释放为止。

显示列表中语句的参数值是固定的不能被更改,所以不能包含顶点指针等内容。列表的id同样适用OpenGL为我们准备的分配函数避免错误。

glGenLists(num)

通过上面的语句可以分配指定数量的id,id是唯一标识符。但是如果语句无法正常分配id的时候,就会返回0,一般在OpenGL中0的id代表着不是用这个对象。

如果对这个id不是很放心,需要查看它是否被使用过,那么可以用

glIsList(id);//查看是否已经是列表

执行列表也有专门的函数

glCallList(id);//简单用法

glIstBase(offset);//基础值,第一个位置值,之后的所有列表的标识都是通过列表id与这个值相加得到的
glCallLists(num,dataType,listIdArray);

参数:

  1. num:需要调用的列表的数量
  2. dataType:列表中的数据类型
  3. listIdArray:存放id的数组,通过数组的id与基础值相加计算得到调用的标识

我们输出文字时,采用ASCII码的值作为列表的标识。

之前有写过轮廓字体的输出,位图字体的输出稍微不同。

wglUseFontBitmaps(m_HDC, base, 256, m_Base);//从base开始创建256个位图的列表

轮廓字体调用的是wglUseFontOutlines,同时输出文字的位置要使用

glRasterPos2f(x,y);

这个语句与glVertex类似,只不过是给字符显示设置起始位置的。

要在OpenGL输出文字,您需要使用一个库或API,例如: 1. FreeType库 - 它是一个免费的,开源的库,用于处理字体文件,并将字形转换为可呈现的形式。 2. GLFW库 - 它是一个用于创建窗口和处理用户输入的库,它还提供了一个简单的API用于输出文字。 下面是使用FreeType库在OpenGL输出文字的步骤: 1. 下载并安装FreeType库。 2. 创建一个OpenGL窗口。 3. 加载字体文件并创建字形。 4. 将字形转换为纹理。 5. 在OpenGL窗口中呈现纹理。 下面是代码示例: ``` #include <ft2build.h> #include FT_FREETYPE_H FT_Library ft; FT_Face face; if (FT_Init_FreeType(&ft)) { // 处理错误 } if (FT_New_Face(ft, "font.ttf", 0, &face)) { // 处理错误 } FT_Set_Pixel_Sizes(face, 0, 48); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (unsigned char c = 0; c < 128; c++) { if (FT_Load_Char(face, c, FT_LOAD_RENDER)) { // 处理错误 continue; } GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, face->glyph->bitmap.width, face->glyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 将纹理渲染到屏幕上 } ``` 注意:在上面的示例中,我们只是将纹理渲染到屏幕上,实际上,您需要使用一些算法来确定每个字符的位置和大小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值