OpenGL蓝宝书第九章学习笔记:片段着色器和帧缓存

news2024/11/27 8:26:55
前言
本篇在讲什么

OpenGL蓝宝书第九章学习笔记之片段着色器和帧缓存
本篇适合什么

适合初学OpenGL的小白
本篇需要什么

C++语法有简单认知
OpenGL有简单认知
最好是有OpenGL超级宝典蓝宝书
依赖Visual Studio编辑器

本篇的特色

具有全流程的图文教学
重实践,轻理论,快速上手
提供全流程的源码内容


★提高阅读体验★

👉 ♠ 一级标题 👈

👉 ♥ 二级标题 👈

👉 ♣ 三级标题 👈

👉 ♦ 四级标题 👈


目录

  • ♠ 本章的学习要点
  • ♠ 片段着色器
    • ♥ 插值与存储限定符
      • ♣ 禁用差值
      • ♣ 无透视校正的插值
  • ♠ 单片段测试
    • ♥ 剪裁测试
    • ♥ 模板测试
    • ♥ 深度测试
      • ♣ 控制深度缓冲更新
      • ♣ 深度夹紧
  • ♠ 颜色输出
    • ♥ 混合
      • ♣ 混合函数
    • ♥ 逻辑运算
    • ♥ 颜色遮罩
  • ♠ 离屏渲染
    • ♥ 多个帧缓冲附件
    • ♥ 分层渲染
    • ♥ 帧缓存的完整性
      • ♣ 附件完整性
      • ♣ 全帧缓存完整性
      • ♣ 检查帧缓冲
    • ♥ 立体渲染
  • ♠ 反混叠
    • ♥ 过滤法反混叠
    • ♥ 多样本反混叠
    • ♥ 多样本纹理
      • ♣ 样本覆盖率
    • ♥ 采样率着色
    • ♥ 重心采样
  • ♠ 高级帧缓冲格式
    • ♥ 无附件渲染
    • ♥ 浮点帧缓冲
      • ♣ 使用浮点格式
    • ♥ 整数帧缓冲
    • ♥ SRGB颜色空间
  • ♠ 点精灵
    • ♥ 点纹理化
    • ♥ 点参数
    • ♥ 有形点
    • ♥ 旋转点
  • ♠ 获取图像
    • ♥ 从帧缓存中读取
    • ♥ 在帧缓冲之间复制数据
    • ♥ 读取纹理数据
  • ♠ 推送
  • ♠ 结语


♠ 本章的学习要点

  • 如何将数据传递到片段着色器,如何控制数据发送给片段着色器的方式以及片段着色器后如何处理数据
  • 如何创建自己的帧缓存并控制它们存储的数据格式
  • 如何从单个片段着色器生成多个输出
  • 如何获取帧缓冲数据并将数据输入纹理、缓冲以及应用程序的内存

♠ 片段着色器

片段着色器确定每个片段的颜色,然后组合发送给帧缓冲
默认情况下,片段着色器的所有输入块都平滑地在经过光栅化的基元上进行插值,该插值的端点由前端最后一个阶段提供(顶点着色器或曲面细分阶段)
你可以在很大程度上控制插值方式甚至决定是否插值


♥ 插值与存储限定符

GLSL支持的一些存储限定符,有一些存储限定符可用于控高级渲染时可使用的插值


♣ 禁用差值

每当从前端传递一个整数到后端时,就必须禁用插值,这一设置是自动完成的,因为 OpenGL王法平滑地插值整数

要为未插的片段着色器创建平场输入,可以使用’flat’存储限定符进行声明

flat in vec4 foo;
flat in int bar;
flat in mat3 baz;

可以将插值限定符应用于输入块
可以对输入块的各元素应用不同的限定符

flat in INPUT BLOCK
{
    vec4 foo;
    int  bar;
    smooth mat3 baz;
}

