【Android OpenGL ES 开发 (三)】Shader 扩展

编译Shader代码

1.封装一个编译shader的接口

GLuint CompileShader(GLenum shaderType,const char *shaderCode){GLuint shader=glCreateShader(shaderType);glShaderSource(shader,1,&shaderCode,NULL);glCompileShader(shader);GLint compileResult=GL_TRUE;glGetShaderiv(shader,GL_COMPILE_STATUS,&compileResult);if(compileResult==GL_FALSE){char szLog[1024]={0};GLsizei logLen=0;glGetShaderInfoLog(shader,1024,&logLen,szLog);__android_log_print(ANDROID_LOG_INFO,"BattleFire","CompileShader %s\n%s\n",szLog,shaderCode);glDeleteShader(shader);shader=0;}return shader;
}

2.调用编译shader的接口

    //编译shaderint filesize=0;unsigned char *filecontent=LoadfileContent("test.vs",filesize);GLuint vsshader = CompileShader(GL_VERTEX_SHADER,(char*)filecontent);delete [] filecontent;filecontent=LoadfileContent("test.fs",filesize);GLuint fsshader = CompileShader(GL_VERTEX_SHADER,(char*)filecontent);delete [] filecontent;

生成GPU程序

1.实现生成GPU程序接口

GLuint CreateProgram(GLuint vs,GLuint fs){GLuint program=glCreateProgram();glAttachShader(program,vs);glAttachShader(program,fs);glLinkProgram(program);glDetachShader(program,vs);glDetachShader(program,fs);GLint nResult;glGetProgramiv(program,GL_LINK_STATUS,&nResult);if(nResult==GL_FALSE){char szLog[1024]={0};GLsizei logLen=0;glGetProgramInfoLog(program,1024,&logLen,szLog);__android_log_print(ANDROID_LOG_INFO,"BattleFire","CreateProgram %s\n",szLog);glDeleteProgram(program);program=0;}return program;
}

2.编译与生成GPU程序合并封装

GLuint CreateStanarProgram(const char *vertex_shader_path,const char * fragment_shader_path)
{//编译shaderint filesize=0;unsigned char *filecontent=LoadfileContent(vertex_shader_path,filesize);GLuint vsShade = CompileShader(GL_VERTEX_SHADER,(char*)filecontent);delete [] filecontent;filecontent=LoadfileContent(fragment_shader_path,filesize);GLuint fsShader = CompileShader(GL_VERTEX_SHADER,(char*)filecontent);delete [] filecontent;GLuint program=CreateProgram(vsShade,fsShader);glDeleteShader(vsShade);glDeleteShader(fsShader);return program;
}

配置好属性组并进行绘制

extern "C" JNIEXPORT void JNICALL
Java_com_example_learnogles_MainActivity_Render(JNIEnv* env,jobject /* this */) {//__android_log_print(ANDROID_LOG_INFO,HANGYU_LOG_TAG,"Render");glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);glBindBuffer(GL_ARRAY_BUFFER,vbo);//设置状态机glUseProgram(program);glUniformMatrix4fv(modelMatrixLocation,1,GL_FALSE,glm::value_ptr(modelMatrix));//模型矩阵glUniformMatrix4fv(viewMatrixLocation,1,GL_FALSE,glm::value_ptr(viewMatrix));//视口矩阵glUniformMatrix4fv(projectionMatrixLocation,1,GL_FALSE,glm::value_ptr(projectionMatrix));//投影矩阵//set attribute//激活属性组glEnableVertexAttribArray(positionLocation);//激活属性位置glVertexAttribPointer(positionLocation,4,GL_FLOAT,GL_FALSE,sizeof(Vectice),0);
//    glEnableVertexAttribArray(colorLocation);
//    glVertexAttribPointer(colorLocation,4,GL_FLOAT,GL_FALSE,sizeof(float)*8,(void*)(sizeof(float)*4));glDrawArrays(GL_TRIANGLES,0,3);//从第0个点绘制,绘制三个点,会从vbo中取值glBindBuffer(GL_ARRAY_BUFFER,0);glUseProgram(0);}

属性在shader间的传递

1.VS

attribute vec4 position;
attribute vec4 color;
uniform mat4 U_ModelMatrix;
uniform mat4 U_ViewMatrix;
uniform mat4 U_ProjectionMatrix;
varying vec4 V_Color;
void main(){V_Color=color;gl_Position=U_ProjectionMatrix*U_ViewMatrix*U_ModelMatrix*position;
}

2.FS

#ifdef GL_ES
precision mediump float;
#endif
varying vec4 V_Color;
void main(){gl_FragColor=V_Color;
}

模型矩阵的使用

1.在世界坐标Z为0的时候,由于平行不能看见任何东西。在这种情况我们可以使用模型矩阵整体平移(原理:是uniform变量,会影响所有点)

//平移
modelMatrix=glm::translate(0.0f,0.0f,-2.0f)
//缩放
glm::scale(0.5f,0.5f,0.5f)
//旋转
glm::rotate(30.0f,0.0f,0.0f,1.0f);//旋转角度,旋转哪个轴修改哪个轴

正交投影与2DUI元素的绘制

备注:透视投影,进大远小。

1.根据屏幕像素坐标来写绘图数据,而不需要3D坐标,使用前提必须写成以下内容才可以正确使用。

float half_width=float(width)/2.0f; //画布的宽
float half_height=float(height)/2.0f;//画布的高
//左边界,有边界,下边界,上边界,最近点,最远点
projectionMatrix=glm::ortho(-half_width,half_width,-half_height,half_height,0.1f,100.0f);

控制UI前后关系的方法之一

1.通过修改模型矩阵来修改UI前后关系。

2.可以通过修改Z的坐标来确定谁覆盖谁,前提是需要开启深度缓冲区才能管理物体远近关系。

glEnable(GL_DEPTH_TEST)

使用索引数据绘制UI

1.定义一个 GLuint ibo;//index buffer object ,element array buffer object

    unsigned short indexes[]={ 0,1,2,1,3,2};glGenBuffers(1,&ibo);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(unsigned short)*6, nullptr,GL_STATIC_DRAW);//alloc gpuglBufferSubData(GL_ELEMENT_ARRAY_BUFFER,0,sizeof(unsigned short)*6,indexes);//cpu -> gpu//glBufferData(GL_ARRAY_BUFFER,sizeof(Vertice)*3,vertices,GL_STATIC_DRAW);//cpu -> gpuglBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);

