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