上述代码foo已禁用插值,因为它从父输入块继承了flat限定
bar是一个整数,因此自动禁用插值
baz虽然父块是禁用限定符flat,但是因为因为限定符smooth存在,所以依旧是平滑插值

当渲染基元为线条或三角形时,则使用基元的第一个或最后一个顶点,可以通过调用以下函数决定

void glProvokingVertex(GLenum provokeMode);

♣ 无透视校正的插值

因为空间是立体的,所以三角形对于视线来说很少是直接垂直的,这意味屏幕空间内的步长不是线性相关,OpenGL通过使用透视校正插值来纠正这个问题

如果要在屏幕空间中执行插值而不考虑基元方向,则可使用noperspective存储限定符


♠ 单片段测试

片段着色器运行后,会对片段进行了许多其他测试,以确定是否以及如何将其写入帧缓存。包括剪裁测试模板测试以及深度测试


♥ 剪裁测试

剪裁测试默认是禁用的,OpenGL支持很多剪裁矩形。如果要设置这些矩形则可调用glscissorIndexed()glScissorIndexedv(),其原型为

void glScissorIndexed(GLuint indexGLint left,GLint bottom,GLsizei width,GLsizei height)

void glScissorIndexedv(GLuint index,const GLint * v)

可以通过调用以下函数设置每个剪裁工具的矩形,无论OpenGL实现支持多大的数量

void glScissor(GLint x, GLint y,GLsizei width,GLsizei height);

全域启动裁剪测试

glEnable(GL_SCISSOR_TEST)

禁用剪裁测试

glDisable(GL_SCISSOR_TEST)

单个视口矩形启用剪裁测试

glEnablei(GL_SCISSOR_TEST,index);

单个视口矩形禁用剪裁测试

glDisablei(GL SCISSOR_TEST,index);

♥ 模板测试

简单理解,用镂空的纸板在墙上喷漆,只有镂空的位置会形成图案

启用模板测试

glEnable(GL_STENCIL_TEST)

glstencilFuncSeparate()该命令用于控制模板测试通过或不通过的条件,其原型如下

void glStencilFuncSeparate(GLenum faceGLenum func,GLint ref,GLuint mask);

可为face传递GL_FRONT、GL_BACK或GL_FRONTAND_BACK,放大将受到影响的几何体
func的值可以是下表中的任意值,这些值指定了几何体通过模板测试的条件

功能通过条件
GL_BQUAL参考值等于缓冲值
GL_GEQUAL参考值大于或等于缓冲值
GL_GREATER参考值大于缓冲值
GL_NOTEQUAL参考值不等于缓冲值
GL_EQUAL参考值等于缓冲值
GL_GEQUAL参考值大于或等于缓冲值
GL_GREATER参考值大于缓冲值
GL_NOTEQUAL参考值不等于缓冲值

ref值是用于计算结果通过或失败的引用,mask参数可以控制将哪些引用位与缓存进行比较

glstencilopSeparate()告诉OpenGL在模板测试通过或失败后应如何处理,其原型如下

void glstencilOpSeparate(GLenum face,GLenum sfail,GLenum dpfail,GLenum dppass)

参数face指定哪些面会受到影响。接下来的3个参数控制执行模板测试后发生的事情,可以是下表中的任意值

功能结果
GL_KEEP不修改模板缓冲
GL_ZERO将模板缓冲值设置为0
GL_REPLACE将模板值替换成参考值
GL_INCR带饱和度的增量模板
GL_DECR带饱和度的减量模板
GL_INVERT按位倒转模板值
GL_INCR_WRAP无饱和度的增量模板
GL_DECR_WRAP无饱和度的减量模板

sfail是模板测试失败后行的操作
dpfail参数指定深度缓冲测试失败后执行的操作
dppass指定深度冲测试通过后执行的操作


♥ 深度测试

启用深度测试

glEnable(GL_DEPTH_TEST)

禁用深度测试

glDisable(GL_DEPTH_TEST)

要设置深度比较运算符(或深度函数),则调用glDepthFunc(),其原型为