2.绘制修改,改变的是绘制三角形的方式

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,0);//glDrawArrays(GL_TRIANGLE_STRIP,0,4);glUniformMatrix4fv(modelMatrixLocation,1,GL_FALSE,glm::value_ptr(modelMatrix2));glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,0);//glDrawArrays(GL_TRIANGLE_STRIP,0,4);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);

封装VBO和IBO相关API

GLuint CreateBufferObject(GLenum type,void * data,int size,GLenum usage){GLuint object_to_ret;glGenBuffers(1,&object_to_ret);glBindBuffer(type,object_to_ret);glBufferData(type,size,data,usage);//cpu -> gpuglBindBuffer(type,0);return object_to_ret;
}
void UpdateBufferObject(GLuint object,GLenum type,void * data,int size,int offset){glBindBuffer(type,object);glBufferSubData(type,offset,size,data);//cpu -> gpuglBindBuffer(type,0);
}

 

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

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

相关文章

css阴影属性_第三场阴影场与属性访问器接口

css阴影属性这是“ 影子字段与属性访问器”界面的 第3轮 。 如果您是新手,但不确定要怎么做,请查看我以前的文章或关于开发JavaFX应用程序时节省内存的第一篇文章 。 作为Java开发人员,我主要关心的是在开发JavaFX域模型时在性能 &#xff0c…

js if判断多个条件_JS条件判断小技巧(一)

经常code review,我发现JS newbie很容易写出一堆冗长的代码。今天就列几个比较常见的“解决之道”,看看如何减少JS里的条件判断。提前返回,少用if...else“if...else是编程语言的精华。——鲁迅”但是过多的嵌套,还是挺令人抓狂的…

【Android OpenGL ES 开发 (四)】纹理相关(一)

