博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
梳理 Opengl ES 3.0 (二)剖析一个GLSL程序
阅读量:5307 次
发布时间:2019-06-14

本文共 3691 字,大约阅读时间需要 12 分钟。

OpenGL ES shading language 3.0 也被称作 GLSL,是个 C风格的编程语言。

 

Opengl ES 3.0内部有两种可编程处理单元,即Vertex processor和Fragment processor,分别用来处理Vertex shader executable和Fragment shader executable。注意,Opengl ES 3.0不支持Geometry Shader。上图中,紫色部分就是可执行体了,即 executable .

 先来一段Vertex shader代码

#version 300 es //版本号in vec4 VertexPosition; //应用层输入逐顶点位置坐标数据in vec4 VertexColor; //应用层输入逐顶点颜色数据uniform float RadianAngle; //应用层输入数据out vec4 TriangleColor; mat2 rotation = mat2(cos(RadianAngle),sin(RadianAngle),-sin(RadianAngle),cos(RadianAngle));
void main() {
  gl_Position = mat4(rotation)*VertexPosition;//给内置数据赋值   TriangleColor = VertexColor;
}

再来一段Fragment shader代码

#version 300 esprecision mediump float;//配置精度in vec4 TriangleColor;out vec4 FragColor;void main() {FragColor = TriangleColor;};

 上面这两段代码,只是文本数据,上述的两种processor可没办法直接执行,这就需要一个叫做编译和链接的步骤,来将这个文本数据变成executable的数据。可以通过下图来了解这个创建executable的过程:

 

需要在应用层加载和编译shader,使用如下代码进一步说明:

GLuint loadAndCompileShader(GLenum shaderType, const char* sourceCode) {  // Create the shader  GLuint shader = glCreateShader(shaderType);  if ( shader )   {    // Pass the shader source code    glShaderSource(shader, 1, &sourceCode, NULL);    // Compile the shader source code    glCompileShader(shader);    // Check the status of compilation    GLint compiled = 0;    glGetShaderiv(shader,GL_COMPILE_STATUS,&compiled);    if (!compiled)     {    // Get the info log for compilation failure    GLint infoLen = 0;    glGetShaderiv(shader,GL_INFO_LOG_LENGTH, &infoLen);    if (infoLen)     {      char* buf = (char*) malloc(infoLen);      if (buf)       {        glGetShaderInfoLog(shader, infoLen, NULL, buf);        printf("Could not compile shader %s:" buf);        free(buf);      }    // Delete the shader program    glDeleteShader(shader);    shader = 0;    }  }}return shader;}

 

使用如下代码来执行链接过程:

GLuint linkShader(GLuint vertShaderID,GLuint fragShaderID){if (!vertShaderID || !fragShaderID){ // Fails! returnreturn 0;}// Create an empty program objectGLuint program = glCreateProgram();if (program) {// Attach vertex and fragment shader to itglAttachShader(program, vertShaderID);glAttachShader(program, fragShaderID);// Link the programglLinkProgram(program);GLint linkStatus = GL_FALSE;glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);if (linkStatus != GL_TRUE) {GLint bufLength = 0;glGetProgramiv(program, GL_INFO_LOG_LENGTH,&bufLength);if (bufLength) {char* buf = (char*) malloc(bufLength);if(buf) { glGetProgramInfoLog(program,bufLength,NULL,buf);printf("Could not link program:\n%s\n", buf);

free(buf);

}
}
glDeleteProgram(program);
program = 0;
}
}
return program;
}

前文一直提到的executable就是这个返回的句柄变量 program。这个program将会在流水线的Processor上执行。

回过头再来分析vertex shader代码和fragment shader代码。

in vec4 VertexPosition;in vec4 VertexColor;

shader代码里声明的这两个变量的值是从哪里获取的呢,这就涉及了一个重要的环节,就是应用层和shader层的数据通信问题。为了方便理解,根据执行的位置不同,可以把应用层看做CPU,把shader层看做GPU。即可抽象为CPU与GPU通信,进一步抽象为客户端C和服务端S之间的通信。下面来解释这个通信的流程,从通信上来说,必然是要先让客户端找到服务器端的一个通信端口,然后客户端建立与这个通信端口的连接,最后只要往这个连接上扔数据,这样服务端就能收到数据了。

首先实现寻找到服务端通信端口的功能,以下代码就帮助CPU端找到GPU端的数据通信端口

GLuint positionAttribHandle;GLuint colorAttribHandle;positionAttribHandle = glGetAttribLocation(programID, "VertexPosition");colorAttribHandle = glGetAttribLocation(programID, "VertexColor");

以下代码,实现了往通信通道上扔数据的功能:

// Send data to shader using queried attrib locationglVertexAttribPointer(positionAttribHandle, 2, GL_FLOAT,GL_FALSE, 0, gTriangleVertices);glVertexAttribPointer(colorAttribHandle, 3, GL_FLOAT,GL_FALSE, 0, gTriangleColors);

GPU端,默认所有这些顶点属性端口都是关闭的,因此需要打开这些通信端口:

// Enable vertex position attributeglEnableVertexAttribArray(positionAttribHandle);glEnableVertexAttribArray(colorAttribHandle);

这样,一条通信信道就算建立起来了。

 

转载于:https://www.cnblogs.com/designyourdream/p/6739413.html

你可能感兴趣的文章
[leetcode]217. Contains Duplicate
查看>>
Python_day02——分支结构 if_else、for、while、break与continue
查看>>
Clion IDE的安装
查看>>
ERROR ITMS-90167: "No .app bundles found in the package"错误
查看>>
python 堆栈
查看>>
CentOS7 下curl使用
查看>>
[Poi2000]病毒——补全AC自动机
查看>>
求 Discuz!NT 3.5论坛 好看的模版
查看>>
String和Boolean互相转换
查看>>
angularJs基础
查看>>
熟悉 IBM Rational Application Developer以及Portal Server
查看>>
mysql悲观锁与乐观锁
查看>>
PHP 时间函数time、date和microtime的区别
查看>>
快速排序_C语言_数组
查看>>
table中内容过长,table改变的问题
查看>>
月末关账流程和政策规定
查看>>
centos6.2 配置ISE12.2
查看>>
poi实现Excel导出
查看>>
Maven修改镜像仓库地址
查看>>
透彻分析反射的基础---class类
查看>>