位置: 编程技术 - 正文

OpenGL编程逐步深入(四)Shaders(简述opengl的编程步骤)

编辑:rootadmin

推荐整理分享OpenGL编程逐步深入(四)Shaders(简述opengl的编程步骤),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:简述opengl的编程步骤,opengl编程基础,opengl 编程,opengl gpu编程,opengl编程基础,opengl 编程,opengl编程基础,opengl编程实例,内容如对您有帮助,希望把文章链接给更多的朋友!

OpenGl 中的 Shader在一些中文书籍或资料中都被翻译为“着色器”, 单从字面意思也看不出Shader到底是什么,Shader实际上就是一段代码,用于完成特定功能的一个模块。Shader分为Vertex Shader(顶点着色器)和Pixel Shader(像素着色器)两种,其中Pixel Shader在本文中又被称为Fragment Shader(片段着色器)

准备知识

从本节开始我们將使用Shader来实现游戏中的各种特效,Shader是现代3D图形学中重要的渲染技术。从某种程度上,你可以抱怨这种做法是比较落后的,因为固定渲染管道(fixed function pipeline)提供的3d功能本来只需要开发人员指定配置参数(例如光照属性、旋转值)就可以了,现在都要通过编写Shader代码来实现。然而这种可编程方式为编写程序提供了更大的灵活性和创新性。

OpenGl的可编程管道可以由下图直观的表达:

顶点处理器(vertex processor)负责执行每个通过管道的顶点的vertex shader(数量取决于调用绘图函数是传入的参数),Vertex shaders并不知道渲染图元的拓扑结构(是绘制四边形还是三角形?),因此顶点处理器(vertex processor)是必须的。每个顶点只进入顶点处理器一次,经过变换后沿着管道执行下一步处理。(注:所谓的管道是指从顶点输入到渲染到屏幕上经历的整个过程)

接下来是几何处理器(geometry processor)阶段。在这个阶段,一组连续的顶点如何构成图形的信息将会提供给Shader。这使得我们需要考虑除了顶点自身之外的额外信息。几何处理器(geometry processor)能够改变调用绘图函数时指定的拓扑结构(点、线、三角形等),例如你可以將它用在一组点上,將原指定拓扑结构生成的四边形变成两个三角形(公告牌技术的应用)。此外,你还可以让几何处理器(geometry processor)忽略多个指定的点,让这些点以调用绘图函数时指定的拓扑结构来绘制图形。

管道中的下一阶段为裁剪阶段(Clipper),这是一个任务较为简单的固定功能单元,会裁剪掉上一节教程中的正方形以外的图形元素,除此之外Z轴方向上的近裁剪面和远裁剪面以外的部分也会被裁剪掉。能够映射到屏幕的顶点不会被裁剪,光栅化程序会根据绘图函数指定的拓扑结构(三角形、四边形等)將图形渲染在屏幕上。例如:拓扑结构指定为三角形时光栅化程序会找到三角形内部的所有点并对它们进行渲染。对于每个点光栅化程序会调用片段处理器。在这里你可以通过对纹理采样(或者使用其他技术)确定像素的颜色。

上面的三个可编程阶段是可有可无的,如果不对它们绑定Shader,一些默认的功能将会被执行。

Shader的创建和c/c++程序非常相似,首先编写Shader代码,然后确保它在你的程序中能正确执行。可以在程序中使用字符数组来存储Shader代码或者將Shader写在一个外部的文件中,然后在程序中加载它。接着把这些Shader全部的编译成Shader对象,最后使用链接器將这些Shader链接到一个单独的program 对象加载到GPU中。链接Shader对象使得驱动能够对这些Shader进行裁剪并根据它们的关系做优化处理。

项目配置

1.在前几节项目解决方案中新建控制台应用。 2.在项目上点击右键选择属性,將配置属性->常规->项目默认值->字符集设置为“使用多字节字符集”。 在配置属性->VC++目录下的包含目录中添加$(SolutionDir)Include和$(SolutionDir)Includeassimp在库目录中添加$(SolutionDir)Lib 在配置属性->链接器->输入->附加依赖项中添加freeglut.lib、glew.lib、assimp.lib

程序代码

清单1.主程序 tutorial.cpp代码

代码解读

这里我们创建一个Program对象,你可以把它是Shader的容器,我们将会把所有的Shader对象链接到这个Program对象中。

我们通过glCreateShader函数的调用创建两个Shader对象,其中一个Shader类型为GL_VERTEX_SHADER(Vertex Shader),另外一个为GL_FRAGMENT_SHADER(Fragment Shader)。 Shader对象用于维护我们编写的Shader代码。