纹理贴图的原理 1.作用:可以用来渲染视频。 2.纹理坐标 生成OpenGL中的纹理对象 1.像素数据想要绘制出来需要先变成纹理 2.创建纹理放在GPU上 GLuint CreateTexture2D(unsigned char *pixelData,int width,int height,GLenum type) {GLuint texture;glGenTextu…

python selenium循环判断元素是否存在_检查Python Selenium是否存在元素

我有一个问题-我正在使用Selenium(firefox)Web驱动程序打开网页,单击一些链接等,然后捕获屏幕截图。我的脚本可以从CLI正常运行,但是通过cronjob运行时,它并没有通过第一个find_element()测试。我需要添加一些调试,或一…

jmx 替代_使用JMX作为Ganglia的现代替代品进行CLDB监视

jmx 替代有许多选项可用于监视MapR集群的性能和运行状况。 在本文中,我将介绍使用Java管理扩展(JMX)监视CLDB的鲜为人知的方法。 据最受尊敬的MapR数据工程师之一,Akihiko Kusanagi称,与使用Ganglia相比,使…

WPScan安全建议和防护

加固WordPress安全性 保护WordPress网站的安全性至关重要,因为它是全球最受欢迎的内容管理系统之一,也是攻击者经常瞄准的目标。本文将深入探讨如何加固WordPress安全性,包括实施强密码策略、保持更新、使用可靠的主题和插件、限制登录尝试、…

red hat安装宝塔_如何在几分钟内安装Red Hat Container Development Kit(CDK)

red hat安装宝塔作为负责开发容器化应用程序提供的可能性的应用程序开发人员或架构师,将所有工具组合在一起以帮助您入门时几乎没有帮助。 到现在。 红帽容器开发套件(CDK) 安装变得简单! 红帽提供了一个容器开发套件&#xf…

python收集数据程序_用Python挖掘Twitter数据:数据采集

原标题:用Python挖掘Twitter数据:数据采集作者:Marco Bonzanini 翻译:数盟这是7部系列中的第1部分,注重挖掘Twitter数据以用于各种案例。这是第一篇文章,专注于数据采集,起到奠定基础的作用。Tw…

【FFMPEG中PTS与DTS统一转换为毫秒】

对于PTS和DTS 是两个非常重要的参数,在音视频同步时是必要的,为了方便使用,将二者统一为毫秒级别 static double r2d(AVRational r) {return r.den 0 ? 0 : (double)r.num / (double)r.den; } //转换为毫秒,方便做同步 AVPacke…

threejs 影子属性_影子场vs.属性访问器接口第2轮

threejs 影子属性如果你们还没有注意到Dirk Lemmerman和我之间的(轻松) 摊牌 ,那么让我快速提及一下我们是如何做到这一点的。 首先,Dirk创建了JavaFX技巧23:“ 为属性保存内存阴影字段 ”,以帮助应用程序开…

【OpenGL从入门到精通】Shader专题

详解GPU的工作流程 1.shader通常称为着色器,作用是把CPU上的点渲染出来。 2.shader是并行的。 3.流程:数据data (顶点数据) ----->VS(输入:data的顶点数据,输出:gl_Position的 vec4 顶点数据)----->光栅化处理…

python内存管理可以使用del_Python深入学习之内存管理

语言的内存管理是语言设计的一个重要方面。它是决定语言性能的重要因素。无论是C语言的手工管理,还是Java的垃圾回收,都成为语言最重要的特征。这里以Python语言为例子,说明一门动态类型的、面向对象的语言的内存管理方式。对象的内存使用赋值…

【OpenGL从入门到精通(六)】纹理对象与纹理坐标

1.在OpenGL想要显示一张图片,需要先绘制一个自定义的几何体。 2.把图片加载到纹理对象中 3.当进行纹理贴图时候,使用纹理坐标来设置纹理对象。 2.

yeoman_具有Spring Boot和Yeoman的单页Angularjs应用程序

yeoman我非常感谢yeoman之类的工具,这些工具提供了一种非常快速的方法来将不同的javascript库组合在一起成为一个一致的应用程序。 Yeoman提供了UI层,如果您需要开发服务层和静态资产的Web层,则打包的一种好方法是使用Spring Boot 。 我知道有…

python30行代码_仅利用30行Python代码来展示X算法

假如你对数独解法感兴趣,你可能听说过精确覆盖问题。给定全集 X 和 X 的子集的集合 Y ,存在一个 Y 的子集 Y*,使得 Y* 构成 X 的一种分割。这儿有个Python写的例子。X {1, 2, 3, 4, 5, 6, 7}Y {A: [1, 4, 7],B: [1, 4],C: [4, 5, 7],D: [3,…

LeetCode 203. 移除链表元素

原题链接 class Solution { public:ListNode* removeElements(ListNode* head, int val) {auto dummy new ListNode(-1);dummy->next head;for (auto p dummy; p; p p->next) {auto q p->next;while (q && q->val val) q q->next;p->next q…

双向链表删除节点时间复杂度_「十分钟学算法」删除链表的倒数第N个节点

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。示例:给定一个链表: 1->2->3->4->5, 和 n 2.当删除了倒数第二个节点后,链表变为 1->2->3->5.说明:给定的 n 保证是有效的。题解…

netbeans连接数据库_NetBeans Java EE技巧3:数据库中的RESTful Web服务

netbeans连接数据库许多现代的Web应用程序正朝着使用HTTP使用无状态通信的方向发展。 REST(表示状态转移)体系结构样式通常用于设计网络应用程序,而使用Java EE 7,很容易开发用于数据库通信的RESTful后端。 使用简单的POJO&#x…

双指针算法核心

1.双指针算法主要是为了提高朴素算法的复杂度&#xff0c;即O(n^2)的算法&#xff0c;优化为O(n)的算法。 2.常见模板 for (int i 0, j 0; i < n; i ) {while (j < i && check(i, j)) j ;// 具体问题的逻辑 } 常见问题分类&#xff1a;(1) 对于一个序列&am…