c语言opengles程序,OpenGL ES _ 着色器_程序

5gUAjZkpscARYRVd.png

演示图

你不知道这个东西,请不要看了,请看我的其他文章先了解一下O!

学习目标

掌握着色器程序的执行过程

简单的例子

``

uniform float t; // 时间

uniform mat4 gl_ModelViewMatrix; // 模型视图矩阵

attribute vec4 vel;

const vec4 g = vec4(0.0,-9.8,0.0) // 重力加速度

void main()

{

vec4 position = vel;

position += t*vel + t*t*g;

gl_Position = gl_ModelViewMatrix * position;

}

稍微解释一下:代码的作用是模拟重力加速度,对一个点的位置进行变换.

OpenGL /GLSL 程序接口

先上图

ofzuFZcW5cdtIu28.png

着色器创建流程

C语言,大家应该很熟悉吧! C 语言的编译过程步骤:

1.编译器检查错误

2.将他转换成目标代码(.o文件)

3.将一组目标文件进行链接,最后成为一个可执行文件

在OpenGL 程序中使用GLSL 着色器也是一个相似的过程,要在应用程序中使用顶点或者片段着色器需要按照**顺序**执行下面的步骤:

1.创建着色器对象

2.把着色器代码编译成源代码

3.验证是否着色器是否编译成功

为了把多个着色器对象链接起来,我们需要创建着色器程序

4.创建一个着色器程序

5.把着色器对象链接到这个着色器程序中

6.链接着色器

7.验证着色器链接阶段已经成功完成.

8.使用着色器进行顶点或者片段处理.

函数讲解 (用到的主要是C语法)

GLUint glCreateShader(GLenum type);

作用:创建着色器对象

type 类型值两个: GL_VERTEX_SHADER(顶点做色器) 和 GL_VERTEX_SHADER(片段着色器) 返回一个非零的值,作为着色器的标记

void glShaderSource(GLuint shader,GLsizei count,const GLchar**string,const Glint* length);

作用:创建着色器对象后,需要把着色器的源代码和着色器对象关联

参数1:shader 就是创建着色器成功返回的那个值

参数2:count 包含多个字符串,一般就1个字符串

参数3:字符串数组地址

参数4:,可以为NULL 代表字符串为NULL 结尾的,否则,length就代表具有就有count个元素,每个元素指定了string中对应字符串的长度,如果length数组中的某个元素对应一个正整数,就代表string数组中对应字符串的长度,如果是负整数,对应的字符串就是以NULL 结尾的.

void glCompileShader(GLuint shader)

作用:编译着色器源代码

参数 : shader 着色器标示

glGetShaderiv (GLuint shader, GLenum pname, GLint* params)

作用: 查询编译结果

参数1:shader 着色器标识

参数2:GL_COMPLE_STATUS

参数3:查询结果返回

void glGetShaderInfoLog(GLuint shader,GLsizei bufsize,GLsizei length ,char infoLog);

作用: 获取编译相关日志,调试情况下使用

参数1: shader 着色器对象标识

参数2: bufsize 最大日志长度

参数3: length 如果为NULL 不返回任何日志

参数4:infoLog 保存在缓冲区中

GLuint glCreateProgram()

作用:创建空的着色器程序

返回:非零,如果是0 则创建失败

void AttachShader(GLuint program,GLuint shader);

作用: 把着色器和程序相关联

参数1:program 着色器程序标识

参数2:shader 着色器对象标识

void glDetachShader(GLuint program,Gluint shader);

作用: 把着色器对象从着色器程序中分离出来,以更改着色器的操作。

参数1:program 着色器程序标识

参数2:shader 着色器对象标识

void glLinkProgram()

作用:在着色器对象都连接到着色器程序之后,就要把这些对象连接成一个可执行程序.

void glGetProgramInfoLog(GLuint program,GLsizei bufsize,GLsize length char infoLog)

作用:连接着色器程序也可能出现错误,我们需要进行查询,获取错误日志信息

参数1: program 着色器程序标识

参数2: bufsize 最大日志长度

参数3: length 如果为NULL 不返回任何日志

参数4:infoLog 保存在缓冲区中

void glGetProgramiv (GLuint program, GLenum pname, GLint* params)

作用:查询程序连接后的结果

参数1:program 着色器程序标识

参数2: GL_LINK_STATUS

参数3:params 返回状态

void glUserProgram(GLuint program)