void glDepthFunc(GLenum func);

参数func是一种可用的深度比较运算符,func的选择可见下表

功能含义
GL_ALWAYS深度测试始终通过一所有片段均视为已通过深度测试
GL_NEVER深度测试从未通过一一所有片段均视为未通过深度测试
GL_LESS如果新片段的深度值小于旧片段的深度值,则通过深度测试
GL_LEQUAL如果新片段的深度值小于或等于旧片段的深度值,则通过深度测试
GL_EQUAL如果新片段的深度值等于旧片段的深度值,则通过深度测试
GL_NOTEQUAL如果新片段的深度值不等于旧片段的深度值,则通过深度测试
GL_GREATER如果新片段的深度值大于旧片段的深度值,则通过深度测试
GL_GEQUAL如果新片段的深度值大于或等于旧片段的深度值,则通过深度测试

♣ 控制深度缓冲更新

glDepthMask()函数空值深度缓存的写入,GL_TRUE则启用,GL_FALSE则禁用

glDepthMask(GL_FALSE);

♣ 深度夹紧

OpenGL可以选择关闭对近平面和远平面的裁剪,将生成的深度值限制在0~1

启用深度夹紧

glEnable(GL_DEPTH_CLAMP)

禁用深度夹紧

glDisable(GL_DEPTH_CLAMP)

♠ 颜色输出

颜色输出阶段是片段被写入帧缓存前所经历的最后一个openGL管线阶段,它确定了颜色数据离开片段着色器后最终显示给用户之前所经历的操作


♥ 混合

就是颜色叠加,几乎所有的动画或者游戏引擎都支持颜色叠加效果

启用混合

glEnable(GL_BLEND);

禁用混合

glDisable(GL BLEND);

♣ 混合函数

可以调用gIBlendFunc()glBlendFuncSeparate()函数,其函数原型如下

glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB,GLenum srcAlpha, GLenum dstaAlpha) ;
glBlendFunc(GLenum src, GLenum dst);

最后一个值常量混色可通过调用 glBlendColor()设置


♥ 逻辑运算

在传递像素颜色前可以先对其应用一次逐辑运算

启用逻辑运算

glEnable(GL_COLOR_LOGIC_OP);

禁用逻辑运算

glDisable(GL_COLOR_LOGIC_OP);

逻运算使用输入像素和现有帧缓冲的值计算最终值,可通过调用glLogicop()来选择计算最终值的操作


♥ 颜色遮罩

写入片段前可以对其进行的最后修改之一是遮罩
为了应用颜色遮罩或禁用颜色遮,可以使用gColorMask()gcolorMaski()函数
函数g1ColorMask()允许你屏蔽当前已启用的所有演染缓存
函数glcolorMaski()许你将罩设置成特定颜色缓存


♠ 离屏渲染

OpenGL包含用户可自行设置帧缓存并用于直接绘制到纹理的功能

OpenGL中的大多数对象,可使用适当的创建函数glCreateFramebuffers()创建一个或多个缓存对象

  • 生成帧缓存对象的名称
void glGenFramebuffers(GLsizei n,GLuint * framebuffers);
  • 要将缓存绑定到语境
void glBindFramebuffer(GLenum target,GLuint framebuffer)
  • 附加纹理到帧缓存
void glNamedFramebufferTexture (GLuint framebuffer, GLenum attachment,GLuint texture,GLint level);
void glFramebufferTexture(GLenum target,GLenum attachment,GLuint texture,GLint level);

♥ 多个帧缓冲附件

用户定义帧缓存的另一个极其有用的功能是,它们支持多个附件,也就是说,可将多个纹理附加到单个帧缓存并同时使用单个片段着色器渲染到其中

纹理附加到FBO,我们需要调用glFramebufferTexture()gINamedFramebufferTexture()函数

要从单个片段着色器渲染到多个附件,则必须在着色器中声明多个输出并将其关联到附着点。为此,我们使用布局限定符,如下所示

layout (location = 0) out vec4 color0;
layout (location = 1) out vec4 colorl;
layout (location = 2) out vec4 color2;

绘制使用函数glDrawBuffers()(复数)函数


♥ 分层渲染

分层排列的可索引至着色器的2D纹理,也可将纹理附加到缓存对象,这种帧缓存就叫作分层缓存


♥ 帧缓存的完整性

完整性分为两类:附件完整性全帧缓存完整性


♣ 附件完整性

FBO的每个附件必须满足某些标准才能视为完整

  • 附件对象无任何相关图像
  • 附加图像的宽度或高度为零
  • 将非彩色可渲染格式附加到彩色附件
  • 将非深度可渲染格式附加到深度附件
  • 将非模板可渲染格式附加到模板附件

要确定颜色深度或模板格式是否可渲染,使用下面函数,结果为GL_TRUE或GL_FALSE

glGetInternalformativ(GL_COLOR_RENDERABLE)   //(颜色)
glGetInternalformativ(GL_DEPTH_RENDERABLE)   //(深度)
glGetInternalformativ(GL_STENCIL_RENDERABLE) //(模板)

♣ 全帧缓存完整性

帧缓存对象作为一个整体也必须是完整的,全帧缓存不完整的常见情形如下

  • glDrawBuffers()已将输出映射到一个无附加图像的FBO附件
  • OpenGL驱动器不支持同时使用多种内部格式

♣ 检查帧缓冲

当用户认为已经完成FBO设置时,可以通过调用以下函数检查FBO是否完整

Glenum fbostatus = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
GLenum fbostatus = glCheckNamedFramebufferStatus (framebuffer);

♥ 立体渲染

OpenGL可根据所用显示设备生成成对的图像,这些图像可分别呈现给两眼并提高图像景深感

  • 渲染到左眼图像
glDrawBuffer(GLBACK_LEFT);
  • 渲染到右眼图像
glDrawBuffer(GL_BACK RIGHT);

♠ 反混叠

混叠就是锯齿锯齿。减少或消除混叠的方法叫作反混叠技术


♥ 过滤法反混叠

启用方式

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LINE_SMOOTH);

仅适合少数情况,对于立方体,需要把GL_LINE_SMOOTH替换成GL_POLYGON_SMOOH,如下代码所示

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_POLYGON_SMOOH);

♥ 多样本反混叠

为增加图像的采样率,OpenGL支持在屏幕上存储每个像素的多个样本。这种技术称为多样本反混叠(MSAA)

启用多采样

glEnable(GL_MULTISAMPLE);

禁用多采样

glDisable(GL_MULTISAMPLE);

♥ 多样本纹理

我们可以创建一个多采样纹理并将其附加到帧缓存对象进行渲染

  • 多采样纹理

例如:GL_TEXTURE_2D_MULTISAMPLE或GL_TEXTURE_2D_MULTISAMPLE_ARRAY

  • 分配储存空间

glTextureStorage2DMultisample()或glTextureStorage3DMultisample()


♣ 样本覆盖率

覆盖率指片段“覆盖”的像素占比

OpenGL将片段透明度值直接转换成覆盖率值,调用glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);

也可以通过调用gl_SampleCoverage()手动设置样本覆盖率

另一种可以生成覆盖信息的方法是在片段着色器中明确设置该信息,使用片段着色器内置变量即gl_SampleMaskIn[]gl_SampleMask[]


♥ 采样率着色

-启用采样率着色

gl_Enable(GL SAMPLE SHADING);

-禁用采样率着色

gl_Disable(GL_SAMPLE_SHADING);

单独对哪部分样本着色,可以调用gl_MinSampleShading()


♥ 重心采样

它仅适用于渲染到多采样帧缓存的情形
要创建带有 centroid 存储限定符的易变变量


♠ 高级帧缓冲格式

适用于帧缓存的更高级的格式


♥ 无附件渲染

可以创建帧缓存但不附加任何纹理

