当前位置: 首页 > news >正文

建设网站的模板下载ui设计模板网站

建设网站的模板下载,ui设计模板网站,古蔺网站建设,北京怎么进行网页设计NDK​系列之OpenGL离屏渲染与工程代码整合#xff0c;本节主要是对上一节OpenGL渲染画面效果代码进行封装设计#xff0c;将各种特效代码进行分离解耦#xff0c;便于后期增加其他特效。 实现效果#xff1a; 实现逻辑#xff1a; 1.封装BaseFilter过滤器基类#xff0c…NDK​系列之OpenGL离屏渲染与工程代码整合本节主要是对上一节OpenGL渲染画面效果代码进行封装设计将各种特效代码进行分离解耦便于后期增加其他特效。 实现效果 实现逻辑 1.封装BaseFilter过滤器基类实现通用的顶点着色器、片元着色器和着色器程序的初始化赋值和绘制操作 2.编写CamreaFilter相机过滤器实现FBO离屏渲染和变换矩阵等相机相关操作绘制操作完成后将相机过滤器实现的效果的纹理ID传递给下一个过滤器在相机过滤器效果上进行叠加其他效果。 本节主要内容 1.封装BaseFilter过滤器基类 2.实现CamreaFilter相机过滤器 3.实现ScreenFilter屏幕过滤器 4.自定义渲染器MyGlRenderer 源码 NdkOpenGLPlay: NDK OpenGL渲染画面效果 一、封装BaseFilter过滤器基类 1BaseFilter构造方法保存顶点着色器和片元着色器代码资源文件id,保存坐标系到数据缓冲区 public BaseFilter(Context context, int vertexSourceId, int fragmentSourceId) {this.mVertexSourceId vertexSourceId; // 子类传递过来的顶点着色器代码IDthis.mFragmentSourceId fragmentSourceId; // 子类传递过来的片元着色器代码ID// 顶点相关 坐标系float[] VERTEX {-1.0f, -1.0f,1.0f, -1.0f,-1.0f, 1.0f,1.0f, 1.0f,};mVertexBuffer BufferHelper.getFloatBuffer(VERTEX); // 保存到 顶点坐标数据缓冲区// 纹理相关 坐标系float[] TEXTURE {0.0f, 0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f, 1.0f,};mTextureBuffer BufferHelper.getFloatBuffer(TEXTURE); // 保存到 纹理坐标数据缓冲区init(context); } 2加载并编译着色器代码链接色器ID输出着色器程序并获取着色器的索引值 private void init(Context context) {String vertexSource TextResourceReader.readTextFileFromResource(context, mVertexSourceId); // 顶点着色器代码字符串String fragmentSource TextResourceReader.readTextFileFromResource(context, mFragmentSourceId); // 片元着色器代码字符串int vertexShaderId ShaderHelper.compileVertexShader(vertexSource); // 编译顶点着色器代码字符串int fragmentShaderId ShaderHelper.compileFragmentShader(fragmentSource); // 编译片元着色器代码字符串mProgramId ShaderHelper.linkProgram(vertexShaderId, fragmentShaderId); // 链接 顶点着色器ID片元着色器ID 最终输出着色器程序// 删除 顶点 片元 着色器IDglDeleteShader(vertexShaderId);glDeleteShader(fragmentShaderId);// 顶点着色器里面的如下vPosition glGetAttribLocation(mProgramId, vPosition); // 顶点着色器的索引值vCoord glGetAttribLocation(mProgramId, vCoord); // 顶点着色器纹理坐标采样器采样图片的坐标 的索引值vMatrix glGetUniformLocation(mProgramId, vMatrix); // 顶点着色器变换矩阵 的索引值// 片元着色器里面的如下vTexture glGetUniformLocation(mProgramId, vTexture); // 片元着色器采样器 } 3完成绘制操作顶点坐标赋值纹理坐标赋值采样器赋值通知opengl绘制将过滤器实现的效果的纹理ID返回给下一个过滤器 public int onDrawFrame(int textureId) {// 设置视窗大小glViewport(0, 0, mWidth, mHeight);glUseProgram(mProgramId); // 必须要使用着色器程序一次// TODO 画画绘制 等工作// TODO 1.顶点坐标赋值mVertexBuffer.position(0);// 传值glVertexAttribPointer(vPosition, 2, GL_FLOAT, false, 0, mVertexBuffer);// 激活glEnableVertexAttribArray(vPosition);// TODO 2.纹理坐标赋值mTextureBuffer.position(0);// 传值glVertexAttribPointer(vCoord, 2, GL_FLOAT, false, 0, mTextureBuffer);// 激活glEnableVertexAttribArray(vCoord);// 只需要把OpenGL的纹理ID渲染到屏幕上就可以了不需要矩阵数据传递给顶点着色器了// 变换矩阵 把mtx矩阵数据 传递到 vMatrix// glUniformMatrix4fv(vMatrix, 1, false, mtx, 0);// TODO 3.片元 vTextureglActiveTexture(GL_TEXTURE0); // 激活图层// 不需要关心摄像头 和 矩阵// 绑定图层为什么不需要GL_TEXTURE_EXTERNAL_OES答目前拿到的textureId已经是纹理ID了不是摄像头直接采集到的纹理IDglBindTexture(GL_TEXTURE_2D ,textureId);// 因为CameraFilter已经做过了我就直接显示我用OepnGL 2D GL_TEXTURE_2D 显示就行了// glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId); // 由于这种方式并不是通用的所以先去除glUniform1i(vTexture, 0); // 传递采样器glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 通知 opengl 绘制return textureId; // 返回纹理ID可以告诉下一个过滤器 } 二、实现CamreaFilter相机过滤器 1CameraFilter构造方法将顶点着色器和片元着色器代码资源文件id传给父类完成顶点着色器、片元着色器和着色器程序的初始化工作 public CameraFilter(Context context) {super(context, R.raw.camera_vertex, R.raw.camera_fragment); } 2准备工作创建FBO帧缓冲区和FBO的纹理ID并绑定起来 public void onReady(int width, int height) {super.onReady(width,height);// TODO 准备工作// TODO 第一步创建 FBO 看不见的离屏的屏幕mFrameBuffers new int[1];// 参数1int n, fbo 个数// 参数2int[] framebuffers, 用来保存 fbo id 的数组// 参数3int offset 从数组中第几个id来保存,从零下标开始glGenFramebuffers(mFrameBuffers.length, mFrameBuffers, 0); // 实例化创建帧缓冲区FBO缓冲区// TODO 第二步创建属于 fbo 纹理(第一节课是没有配置的但是这个是FOB纹理所以需要配置纹理)// 既然上面的 FBO看不见的离屏的屏幕下面的目的就是要把画面显示到FBO中mFrameBufferTextures new int[1]; // 记录FBO纹理的IDTextureHelper.genTextures(mFrameBufferTextures); // 生成并配置纹理// TODO 第三步上面的 FBO缓冲区 与 FBO纹理 还没有任何关系现在要让他们绑定起来glBindTexture(GL_TEXTURE_2D, mFrameBufferTextures[0]);// 生产2D纹理图像/*int target, 要绑定的纹理目标int level, level一般都是0int internalformat, 纹理图像内部处理的格式是什么rgbaint width, 宽int height, 高int border, 边界int format, 纹理图像格式是什么rgbaint type, 无符号字节的类型java.nio.Buffer pixels*/glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);glBindFramebuffer(GL_FRAMEBUFFER, mFrameBuffers[0]); // 发生关系/*int target, fbo的纹理目标int attachment, 附属到哪里int textarget, 要绑定的纹理目标int texture, 纹理int level level一般都是0*/glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mFrameBufferTextures[0], 0);// TODO 第四步解绑操作glBindTexture(GL_TEXTURE_2D, 0);glBindFramebuffer(GL_FRAMEBUFFER, 0); } 3完成绘制操作渲染到FBO离线缓存中顶点坐标赋值纹理坐标赋值变换矩阵把mtx矩阵数据传递到vMatrix相机过滤器处理过后其他过滤器不需要再变换矩阵采样器赋值通知opengl绘制将FBO的纹理ID返回给下一个过滤器 public int onDrawFrame(int textureId) {// 不能调用super因为父类做的事情和子类是很大区别的// super.onDrawFrame(textureId);glViewport(0, 0, mWidth, mHeight); // 设置视窗大小// TODO 渲染到 FBO离线缓存中// 绑定FBO缓存否则会绘制到屏幕上 我们最终的效果是 离屏渲染glBindFramebuffer(GL_FRAMEBUFFER, mFrameBuffers[0]);glUseProgram(mProgramId); // 必须要使用着色器程序一次// 画画 绘制操作mVertexBuffer.position(0); // 顶点坐标赋值glVertexAttribPointer(vPosition, 2, GL_FLOAT, false, 0, mVertexBuffer); // 传值glEnableVertexAttribArray(vPosition); // 激活mTextureBuffer.position(0); // 纹理坐标赋值glVertexAttribPointer(vCoord, 2, GL_FLOAT, false, 0, mTextureBuffer); // 传值glEnableVertexAttribArray(vCoord); // 激活// TODO 变换矩阵在我们CameraFilter这里就需要处理了后面的BaseFilter就不需要了glUniformMatrix4fv(vMatrix, 1, false, matrix, 0);// 片元 vTextureglActiveTexture(GL_TEXTURE0); // 激活图层// glBindTexture(GL_TEXTURE_2D ,textureId); // 公用的那个 1glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId); // 摄像头打交道采样器使用额外拓展的不能使用公用的那个 2glUniform1i(vTexture, 0);glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 通知 opengl 绘制// 解绑 fboglBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);glBindFramebuffer(GL_FRAMEBUFFER, 0);// FBO的纹理ID返回了return mFrameBufferTextures[0]; // 你没有学过C你就不明白如果你学过无需多言 } 4相机过滤器顶点着色器代码 attribute vec4 vPosition; // 顶点坐标相当于相机的四个点位置排版attribute vec4 vCoord; // 纹理坐标用来图形上色的uniform mat4 vMatrix; // 变换矩阵4*4的格式的varying vec2 aCoord; // 把这个最终的计算成果给片元着色器 【不需要Java传递他是计算出来的】void main() {gl_Position vPosition; // 确定好位置排版aCoord (vMatrix * vCoord).xy; // 兼容所有设备 } 5相机过滤器片元着色器代码 // 导入 samplerExternalOES #extension GL_OES_EGL_image_external : require// float 数据的精度 precision lowp 低精度 precision mediump 中精度 precision highp 高精度 precision mediump float;// 根据上面的数据的精度写下面的 采样器 相机的数据 // uniform sampler2D vTexture; 由于我们用的是 安卓的相机就不能用他 uniform samplerExternalOES vTexture; // samplerExternalOES才能采样相机的数据varying vec2 aCoord; // 把这个最终的计算成果给片元着色器拿到最终的成果我才能上色void main() {// 底片效果vec4 rgba texture2D(vTexture,aCoord); // rgbagl_FragColor vec4(1.-rgba.r, 1.-rgba.g, 1.-rgba.b, rgba.a); } 三、实现ScreenFilter屏幕过滤器 1ScreenFilter构造方法将顶点着色器和片元着色器代码资源文件id传给父类完成顶点着色器、片元着色器和着色器程序的初始化工作 public ScreenFilter(Context context) {super(context, R.raw.base_vertex, R.raw.base_fragment); // base_vertex(没有矩阵) base_fragment(没有OES 是sampler2D) } 2准备工作和绘制操作复用父类完成 3屏幕过滤器顶点着色器代码 attribute vec4 vPosition; // 顶点坐标相当于相机的四个点位置排版attribute vec2 vCoord; // 纹理坐标用来图形上色的varying vec2 aCoord; // 把这个最终的计算成果给片元着色器 【不需要Java传递他是计算出来的】void main() {gl_Position vPosition; // 确定好位置排版 gl_Position OpenGL着色器语言内置的变量// 着色器语言基础语法// aCoord vCoord.xy;// aCoord是2个分量的 vCoord是四个分量的.xy取出两个分量aCoord vCoord; } 4屏幕过滤器片元着色器代码 // float 数据的精度 precision lowp 低精度 precision mediump 中精度 precision highp 高精度 precision mediump float;// 根据上面的数据的精度写下面的 采样器 相机的数据 uniform sampler2D vTexture;// 由于我们用的是 安卓的相机就不能用他(用OpenGL 2D显示就行了不需要摄像头了sampler2D)varying vec2 aCoord;// 把这个最终的计算成果给片元着色器拿到最终的成果我才能上色void main() {// texture2D (采样器, 坐标) gl_FragColor OpenGL着色器语言内置的变量gl_FragColor texture2D(vTexture, aCoord);// 直接上色你直接上色是上camera_fragment.glsl的底片效果 } 四、自定义渲染器MyGlRenderer 从上一节中我们知道MyGlRenderer实现GLSurfaceView.Renderer接口实现接口的onSurfaceCreated()、onSurfaceChanged()和onDrawFrame()方法 1当Surface创建时回调onSurfaceCreated()函数创建ScreenFilter屏幕过滤器同样在创建ScreenFilter屏幕过滤器之前我们要先创建CamreaFilter相机过滤器 Override public void onSurfaceCreated(GL10 gl, EGLConfig config) {mCameraFilter new CameraFilter(myGLSurfaceView.getContext()); // 先 FBOmScreenFilter new ScreenFilter(myGLSurfaceView.getContext()); // 后 渲染屏幕 } 2当Surface改变时回调onSurfaceChanged()函数完成过滤器准备工作 Override public void onSurfaceChanged(GL10 gl, int width, int height) {mCameraFilter.onReady(width, height);mScreenFilter.onReady(width, height); } 3绘制一帧图像时回调onDrawFrame()函数获取纹理对象的图像数据先通过CamreaFilter相机过滤器实现相关效果再将其FBO的纹理ID传递给下一个过滤器这里由于暂无实现其他特效就传递给了ScreenFilter屏幕过滤器将最终成果的纹理ID通过OpenGL渲染到屏幕 Override public void onDrawFrame(GL10 gl) {// 相机过滤器绘制一帧图像不可见mCameraFilter.setMatrix(mtx);int textureId mCameraFilter.onDrawFrame(mTextureID[0]); // 摄像头矩阵都已经做了// 增加其他特效/*textureId 美白.onDrawFrame(textureId);textureId 大眼.onDrawFrame(textureId);textureId xxx.onDrawFrame(textureId);*/// 屏幕过滤器绘制一帧图像屏幕显示mScreenFilter.onDrawFrame(textureId); // textureId 最终成果的纹理ID } 注后续将会在CamreaFilter相机过滤器和ScreenFilter屏幕过滤器中间增加各种效果过滤器实现其他特效如美白大眼兔耳朵等。 至此OpenGL离屏渲染与工程代码整合已完成。 源码 NdkOpenGLPlay: NDK OpenGL渲染画面效果
http://www.sczhlp.com/news/170527/

