效果图

核心代码

//纹理矩形
public class TextureRect
{   int mProgram;//自定义渲染管线程序idint muMVPMatrixHandle;//总变换矩阵引用idint 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);//设置缓冲区起始位置}//初始化shaderpublic 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");//获取程序中总变换矩阵引用idmuMVPMatrixHandle = 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.0mRenderer = new SceneRenderer();  //创建场景渲染器setRenderer(mRenderer);                //设置渲染器setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//设置渲染模式为主动渲染}//触摸事件回调方法@Overridepublic 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) {//设置屏幕背景色RGBAGLES20.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_2D0,                    //纹理的层次,0表示基本图像层,可以理解为直接贴图bitmapTmp,              //纹理图像0                     //纹理边框尺寸);bitmapTmp.recycle();          //纹理加载成功后释放图片return textureId;}
}

代码下载地址:

http://download.csdn.net/detail/hb707934728/9651729

opengles绘制天空盒相关推荐

  1. android命令行 gles,Android利用OpenGLES绘制天空盒实例教程

    前言 天空盒这个效果最早是在腾讯的实景地图里看到的,当时觉得很牛逼,但是没有想过自己去实现以下.最近这段时间对opengl很有兴趣,顺便就搞了这个天空盒,话不多说,先上效果. 天空盒的原理就是在三维空 ...

  2. Android OpenGLES绘制天空盒

    0. 天空盒这个效果最早是在腾讯的实景地图里看到的,当时觉得很牛逼,但是没有想过自己去实现以下.最近这段时间对opengl很有兴趣,顺便就搞了这个天空盒,话不多说,先上效果. 天空盒的原理就是在三维空 ...

  3. opengles绘制可旋转的六角星

    package com.bn.Sample5_1;import android.opengl.Matrix;//存储系统矩阵状态的类 public class MatrixState {private ...

  4. 使用opengles绘制灰度地形图

    效果图: 基本原理: 灰度地形图生成技术的基本原理是利用MxN的网格表示地形,同时提供一副对应尺寸的灰度图,根据灰度图中每个像素的灰度来确定网格中顶点的海拔,黑色像素(RGB各个色彩通道的值为0)代表 ...

  5. OPENGLES 绘制纹理带黑圈pre-multiplying

    1. 问题 在进行 OpenGL 纹理混合的过程中,遇到一个诡异的现象,两个纹理混合的效果出人所料: 将一个ALPHA渐变的[胡须]加在另一张图片上,这个 [胡须]是由外向里逐渐增加透明度的,也就是最 ...

  6. opengles绘制天空穹

    天空穹技术中不再使用立方体模拟天空,而是用一个半球面模拟天空,此半球面上贴上对应的天空纹理,摄像机位于天空穹内部. 效果图 核心代码 半球的绘制 package test.com.opengles11 ...

  7. opengles绘制点精灵

    什么是点精灵 opengl图形由顶点构成,所谓点精灵就是对点进行纹理映射,简单说就是把一副纹理贴在一个点上 原来4个顶点构成一个矩形,现在一个顶点就完成了,典型的如粒子效果,云雾,水流火花都可以用点精 ...

  8. Android OpenGLES2.0(十七)——球形天空盒VR效果实现

    在3D游戏中通常都会用到天空盒,在3D引擎中也一般会存在天空盒组件,让开发者可以直接使用.那么天空盒是什么?天空盒又是如何实现的呢?本篇博客主要介绍如何在Android中利用OpenGLES绘制一个天 ...

  9. DirectX11 With Windows SDK--22 立方体映射:静态天空盒的读取与实现

    前言 这一章我们主要学习由6个纹理所构成的立方体映射,以及用它来实现一个静态天空盒. 但是在此之前先要消除两个误区: 认为这一章的天空盒就是简单的在一个超大立方体的六个面内部贴上天空盒纹理: 认为天空 ...

最新文章

  1. [WCF编程]1.WCF入门示例
  2. idea新建项目写html5,Intellij IDEA搭建vue-cli项目
  3. 惨烈!程序员放弃了 Python!?发生了啥?
  4. 360极速浏览器进行打印时会带出网页地址问题
  5. boost::type_erasure模块实现类型安全的 printf的测试程序
  6. php视频上传教程,php上传视频的代码_PHP教程
  7. jquery ajax 上传文件 demo,Jquery+AJAX上传文件,无刷新上传并重命名文件
  8. 计算机会考咋查成绩,2019会考成绩查询网址入口 高中会考怎么查成绩
  9. 创业奇才:才3年5000元变600万
  10. ubuntu安装经常使用记录
  11. 再谈Bellman-Ford
  12. Microsoft office 各个版本镜像下载
  13. 自然语言处理技术有哪些?NLP简介
  14. Proteus常用元件对照表(最全)
  15. 2.Apache服务器配置(Ubuntu)
  16. 海康SDK的NET_DVR_GET_FTPCFG_V40
  17. 山东菏泽家乡网页代码 html静态网页设计制作 dw静态网页成品模板素材网页 web前端网页设计与制作 div静态网页设计
  18. 安卓手机怎么设置蓝牙耳机弹窗动画_链接重推其他团无线蓝牙耳机
  19. 恋恋不忘Day 1-1
  20. jquery:选择器【基础选择器、层级选择器、属性选择器和方法操作、过滤选择器、筛选选择器和方法,可见性过滤选择器】

热门文章

  1. flask项目之5:短信验证码发送
  2. dw01均衡电路_一种基于dw01的电池保护电路调试测试方法
  3. 20180210-第三方应用App2SD使用教程【需ROOT】
  4. quartus错误集锦(未完待续)
  5. 楼宇自控BACnet/IP协议网关功能特点
  6. 软件开发V模型--解读
  7. [转载] 中华典故故事(孙刚)——30 千里马常有_而伯乐不常有
  8. 基于python的气象数据分析统计服_基于Python的风向风速数据分析的设计与实现
  9. html5绘制圣诞树,【Html5】JavaScript和html5实现3D圣诞树的代码
  10. 《CrowdDetection:Detection in Crowded Scenes: One Proposal, Multiple Predictions》论文笔记