每个帧缓存对象都有一组参数,用于替代无附件时从其附件获得的参数。为了指定这些参数,需要调用gl_FramebufferParameteri()


♥ 浮点帧缓冲

浮点格式的附件


♣ 使用浮点格式

创建缓存时可使用两种新记号,即GL_RGBA16EGL_RGBA32F,如下所示

glTextureStorage2D(texture,1,GL_RGBA16F,width, height);
glTextureStorage2D(texture,1,GL_RGBA32F,width, height);

有许多可用格式如下表所示

格式内容
GL_RGBA32F4个32位浮点分量
GL_RGBA16F4个16位浮点分量
GL_RGB32F3 个32 位浮点分量
GL_RGB16F3个16 位浮点分量
GL_RG32F两个32位浮点分量
GL_RG16F两个 16 位浮点分量
GL_R32F一个32位浮点分量
GL_R16F一个16 位浮点分量
GL_R11F_G11F_B10F两个 11 位浮点分量和一个 10 位浮点分量

♥ 整数帧缓冲

使用正数内部格式创建纹理并附加到帧缓存对象来创建整数帧缓冲

使用包含整数分量的内部格式创建纹理并附加到帧缓存对象(例如,GL RGBA32UI),如下所示

glTextureStorage2D(tex,1,GLRGBA32UI,10241024);

♥ SRGB颜色空间

如果输入电压达到最大电压的-半,则光输出还略低于最大可能光输出的四分之一!为了弥补这一点,在计算机图形中,使用伽马校正(以y项的幂函数命名),通过低幂次提高线性值、缩放结果和补偿结果值。生成的颜色空间叫作 sRGB


♠ 点精灵

术语点精灵(pointsprites)通常指纹理点,指以点的渲染来代替纹理,绘制单个 3D点将2D纹理图像置于屏幕上,常见于粒子系统


♥ 点纹理化

使用点精灵只需要绑定一个2D纹理并使用内置变量gl_PointCoord从片段着色器中读取该纹理,如下述代码所示

#version 450 core
out vec4 vFragColor;

in vec4 vStarColor;

layout (binding =0) uniform sampler2D starImage;

void main(void)
{
    vFragColor = texture(starImage, gl_PointCoord) * vStarColor;
}

♥ 点参数

可以使用函数glPointParameteri()对点精灵(以及一般点)的一些特征进行微调


♥ 有形点

除使用gl_PointCoord对纹理坐标应用纹理外,还可以使用gl_PointCoord导出除纹理坐标外的许多其他信息
例如,可以使用片段着色器中的discard关键词生成非正方形的点,从而舍弃预期点形状外的片段


♥ 旋转点

可以在片段着色器中直接创建旋转矩阵,然后将其与gl_Pointcoord相乘使它旋转


♠ 获取图像

仅仅获取最终的渲染图像,不一定需要向用户展示,例如截图、打印图像等


♥ 从帧缓存中读取

OpenGL提供函数glReadPixels()能从帧缓存中读取像素数据,其原型如下

void glReadPixels(GLint X, GLint y,GLsizei width,GLsizei height, GLenum format, GLenum type,GLvoid * data);


♥ 在帧缓冲之间复制数据

图形API允许应用程序将像素或缓冲数据读取至系统内存,还提供了将这些像素或数据绘制至屏幕的方法

上述方法很低效,可以使用位块传输命令将像素数据从一个点快速移动到另一个点,步骤如下

  • 复制源是通过调用glReadBuffer()指定的读取缓存的读取缓存
  • 复制目标是通过调用glDrawBuffer()指定的当前绘制缓存的绘制缓存
  • 通过调用glReadPixels()将缓存中的数据读入应用程序的内存
  • 使用g1BlitFramebuffer()从一个缓存读入另一个缓存
  • 更简单地将数据直接从缓存复制到纹理中,通过glCopyTexSubImage2D()glcopyTexturesubImage2D()
  • 如果想要将纹理中的数据复制到另一个纹理中,则可以通过调用glCopyImageSubData()来实现