作用: 程序连接成功后,就可以调用这个函数,启动这个顶点或者片段着色器程序了,为了恢复使用固定功能的管线,可以向这个函数传递 0作为参数.

void glDeleteShader(GLuint shader)

作用:删除着色器对象,如果这个着色器对象被多个程序连接,一旦程序不再使用这个对象,那么它便会实际删除

参数: shader 着色器对象标识

void glDeleteProgram(GLuint program)

作用: 删除着色器程序 ,如果这个着色器未在任何渲染环境中使用,它将立即删除。否则,会标记为删除,一旦它没不被使用了,便立即被删除

void GLboolean glIsShader(GLuint shader)

作用: 如果shader 是一个着色器对象名称,则返回GL_TRUE, 否则返回GL_FALSE

void GLboolean glIsProgram(GLuint program)

作用: 如果program 是一个着色器程序,则返回GL_TRUE ,否则返回GL_FALSE

void glValidateProgram(GLuint program)

作用:用于验证一个着色器程序是否可以在当前OpenGL 环境下使用,验证结果查询,使用glGetProgramiv() 传入参数GL_VALIDATE_STATUS 为参数,查询程序验证结果

IOS 代码上一份方便大家理解

导入shader的步骤

第一步. 创建GLuint 类型的shader 标示

第二步. 获取shader 文件所在的路径

第三步 获取文件的内容 并进行NSUTF8StringEncoding 编码

第四步. 根据类型创建shader 着色器对象

第五步. 关联shader着色器源代码

第六步. 编译shader着色器对象源代码

第七步. 检查着色器源代码编译是否成功

第八步. 创建着色器程序

第九步. 将编译好的着色器目标文件链接到程序中去

第十步. 绑定着色器的属性

第十一步. 将着色器和程序分开,并且释放着色器

步骤就是多,最好封装好,不重复敲代码才是王道

``

- (BOOL)loadShaders

{

// 第一步.创建标示

GLuint vertShader, fragShader;

// 第二步.获取文件路径

NSString *vertShaderPathname, *fragShaderPathname;

vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];

if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {

NSLog(@"编译失败 vertex shader");

return NO;

}

// 创建 编译 片断着色器对象

fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];

if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {

NSLog(@"Failed to compile fragment shader");

return NO;

}

// 第八步 创建一个着色器空程序

_program = glCreateProgram();

// 第九步 将顶点着色器链接到程序中

glAttachShader(_program, vertShader);

// 将片断着色器链接到程序中

glAttachShader(_program, fragShader);

//第十步 绑定着色器的属性

glBindAttribLocation(_program, GLKVertexAttribPosition, "position");

glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");

if (![self linkProgram:_program]) {

NSLog(@"Failed to link program: %d", _program);

if (vertShader) {

glDeleteShader(vertShader);

vertShader = 0;

}

if (fragShader) {

glDeleteShader(fragShader);

fragShader = 0;

}

if (_program) {

glDeleteProgram(_program);

_program = 0;

}

return NO;

}

// Get uniform locations.

uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");

uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");

// 第十三步 . 分离释放顶点着色器对象 和片段着色器对象

if (vertShader) {

glDetachShader(_program, vertShader);

glDeleteShader(vertShader);

}

if (fragShader) {

glDetachShader(_program, fragShader);

glDeleteShader(fragShader);

}

return YES;

}

-(BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file

{

//第三步 获取文件的内容 并进行NSUTF8StringEncoding 编码

const GLchar *source;

source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];

if (!source) {

NSLog(@"Failed to load vertex shader");

return NO;

}

//第四步 根据类型创建着色器对象

*shader = glCreateShader(type);

//第五步. 获取着色器源代码和着色器关联

glShaderSource(*shader, 1, &source, NULL);

//第六步. 开始编译着色器源代码

glCompileShader(*shader);

#if defined(DEBUG)

GLint logLength;

glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);

if (logLength > 0) {

GLchar *log = (GLchar *)malloc(logLength);

glGetShaderInfoLog(*shader, logLength, &logLength, log);

NSLog(@"Shader compile log:\n%s", log);

free(log);

}

#endif

//第七步. 查看是着色器源代码否编译成功

GLint status;

glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);

if (status == 0) {

glDeleteShader(*shader);

return NO;

}

return YES;

}

- (BOOL)linkProgram:(GLuint)prog

{

// 第十一 链接程序

glLinkProgram(prog);

#if defined(DEBUG)

GLint logLength;

glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);

