zoukankan      html  css  js  c++  java
  • 雾的实现以及Opengl的数组存储与java不同的工具包BufferUtil的实现

    一、雾和流动红旗的形成,Render类如下:

    package com.example.user.flagdemo;
     
    import android.graphics.Bitmap;
    import android.opengl.GLSurfaceView;
    import android.opengl.GLUtils;
     
    import java.nio.FloatBuffer;
    import java.nio.IntBuffer;
     
    import javax.microedition.khronos.egl.EGLConfig;
    import javax.microedition.khronos.opengles.GL10;
     
    /**
    * Created by user on 2016/9/14.
    */
    public class GLRendererfog implements GLSurfaceView.Renderer {
     
    int textureSize = 2;
    int texture[] = new int [textureSize];
    private Bitmap mBitmap[];
    Point [][] points = new Point[45][45];
    private int wiggle_count=0;
     
    //设置雾的属性参数
    int fogMode[]= { GL10.GL_EXP, GL10.GL_EXP2, GL10.GL_LINEAR }; // 雾气的模式
    int fogfilter= 1; // 使用哪一种雾气
    float fogColor[]= {0.5f, 0.5f, 0.0f, 1.0f}; // 雾的颜色设为白色
     
    public GLRendererfog(Bitmap mBitmap[])
    {
    this.mBitmap = mBitmap;
    }
     
     
     
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    // 黑色背景
    gl.glClearColor(0, 0, 0, 0);
    // 启用阴影平滑
    gl.glShadeModel(GL10.GL_SMOOTH);
    // 启用深度测试
    gl.glEnable(GL10.GL_DEPTH_TEST);
     
     
    gl.glFogx(GL10.GL_FOG_MODE, fogMode[fogfilter]); // 设置雾气的模式
    gl.glFogfv(GL10.GL_FOG_COLOR, fogColor,0); // 设置雾的颜色
    gl.glFogf(GL10.GL_FOG_DENSITY, 0.1f); // 设置雾的密度
    gl.glHint(GL10.GL_FOG_HINT, GL10.GL_DONT_CARE); // 设置系统如何计算雾气
    gl.glFogf(GL10.GL_FOG_START, 1.0f); // 雾气的开始位置
    gl.glFogf(GL10.GL_FOG_END, 5.0f); // 雾气的结束位置
    gl.glEnable(GL10.GL_FOG); // 使用雾气
     
    // 启用混合模式
    gl.glEnable(GL10.GL_BLEND);
    gl.glDisable(GL10.GL_DEPTH_TEST); // 关闭深度测试
    //设置光线,,1.0f为全光线,a=50%
    gl.glColor4f(1.0f,1.0f,1.0f,0.5f);
    // 基于源象素alpha通道值的半透明混合函数
    gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE);
     
    //启用纹理映射
    gl.glClearDepthf(1.0f);
    //深度测试的类型
    gl.glDepthFunc(GL10.GL_LEQUAL);
    //精细的透视修正
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
    //允许2D贴图,纹理
    gl.glEnable(GL10.GL_TEXTURE_2D);
    getTextures(gl);
    getPoints();
     
     
    // //设置光颜色
    // FloatBuffer lightAmbient = BufferUtil.floatToBuffer(new float[]{
    // 1f, 1f, 1f, 1f
    // } );
    // FloatBuffer lightDiffuse = BufferUtil.floatToBuffer(new float[]{
    // 1f,1f,1f,1f
    // } );
    // //定义光源位置
    // FloatBuffer lightPosition = BufferUtil.floatToBuffer(new float[]{
    // -2f,0f,-4f,1f
    // } );
    //
    //// //设置环境光
    // gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, lightAmbient);
    //
    // //设置漫射光
    // gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, lightDiffuse);
    //
    // //设置光源位置
    // gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPosition);
    //
    // //开启一号光源
    // gl.glEnable(GL10.GL_LIGHT1);
    }
     
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
    float ratio = (float) width / height;
    //设置OpenGL场景的大小
    gl.glViewport(0, 0, width, height);
    //设置投影矩阵
    gl.glMatrixMode(GL10.GL_PROJECTION);
    //重置投影矩阵
    gl.glLoadIdentity();
    // 设置视口的大小
    gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
    // 选择模型观察矩阵
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    // 重置模型观察矩阵
    gl.glLoadIdentity();
    }
     
    @Override
    public void onDrawFrame(GL10 gl) {
    // 清除屏幕和深度缓存
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    // 重置当前的模型观察矩阵
    // gl.glEnable(GL10.GL_LIGHTING);
     
    gl.glLoadIdentity();
    gl.glTranslatef(0f , 0f , -9f);
     
    FloatBuffer texCoords2 = BufferUtil.getFloatBuffer(8);
    FloatBuffer vertices2 = BufferUtil.getFloatBuffer(12);;
     
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);//启用纹理映射
    gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);
     
    for (int x = 0; x < 44; x++){
    for (int y = 0; y < 44; y++) {
     
    //文理映射,每个点在纹理中的映射位置,文理的大小为1f
    float float_x = (float) (x) / 44.0f; //生成 x 浮点值
    float float_y = (float) (y) / 44.0f; //生成 Y 浮点位
    float float_xb = (float) (x + 1) / 44.0f; // x 浮点值+0.0227f
    float float_yb = (float) (y + 1) / 44.0f; // Y 浮点值+0.0227f
    vertices2.clear();
    vertices2.put(points[x][y].x);
    vertices2.put(points[x][y].y);
    vertices2.put(points[x][y].z);
    vertices2.put(points[x][y + 1].x);
    vertices2.put( points[x][y + 1].y);
    vertices2.put( points[x][y + 1].z);
    vertices2.put( points[x + 1][y + 1].x);
    vertices2.put(points[x + 1][y + 1].y);
    vertices2.put(points[x + 1][y + 1].z);
    vertices2.put( points[x + 1][y].x);
    vertices2.put( points[x + 1][y].y);
    vertices2.put( points[x + 1][y].z);
    //position是当前访问位置,因此每次put后position都是指向存储的位置的,绘图点映射必须从头开始的
    vertices2.position(0);
     
    texCoords2.clear();
    texCoords2.put(float_x);
    texCoords2.put(1 - float_y);
    texCoords2.put(float_x);
    texCoords2.put(1 - float_yb);
    texCoords2.put( float_xb);
    texCoords2.put( 1 - float_yb);
    texCoords2.put( float_xb);
    texCoords2.put( 1 - float_y);
    texCoords2.position(0);
     
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertices2);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texCoords2);
    gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 4);
    }
    }
    wiggle_count++;
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    //两帧渲染一次,正弦改变z坐标的值让红旗飘动 
    float hold;
    if(wiggle_count == 2)
    {
    for( int y = 0; y < 45; y++ )//沿 Y 平面循环
    {
    hold = points[0][y].z; //存储当前左侧波浪值
    for (int x = 0; x < 44; x++)// 沿 x 乎面循环
    { // 当前波浪值等于其右侧的波浪值
    points[x][y].z = points[x + 1][y].z;
    }
    points[44][y].z = hold; //刚才的位成为最左侧的波浪值
    wiggle_count = 0; //计数器清零
    }
    wiggle_count = 0;
    }
     
    }
    private void getTextures(GL10 gl)
    {
    IntBuffer intBuffer = IntBuffer.allocate(2);//申请2个纹理存储空间
    // 创建纹理
    gl.glGenTextures(2 , intBuffer); //创建2个纹理,绑定intuffer
    texture[0] = intBuffer.get(); // 获取第一个纹理的存储指针,即纹理存储位置,位置+1
    texture[1] = intBuffer.get(); //获取下一个纹理存储的位置
     
    // 设置要使用的纹理
    gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);
    //生成纹理
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0 , mBitmap[0] , 0);//利用图mBitmap[0]生成纹理,存储在texture[0]
    // 线形滤波
    gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
     
    //生成第二个纹理
    gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0 , mBitmap[1] , 0);//利用图mBitmap[0]生成纹理,存储在texture[1]
    gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
     
    }
     
    public Point getPoint(int x,int y)
    {
    float x1=( (float)x/5.0f) -4.5f ;
    float y1= ( ((float)y/5.0f)- 4.5f );
    float z1 = (float) (Math.sin(((((float)x/5.0f) *40.0f)/360.0f)*
    3.141592654*2.0f));
    return new Point(x1,y1,z1);
    }
     
    public void getPoints() {
    for (int x = 0; x < 45; x++)
    for (int y = 0; y < 45; y++)
    {
    points[x][y] = getPoint( x, y);
    }
    }
    }
     
    notice:1、正弦改变z的坐标来实现红旗飘动的。
                  2、当向buffer里put值时候,position的值就会自动加1,因此当存完了buffer里的值时候要将position置为0,让绘图的时候可以读取所有的点信息
     
    二、将java数组或者缓冲区转化为opengl的存储方式的工具类:
    package com.example.user.flagdemo;
     
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.FloatBuffer;
    import java.nio.IntBuffer;
     
    /**
    * Created by lenovo on 2016/9/6.
    */
    public class BufferUtil {
     
     
    public static FloatBuffer floatToBuffer(float[] a) {
    //先初始化buffer,数组的长度*4,因为一个float占4个字节
    ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);
    //数组排序用nativeOrder,根据本地的排列顺序,指定存储方式,是1. Little endian(小头):将低序字节存储在起始地址
    // 2. Big endian(大头):将高序字节存储在起始地址
    mbb.order(ByteOrder.nativeOrder());
    FloatBuffer mBuffer = mbb.asFloatBuffer();
    mBuffer.put(a);
    mBuffer.position(0);
    return mBuffer;
    }
    // 将数组a转化为intbuffer
    public static IntBuffer intToBuffer(int[] a) {
    //先初始化buffer,数组的长度*4,因为一个float占4个字节
    ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);
    //数组排序用nativeOrder
    mbb.order(ByteOrder.nativeOrder());
    IntBuffer mBuffer2 = mbb.asIntBuffer();
    mBuffer2.put(a);
    mBuffer2.position(0);
    return mBuffer2;
    }
     
    public static FloatBuffer getFloatBuffer(int length)
    {
    ByteBuffer mbb = ByteBuffer.allocateDirect(length * 4);
    mbb.order(ByteOrder.nativeOrder());
    FloatBuffer mBuffer = mbb.asFloatBuffer();
    mBuffer.position(0);
    return mBuffer;
    }
     
    public static IntBuffer getIntBuffer(int length)
    {
    ByteBuffer mbb = ByteBuffer.allocateDirect(length * 4);
    mbb.order(ByteOrder.nativeOrder());
    IntBuffer mBuffer = mbb.asIntBuffer();
    mBuffer.position(0);
    return mBuffer;
    }
     
     
    }
     
    class Point{
    float x;
    float y;
    float z;
    public Point(float x, float y , float z)
    {
    this.x=x;
    this.y=y;
    this.z=z;
    }
     
    }
     前面2个方法是将java的float和int数组转化为对应的opengl存储方式的缓冲区,后面的2个方法是定义相对应的一定长度的opengl存储的对应的缓冲区
     
  • 相关阅读:
    02梦断代码阅读笔记之二
    每日日报
    每日日报
    每日日报
    每日日报
    02梦断代码阅读笔记之一
    每日日报
    SQL语句分为哪几种?
    数据库三范式是什么?
    什么是数据库事务?
  • 原文地址:https://www.cnblogs.com/bokeofzp/p/5967490.html
Copyright © 2011-2022 走看看