外贸网站做流量,如何加强省市级门户网站的建设,网站设置默认首页,网店美工需要做什么一.概述
上一篇博文讲解了怎么绘制一个彩色旋转的立方体
这一篇讲解怎么绘制一个彩色旋转的圆柱
圆柱的顶点创建主要基于2D圆进行扩展#xff0c;与立方体没有相似之处
圆柱绘制的关键点就是将圆柱拆解成#xff1a;两个Z坐标不为0的圆 一个长方形的圆柱面
绘制2D圆的…一.概述
上一篇博文讲解了怎么绘制一个彩色旋转的立方体
这一篇讲解怎么绘制一个彩色旋转的圆柱
圆柱的顶点创建主要基于2D圆进行扩展与立方体没有相似之处
圆柱绘制的关键点就是将圆柱拆解成两个Z坐标不为0的圆 一个长方形的圆柱面
绘制2D圆的过程这里不再复述不理解的可以参看前面这篇博文《OpenGLES绘制一个颜色渐变的圆》
废话不多说正文开始了。
二.Render变量定义
2.1 常规变量定义
//着色器程序/渲染器
private int shaderProgram;//着色器mvp矩阵属性
private int mvpMatrix;
//位置属性
private int aPositionLocation;//surface宽高比率
private float ratio;
2.2 定义顶点坐标数组和缓冲
概述中提到过绘制圆柱的关键思路是将圆柱拆解成两个Z坐标不为0的圆 一个长方形的圆柱面
所以定义三个顶点坐标数组和对应缓冲
//圆柱柱面顶点数组
private float[] vertexData;
//圆柱顶部圆的顶点数组
private float[] vertexData1;
//圆柱底部圆的顶点数组
private float[] vertexData2;//圆柱柱面顶点缓冲
private FloatBuffer vertexBuffer;
//圆柱顶部圆的顶点缓冲
private FloatBuffer vertexBuffer1;
//圆柱顶部圆的顶点缓冲
private FloatBuffer vertexBuffer2;
需要注意的是这次我并没有把顶点颜色单独定义成一个数组而且在Render类中也不会像上一篇绘制立方体时动态加载和填充顶点颜色值
这次我会换一种方式直接把颜色填充和变换在着色器代码中实现
最终的色彩渐变效果是一样的殊途同归丰富对OpenGLES不同实现方式的学习。
2.3 定义MVP矩阵
//MVP矩阵
private float[] mMVPMatrix new float[16];
三.Render着色器、内存分配等
3.1 着色器创建、链接、使用
3.2 着色器属性获取、赋值
3.3 缓冲内存分配
这几个部分的代码实现2D图形绘制基本一致
可参考以前2D绘制的相关博文里面都有详细的代码实现
不再重复展示代码
四.Render动态创建顶点
float radio 0.6f;
int spanIdx 60;vertexData createSidePos(radio, spanIdx);
vertexData1 createBottomCirclePos(radio, spanIdx, 0.7f);
vertexData2 createBottomCirclePos(radio, spanIdx, -0.7f);
重点就在于创建圆柱顶点的两个函数
createSidePos()createBottomCirclePos()
4.1 createSidePos()
private float[] createSidePos(float radius, int n) {ArrayListFloat data new ArrayList();//设置顶部/底部圆的顶点坐标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)));//顶部/底部圆的顶点Z坐标设置为-0.7fdata.add(-0.7f);data.add((float) (radius * Math.sin(i * Math.PI / 180f)));data.add((float) (radius * Math.cos(i * Math.PI / 180f)));//顶部/底部圆的顶点Z坐标设置为-0.7fdata.add(0.7f);}//所有顶点坐标float[] f new float[data.size()];for (int i 0; i data.size(); i) {f[i] data.get(i);}return f;
}4.2 createBottomCirclePos()
private float[] createBottomCirclePos(float radius, int n, float circleCenterZ) {ArrayListFloat data new ArrayList();//顶部/底部圆心坐标data.add(0.0f);data.add(0.0f);data.add(circleCenterZ);//设置顶部/底部圆的顶点坐标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)));//顶部/底部圆的顶点Z坐标设置为-0.7fdata.add(circleCenterZ);}//所有顶点坐标float[] f new float[data.size()];for (int i 0; i data.size(); i) {f[i] data.get(i);}return f;
}五.Render绘制
5.1 MVP矩阵
//填充MVP矩阵
mMVPMatrix TransformUtils.getCylinderMVPMatrix(ratio);
//将变换矩阵传入顶点渲染器
glUniformMatrix4fv(mvpMatrix, 1, false, mMVPMatrix, 0);5.2 绘制圆柱柱面、顶部圆、底部圆
(1).drawSide()
//准备顶点坐标和颜色数据
glVertexAttribPointer(aPositionLocation, 3, GL_FLOAT, false, 0, vertexBuffer);
//绘制
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexData.length / 3);
(2).drawBottomCircle1()
//准备顶点坐标和颜色数据
glVertexAttribPointer(aPositionLocation, 3, GL_FLOAT, false, 0, vertexBuffer1);
//绘制
glDrawArrays(GL_TRIANGLE_FAN, 0, vertexData1.length / 3);
(3).drawBottomCircle2()
//准备顶点坐标和颜色数据
glVertexAttribPointer(aPositionLocation, 3, GL_FLOAT, false, 0, vertexBuffer2);
//绘制
glDrawArrays(GL_TRIANGLE_FAN, 0, vertexData2.length / 3);
六.着色器代码
6.1 cylinder_vertex_shader.glsl
先实现一个顶部绿色底部红色柱面绿红渐变的旋转圆柱
#version 300 eslayout (location 0) in vec4 vPosition;
layout (location 1) in vec4 aColor;uniform mat4 mvpMatrix;out vec4 vColor;void main() {gl_Position mvpMatrix * vPosition;if (vPosition.z 0.7) {vColor vec4(0.0, 1.0, 0.0, 0.0); //绿} else if (vPosition.z -0.7) {vColor vec4(1.0, 0.0, 0.0, 0.0); //红}
}
6.2 cylinder_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;
}七.最终效果
上一节中讲了先来一个顶部绿底部红柱面绿红渐变的旋转3D圆柱
效果如下 如何实现混色渐变的旋转圆柱呢
很简单只要修改顶点着色器代码
void main() {gl_Position mvpMatrix * vPosition;//颜色混合渐变vColor vec4(vPosition.x,vPosition.y, vPosition.z,0.0);
}
效果如下 八.结束
彩色旋转的3D圆柱绘制到此结束
下一篇讲解彩色旋转的圆锥