在编译Shader对象之前我们必须指定它的源码,glShaderSource 函数以Shader对象作为参数,提供了一种灵活的方式指定Shader源码。源码可以分布在多个字符数组中,你需要提供一个存放这些字符数组地址的数组的指针和一个存放每个数组长度的数组的指针。为了简单起见,我们使用一个字符数组存放所有的Shader源码和只有一个元素的GLint数组存放字符数组的长度。 第二个参数指定这两个数组元素个数。

调用该函数编译Shader对象。

OpenGL编程逐步深入(四)Shaders(简述opengl的编程步骤)

这段代码用于输出Shader对象编译出错时的错误信息。

將编译后的Shader对象附加到之前创建的Program对象中,非常类似于在makefile文件中添加需要链接的对象列表。因为我们没有一个makefile文件来效仿gnu make的行为,所以只能调用函数的方式为链接处理做准备。

在所有的Shader对象经过编译并把它们附加到Program对象之后,调用glLinkProgram来链接它们。需要注意的是,完成Program对象的链接后,可以调用glDetachShader 和glDeleteShader 函数来解除附加的Shader对象。OpenGl驱动中维护着它所生成的大多数对象的引用计数,如果一个Shader对象创建之后又被删除,驱动程序去把它去除,但是如果它被附加到Program对象中,调用glDeleteShader 后驱动程序仅仅会把它标记为删除,你还需调用glDetachShader 將它的引用计数置为0,然后它才会被删除。

注意:我们检测Program对象相关错误(例如链接错误)和检测Shader对象错误调用的函数有些不同,使用glGetProgramiv 代替glGetShaderiv ,使用glGetProgramInfoLog代替glGetShaderInfoLog 。

看到这段代码,你可能会问为什么已经成功链接Program对象后还要调用glValidateProgram来校验该对象。所不同的是链接错误检测针对的是Shader对象的合并,而该函数是检测Program对象在该管道状态下是否能正确执行。

最后调用调用上面这个函数,安装Program对象作为当前渲染状态的一部分。这个Program对象会影响所有绘图函数的调用,直到你替换它或使用glUseProgram指定参数为NULL来显式的禁用它。

清单2.shader.vs代码

告诉编译器GLSL版本为3.3,如果编译器不支持將会抛出异常。

这段代码在Shader中声明一个顶点特定属性(vertex specific attribute)Position,它是由3个float类型构成的向量。顶点特定(vertex specific)意味着在GPU调用每一个shader时,在缓冲区中的新顶点的值会被提供。声明的第一部分layout (location = 0),创建属性名和缓冲区中属性的绑定。这样做是为了防止我们的顶点中有多个属性(位置、法线、纹理坐标等)。我们需要让编译器知道顶点中的哪个属性必须映射到shader中声明的属性。有两种做法,我们可以像上面代码一样不明确的设置(指定为0)。如果这样我们可以在程序中使用一个硬编码的值(即调用glVertexAttributePointer函数时的第一个参数值)。或者我们可以不管它(即上面语句直接写成‘in vec3 Position’),然后在运行时使用glGetAttribLocation从程序中查询该location 。这时我们需要將返回值用在glVertexAttributePointer 函数参数中来取代硬编码方式。这里我们选择较为简单的方式,但是在更复杂的程序中最好让编译器决定属性的索引并且在运行时查询它们。这使得把Shader从多个源文件整合起来变的更简单,而无需把它们调整到缓冲区布局中。

你可以通过把多个Shader对象链接来创建你自己的Shader,然而在每个着色阶段(VS,GS,FS)只能有一个main函数作为Shader的入口点。

这里我们通过硬编码方式对传过来的顶点位置进行变换。把X/Y的值减半,Z的值保持不变,gl_Position是一个特殊的内置变量应该包含齐次的顶点坐标位置。光栅化程序会找到这个变量,并使用它作为屏幕空间的位置。使X/Y值减半意味着我们能看到的三角形的大小将是前面教程中的1/4。需要注意的是我们把W的值设为1,这对三角形的正确显示是至关重要的。投影从3D到2D实际上是在两个独立的阶段完成。首先你需要把所有顶点乘上投影矩阵,在顶点到底光栅化程序之前,GPU会为位置属性自动执行所谓的“透视分割”。这意味着所有的组件都会除以gl_Position 的W组件值。在本教程中我们还没有在vertex shader中做任何投影,但是透视分割(perspective divide)阶段不可缺少。

清单3. shader.fs代码