♥ 读取纹理数据

通过调用以下任意函数从纹理中读取图像数据

void glGetTexImage(GLenum targetGLint Ievel,GLenum format, GLenum type,GLvoid *img);
void glGetTextureImage(GLuint texture, Glint level,GLenum format,GLenum type,GLsizei bufsize, void *pixels)

上述函数都将整级纹理读回到内存中,如果只需要一小片纹理,则可调用下面函数

void glGetTextureSubImage (GLuint texture, GLint level,
GLint xoffset,GLint yoffset, GLint zoffset,GLsizei width,GLsizei height, GLsizei depth,GLenum format,GLenum type,GLsizei bufSize, void *pixels);


♠ 推送

  • Github
https://github.com/KingSun5

♠ 结语

若是觉得博主的文章写的不错,不妨关注一下博主,点赞一下博文,另博主能力有限,若文中有出现什么错误的地方,欢迎各位评论指摘。

👉 本文属于原创文章,转载请评论留言,并在转载文章头部著名作者出处👈

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/620882.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Node服务器 - koa框架

1 koa的基本使用 2 koa的参数解析 3 koa响应和错误 4 koa静态服务器 5 koa的源码解析 6 和express对比 koa的基本使用过程 const Koa require(koa)// 创建app对象 const app new Koa()// 注册中间件(middleware) // koa的中间件有两个参数: ctx/next app.use((ctx, next…

Apple Vision Pro:空间计算的未来已来,你准备好了吗?

“ 正如iPhone带我们进入移动计算时代,Apple Vision Pro将带我们进入空间计算时代。” 我虽然没有亲身体验,但观看了许多国内外第一批体验者的体验分享,看得出来,这些体验者都十分兴奋,根据他们的描述,我…

Mac安装zookeeper

文章目录 1.下载zookeeper安装包2.解压安装包3.修改配置文件4.启动服务端5.启动客户端 1.下载zookeeper安装包 https://archive.apache.org/dist/zookeeper/ 选择需要的版本下载 下载的时候要注意下载已经编译好的二进制版本 2.解压安装包 将下载的安装包解压到你想要的位…

基于Faster RCNN时间钢铁表面的缺陷检测

目标检测在许多行业中都有许多实际应用。大多数时候,在工业环境中,物体检测目标很小。因此,有效地训练目标检测模型变得非常困难。其中一个问题是钢材表面缺陷检测。即使使用深度学习,也很难高精度地解决问题。在本文中,我们将使用 PyTorch 库训练 Faster RCNN 对象检测模…

【3DsMAX】从零开始建房(5)

目录 1. 制作护栏 2. 制作梯子 3. 制作二层窗户 1. 制作护栏 选中顶部三条边线 点击“利用所选内容创建图形” 选择线性 此时我们就成功的创建了一个二维样条线 选中样条线上其中的一个点,移动点使线条缩短 缩小一点 渲染 同样的方法再制作一根 新建一个圆柱体 …

浅谈Spring Cloud OpenFeign

OpenFeign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用OpenFeign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问HTTP请求。 Spring Cloud OpenFe…

临期食品电商 APP 的设计与开发

摘 要 : 在移动互联网和电子商务产业的快速发展中,越来越多的消费者开始慢慢的接触网上购 物,互联网经济的全面动员将席卷全球,各种电商应用将在时代的浪潮中层出不穷。在未来各国的 不断发展中互联网很可能会成为销售各种货物的…

在线商城前台开发环境配置

一、项目配置 node 15.14.0 官网下载 https://nodejs.org/zh-cn/download/releases npm 7.7.6 下载node后自动安装npm,如果版本不对就更换对应版本 npm install react7.7.6 下载项目源码 链接:https://www.123pan.com/s/bT07Vv-WICcv.html 解压到一…

【P50】JMeter 汇总报告(Summary Report)

