opengles绘制天空盒
来源:互联网 发布:淘宝助理批量修改 编辑:程序博客网 时间:2024/05/17 18:01
效果图
核心代码
//纹理矩形public class TextureRect {int mProgram;//自定义渲染管线程序id int muMVPMatrixHandle;//总变换矩阵引用id int maPositionHandle; //顶点位置属性引用id int maTexCoorHandle; //顶点纹理坐标属性引用id String mVertexShader;//顶点着色器 String mFragmentShader;//片元着色器FloatBuffer mVertexBuffer;//顶点坐标数据缓冲FloatBuffer mTexCoorBuffer;//顶点纹理坐标数据缓冲 int vCount=0; public TextureRect(MySurfaceView mv) { //初始化顶点坐标与着色数据 initVertexData(); //初始化shader initShader(mv); } //初始化顶点坐标与着色数据的方法 public void initVertexData() { //顶点坐标数据的初始化 vCount=6; float vertices[]=new float[] { -UNIT_SIZE,UNIT_SIZE,0, -UNIT_SIZE,-UNIT_SIZE,0, UNIT_SIZE,-UNIT_SIZE,0, UNIT_SIZE,-UNIT_SIZE,0, UNIT_SIZE,UNIT_SIZE,0, -UNIT_SIZE,UNIT_SIZE,0 }; //创建顶点坐标数据缓冲 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); vbb.order(ByteOrder.nativeOrder());//设置字节顺序 mVertexBuffer = vbb.asFloatBuffer();//转换为Float型缓冲 mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据 mVertexBuffer.position(0);//设置缓冲区起始位置 //顶点纹理坐标数据的初始化 float texCoor[]=new float[]//顶点颜色值数组,每个顶点4个色彩值RGBA { 1,0, 1,1, 0,1, 0,1, 0,0, 1,0 }; //创建顶点纹理坐标数据缓冲 ByteBuffer cbb = ByteBuffer.allocateDirect(texCoor.length*4); cbb.order(ByteOrder.nativeOrder());//设置字节顺序 mTexCoorBuffer = cbb.asFloatBuffer();//转换为Float型缓冲 mTexCoorBuffer.put(texCoor);//向缓冲区中放入顶点着色数据 mTexCoorBuffer.position(0);//设置缓冲区起始位置 } //初始化shader public void initShader(MySurfaceView mv) { //加载顶点着色器的脚本内容 mVertexShader=ShaderUtil.loadFromAssetsFile("vertex_tex.sh", mv.getResources()); //加载片元着色器的脚本内容 mFragmentShader=ShaderUtil.loadFromAssetsFile("frag_tex.sh", mv.getResources()); //基于顶点着色器与片元着色器创建程序 mProgram = createProgram(mVertexShader, mFragmentShader); //获取程序中顶点位置属性引用id maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition"); //获取程序中顶点纹理坐标属性引用id maTexCoorHandle= GLES20.glGetAttribLocation(mProgram, "aTexCoor"); //获取程序中总变换矩阵引用id muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); } public void drawSelf(int texId) { //指定使用某套shader程序 GLES20.glUseProgram(mProgram); //将最终变换矩阵传入shader程序 GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0); //传送顶点位置数据 GLES20.glVertexAttribPointer ( maPositionHandle, 3, GLES20.GL_FLOAT, false, 3*4, mVertexBuffer ); //传送顶点纹理坐标数据 GLES20.glVertexAttribPointer ( maTexCoorHandle, 2, GLES20.GL_FLOAT, false, 2*4, mTexCoorBuffer ); //允许顶点位置、纹理坐标数据数组 GLES20.glEnableVertexAttribArray(maPositionHandle); GLES20.glEnableVertexAttribArray(maTexCoorHandle); //绑定纹理 GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId); //绘制纹理矩形 GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount); }}
surfaceview类
class MySurfaceView extends GLSurfaceView {private final float TOUCH_SCALE_FACTOR = 180.0f/320;//角度缩放比例 private SceneRenderer mRenderer;//场景渲染器 private float mPreviousY;//上次的触控位置Y坐标 private float mPreviousX;//上次的触控位置X坐标 //摄像机的位置角度 float cx=0; float cy=2; float cz=24; float cr=24;//摄像机半径 float cAngle=0; int[] textureIdA=new int[6];//天空盒六面的纹理public MySurfaceView(Context context) { super(context); this.setEGLContextClientVersion(2); //设置使用OPENGL ES2.0 mRenderer = new SceneRenderer();//创建场景渲染器 setRenderer(mRenderer);//设置渲染器 setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//设置渲染模式为主动渲染 }//触摸事件回调方法 @Override public boolean onTouchEvent(MotionEvent e) { float y = e.getY(); float x = e.getX(); switch (e.getAction()) { case MotionEvent.ACTION_MOVE: float dy = y - mPreviousY;//计算触控笔Y位移 float dx = x - mPreviousX;//计算触控笔X位移 cAngle+=dx * TOUCH_SCALE_FACTOR; cx=(float) (Math.sin(Math.toRadians(cAngle))*cr); cz=(float) (Math.cos(Math.toRadians(cAngle))*cr); cy+=dy/10.0f; } mPreviousY = y;//记录触控笔位置 mPreviousX = x;//记录触控笔位置 return true; }private class SceneRenderer implements GLSurfaceView.Renderer { TextureRect texRect;//纹理矩形 public void onDrawFrame(GL10 gl) { //清除深度缓冲与颜色缓冲 GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); //调用此方法产生摄像机9参数位置矩阵 MatrixState.setCamera(cx,cy,cz,0f,0f,0f,0f,1.0f,0.0f); //天空盒六面调整值 final float tzz=0.4f; //绘制天空盒后面 MatrixState.pushMatrix(); MatrixState.translate(0, 0, -UNIT_SIZE+tzz); texRect.drawSelf(textureIdA[0]); MatrixState.popMatrix(); //绘制天空盒前面 MatrixState.pushMatrix(); MatrixState.translate(0, 0, UNIT_SIZE-tzz); MatrixState.rotate(180, 0, 1, 0); texRect.drawSelf(textureIdA[5]); MatrixState.popMatrix(); //绘制天空盒左面 MatrixState.pushMatrix(); MatrixState.translate(-UNIT_SIZE+tzz, 0, 0); MatrixState.rotate(90, 0, 1, 0); texRect.drawSelf(textureIdA[1]); MatrixState.popMatrix(); //绘制天空盒右面 MatrixState.pushMatrix(); MatrixState.translate(UNIT_SIZE-tzz, 0, 0); MatrixState.rotate(-90, 0, 1, 0); texRect.drawSelf(textureIdA[2]); MatrixState.popMatrix(); //绘制天空盒下面 MatrixState.pushMatrix(); MatrixState.translate(0, -UNIT_SIZE+tzz, 0); MatrixState.rotate(-90, 1, 0, 0); texRect.drawSelf(textureIdA[3]); MatrixState.popMatrix(); //绘制天空盒上面 MatrixState.pushMatrix(); MatrixState.translate(0, UNIT_SIZE-tzz, 0); MatrixState.rotate(90, 1, 0, 0); texRect.drawSelf(textureIdA[4]); MatrixState.popMatrix(); } public void onSurfaceChanged(GL10 gl, int width, int height) { //设置视窗大小及位置 GLES20.glViewport(0, 0, width, height); //计算GLSurfaceView的宽高比 float ratio = (float) width / height; //调用此方法计算产生透视投影矩阵 MatrixState.setProjectFrustum(-ratio, ratio, -1, 1, 2, 1000); } public void onSurfaceCreated(GL10 gl, EGLConfig config) { //设置屏幕背景色RGBA GLES20.glClearColor(0.0f,0.0f,0.0f,1.0f); //打开深度检测 GLES20.glEnable(GLES20.GL_DEPTH_TEST); //打开背面剪裁 GLES20.glEnable(GLES20.GL_CULL_FACE); //初始化变换矩阵 MatrixState.setInitStack(); //创建纹理矩形对对象 texRect=new TextureRect(MySurfaceView.this); //加载纹理 textureIdA[0]=initTexture(R.raw.skycubemap_back); textureIdA[1]=initTexture(R.raw.skycubemap_left); textureIdA[2]=initTexture(R.raw.skycubemap_right); textureIdA[3]=initTexture(R.raw.skycubemap_down); textureIdA[4]=initTexture(R.raw.skycubemap_up); textureIdA[5]=initTexture(R.raw.skycubemap_front); } } public int initTexture(int drawableId)//textureId{//生成纹理IDint[] textures = new int[1];GLES20.glGenTextures(1, //产生的纹理id的数量textures, //纹理id的数组0 //偏移量); int textureId=textures[0]; GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST);GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_REPEAT);GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_REPEAT); //通过输入流加载图片 InputStream is = this.getResources().openRawResource(drawableId); Bitmap bitmapTmp; try { bitmapTmp = BitmapFactory.decodeStream(is); } finally { try { is.close(); } catch(IOException e) { e.printStackTrace(); } } //实际加载纹理 GLUtils.texImage2D ( GLES20.GL_TEXTURE_2D, //纹理类型,在OpenGL ES中必须为GL10.GL_TEXTURE_2D 0, //纹理的层次,0表示基本图像层,可以理解为直接贴图 bitmapTmp, //纹理图像 0 //纹理边框尺寸 ); bitmapTmp.recycle(); //纹理加载成功后释放图片 return textureId;}}
代码下载地址:
http://download.csdn.net/detail/hb707934728/9651729
0 0
- opengles绘制天空盒
- opengles绘制天空穹
- 绘制天空盒
- ios-OPENGL之绘制天空盒
- OpenGL Shader 绘制天空盒_基础
- opengles-绘制旋转三角形
- opengles绘制立方体
- opengles 绘制球
- opengles绘制点精灵
- 天空盒子的绘制
- OpenGL Shader 绘制天空盒_基础 2
- opengles绘制纹理(一)
- opengles绘制圆柱体(光照+纹理)
- opengles绘制圆锥体(光照+纹理)
- 使用opengles绘制灰度地形图
- opengles 2.0如何绘制纹理
- opengles绘制圆锥体(光照+纹理)
- opengles绘制圆柱体(光照+纹理)
- 算法习题
- HTML压缩
- 欢迎使用CSDN-markdown编辑器
- PAT 1033. To Fill or Not to Fill
- JavaWEB前端JS向服务器端发送对象
- opengles绘制天空盒
- CNN人脸关键点检测
- android 6.0
- burpsuite1.6安装使用方法详解
- Spark调优之旅<一>
- 查询数据库中重复记录的方法
- 【项目3 - 括号的匹配】
- php 如何防止不同项目的 session key冲突
- AndroidStudio导入新项目一直卡在Building gradle project info的解决解决方案