if (logLength > 0) {

GLchar *log = (GLchar *)malloc(logLength);

glGetProgramInfoLog(prog, logLength, &logLength, log);

NSLog(@"Program link log:\n%s", log);

free(log);

}

#endif

// 第十二步 检查着色器程序链接结果

GLint status;

glGetProgramiv(prog, GL_LINK_STATUS, &status);

if (status == 0) {

return NO;

}

代码下载地址

点我下载

参考

OpenGL 编程指南>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/573959.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring IOC加载流程

看了网上、书上很多对于spring IOC容器加载过程的分析。大多都只是粗略的讲一下加载流程。其实这样也不错,简单粗暴。清晰记得之前和一个前辈交流时他说的一句话:什么设计模式、设计框架都是扯淡,能实现这个功能就是最好的。其实这样的说法是…

pytorch 模型可视化_【深度学习】高效使用Pytorch的6个技巧:为你的训练Pipeline提供强大动力...

作者:Eugene Khvedchenya 编译:ronghuaiyang导读只报告模型的Top-1准确率往往是不够的。将train.py脚本转换为具有一些附加特性的强大pipeline每一个深度学习项目的最终目标都是为产品带来价值。当然,我们想要最好的模型。什么是“最好的”…

c语言 %-20s,一次 Rust 和C语言的混搭

存在内存泄露extern crate libc;use libc::size_t;use libc::{FILE,c_char};use std::string;#[repr(C)]pub struct mntent {mnt_fsname :*mut c_char, /* 挂载的文件系统的名字 */mnt_dir :*mut c_char, /* 挂载点 */mnt_type :*mut c_char, /* 文件系统类型:ufs、…

KMP算法———模板

做出KMP字符串匹配算法心情也是好好哒&#xff0c;萌萌哒。 感谢黄学长&#xff0c;感谢栋栋&#xff01; #include<cstdio>#include<string>#include<iostream>using namespace std;int p[101];int main(){ string a,b; cin>>a>>b; int na.leng…

tstringlist怎么查看是否存在该数据_注意!研究生招生信息只公开1个月!应该怎么用?...

请注意&#xff01;全国硕士研究生招生信息公开平台&#xff08;以下简称“研招信息公开平台”&#xff09;已于2019年7月1日开放-2019年7月30日结束。招生信息怎么看&#xff1f;老师在线教你看懂研究生招生信息&#xff01;本篇目录&#xff1a;1.全国硕士研究生招生信息公开…

山东外贸职业学院王彩霞老师网上考试系统及c语言考试题库》,2015年山东外贸职业学院单招考试内容...

测试方式及内容1、夏季高考考生&#xff1a;文化考试、基本技能测试、面试(总分400分)(1)文化考试&#xff1a;考试形式为笔试&#xff0c;考试科目&#xff1a;语文、数学。两科一套卷子&#xff0c;分值为&#xff1a;语文100分、数学100分&#xff0c;总分200分&#xff0c;…

5.UiScrollable API 详细介绍

Tip&#xff1a; 1.扫动过程中如果界面停留在滚动条的中间部分会先回到起点再进行滚动 2.扫动过程中设置的步长长短决定划过内容的多少&#xff0c;步长越长滑过的内容就越少&#xff1b;步长越短划过的内容就越长 一、UiScrollable 类介绍 1.UiScrollable类说明 1&#xff09;…

delphi读取xml中的内容property name传递参数_Python 进阶知识全篇-XML 解析

什么是 XML&#xff1f;XML 指可扩展标记语言&#xff08;eXtensible Markup Language&#xff09;&#xff0c;标准通用标记语言的子集&#xff0c;是一种用于标记电子文件使其具有结构性的标记语言。 你可以通过本站学习 XML 教程XML 被设计用来传输和存储数据。XML 是一套定…

c语言getline读取一行命令行,如何从文件的特定行中获取getline()? C ++

这个问题非常不清楚。您如何确定具体线&#xff1f;如果是第n行&#xff0c;最简单的解决方案就是调用getlinen次&#xff0c;扔掉除最后一个结果以外的所有结果&#xff1b;呼唤ignoren-1次可能会快一点&#xff0c;但我怀疑如果您总是读入相同的字符串(而不是构造一个每次都更…

12.UiAutomator 获取系统信息

一、Build构建信息 1.build类&#xff1a; Build类提供了硬件厂商、编号、序列号、SDK版本等重要信息。 类名&#xff1a;android.os.Build 常量名 说明 BOARD底层板名称BOOTLOADERBootloader版本号BRAND品牌CPU_ABICPU指令集CPU_ABI2CPU第二指令集DEVICE工业设计名称DISPLAY显…

