Modern OpenGL ES: ndk编程——画一个三角形之Shader工程
来源:互联网 发布:sql 查询数据库大小 编辑:程序博客网 时间:2024/06/10 05:23
OpenGL ES2.0以后,想画一个东西必须使用 shader来完成。 而使用shader需要创建shader工程。使用shader来画一个东西的大体步骤如下:
1 创建和编译shader
2 创建和链接shader工程
3 为shader工程设置 uniform 和 attrubte变量
4 Shader编译 并链接到工程,成最终的可执行文件
Vertex Shader 和 Fragment Shader
OpenGL 有很多种Shader对象,但我们需要经常使用的只有两种,一种是 光栅化之前的Vertex Shader ,一种是光栅化之后的Fragment Shader
光栅化,就是将OpenGL中定义的 物体的顶点映射到屏幕像素的过程。
光栅化之前,我们需要定义所画物体的顶点,顶点包括 位置,颜色等属性, 通过这些属性能实现物体的不同方向和位置,以及不同的表像、光照,这些都是通过 Vertex Shader来完成的
光栅化之后,我们需要将所画物体映射为屏幕的像素,最终现实出来图像,这一步我们可以决定现实 图像的哪一部分,如果两个图像叠加在一起,那么它们的混合模式是怎样的? 这些都是通过 Fragment Shader完成的
创建和编译Shader对象
1 创建Shader
GLuint glCreateShader(GLenum type)
参数: 要创建的shader类型,如GL_VERTEX_SHADER, GL_FRAGMENT_SHADER
返回: 返回这个Shader对象的句柄
功能: 获得了该shader的句柄后,我们就可以进一步对它操作了,如送入shader source, 编译shader, 删除shader。
2 删除Shader
void glDeleteShader(GLuint shader)
参数: 删除的shader句柄
注意: 如果该shader已经依附了一个shader工程,那么调用该函数并不能立即删除shader对象,知道该对象不再使用
3 提供shader源码
void glShaderSource(GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length)
参数:
shader:
count: shader 源码字串的个数。 一个完整的shader 源码可能会有很多个字符串组成
const GLchar* const *string: 指向一组shader源码字符串
length: shader源码的字数,如果NULL,就是字符串到NULL时结束
4 编译源码
shader对象,一旦被赋值了字符串
void glCompileShader(GLuint shader)
5 获取shader信息
void glGetShaderiv(GLuint shader, GLenum pname, GLint *params)
参数:
shader:
pname: 要获取信息的类型:
GL_COMPILE_STATUS
GL_DELETE_STATUS
GL_INFO_LOG_LEGTH
GL_SHADER_SOURCE_LENGTH
GL_SHADER_TYPE
params:
用一个 整数来代表结果
GL_COMPILE_STATUS 表示要查询编译信息, params如果是 GL_TRUE, 表示编译成功, 反之,失败
6 获取shader日志信息
如果第5步获取的信息失败, 会将错误信息写的日志里,通过以下函数获取
void glGetSahderInfoLog(GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *infoLog)
参数:
shader :
maxLength: 需要存储 info log的buffer大小
length: 需要写进info的长度。 如果不知道长度,可以是NULL
infoLog: 指向log字符串的buffer。
创建和链接工程:
继创建完shader对象之后,我们需要创建shader工程了。 shader工程更像是 一个 容纳了shader对象的容器,假如shader好比.obj的话,那么shader工程还具有将它们按照 管线流程,将这些.obj编译链接成一个 .o文件。
1 创建 shader工程
GLuint glCreateProgram()
如创建shader对象一样, 创建了一个program的句柄
2 删除shader工程
void glDeleteProgram(GLuint program)
3 需要将shader对象添加到 shader program这个容器中
void glAttachShader(GLuint program, GLuint shader)
4 Link完,或者Link失败,都需要删除shader工程里的shader对象
void glDetachShader(GLuint program, GLuint shader)
5 链接这些shader对象
void glLinkProgram(GLuint program)
Link的目的是要将这些shader对象 变为一个GPU能执行的可执行文件
6 与获取shader信息一样,也可以获取shader工程信息
void glGetProgramiv(GLuint program, GLenum pname, GLint *params)
参数:
program:
pname:
GL_ACTIVE_ATTRIBUTES // 激活的(使用的)attribute变量的个数
GL_ACTIVE_ATTRIBUTE_MAX_LENGTH //attribute名字的最大长度
GL_ACTIVE_UNIFORM_BLOCK
GL_ACTIVE_UNIFORM_BLOCK_MAX_LENGTH
GL_ACTIVE_UNIFORMS
GL_ACTIVE_UNIFORM_MAX_LENGTH
GL_ATTACHED_SHADERS // 依附的 shader数
GL_DELETE_STATUS
GL_INFO_LOG_LENGTH
GL_LINK_STATUS // 检测链接是否成功
GL_PROGRAM_BINARY_RETERIEVABLE_HINT
GL_TRANSFORM_FEEDBACK_BUFFER_MODE
GL_TRANSFORM_FEEDBACK_VARYINGS //在feedback 阶段输出的变量数
GL_TRANSFORM_FEEDBACK_VARING_MAX_LENGTH
GL_VALIDATE_STATUS
7 获取shader工程日志
void glGetProgramInfoLog(GLuint program, GLsizei maxLength, GLsizel *length, GLchar *infoLog)
参数:
program:
maxLength: 存储的最大buffer大小
length: 需要写入的字符长度,如果不知道天下null
infoLog: 字符串
8 一旦创建好, 我们就可以渲染该shader工程了。 这之前,还需要确定shader工程是否有效
void glValidateProgram(GLuint program)
9 使用shader工程
void glUseProgram(GLuint program)
0 0
- Modern OpenGL ES: ndk编程——画一个三角形之Shader工程
- Modern OpenGL ES: ndk编程——画一个三角形之NativeWindow
- Modern OpenGL ES: ndk编程——画一个三角形之创建EGL窗口
- iOS下OpenGL ES 3.0编程入门(二 ):画一个简单三角形
- iOS下OpenGL ES 3.0编程入门(二 ):画一个简单三角形
- OpenGL ES 学习教程(二) 可编程管线,Shader,一个彩色三角形!
- 基于Cocos2d-x学习OpenGL ES 2.0系列——OpenGL ES渲染之Shader准备(7)
- 【Modern OpenGL】Shader
- [Modern OpenGL系列(三)]用OpenGL绘制一个三角形
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——1.2 用OpenGL ES 2.0画一个三角形
- OpenGL ES渲染之Shader准备
- android OpenGL ES开发之shader
- OpenGL ES 2.0——顶点着色器Vertex Shader
- OpenGL ES 2.0——片段着色器Fragment Shader
- OpenGL ES 2.0——顶点着色器Vertex Shader
- OpenGL ES 2.0 - Shader
- OpenGL ES 2.0 Shader
- OpenGL ES 2.0 Shader
- 逻辑斯蒂回归 Logstic Regression in Python
- 开源框架spring AOP的深刻理解
- form表单被自动提交
- 【设计模式】Filter-Chain 的应用
- 关联选择器和组合选择器,伪元素选择器
- Modern OpenGL ES: ndk编程——画一个三角形之Shader工程
- Linux 的文件权限与目录配置
- 二叉搜索树的后序遍历序列
- 正则化方法:L1和L2 regularization、数据集扩增、dropout
- Fragment基础点滴学习---动态加载加载
- 编译原理(词法分析)
- Lesson 9 Array multiplication
- maven仓库
- JAVA学习(二)