文章目录 一、汇总报告(Summary Report)参数说明二、准备工作三、测试计划设计 一、汇总报告(Summary Report)参数说明 可以查看事务或者取样器在某个时间范围内执行的汇总结果 使用场景:用于评估测试结果 使用频率…

java boot将一组yml配置信息装配在一个对象中

其实将一组yml数据封进一个对象中才是以后的主流开发方式 我们创建一个springboot项目 找到项目中的启动类所在目录 在同目录下创建一个类 名字你们可以随便取 我这里直接叫 dataManager 然后 在yml中定义这样一组数据信息 然后 我们在类中定义三个和这个配置信息相同的字段…

全志V3S嵌入式驱动开发(触摸屏驱动)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 所谓的触摸屏,其实就是在普通的lcd屏幕之上,再加一层屏而已。这个屏是透明的,这样客户就可以看到下面lcd屏幕的…

想要提高办公效率,可以采用表单自定义工具

当前,随着社会的进步和科技的发展,表单自定义工具逐渐在现代化办公场所中得到重用和喜爱。因为它的灵活、简便、易操作等优势特性,使得其突破了传统表单制作工具的局限,成为广大中大型企业实现流程化管理和数字化进程的得力助手。…

UnityVR--组件5--Animation动画

目录 新建动画Animation Animation组件解释 应用举例1:制作动画片段 应用举例2:添加动画事件 Animator动画控制器 应用举例3:在Animator中设置动画片段间的跳转 本篇使用的API:Animation、Animator以及Animator类中的SetFlo…

程序语言排行榜有哪些

程序语言排名 程序语言排行NO.1Java Java是基于类的面向对象的编程语言,拥有跨平台、面向对象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。任职于Sun Microsystems的詹姆斯高斯林等人于1990年代初开发Java语言的雏形,最初被…

超低功耗待机血压计语音IC方案,智能提示NV080C-S8

随着我国步入21世纪的步伐和改革开放的不断深入,我国医疗水平和人民的生活水平不断提高,致使我国已经成为了全球老龄化为严重的国家,老年人占据的比重越来越大,一些常见的却不容易治愈的老年性疾病的预防工作已成为现今确保老年人…

LVM逻辑卷元数据丢失恢复案例 —— 筑梦之路

Lvm常见的故障主要是pv出现异常,有以下几种情况 一个是pv所在的磁盘发生了lvm的元数据损坏一个是系统无法识别到pv所在的磁盘一个是系统异常,断电等导致重启后盘符发生变化,也就是系统识别的磁盘uuid发生变化,但是wwid还是可以对应…

4.6 Monitor概念

目录 1、对象头2、原理Monitor3、原理之Synchronized4、原理之Synchronized进阶1)轻量级锁2)锁膨胀3)自旋优化4)偏向锁5)锁消除 1、对象头 64 位虚拟机 在加锁的过程中,Mark Word中的62位将会指向操作系统…

外包呆了5年终上岸,劝各位别去了...

有些测试员朋友找工作过程中问我,或者网上问有外包公司的offer,要不要去外包公司?在这里我结合我自己的经历和身边一些朋友的情况来谈谈这个问题。首先我呆过两家外包公司,并且身边有不少朋友是在外包公司工作。所以我只是尽量客观的分析这个…

Python 接口自动化测试导入接口无法上传文件有什么原因? 详细教程

在Python接口自动化测试中,上传文件通常需要使用requests库来发送HTTP请求。以下是一个示例代码来实现上传文件的功能: 如果你想学习自动化测试,我这边给你推荐一套视频,这个视频可以说是B站百万播放全网第一的自动化测试教程&am…

畅聊趣坊项目测试报告

文章目录 项目背景项目功能测试计划与设计功能测试自动化测试 测试结果功能测试结果UI自动化测试结果 项目背景 在浏览网站时,发现好多网站开放出聊天的窗口,我们一发送消息就会收到一条消息,好奇这个功能是怎么实现的,最后查阅资…