相关文章:

  • 孝感做网站的公司wordpress集成文库
  • 工商核名在哪个网站撰写网站的建设方案
  • 哈尔滨大连工程建设信息网站互联网营销师资格证
  • 网站欣赏网站欣赏礼服购物车网站模板
  • 建设新北川网站国外网站建设设计欣赏
  • 易无忧建站汕头网站建设推广平台
  • 医美类网站如何做推广寺院的网站怎么做
  • 成都开发网站建设高淳建设发展集团网站
  • 重庆手机网站方案设计国内大型php网站建设
  • 17_AiAgentMCP实现技术选型
  • JVM_XMS 和 java_opts哪种写法对?如何在JVM中设置JVM_XMS和java_opts?
  • 浅谈并查集
  • 网站建设托管推广海报排名优化公司口碑哪家好
  • 在线旅游网站建设方案制作wordpress页面模板下载
  • 寻找网站建设义乌有什么企业网站吗
  • 俄罗斯网站设计南宁小程序定制开发公司
  • 做网站的文章同程商旅企业版
  • 加强网站技术建设中小型企业网络拓扑图
  • 网站建设进度以及具体内容中国开源网
  • 个人做外贸网站编程培训机构哪里好
  • 邮箱注册过的网站查询在线制作头像文字图片
  • 南京学习做网站wordpress安装主题后进不去后台
  • 合肥网络公司 网站建设wordpress 文章目录插件
  • 淄博网站制作形象如何申请域名后缀
  • 网站建设贵吗南京成旭通网站建设公司怎么样
  • 网上购物商城网站wordpress支付可见下载
  • 定制高端网站建设缙云建设局网上协同办公oa网站
  • 珠海网页模板建站酒店微信网站建设
  • 内蒙古建设工程交易中心网站写文章在哪里发表挣钱
  • 越秀手机网站建设安阳网站建设哪家便宜