opengles绘制圆锥体(光照+纹理)
来源:互联网 发布:威海淘宝代运营 编辑:程序博客网 时间:2024/04/29 02:44
转自:http://blog.csdn.net/hb707934728/article/details/52470649
效果图
圆面的绘制
[java] view plain copy
- package test.com.opengles8_2;
- /**
- * Created by hbin on 2016/9/7.
- */
- import java.nio.ByteBuffer;
- import java.nio.ByteOrder;
- import java.nio.FloatBuffer;
- import android.opengl.GLES20;
- public class Circle {
- int mProgram;//自定义渲染管线着色器程序id
- int muMVPMatrixHandle;//总变换矩阵引用
- int maPositionHandle; //顶点位置属性引用
- int maTexCoorHandle; //顶点纹理坐标属性引用
- int muMMatrixHandle;
- int maCameraHandle; //摄像机位置属性引用
- int maNormalHandle; //顶点法向量属性引用
- int maLightLocationHandle;//光源位置属性引用
- String mVertexShader;//顶点着色器代码脚本
- String mFragmentShader;//片元着色器代码脚本
- FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
- FloatBuffer mTexCoorBuffer;//顶点纹理坐标数据缓冲
- FloatBuffer mNormalBuffer;//顶点法向量数据缓冲
- int vCount=0;
- float xAngle=0;//绕x轴旋转的角度
- float yAngle=0;//绕y轴旋转的角度
- float zAngle=0;//绕z轴旋转的角度
- public Circle(MySurfaceView mv,float scale,float r,int n)
- {
- //调用初始化顶点数据的initVertexData方法
- initVertexData(scale,r,n);
- //调用初始化着色器的intShader方法
- initShader(mv);
- }
- //自定义的初始化顶点数据的方法
- public void initVertexData(
- float scale, //大小
- float r, //半径
- int n) //切分的份数
- {
- r=r*scale;
- float angdegSpan=360.0f/n; //顶角的度数
- vCount=3*n;//顶点个数,共有n个三角形,每个三角形都有三个顶点
- float[] vertices=new float[vCount*3];//坐标数据
- float[] textures=new float[vCount*2];//顶点纹理S、T坐标值数组
- //坐标数据初始化
- int count=0;
- int stCount=0;
- for(float angdeg=0;Math.ceil(angdeg)<360;angdeg+=angdegSpan)
- {
- double angrad=Math.toRadians(angdeg);//当前弧度
- double angradNext=Math.toRadians(angdeg+angdegSpan);//下一弧度
- //中心点
- vertices[count++]=0;//顶点坐标
- vertices[count++]=0;
- vertices[count++]=0;
- textures[stCount++]=0.5f;//st坐标
- textures[stCount++]=0.5f;
- //当前点
- vertices[count++]=(float) (-r*Math.sin(angrad));//顶点坐标
- vertices[count++]=(float) (r*Math.cos(angrad));
- vertices[count++]=0;
- textures[stCount++]=(float) (0.5f-0.5f*Math.sin(angrad));//st坐标
- textures[stCount++]=(float) (0.5f-0.5f*Math.cos(angrad));
- //下一点
- vertices[count++]=(float) (-r*Math.sin(angradNext));//顶点坐标
- vertices[count++]=(float) (r*Math.cos(angradNext));
- vertices[count++]=0;
- textures[stCount++]=(float) (0.5f-0.5f*Math.sin(angradNext));//st坐标
- textures[stCount++]=(float) (0.5f-0.5f*Math.cos(angradNext));
- }
- ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);//创建顶点坐标数据缓冲
- vbb.order(ByteOrder.nativeOrder());//设置字节顺序为本地操作系统顺序
- mVertexBuffer = vbb.asFloatBuffer();//转换为float型缓冲
- mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
- mVertexBuffer.position(0);//设置缓冲区起始位置
- //法向量数据初始化
- float[] normals=new float[vertices.length];
- for(int i=0;i<normals.length;i+=3){
- normals[i]=0;
- normals[i+1]=0;
- normals[i+2]=1;
- }
- ByteBuffer nbb = ByteBuffer.allocateDirect(normals.length*4);//创建顶点法向量数据缓冲
- nbb.order(ByteOrder.nativeOrder());//设置字节顺序为本地操作系统顺序
- mNormalBuffer = nbb.asFloatBuffer();//转换为float型缓冲
- mNormalBuffer.put(normals);//向缓冲区中放入顶点法向量数据
- mNormalBuffer.position(0);//设置缓冲区起始位置
- //纹理坐标数据初始化
- ByteBuffer cbb = ByteBuffer.allocateDirect(textures.length*4);//创建顶点纹理数据缓冲
- cbb.order(ByteOrder.nativeOrder());//设置字节顺序为本地操作系统顺序
- mTexCoorBuffer = cbb.asFloatBuffer();//转换为float型缓冲
- mTexCoorBuffer.put(textures);//向缓冲区中放入顶点纹理数据
- mTexCoorBuffer.position(0);//设置缓冲区起始位置
- }
- //自定义初始化着色器initShader方法
- public void initShader(MySurfaceView mv){
- //加载顶点着色器的脚本内容
- mVertexShader=ShaderUtil.loadFromAssetsFile("vertex_tex_light.sh", mv.getResources());
- //加载片元着色器的脚本内容
- mFragmentShader=ShaderUtil.loadFromAssetsFile("frag_tex_light.sh", mv.getResources());
- //基于顶点着色器与片元着色器创建程序
- mProgram = ShaderUtil.createProgram(mVertexShader, mFragmentShader);
- //获取程序中顶点位置属性引用id
- maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
- //获取程序中顶点纹理坐标属性引用id
- maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
- //获取程序中总变换矩阵引用id
- muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
- //获取程序中顶点法向量属性引用id
- maNormalHandle= GLES20.glGetAttribLocation(mProgram, "aNormal");
- //获取程序中摄像机位置引用id
- maCameraHandle=GLES20.glGetUniformLocation(mProgram, "uCamera");
- //获取程序中光源位置引用id
- maLightLocationHandle=GLES20.glGetUniformLocation(mProgram, "uLightLocation");
- //获取位置、旋转变换矩阵引用id
- muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
- }
- public void drawSelf(int texId)
- {
- //制定使用某套shader程序
- GLES20.glUseProgram(mProgram);
- //将最终变换矩阵传入shader程序
- GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
- //将位置、旋转变换矩阵传入shader程序
- GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
- //将摄像机位置传入shader程序
- GLES20.glUniform3fv(maCameraHandle, 1, MatrixState.cameraFB);
- //将光源位置传入shader程序
- GLES20.glUniform3fv(maLightLocationHandle, 1, MatrixState.lightPositionFB);
- //传送顶点位置数据
- GLES20.glVertexAttribPointer
- (
- maPositionHandle,
- 3,
- GLES20.GL_FLOAT,
- false,
- 3*4,
- mVertexBuffer
- );
- //传送顶点纹理坐标数据
- GLES20.glVertexAttribPointer
- (
- maTexCoorHandle,
- 2,
- GLES20.GL_FLOAT,
- false,
- 2*4,
- mTexCoorBuffer
- );
- //传送顶点法向量数据
- GLES20.glVertexAttribPointer
- (
- maNormalHandle,
- 4,
- GLES20.GL_FLOAT,
- false,
- 3*4,
- mNormalBuffer
- );
- //启用顶点位置数据
- GLES20.glEnableVertexAttribArray(maPositionHandle);
- //启用顶点纹理数据
- GLES20.glEnableVertexAttribArray(maTexCoorHandle);
- //启用顶点法向量数据
- GLES20.glEnableVertexAttribArray(maNormalHandle);
- //绑定纹理
- GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
- //绘制纹理矩形
- GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, vCount);
- }
- }
圆锥侧面的绘制
[java] view plain copy
- package test.com.opengles8_2;
- import java.nio.ByteBuffer;
- import java.nio.ByteOrder;
- import java.nio.FloatBuffer;
- import android.opengl.GLES20;
- /**
- * Created by hbin on 2016/9/7.
- * 圆锥侧面
- */
- public class ConeSide {
- int mProgram;//自定义渲染管线着色器程序id
- int muMVPMatrixHandle;//总变换矩阵引用
- int maPositionHandle; //顶点位置属性引用
- int maTexCoorHandle; //顶点纹理坐标属性引用
- int muMMatrixHandle;//位置、旋转、缩放变换矩阵
- int maCameraHandle; //摄像机位置属性引用
- int maNormalHandle; //顶点法向量属性引用
- int maLightLocationHandle;//光源位置属性引用
- String mVertexShader;//顶点着色器代码脚本
- String mFragmentShader;//片元着色器代码脚本
- FloatBuffer mVertexBuffer;//顶点坐标数据缓冲
- FloatBuffer mTexCoorBuffer;//顶点纹理坐标数据缓冲
- FloatBuffer mNormalBuffer;//顶点法向量数据缓冲
- int vCount=0;
- float xAngle=0;//绕x轴旋转的角度
- float yAngle=0;//绕y轴旋转的角度
- float zAngle=0;//绕z轴旋转的角度
- public ConeSide(MySurfaceView mv,float scale,float r,float h,int n)
- {
- //调用初始化顶点数据的initVertexData方法
- initVertexData(scale,r,h,n);
- //调用初始化着色器的intShader方法
- initShader(mv);
- }
- //自定义初始化顶点坐标数据的方法
- public void initVertexData(
- float scale, //尺寸大小
- float r, //半径
- float h, //高度
- int n //切分的份数
- )
- {
- r=scale*r;
- h=scale*h;
- float angdegSpan=360.0f/n;
- vCount=3*n*4;//顶点个数,共有3*n*4个三角形,每个三角形都有三个顶点
- //坐标数据初始化
- float[] vertices=new float[vCount*3];
- float[] textures=new float[vCount*2];//顶点纹理S、T坐标值数组
- float[] normals=new float[vertices.length];//法向量数组
- //坐标数据初始化
- int count=0;
- int stCount=0;
- int norCount=0;
- for(float angdeg=0;Math.ceil(angdeg)<360;angdeg+=angdegSpan)//侧面
- {
- double angrad=Math.toRadians(angdeg);//当前弧度
- double angradNext=Math.toRadians(angdeg+angdegSpan);//下一弧度
- //顶点(圆锥最高的点)
- vertices[count++]=0;
- vertices[count++]=h;
- vertices[count++]=0;
- //纹理坐标
- textures[stCount++]=0.5f;//st坐标
- textures[stCount++]=0;
- //当前点
- vertices[count++]=(float) (-r*Math.sin(angrad));
- vertices[count++]=0;
- vertices[count++]=(float) (-r*Math.cos(angrad));
- //纹理坐标
- textures[stCount++]=(float) (angrad/(2*Math.PI));
- textures[stCount++]=1;
- //下一点
- vertices[count++]=(float) (-r*Math.sin(angradNext));
- vertices[count++]=0;
- vertices[count++]=(float) (-r*Math.cos(angradNext));
- //纹理坐标
- textures[stCount++]=(float) (angradNext/(2*Math.PI));
- textures[stCount++]=1;
- }
- //法向量数据的初始化
- for(int i=0;i<vertices.length;i=i+3)
- {
- //如果当前的顶点为圆锥的最高点
- if(vertices[i]==0&&vertices[i+1]==h&&vertices[i+2]==0){
- normals[norCount++]=0;
- normals[norCount++]=1;
- normals[norCount++]=0;
- }else{//当前的顶点为底面圆上的顶点
- float [] norXYZ=VectorUtil.calConeNormal(//通过三个顶点求出法向量
- 0, 0, 0, //底面圆的中心点
- vertices[i], vertices[i+1], vertices[i+2], //当前的顶点坐标
- 0, h, 0); //顶点坐标(圆锥最高点)
- normals[norCount++]=norXYZ[0];
- normals[norCount++]=norXYZ[1];
- normals[norCount++]=norXYZ[2];
- }
- }
- ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);//创建顶点坐标数据缓冲
- vbb.order(ByteOrder.nativeOrder());//设置字节顺序为本地操作系统顺序
- mVertexBuffer = vbb.asFloatBuffer();//转换为float型缓冲
- mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据
- mVertexBuffer.position(0);//设置缓冲区起始位置
- //法向量数据初始化
- ByteBuffer nbb = ByteBuffer.allocateDirect(normals.length*4);//创建顶点法向量数据缓冲
- nbb.order(ByteOrder.nativeOrder());//设置字节顺序为本地操作系统顺序
- mNormalBuffer = nbb.asFloatBuffer();//转换为float型缓冲
- mNormalBuffer.put(normals);//向缓冲区中放入顶点法向量数据
- mNormalBuffer.position(0);//设置缓冲区起始位置
- //st坐标数据初始化
- ByteBuffer cbb = ByteBuffer.allocateDirect(textures.length*4);//创建顶点纹理数据缓冲
- cbb.order(ByteOrder.nativeOrder());//设置字节顺序为本地操作系统顺序
- mTexCoorBuffer = cbb.asFloatBuffer();//转换为float型缓冲
- mTexCoorBuffer.put(textures);//向缓冲区中放入顶点纹理数据
- mTexCoorBuffer.position(0);//设置缓冲区起始位置
- }
- //自定义初始化着色器的initShader方法
- public void initShader(MySurfaceView mv)
- {
- //加载顶点着色器的脚本内容
- mVertexShader=ShaderUtil.loadFromAssetsFile("vertex_tex_light.sh", mv.getResources());
- //加载片元着色器的脚本内容
- mFragmentShader=ShaderUtil.loadFromAssetsFile("frag_tex_light.sh", mv.getResources());
- //基于顶点着色器与片元着色器创建程序
- mProgram = ShaderUtil.createProgram(mVertexShader, mFragmentShader);
- //获取程序中顶点位置属性引用id
- maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
- //获取程序中顶点纹理坐标属性引用id
- maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor");
- //获取程序中总变换矩阵引用id
- muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
- //获取程序中顶点法向量属性引用id
- maNormalHandle= GLES20.glGetAttribLocation(mProgram, "aNormal");
- //获取程序中摄像机位置引用id
- maCameraHandle=GLES20.glGetUniformLocation(mProgram, "uCamera");
- //获取程序中光源位置引用id
- maLightLocationHandle=GLES20.glGetUniformLocation(mProgram, "uLightLocation");
- //获取位置、旋转变换矩阵引用id
- muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
- }
- public void drawSelf(int texId)
- {
- //制定使用某套shader程序
- GLES20.glUseProgram(mProgram);
- //将最终变换矩阵传入shader程序
- GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
- //将位置、旋转变换矩阵传入shader程序
- GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
- //将摄像机位置传入shader程序
- GLES20.glUniform3fv(maCameraHandle, 1, MatrixState.cameraFB);
- //将光源位置传入shader程序
- GLES20.glUniform3fv(maLightLocationHandle, 1, MatrixState.lightPositionFB);
- //传送顶点位置数据
- GLES20.glVertexAttribPointer
- (
- maPositionHandle,
- 3,
- GLES20.GL_FLOAT,
- false,
- 3*4,
- mVertexBuffer
- );
- //传送顶点纹理坐标数据
- GLES20.glVertexAttribPointer
- (
- maTexCoorHandle,
- 2,
- GLES20.GL_FLOAT,
- false,
- 2*4,
- mTexCoorBuffer
- );
- //传送顶点法向量数据
- GLES20.glVertexAttribPointer
- (
- maNormalHandle,
- 4,
- GLES20.GL_FLOAT,
- false,
- 3*4,
- mNormalBuffer
- );
- //启用顶点位置数据
- GLES20.glEnableVertexAttribArray(maPositionHandle);
- //启用顶点纹理数据
- GLES20.glEnableVertexAttribArray(maTexCoorHandle);
- //启用顶点法向量数据
- GLES20.glEnableVertexAttribArray(maNormalHandle);
- //绑定纹理
- GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
- //绘制纹理矩形
- GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);
- }
- }
0 0
- opengles绘制圆锥体(光照+纹理)
- opengles绘制圆锥体(光照+纹理)
- opengles绘制圆柱体(光照+纹理)
- opengles绘制圆柱体(光照+纹理)
- opengles绘制纹理(一)
- opengles 2.0如何绘制纹理
- Android OpenglES 绘制多个纹理
- OpenGlES--光照
- 从头开始绘制一个圆锥体
- opengles加载obj格式3D模型含光照和纹理
- openGL绘制正方体分别实现简单颜色绘制、纹理绘制、光照绘制
- opengles 纹理对象&纹理单元
- opengles绘制球体之三种光照通道的合成(环境光,散射光,镜面光)
- 圆锥体
- 圆锥体
- OpenGLES---加载纹理
- OpenGLES---纹理的API
- android opengles 纹理
- 相机标定工具GML Camera Calibration的使用教程
- node连接redis
- 判断http 请求来自于手机还是PC
- 字符串相关问题
- centOS下搭建nodeJS环境(就是装几个东西啦~)
- opengles绘制圆锥体(光照+纹理)
- 类和接口
- hiho1037 数字三角形 (数塔 dp)
- Android运行时候报错:android.view.InflateException: Binary XML file line #19: Binary XML file lin
- Python高级特性
- 更换pip源到国内镜像
- GPUImage、openGL学习资料汇总
- Java获得本地IP地址
- 泛型类型