OpenGL3.3_C++_Windows(37调试,文本渲染)

调试:

视觉错误与CPU调试不同,在GLSL代码中也不能设置断点,出现错误的时候寻找错误的源头可能会非常困难。

glGetError()

GLenum glGetError();返回整形数字,查询错误标记,但是当一个错误标记被返回的时候,将不会报告其它的错误标记。

因此根据这个特性,代码中通常使用大量的glGetError()函数(间隔尽量小),以便确定错误发生的的大致位置

为了显示更多的信息,可以写一个错误检测宏,它返回错误类型,文件名,和行数

如果你使用GLEW库,调用glewInit()会设置一个GL_INVALID_ENUM的错误标记,所以首先需要glewInit之后立即调用glGetError消除这个标记

调试输出

更为完善的错误或警告信息给用户,只有4.3以上的openGL版本支持

在调用glfwCreateWindow之前提醒到GLFW中:调试输出启用glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);

检查我们是否成功地初始化了调试上下文,我们可以对OpenGL进行查询。GL_CONTEXT_FLAG_DEBUG_BIT

调试输出回调函数,在这里我们将输出一些有用的错误数据到控制台中。

void APIENTRY glDebugOutput(GLenum source, GLenum type, GLuint id, GLenum severity, 
    GLsizei length, const GLchar *message, void *userParam);

可以通过glDebugMessageControl()过滤出你需要的错误类型

调式输出可以很容易的找出错误发生的准确行号或者调用,通过在glDebugOutput()中(特定的错误类型上)设置一个断点,查找调用栈(vs的Call Stack)直到找到消息发出的源头。

我们也可以使用glDebugMessageInsert将自定义信息推送到调试输出系统:

着色器调试

因为shader无法断点或者输出日志,所以只能用颜色来调试

通常将所有相关的变量直接发送到片段着色器的输出通道,以评估它们

比如法线可视化

参考编译器

不同的显卡商(AMD,NVidia,以及Intel)的GLSL间有不同的细微差别,如果你想要保证你的着色器代码在所有的机器上都能运行,可以直接使用官方的参考编译器(语言校验器),你可以很方便的检查你的着色器代码规范

GLSL语言校验器是通过下列固定的后缀名来决定着色器的类型的

  • .vert:顶点着色器(Vertex Shader)
  • .frag:片段着色器(Fragment Shader)
  • .geom:几何着色器(Geometry Shader)
  • .tesc:细分控制着色器(Tessellation Control Shader)
  • .tese:细分计算着色器(Tessellation Evaluation Shader)
  • .comp:计算着色器(Compute Shader)

帧缓冲输出

在OpenGL程序中一块特定区域显示帧缓冲的内容

也属于shader调试,但是这种可以看到多个效果,主场景,和调试的帧缓冲

外部调试器 

RenderDoc

文本渲染

OpenGL这样的底层API没有包含文本处理的功能

可能的做法:通过GL_LINES来绘制字形,创建文本的3D网格(Mesh),或在3D环境中将字符纹理渲染到2D四边形上。

原始渲染方式

    /位图(Bitmap)矢量图(Vector Graphics)
定义由像素组成的图像,每个像素存储颜色信息由几何图形(点、线、曲线)组成,使用数学公式描述图像
缩放效果放大会失真,出现锯齿或模糊,分辨率依赖可无损缩放,边缘始终光滑,分辨率无关
文件大小文件较大,尤其是高分辨率图像文件较小,复杂图形也比同等尺寸位图小
适用场景适合照片、数码绘画、复杂细节和渐变色的图像适合图标、标志、插图和排版设计,简单且可缩放的图像
常见格式.bmp, .png, .jpg, .gif, .tiff.svg, .eps, .pdf, .ai
颜色表现支持丰富的颜色和渐变,适合细节精细的图像通常使用填充和边框定义颜色,渐变较为有限
编辑方式像素级编辑,修改每个像素,适合精细图像编辑形状编辑,调整几何属性,适合图形设计
渲染方式直接将像素绘制到屏幕,处理高分辨率时资源占用高由几何公式计算形状,渲染时较轻量
文件依赖分辨率分辨率依赖,图像缩放会导致质量变化分辨率无关,可无损缩放,不影响质量
适用软件Photoshop, GIMPAdobe Illustrator, CorelDRAW, Inkscape

位图字体(Bitmap Font):在纹理的预定义区域中包含了我们想要使用的所有字形(Glyph)。每个字形都关联着一个特定的纹理坐标区域。

渲染方式:从特定位图纹理区域采样对应的字形,并渲染它们到多个2D四边形上,需要启用混合,让背景保持透明

优点:很容易实现

缺点:会被限制在一个固定的分辨率,通常会局限于非常小的字符集,当你想要使用不同的字体时,你需要重新编译一套全新的位图字体

现代文本FreeType库

FreeType跨平台字体库:

是一个能够用于加载字体(例如TrueType字体),并为每一个字形生成位图以及计算unsigned char度量值(Metric),我们可以提取出它生成的位图作为字形纹理,并使用这些度量值指定每个字符的大小和位置。

TrueType字体:它是通过数学公式(曲线的组合)来定义的。类似矢量图,轻易渲染不同大小的字形而不造成任何质量损失。

首先包含官方预编译好的lib库,并配置到项目中GitHub - ubawurinna/freetype-windows-binaries: Windows binaries of FreeType

字体定义了字符的外观,字形是单个字符的具体形状

//

API:

FT_Init_FreeType初始化FreeType库,

FT_New_Face指定一个ttf格式的字体文件,加载为FT_Face,

FT_Set_Pixel_Sizes定义字体大小(FT_Face ,宽度,高度)

FT_Load_Char,加载某个字符:面中包含了一个字形的集合,将其中一个字形设置为激活字形,我们告诉FreeType去创建一个8位的灰度位图(大小恰好能包含这个字符可见区域),我们可以通过face->glyph->bitmap来访问这个位图。

每一个字形都放在一个水平的基准线(Baseline)上

FT_Done_Face,FT_Done_FreeType释放资源

//

字体:

直接查询:在需要渲染字符的时候,为了直接通过它的度量值,获取纹理,预处理字符的数据,保存到字符集map中,

对于每个字符,值存储,纹理的ID,字形大小,基准线到字形左部/顶部的偏移值,原点距下一个字形原点的距离

循环ASCII字符集的前128个字符,FT_Load_Char加载每个字符,将数据存储到字符集map中

因为通过字形生成的位图是一个8位灰度图,我们这里将纹理的internalFormat(如何存储纹理数据)和format(纹理数据的格式)设置为GL_RED,

只使用纹理中的红色通道,没有rgb,也就无法表示颜色(比如红色),适合灰度图像(只有亮度信息,没有颜色信息),

RGB 位深度:每个颜色通道(红、绿、蓝)占用 8 位,共 24 位

//

Shader:指定顶点位置,纹理坐标,字形位图(控制alpha,需要启用混合),字体颜色

正交投影矩阵:不需要透视,将范围指定位窗口范围

VAO,VBO

为了方便渲染文本,创建一个RenderText函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值