通常片段着色器(fragment shader)的作用是决定像素的颜色。此外,fragment shader可以完全丢弃像素或改变其Z值(将会影响随后的Z test结果)。在该案例中,屏幕图形输出的颜色由上面的变量决定,包含四个组件分别为R、G、B、A(alpha,即透明度),设置到这个变量中的值将会被光栅化程序接收并写入到帧缓冲区。

在前面的教程中没有用到片段着色器,所有绘制的图形默认都是白色,这里通过FragColor 设置为红色。

编译运行程序

你可以看到一个红色的三角形显示在屏幕中间。

OpenGL--纹理贴图基础 理论基础纹理贴图:通俗地讲就是可以把我们读取的纹理加载到图元表面的一种技术,这样大大的提高了图像的表现质量。实例代码//读取tga格式图片/*t

关于模型视图变换的一些理解 OpenGL可以通过glMatrixMode(GL_MODELVIEW)来修改模型视图矩阵的值。模型视图矩阵包含模型变换和视图变换,在OpenGL中经常将这两种变换混在一起进行讨论,这

OpenGL版本查看 本文代码摘自如何查看OpenGL版本?gl和glut库提供了版本查看函数,只需要调用就可以了:#includeWindows.h#includestdio.h#includeGL/glut.hintmain(intargc,char**argv){glutInit

标签: 简述opengl的编程步骤

本文链接地址:https://www.jiuchutong.com/biancheng/369548.html 转载请保留说明!

上一篇:用Quadro卡带Geforce卡实现非SLI多显卡多显示器协同绘制(卡带测评)

下一篇:OpenGL--纹理贴图基础(opengl纹理贴图正方体六个面)

  • 一般纳税人的税种有哪些
  • 合并成本是
  • 固定资产类型表
  • 增值税申报失败怎么撤销
  • 企业所得税预缴计算方法
  • 增值税的核算方式
  • 辅导期一般纳税人和一般纳税人的区别
  • 上一年度凭证不填可以吗
  • 商贸企业收到的检测费可以抵扣进项税吗
  • 年金现值计算公式推导
  • 工程预付款未按时支付
  • 房屋购买安装电梯可以抵扣吗?
  • 增值税降为13
  • 税务代开劳务费税点如何确定
  • 上年度的费用今年开票分录
  • 电子发票怎么作废操作流程视频
  • 广告费预付后收条怎么写
  • 美团扣点怎么做凭证
  • 产品毛利率计算表
  • 因为质量问题
  • 个人所得税做账怎么做
  • 企业员工自行体检流程
  • 培训费没有发票怎么办
  • 1697510614
  • 个人财产转让所得在哪里申报
  • 期末留抵税额可以冲减欠税吗
  • 完工转出产成品成本计算
  • 资不抵债从资产负债表上怎么看出来
  • php字符串函数有哪些
  • linux漏洞复现
  • php技巧
  • 收入的特征包括什么
  • 利尼扬蒂野生动物保护区中的一只雄性豹子,博茨瓦纳 (© Karine Aigner/Tandem Stills + Motion)
  • 整体租赁合同
  • 购买材料结转成本的会计分录
  • laravel实战教程
  • 如何收取会员会费才合法
  • 红字怎么看
  • 董事长报销应该是怎样的流程
  • 收到银联代收短信
  • mongodb快速入门
  • 公司车辆保险费要交印花税吗
  • 待报解预算收入扣款是什么意思
  • 企业所得税怎么算
  • 税控系统如何清卡
  • 一般纳税人的税负率是多少
  • 百旺金赋怎么开红字发票
  • 物业费的税可以抵扣吗
  • 环保税计税依据怎么算
  • sql server中的编程语言
  • sql server 2008使用说明
  • mysql的日期时间函数
  • 去年多摊销了怎么办
  • 存货的盘盈
  • 什么时候计提增值税发票
  • 股东每月分红合理吗?
  • 什么情况下使用for循环
  • 技术合同免税备案税务局
  • django使用mysql
  • sqlsever导入数据时出现ole db连接数据无效
  • 如何设置电脑从d盘启动
  • win8不能启动
  • 高手养成计划 小说
  • win7系统通知在哪
  • win7打印错误怎么解决
  • linux chakan
  • androidhomepage
  • 常用原生js兼容软件
  • XMLHttpRequest Level 2 使用指南
  • android常用命令
  • sql怎么设置自增列
  • 用vue写登录页面
  • js怎么检查错误
  • jquery左右移动动画效果
  • cmd Tasklist与Tskill管理Windows系统进程
  • javascript中cookie
  • 后缀名为是什么意思
  • 安徽监狱待遇qzzn
  • 图书行业税率多少
  • 如果企业所得税没有做计提怎么办?
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设