opengl es api,opengl es是什么意思

  opengl es api,opengl es是什么意思

  在前言中,我们介绍了[OpenglEs]的[EGL环境构造](),在后面的例子中,我们将不可避免地需要使用着色器。着色器是Opengl的灵魂,有了着色器,Opengl就有了一个无拘无束的世界。

  为了理解什么是着色器,着色器做什么,必须首先理解图形渲染管道。

  在OpenGL中,一切都在3D空间中,而屏幕和窗口是2D像素阵列,这导致OpenGL的大部分工作是将3D坐标转换为适合您屏幕的2D像素。将OpenGL中的3D世界转换为屏幕窗口中的2D世界的过程称为图形渲染管道。

  也可以说,将一堆原始图形数据通过一个管道,经过各种变化,最终出现在屏幕上的过程,就是图形渲染管道。图形渲染管道可以分为两个主要部分:第一部分将3D坐标转换为2D坐标,第二部分将2D坐标转换为实际的彩色像素。

  图形管道可以分为几个阶段,每个阶段都将前一阶段的输出作为其输入。所有这些阶段都是高度专门化的(它们都有特定的功能),并且易于并行执行。由于它们的并行执行,现在的大多数显卡都有成千上万的小处理核心,它们在GPU上为每个阶段(渲染管道)运行自己的小程序,从而快速处理你在图形渲染管道中的数据。这些小程序被称为着色器。

  着色器是一种高级的3D图形编程方法。某种意义上,Shader的出现是图形中的一种“回归”,因为在此之前,所有的功能都是由固定的流水线直接提供的,开发者只需要指定参数(如光照属性、旋转角度等。)对他们来说。但是由于Shader的出现,现在这些功能需要开发者自己通过Shader来实现。

  然而,这种可编程性可以为开发人员提供更多的灵活性和创造性。

  下图是Opengl图形渲染管道的抽象过程:

  蓝色部分表示我们可以注入自定义着色器的部分。也就是说,我们可以通过定制顶点着色器、几何着色器和片段着色器来实现各种想要的效果。同时,几何着色器是可选的,通常使用默认的,所以我们只需要关注顶点着色器和片段着色器。

  参照上图,简要介绍各阶段的主要功能和职责:

  顶点着色器

  图形渲染管道的第一部分是顶点着色器,它将单个顶点作为其输入。顶点着色器的主要目的是将3D坐标转换为另一个3D坐标。同时,顶点着色器允许我们对顶点属性进行一些基本的处理,比如矩阵变换。

  汇编原语

  在图元组装阶段,顶点着色器输出的所有顶点都被作为输入,所有点都被组装成指定图元的形状。比如画正方形时,两个三角形组装成一个正方形,画多面体时,n个三角形组装成一个多面体。

  几何着色器

  装配阶段的输出被传递给几何着色器。几何着色器以图元形式的一系列顶点作为输入,它可以通过生成新的顶点和构造新的(或其他)图元来生成其他形状。

  光栅化

  几何着色器的输出将被传递到光栅化阶段,在那里它将把图元映射到最终屏幕上的相应像素,并为片段着色器生成片段。剪辑在片段着色器运行之前执行。将裁剪并丢弃超出您视野的所有像素,以提高执行效率。

  片段着色器

  片段着色器的主要目的是计算像素的最终颜色,这是所有OpenGL高级效果产生的地方。通常,片段着色器包含3D场景的数据(如照明、阴影、光线颜色等)。),可用于计算最终像素的颜色。

  测试和混合

  在这一阶段,检测该段的相应深度(和模板)值,并使用它们来确定该像素是在其他对象的前面还是后面,以及是否应该丢弃它。此阶段还检查alpha值(alpha值定义了对象的透明度)并混合对象。

  因此,即使在片段着色器中计算一个像素输出的颜色,在渲染多个三角形时,最终的像素颜色也可能完全不同。GLSLOpenGL着色器是用OpenGL着色语言编写的,GLSL)。

  在OpenGL中,我们必须定义至少一个顶点着色器和一个片段着色器,因为GPU中没有默认的顶点/片段着色器。

  让我们来看一个最简单的顶点着色器的例子:

  #版本300 esin vec4 aPosvoid main(){ GL _ Position=aPos;}GLSL的语法和C语言非常相似。相信有编程经验的伙伴大概能看懂上面的着色器。

  顶点着色器#version 300 es的第一行首先声明了着色器版本号,这意味着着色器语言需要是3.0以后的版本。

  vec4 aPos中的第二行。声明一个名为aPos的4分量输入变量。Int代表定义一个输入变量,也就是说这个变量可以用来从CPU向GPU传递数据。

  它对应于用out关键字声明的输出变量。注意int和out是Opengl 3.0以后做的修改。在Opengl 2.0中,对应的关键字是attribute和varying,也就是说,在Opengl 3中,attribute改为in,varying改为out。

  后面定义的是main函数,没什么好解析的。就像所有的语言程序一样,它作为程序的一个入口,gl_Position是Opengl中顶点着色器的内置输出变量,表示最终处理后的顶点坐标。

  让我们再看一个简单片段着色器的例子:

  #版本300 esprecision mediaump floatout vec4 FragColorvoid main(){ FragColor=vec4(1.0f,0.5f,0.2f,1.0f);}就像顶点着色器一样,片段着色器的第一行也是声明着色器的版本。第二行:precision mediaump float是声明着色器中浮点变量的默认精度。

  在Opengl ES 3的版本中,我们需要手动使用out关键字来声明输出着色器的颜色变量,比如上面例子中的第三行,但在Opengl ES2中这并不是必须的,因为Opengl ES2中可以直接使用内置变量gl_FragColor。

  至于为什么,我不知道。

  这里有两个简单的例子,让你对着色器有一个初步的了解。更多关于着色器GLSL的编写规范,可以参考相关资料或书籍进行自学。你的知识很多,不是三言两语能描述清楚的,这里就不再赘述了。

  着色器链接和使用以上,我们对着色器有了初步的了解,那么这些着色器小程序该如何使用呢?

  如上图所示,着色器小程序需要通过这些重要步骤来创建、编译、链接和使用。这些步骤没什么好分析的,就像一套规则,照着做就行了。

  以下是作者编写的加载和使用着色器的工具ShaderUtils.h:

  # ifndef NDK _ OPENGLES _ LEARN _ SHADERUTILS _ H #定义NDK _ OPENGLES _ LEARN _ SHADERUTILS _ H # include gles 3/gl3。“包含”日志。 h 静态int loadShaders(int shaderType,const char *code){ //按照类型,创建着色器int shader=glCreateShader(着色器类型);//加载着色器代码glShaderSource(着色器,1,代码,0);//编译glCompileShader(着色器);//检测编译状态int result=GL _ false glgetshaderiv(shader,GL_COMPILE_STATUS,result);如果(结果!=GL _ TRUE){ GLint info len=0;glGetShaderiv(shader,GL_INFO_LOG_LENGTH,infoLen);茶错误[信息镜头1];//获取编译错误glGetShaderInfoLog(shader,sizeof(error)/sizeof(error[0]),infoLen,error);LOGE(着色器编译失败:%s,%s ,错误,代码);}返回着色器;} static int create program(const char * VERTEX,const char * fragment){ int VERTEX SHADER=load shaders(GL _ VERTEX _ SHADER,VERTEX);int FRAGMENT SHADER=load shaders(GL _ FRAGMENT _ SHADER,FRAGMENT);int program=glCreateProgram();格拉塔赫沙尔(程序顶点着色器);格拉塔赫沙尔(程序,fragment shader);glLinkProgram(程序);//获取一下是否有错误闪烁状态=GL _ FALSEglGetProgramiv(程序,GL_LINK_STATUS,状态);如果(状态!=GL _ TRUE){ GLint info len=0;glGetProgramiv(program,GL_INFO_LOG_LENGTH,infoLen);茶错误[信息镜头1];glGetProgramInfoLog(program,sizeof(error)/sizeof(error[0]),infoLen,error);LOGE(着色器程序链接失败:,错误);} //更严谨一点可通过glValidateProgram()验证着色器程序//删除着色器glDeleteShader(vertexShader);glDeleteShader(fragmentShader);返回程序;} # endif//NDK _ OPENGLES _ LEARN _ shader utils _ H关于着色器的介绍就到这里,要想用好着色器,需要在弄懂色语言语法之后多加实践.

  参考资料《LearnOpenGL CN》

  《OPENGL ES 3.0编程指南》

  .

  开放的之欧洲珠宝实验室环境搭建

  关注我,一起进步,人生不止编码!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: