OpenGL--GLSL

作者: 黑眼豆豆_ | 来源:发表于2020-08-05 15:04 被阅读0次

图形管线

在我们之前的了解OpenGL ES这篇文章中,我们了解了OpenGL ES的图形管线,如下图:

image

具体流程如下:

  • 顶点数据一般以顶点数组的形式存放在顶点缓冲区中
  • 顶点着色器负责确定图形的位置和大小(通过顶点数据)
  • 经过图元装配、光栅化等一系列流程后,处理好的数据最终给到片元着色器
  • 如果有纹理的话,纹理坐标可以给顶点着色器,传给片元着色器,或者直接给片元着色器这2种方式给到片元着色器
  • 片元着色器通过对每个像素点进行渲染后将处理的数据存入到帧缓冲区,最后扫描到屏幕上

其实,在整个OpenGL ES阶段,我们这真正能操作的只有顶点着色器和片元着色器,而图元装配、光栅化等这些操作,其实我们控制不了,只能有GPU自己完成。
当然,这也帮我们省了不少事。

向量数据类型

类型 描述
vec2,vec3,vec4 2分量、3分量、4分量浮点向量
ivec2,ivec3,ivec4 2分量、3分量、4分量整型向量
uvec2,uvec3,uvec4 2分量、3分量、4分量⽆符号整型向量
bvec2,bvec3,bvec4 2分量、3分量、4分量bool型向量

矩阵数据类型

类型 描述
mat2,mat2x2 两⾏两列
mat3,mat3x3 三⾏三列
mat4,mat4x4 四⾏四列
mat2x3 三⾏两列
mat2x4 四⾏两列
mat3x2 两⾏三列
mat3x4 四⾏三列
mat4x2 两⾏四列
mat4x3 三⾏四列

变量存储限定符

限定符 描述
<none> 只是普通的本地变量,外部不⻅,外部不可访问
const ⼀个编译常量,或者说是⼀个对函数来说为只读的参数
in/varying 从以前阶段传递过来的变量
in/varying centroid ⼀个从以前的阶段传递过来的变量,使⽤质⼼插值
out/attribute 传递到下⼀个处理阶段或者在⼀个函数中指定⼀个返回值
out/attribute centroid 传递到下⼀个处理阶段,质⼼插值
uniform ⼀个从客户端代码传递过来的变量,在顶点之间不做改变

着色器(Shader)和程序(Program)

创建着⾊器对象和程序⼀般过程包括6个步骤:
1.创建⼀个顶点着⾊器对象和⼀个⽚段着⾊器对象
2.将源代码链接到每个着⾊器对象
3.编译着⾊器对象
4.创建⼀个程序对象
5.将编译后的着⾊器对象连接到程序对象
6.链接程序对象

着色器

  • 创建着色器
// GLenumtype为创建着⾊器的类型,GL_VERTEX_SHADER 或GL_FRAGMENT_SHADER
GLuint glCreateShader(GLenum type);
  • 将着色器源码附着到着色器对象
//参数1:指向着⾊器对象的句柄
//参数2:着⾊器源字符串的数量,着⾊器可以由多个源字符串组成,但是每个着⾊器只有⼀个main函数
//参数3:指向保存数量的count 的着⾊器源字符串的数组指针
//参数4:指向保存每个着⾊器字符串⼤⼩且元素数量为count 的整数数组指针.
void glShaderSource(GLuint shader , GLSizei count ,const GLChar * const *string, const GLint 
*length);
  • 编译着色器
//参数:需要编译的着色器对象句柄
void glCompileShader(GLuint shader);
  • 获取着色器编译后的信息
//参数1:需要编译的着⾊器对象句柄
//参数2:获取的信息参数,可以为 GL_COMPILE_STATUS/GL_DELETE_STATUS/
GL_INFO_LOG_LENGTH/GL_SHADER_SOURCE_LENGTH/ GL_SHADER_TYPE
//参数3:指向查询结果的整数存储位置的指针.
void glGetShaderiv(GLuint shader , GLenum pname , GLint *params );
  • 获取着色器日志信息
//参数1:需要编译的着⾊器对象句柄
//参数2:保存信息⽇志的缓存区⼤⼩
//参数3: 写⼊的信息⽇志的⻓度(减去null 终⽌符); 如果不需要知道⻓度. 这个参数可以为Null
//参数4:指向保存信息⽇志的字符缓存区的指针.
void glGetShaderInfolog(GLuint shader , GLSizei maxLength, GLSizei *length , GLChar *infoLog);
  • 删除着色器
//参数 需要删除的着色器句柄
void glDeleteShader(GLuint shader);

程序(Program)

  • 创建程序
//返回一个执行新程序对象的句柄
GLUint glCreateProgram( )
  • 将着色器附着(连接)到程序上
//参数1:指向程序对象的句柄
//参数2:指向程序连接的着⾊器对象的句柄
void glAttachShader( GLuint program , GLuint shader );
  • 链接程序
//参数:指向程序对象句柄
glLinkProgram(GLuint program)
  • 查看程序信息(是否链接成功等)
//program: 需要获取信息的程序对象句柄
//pname : 获取信息的参数,可以是: 
/**GL_ACTIVE_ATTRIBUTES 
GL_ACTIVE_ATTRIBUTES_MAX_LENGTH 
GL_ACTIVE_UNIFORM_BLOCK 
GL_ACTIVE_UNIFORM_BLOCK_MAX_LENGTH 
GL_ACTIVE_UNIFROMS 
GL_ACTIVE_UNIFORM_MAX_LENGTH 
GL_ATTACHED_SHADERS 
GL_DELETE_STATUS 
GL_INFO_LOG_LENGTH 
GL_LINK_STATUS 
GL_PROGRAM_BINARY_RETRIEVABLE_HINT 
GL_TRANSFORM_FEEDBACK_BUFFER_MODE 
GL_TRANSFORM_FEEDBACK_VARYINGS 
GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 
GL_VALIDATE_STATUS **/
//params : 指向查询结果整数存储位置的指针
void glGetProgramiv (GLuint program,GLenum pname, GLint *params); 
  • 从程序信息日志获取信息
//program : 指向需要获取信息的程序对象句柄
//maxLength : 存储信息⽇志的缓存区⼤⼩
//length : 写⼊的信息⽇志⻓度(减去null 终⽌符),如果不需要知道⻓度,这个参数可以为Null. 
//infoLog : 指向存储信息⽇志的字符缓存区的指针
void glGetPorgramInfoLog( GLuint program ,GLSizei maxLength, GLSizei *length , GLChar *infoLog ) 
  • 使用程序
//program: 设置为活动程序的程序对象句柄.
void glUseProgram(GLuint program) 
  • 断开链接
//program : 指向程序对象的句柄
//shader : 指向程序断开连接的着⾊器对象句柄
void glDetachShader(GLuint program); 
  • 删除程序
//program : 指向需要删除的程序对象句柄
void glDeleteProgram( GLuint program ) 

RenderBuffer 和 FrameBuffer

我们平常创建的纹理(Texture)深度缓冲区(Depth Buffer)模板缓冲区(Stencil Buffer)都是基于渲染缓冲区对象(Render Buffer Objects),而渲染缓冲区最终会附着到FrameBuffer上。

2339413-1efc40b20f319b23.png
  • Color Attachment:存储的是纹理图片颜色值,实质上纹理图片颜色值属于颜色附着点的一种
  • Depth Attachment:指向的是深度缓冲区和颜色缓冲区
  • Stencil Attachment:指向的是模版缓冲区
  • RenderBuffer Objects :渲染缓冲区对象,无论是纹理、图片、颜色、深度缓冲区、模版缓冲区都存在这个对象
  • FrameBuffer 上的附着点其实相当于内存地址,它并没有存储实质的内容,只是三个附着点或三个内存地址在FrameBuffer Objects例如color Attachment ,它仅仅是附着在FrameBuffer身上

代码

将RenderBuffer附着到FrameBuffer上

//参数1:附着的目标 GL_FRAMEBUFFER
//参数2:附着类型的枚举,GL_COLOR_ATTACHMENT0
//参数3:RenderBuffer目标,GL_RENDERBUFFER 
//参数4:具体附着的对象
glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)

相关文章

  • OpenGL--GLSL

    图形管线 在我们之前的了解OpenGL ES这篇文章中,我们了解了OpenGL ES的图形管线,如下图: 具体流程...

网友评论

    本文标题:OpenGL--GLSL

    本文链接:https://www.haomeiwen.com/subject/guhkrktx.html