c语言编写网页图形界面代码,「分享」C语言如何编写图形界面

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼贴吧内经常有人问C语言是不是只能用于字符终端界面开发&#xff0c;不能用于图形界面。大家也都有回答&#xff0c;需要其他的库。MFC&#xff0c;GTK&#xff0c;QT。本人近期刚用GTK库加上纯C写成了第一个LINUX实用程序。现在与大…

python 读取word_教你怎么使用 Python 对 word文档 进行操作

使用Python对word文档进行操作一、安装Python-docxPython-docx是专门针对于word文档的一个模块&#xff0c;只能读取docx 不能读取doc文件。说白了&#xff0c;python就相当于windows操作系统&#xff0c;QQ就是跑在windows操作系统上的软件&#xff0c;QQ最大的作用是可以去聊…

[国嵌攻略][084][信号同步编程]

进程同步 一组并发进程进行相互合作、相互等待&#xff0c;使得各进程按一定的顺序执行的过程称为进程间的同步。 进程同步与进程互斥 进程同步问题的关键在于生产者不需要获取信号量&#xff0c;消费者不需要释放信号量&#xff0c;所以信号量的初值设置为0。但是进程互斥问题…

android 控件覆盖关系,安卓子控件抢占父控件点击事件或者焦点问题

开发中很常见的一个问题&#xff0c;项目中的lListview不仅仅是简单的文字&#xff0c;常常需要自己定义listview&#xff0c;自己的Adapter去继承BaseAdapter&#xff0c;在adapter中按照需求进行编写&#xff0c;问题就出现了&#xff0c;可能会发生点击每一个item的时候没有…

stm32cubemx adc_STM32CubeMX__Exp5_ADC1_2CH_DMA_TIM3_Trig__简明指导文件__jyb

用定时器TIM3触发DMA方式的双通道ADC定时采样&#xff1a;拷贝STM32CubeMX工程文件LED_Flash_PC12.ioc&#xff0c;修改为&#xff1a;Exp5_ADC1_2CH_DMA_TIM3_Trig.ioc(1)配置ADC1的通道和参数配置ADC通道参数(2)配置ADC1的DMA①通过点"Add"按钮&#xff0c;添加ADC…

JS 实现 jQuery的$(function(){});

1、浏览器渲染引擎的HTML解析流程 何谓“渲染”&#xff0c;其实就是浏览器把请求到的HTML内容显示出来的过程。渲染引擎首先通过网络获得所请求文档的内容&#xff0c;通常以8K分块的方式完成。下面是渲染引擎在取得内容之后的基本流程&#xff1a; 1&#xff0c;解析html以构…

linux ora-00031,kill session遇到ORA-00031錯誤

今天在處理一個表被鎖死的問題時&#xff0c;遇到ORA-00031: 這個階段作業將被標示為要終結的階段作業具體操作步驟如下&#xff1a;1. 先確認鎖定資源的session信息select OS_USER_NAME,s.MACHINE ,object_name as對象名稱,s.sid,s.serial#,p.spid as系統進程號from v$locked_…

html 分页_MySQL——优化嵌套查询和分页查询

Java识堂&#xff0c;一个高原创&#xff0c;高收藏&#xff0c;有干货的微信公众号&#xff0c;欢迎关注优化嵌套查询嵌套查询(子查询)可以使用SELECT语句来创建一个单列的查询结果&#xff0c;然后把这个结果作为过滤条件用在另一个查询中。嵌套查询写起来简单&#xff0c;也…

从原理上搞定编码-- Base64编码

开发者对Base64编码肯定很熟悉&#xff0c;是否对它有很清晰的认识就不一定了。实际 上Base64已经简单到不能再简单了&#xff0c;如果对它的理解还是模棱两可实在不应该。大概介绍一下Base64的相关内容&#xff0c;花几分钟时间就可以彻底理解它。文 章下边贴了一个Base64的编…

android 点击选择文件夹,Android----弹出框选择文件夹目录以及启用新Task打开文件_IT168文库.pdf...

Android弹弹 出出框框 选选择择 文文件件 夹夹 目目录录 以以及及 启启用用新新 的的T ask打打 开开文文件件首首先先看看效效果果 图图第第一一个个 Act iv it y很很简简单单就就 一一个个按按钮钮 But t o n 加加一一个个 T ext View见见 main.xm l[[ cc -- ss hh aa rr pp ]…