Directx11教程(66) D3D11屏幕文本输出(1)
原文:Directx11教程(66) D3D11屏幕文本输出(1)
在D3D10中,通过ID3DX10Font接口对象,我们可以方便的在屏幕上输出文字信息,一个DrawText函数就能解决所有问题,但在D3D11中个,这个变得超级麻烦,因为微软移除了Font接口,要在屏幕上输出文本,用户需要做很多事情。
通常我们可以用以下的方法来输出文本信息:
(1)用纹理贴图的方法,把所有的字体存储在一张纹理上,再做一个字体查询表,对应纹理的相应位置,可以用2D渲染的方式,把文本染出来,但这种方法不是很灵活,英文还好说,字母字符就那么多,但对于汉字就麻烦了,另外字体大小不能任意缩放。
(2)通过和GDI/GDI+进行交互,得到字体,把它们存储在纹理中,然后再用2D渲染的方式渲染出来,这种方法可以得到任意大小的文字,而且对英文、中文都适用。
(3)用direct write,但据说效率不高,http://www.braynzarsoft.net/index.php?p=D3D11FONT 这篇教程中有详细的介绍。
(4)使用一些文本输出控件,比如CEGUI。
(5)用FreeType2动态生成字体纹理,然后用2D渲染的方式显示。
在本篇教程中,我们先看看第一种方法的具体实现,程序的代码是在myTutorialD3D11_61的基础上修改的。
1、准备一副图片,该图片中包含所有的英文字母、标点以及特殊字符(ascii码32-126之间的所有字符),该图片将被当作纹理。
该图片背景是纯黑色,RGB为(0,0,0),用该图片产生font.dds纹理资源文件。
2、建立一个文本索引文件fontdata.txt,该文件索引ascii码32-126之间的所有字符,该文件的格式为:
[Ascii value of character] [The character] [Left Texture U coordinate] [Right Texture U Coordinate] [Pixel Width of Character]
第一列为字符的ascii码,第二列为字符,第三列为字符左边的纹理坐标,第四列为字符右边的纹理坐标,第五列为像素宽度。
32 0.0 0.0 0
33 ! 0.0 0.000976563 1
34 " 0.00195313 0.00488281 3
35 # 0.00585938 0.0136719 8
…
125 } 0.573242 0.576172 3
126 ~ 0.577148 0.583984 7
通过这几列值,我们就可以把一个字符和纹理中的相应位置对应起来,比如一个字符串"hello”,我们可以动态创建5个四边形,每个四边形有2个三角形组成,三角形的顶点位置为该字符在屏幕上的显示位置,顶点属性中包括纹理坐标,该四边形将通过纹理的方式显示该字符。
下边大致介绍下增加的代码:
我们的2D 文本渲染在TextClass中,可以把该类看作一个sprites class, 主要的功能就是渲染文本。
首先该类用了2个结构来描述文本,第一个是文本句子的结构类型,因为文本都是显示在四边形中,所以该类中包含了顶点缓冲、索引缓冲、顶点数量、顶点颜色等信息。
struct SentenceType
{
ID3D11Buffer *vertexBuffer, *indexBuffer;
int vertexCount, indexCount, maxLength;
float red, green, blue;
};
struct VertexType
{
D3DXVECTOR3 position;
D3DXVECTOR2 texture;
};
通过函数InitializeSentence、UpdateSentence我们生成文本句子数据,RenderSentence函数渲染执行最终的渲染,其中的texture就是包含字体的纹理,该函数调用FontShader类实现最终的渲染。
bool TextClass::RenderSentence(ID3D11DeviceContext* deviceContext, SentenceType* sentence, D3DXMATRIX worldMatrix,
D3DXMATRIX orthoMatrix, ID3D11ShaderResourceView* texture)
类FontClass建立文本句子顶点、索引数据,FontShaderClass类用执行渲染。
另外,还有2个shader文件:font.vs和font.ps, ps文件中会根据纹理的颜色来设置alpha的值,这样既可以很好的把字体纹理和背景混合起来。
// 根据选取字符.
color = shaderTexture.Sample(SampleType, input.tex);
//如果纹理为黑色,设置透明,这样可以镂空不需要的背景,只显示字体
if(color.r == 0.0f)
{
color.a = 0.0f;
}
else
{
color.rgb = pixelColor.rgb;
color.a = 1.0f;
}
最终的渲染代码在GraphicsClass类中,主要在开始文本渲染时,要禁用zbuffer,并开启alpha blend功能,渲染完成后,进行相反的操作。
// 关掉z buffer,以便2d渲染
m_D3D->TurnZBufferOff();
// 打开alpha blending
m_D3D->TurnOnAlphaBlending();
//得到正交投影矩阵
m_D3D->GetOrthoMatrix(orthoMatrix);
// 渲染文本
result = m_Text->Render(m_D3D->GetDeviceContext(), worldMatrix, orthoMatrix,m_TexManager->createTex(m_D3D->GetDevice(),string("font.dds")));
if(!result)
{
return false;
}
// 关闭alpha blending
m_D3D->TurnOffAlphaBlending();
// 打开z buffer
m_D3D->TurnZBufferOn();
程序执行后的界面如下,我们用白色和黄色显示了几个字tessellation demo by mikewolf:
完整的代码请参考:
工程文件myTutorialD3D11_63
代码下载:
稍后提供
Directx11教程(66) D3D11屏幕文本输出(1)的更多相关文章
- Directx11教程(18) D3D11管线(7)
原文:Directx11教程(18) D3D11管线(7) 光栅化阶段(RS)之后,将进入PS/OM阶段. 参考外文资料:http://fgiesen.wordpress.com/2011/07/01 ...
- Directx11教程(15) D3D11管线(4)
原文:Directx11教程(15) D3D11管线(4) 本章我们首先了解一下D3D11中的逻辑管线,认识一下管线中每个stage的含义. 参考资料:http://fgiesen.wordpress ...
- Directx11教程(53) D3D11管线(8) GS的调度执行
原文:Directx11教程(53) D3D11管线(8) GS的调度执行 在前面的教程中,我们分析了VS-PS的shader管线组合执行过程,本章我们分析一下VS-GS-PS的管线执行 ...
- Directx11教程(17) D3D11管线(6)
原文:Directx11教程(17) D3D11管线(6) VS shader输出clip空间的顶点位置及参数信息(比如颜色)到一个FIFO中,之后PA(primitive assembl ...
- Directx11教程(13) D3D11管线(1)
原文:Directx11教程(13) D3D11管线(1) 从本篇教程开始,我们暂停代码的学习,先来了解一下D3D11的管线,这些管线不涉及具体的硬件,而是着重于理解能够支持D3D11的管 ...
- Directx11教程(16) D3D11管线(5)
原文:Directx11教程(16) D3D11管线(5) 本章我们学习VS中具体做些什么事情? 首先再看看我们的VS shader代码: Clolor.vs - PixelInputType Col ...
- Directx11教程(14) D3D11管线(3)
原文:Directx11教程(14) D3D11管线(3) 现在我们开始学习一些CP(command processor)的知识.参考资料: http://fgiesen.wordpres ...
- Directx11教程(14) D3D11管线(2)
下面我们来了解一些GPU memory的知识,主要参考资料:http://fgiesen.wordpress.com/0211/07/02/a-trip-through-the-graphics-pi ...
- Directx11教程(50) 输出depth/stencil buffer的内容
原文:Directx11教程(50) 输出depth/stencil buffer的内容 有时候,我们需要查看depth/stencil buffer的内容,比如上一章中,我们要查看sten ...
随机推荐
- 深入浅出 Java Concurrency (23): 并发容器 part 8 可阻塞的BlockingQueue (3)[转]
在Set中有一个排序的集合SortedSet,用来保存按照自然顺序排列的对象.Queue中同样引入了一个支持排序的FIFO模型. 并发队列与Queue简介 中介绍了,PriorityQueue和Pri ...
- Leetcode238. Product of Array Except Self除自身以外数组的乘积
给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积. 示例: 输入: [1 ...
- git pull拉取远程指定分支
1.若git clone之后想拉取某个指定分支:先git pull ,然后git checkout 指定分支名称 2.若git clone之后想拉取某个指定分支:先git fetch origin 分 ...
- 华为云DevCloud一枝独秀
DevOps,是Development和Operations的组合词,是指一组过程.方法与系统的统称,用于促进开发.技术运营和质量保障部门之间的沟通.协作与整合.DevOps是一种重视“软件开发人员( ...
- loj2324 「清华集训 2017」小 Y 和二叉树
https://loj.ac/problem/2324 太智障,一开始以为中序遍历的第一个点一定是一个叶子,想了个贪心.然而,手算了一下,第一个点都过不了啊. input 5 2 3 4 1 3 3 ...
- Hosts 广告
# 百度 127.0.0.1 cpro.baidustatic.com 127.0.0.1 dup.baidustatic.com 127.0.0.1 hm.baidu.com 127.0.0.1 i ...
- mybatis深入理解(一)-----Mybatis初始化机制详解
对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外.本章将通过以下几点详细介绍MyBatis的初始化过程. 一. MyBatis的初始化做了什么 1.configuration ...
- 一站式WPF--依赖属性(DependencyProperty)一
Windows Presentation Foundation (WPF) 提供了一组服务,这些服务可用于扩展公共语言运行时 (CLR) 属性的功能,这些服务通常统称为 WPF 属性系统.由 WPF ...
- CentOS 7安装与配置Tomcat8
1.下载安装包并上传服务器 2.解压 tar -zxvf apache-tomcat-8.5.16.tar.gz -C /opt/java 3.启动 cd /opt/java/apache-tomca ...
- NKOJ3485 【2015多校联训4】数据
问题描述 Mr_H 出了一道信息学竞赛题,就是给 n 个数排序.输入格式是这样的:试题有若干组数据.每组数据的第一个是一个整数 n,表示总共有 n 个数待排序:接下来 n 个整数,分别表示这n 个待排 ...