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

做网站 技术百度指数免费查询入口

做网站 技术,百度指数免费查询入口,完美世界培训机构,网站背景颜色代码一.概述 今天使用OpenGLES实现一个圆心是玫红色,向圆周渐变成蓝色的圆。 本篇博文的内容也是后续绘制3D图形的基础。 实现过程中,需要重点关注的点是:如何使用数学公式求得图形的顶点,以及加载颜色值。 废话不多说&#xff0c…

一.概述

今天使用OpenGLES实现一个圆心是玫红色,向圆周渐变成蓝色的圆

本篇博文的内容也是后续绘制3D图形的基础。

实现过程中,需要重点关注的点是:如何使用数学公式求得图形的顶点,以及加载颜色值。

废话不多说,开工吧!

二.Render类

Render类中需要关注的重点是:createCirclePositions()

这个函数中实现了圆形的顶点创建和颜色值加载

已知如下两个变量:

  • 圆半径:R;
  • 圆周的点与X轴的夹角:θ

求圆的顶点坐标需要求得两种坐标:

  • 圆心的顶点坐标
  • 圆周的顶点坐标

圆心坐标比较简单:(0,0)

圆周上点的坐标:

  • x = R * cos(θ)
  • y = R * sin(θ)

知道如何求得圆的顶点坐标后,如下就是Render类的实现代码:

public class CircleRender implements GLSurfaceView.Renderer {private final String TAG = CubeRender.class.getSimpleName();private final Context mContext;//圆形顶点位置private float vertexData[];//顶点的颜色private float colorData[];private FloatBuffer vertexBuffer;private FloatBuffer colorBuffer;//MVP矩阵private float[] mMVPMatrix = new float[16];//shader程序/渲染器private int shaderProgram;//返回属性变量的位置//变换矩阵private int uMatrixLocation;//位置private int aPositionLocation;//颜色private int aColorLocation;private float ratio;public CircleRender(Context context) {mContext = context;}@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {Log.v(TAG, "onSurfaceCreated()");glClearColor(0.0f, 0.0f, 0.0f, 1.0f);initGLES();}public void initGLES() {Log.v(TAG, "initGLES!");/************** 着色器程序/渲染器 **************///创建并连接 着色器程序shaderProgram = ShaderUtils.createAndLinkProgram(mContext,"circle_vertex_shader.glsl","circle_fragtment_shader.glsl");if (shaderProgram == 0) {Log.v(TAG, "create And Link ShaderProgram Fail!");return;}//使用着色器源程序glUseProgram(shaderProgram);createCirclePositions(0.8f, 60);/************** 着色器变量 **************///获取着色器中的变量uMatrixLocation = glGetUniformLocation(shaderProgram, "u_Matrix");aPositionLocation = glGetAttribLocation(shaderProgram, "vPosition");aColorLocation = glGetAttribLocation(shaderProgram, "aColor");//为顶点、颜色、索引数据配置内存vertexBuffer = ShaderUtils.getFloatBuffer(vertexData);colorBuffer = ShaderUtils.getFloatBuffer(colorData);//启动深度测试glEnable(GL_DEPTH_TEST);}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {Log.v(TAG, "onSurfaceChanged(): " + width + " x " + height);glViewport(0, 0, width, height);//计算宽高比ratio = (float) width / height;}@Overridepublic void onDrawFrame(GL10 gl) {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glClearColor(0.95f, 0.95f, 0.95f, 0.95f);mMVPMatrix = TransformUtils.getCircleMVPMatrix(ratio);//将变换矩阵传入顶点渲染器glUniformMatrix4fv(uMatrixLocation, 1, false, mMVPMatrix, 0);//准备顶点坐标和颜色数据glVertexAttribPointer(aPositionLocation, 3, GL_FLOAT, false, 0, vertexBuffer);glVertexAttribPointer(aColorLocation, 4, GL_FLOAT, false, 0, colorBuffer);//启用顶点位置和顶点颜色句柄glEnableVertexAttribArray(aPositionLocation);glEnableVertexAttribArray(aColorLocation);//绘制glDrawArrays(GL_TRIANGLE_FAN, 0, vertexData.length / 3);//禁止顶点数组的句柄glDisableVertexAttribArray(aPositionLocation);glDisableVertexAttribArray(aColorLocation);}private void createCirclePositions(float radius, int n) {ArrayList<Float> data = new ArrayList<>();data.add(0.0f);        //设置圆心坐标data.add(0.0f);data.add(0.0f);float angDegSpan = 360f / n;for (float i = 0; i < 360 + angDegSpan; i += angDegSpan) {data.add((float) (radius * Math.sin(i * Math.PI / 180f)));data.add((float) (radius * Math.cos(i * Math.PI / 180f)));data.add(0.0f);}float[] f = new float[data.size()];for (int i = 0; i < f.length; i++) {f[i] = data.get(i);}vertexData = f;//处理各个顶点的颜色colorData = new float[f.length * 4 / 3];ArrayList<Float> temp0 = new ArrayList<>();ArrayList<Float> temp2 = new ArrayList<>();ArrayList<Float> temp1 = new ArrayList<>();temp1.add(1.0f);temp1.add(0.0f);temp1.add(1.0f);temp1.add(0.0f);temp0.add(0.0f);temp0.add(0.0f);temp0.add(1.0f);temp0.add(0.0f);for (int i = 0; i < f.length / 3; i++) {if (i == 0) {temp2.addAll(temp1);} else {temp2.addAll(temp0);}}for (int i = 0; i < temp2.size(); i++) {colorData[i] = temp2.get(i);}}
}

三.ShaderUtils相关函数:

与之前的一样,常规代码

3.1 createAndLinkProgram()

    /** 创建和链接着色器程序* 参数:顶点着色器、片段着色器程序ResId* 返回:成功创建、链接了顶点和片段着色器的着色器程序Id*/public static int createAndLinkProgram(Context context, String vertexShaderFN, String fragShaderFN) {//创建着色器程序int shaderProgram = glCreateProgram();if (shaderProgram == 0) {Log.e(TAG, "Failed to create shaderProgram ");return 0;}//获取顶点着色器对象int vertexShader = loadShader(GL_VERTEX_SHADER, loadShaderSource(context, vertexShaderFN));if (0 == vertexShader) {Log.e(TAG, "Failed to load vertexShader");return 0;}//获取片段着色器对象int fragmentShader = loadShader(GL_FRAGMENT_SHADER, loadShaderSource(context, fragShaderFN));if (0 == fragmentShader) {Log.e(TAG, "Failed to load fragmentShader");return 0;}//绑定顶点着色器到着色器程序glAttachShader(shaderProgram, vertexShader);//绑定片段着色器到着色器程序glAttachShader(shaderProgram, fragmentShader);//链接着色器程序glLinkProgram(shaderProgram);//检查着色器链接状态int[] linked = new int[1];glGetProgramiv(shaderProgram, GL_LINK_STATUS, linked, 0);if (linked[0] == 0) {glDeleteProgram(shaderProgram);Log.e(TAG, "Failed to link shaderProgram");return 0;}return shaderProgram;}

3.2 getFloatBuffer()

    public static FloatBuffer getFloatBuffer(float[] array) {//将顶点数据拷贝映射到 native 内存中,以便opengl能够访问FloatBuffer buffer = ByteBuffer.allocateDirect(array.length * BYTES_PER_FLOAT)//直接分配 native 内存,不会被gc.order(ByteOrder.nativeOrder())//和本地平台保持一致的字节序(大/小头).asFloatBuffer();//将底层字节映射到FloatBuffer实例,方便使用buffer.put(array)//将顶点拷贝到 native 内存中.position(0);//每次 put position 都会 + 1,需要在绘制前重置为0return buffer;}

四.TransformUtils相关函数

与以往不同的是,这次绘制需要求得mvp矩阵

也就是model、viewproject三个矩阵,最终再求得一个总的mvpMatrix矩阵

同时还需要设置投影方式,是透视投影还是正交投影

相关理论知识可以参看官网的这一章:《坐标系统 - LearnOpenGL CN》

本篇博文不再复述

代码:

    public static float[] getCircleMVPMatrix(float ratio) {float[] modelMatrix = getIdentityMatrix(16, 0); //模型变换矩阵float[] viewMatrix = getIdentityMatrix(16, 0); //观测变换矩阵/相机矩阵float[] projectionMatrix = getIdentityMatrix(16, 0); //投影变换矩阵//设置透视投影Matrix.frustumM(projectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);//设置相机位置Matrix.setLookAtM(viewMatrix, 0, 0, 0, 7.0f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);//计算变换矩阵float[] mvpMatrix = new float[16];Matrix.multiplyMM(mvpMatrix, 0, projectionMatrix, 0, viewMatrix, 0);return mvpMatrix;}

五.着色器代码

5.1 circle_vertex_shader.glsl

#version 300 eslayout (location = 0) in vec4 vPosition;
layout (location = 1) in vec4 aColor;uniform mat4 u_Matrix;out vec4 vColor;void main() {gl_Position  = u_Matrix * vPosition;vColor = aColor;
}

5.2 circle_fragtment_shader.glsl

#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
precision mediump float;in vec4 vColor;out vec4 outColor;void main(){outColor = vColor;
}

六.UI实现

Render、GLSurfaceView与Activity、Fragment等之间的实现逻辑请根据自己项目的实际情况去实现

这里只贴出Render在GLSurfaceView中设置的代码:

    mGLSurfaceView = rootView.findViewById(R.id.Circle_GLSurfaceView);//设置GLES版本mGLSurfaceView.setEGLContextClientVersion(3);//创建Render对象,并将其设置到GLSurfaceViewmCircleRender = new CircleRender(getActivity());mGLSurfaceView.setRenderer(mCircleRender);mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

七.最终效果

最终效果如下:

http://www.dinnco.com/news/6975.html

相关文章:

  • 如何创建自己的公司昆山优化外包
  • 郓城建设局网站seo推广的特点
  • java可以做网站前台吗互联网关键词优化
  • 帝国cms 网站地图标签seo优化推广工程师
  • jsp企业网站开发毕业论文网络最有效的推广方法
  • 做进化树的在线网站网络推广公司深圳
  • 新闻列表做的最好的网站上海网络seo
  • 2021年网站有人分享吗平台如何做推广
  • 《高性能网站建设指南seo分析seo诊断
  • 郑州制作企业网站admin5站长网
  • 怎样给公司做推广 网站手机网站模板下载
  • 什么是b2b销售模式百度seo是啥意思
  • 唐山自助网站建设系统推广普通话的意义
  • 免费域名怎么做网站青岛网页搜索排名提升
  • wordpress插件不生效上海网络公司seo
  • 一般做推广网站的客户需求仕什么什么是seo文章
  • 关于花卉的网站怎么做百度sem运营
  • 政府门户网站建设工作总结seo好学吗入门怎么学
  • wordpress主题制作视频广州网页seo排名
  • 班级动态网站怎么做平面设计主要做什么
  • 专门给别人做网站手机如何制作一个网页链接
  • 酒店网站建设研究网站推广如何收费
  • 有哪些站内推广的方式外贸怎么找客户资源
  • 网站建设方案 市场分析镇江关键字优化品牌
  • 如何用api做网站购买链接平台
  • 群晖搭建企业网站seo外包公司怎么样
  • 网站维护费一年多少钱企业网站建设方案论文
  • 网站被攻击怎么让百度重新蜘蛛自动抓百度关键词在线优化
  • 石家庄建网站长沙网站策划
  • 建网站网站建设微指数官网