zoukankan      html  css  js  c++  java
  • OpenGL绘制棱锥,剔除

    /**
     * 缓冲区工具类
     */
    public class BufferUtil {
     /**
      * 将浮点数组转换成字节缓冲区
      */
     public static ByteBuffer arr2ByteBuffer(float[] arr){
      ByteBuffer ibb = ByteBuffer.allocateDirect(arr.length * 4);
      ibb.order(ByteOrder.nativeOrder());
      FloatBuffer fbb = ibb.asFloatBuffer();
      fbb.put(arr);
      ibb.position(0);
      return ibb ;
     }
     
     /**
      * 将list转换成字节缓冲区
      */
     public static ByteBuffer list2ByteBuffer(List<Float> list){
      ByteBuffer ibb = ByteBuffer.allocateDirect(list.size() * 4);
      ibb.order(ByteOrder.nativeOrder());
      FloatBuffer fbb = ibb.asFloatBuffer();
      for(Float f : list){
       fbb.put(f);
      }
      ibb.position(0);
      return ibb ;
     }
    }

    /**  

    * 渲染器

     */

    public abstract class AbstractMyRenderer implements android.opengl.GLSurfaceView.Renderer

    {  

     private float ratio;  

      public float xrotate = 0f;//围绕x轴旋转角度

    public float yrotate = 0f;//围绕x轴旋转角度  

     /**

      * 1.

      */  

    public void onSurfaceCreated(GL10 gl, EGLConfig config)

    {  

     //清平色  

     gl.glClearColor(0f, 0f, 0f, 1f);   

    //启用顶点缓冲区数组

      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  

    }

    /**  

    * 2.

      */

     public void onSurfaceChanged(GL10 gl, int width, int height) {

    //设置视口

      gl.glViewport(0, 0, width, height);   

    ratio = (float)width / (float)height;   

    //投影矩阵  

     gl.glMatrixMode(GL10.GL_PROJECTION);

      //加载单位矩阵  

     gl.glLoadIdentity();  

     //设置平截头体   

    gl.glFrustumf(-ratio, ratio, -1, 1, 3f, 7f);  }

    /**

      * 3.

      */  

    public abstract void onDrawFrame(GL10 gl);

    }

    **  

    * 棱锥,正方形  

    */

    public class MyTriangleConeRenderer extends AbstractMyRenderer{

     public void onSurfaceCreated(GL10 gl, EGLConfig config) {

    gl.glClearColor(0f, 0f, 0f, 1f);
      //顶点缓冲区
      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      //启用颜色缓冲区
      gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
     }
     
     public void onDrawFrame(GL10 gl) {
      //清除颜色缓冲区和深度缓冲区
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
      //设置绘图颜色
      gl.glColor4f(1f, 0f, 0f, 1f);
      
      //启用深度测试
      gl.glEnable(GL10.GL_DEPTH_TEST);
      
      //启用表面剔除
      gl.glEnable(GL10.GL_CULL_FACE);
      //指定前面()
      //ccw:counter clock wise-->逆时针
      //cw:clock wise--> 顺时针
      gl.glFrontFace(GL10.GL_CCW);
      //剔除背面
      gl.glCullFace(GL10.GL_BACK);
      
      //GL10.GL_SMOOTH:平滑着色(默认)
      //GL10.GL_FLAT:单调模式
      gl.glShadeModel(GL10.GL_FLAT);
      
      //操作模型视图矩阵
      gl.glMatrixMode(GL10.GL_MODELVIEW);
      gl.glLoadIdentity();
      //设置眼球的参数
      GLU.gluLookAt(gl,0f,0f,5f, 0f, 0f, 0f, 0f,1f,0f);
      
      //旋转角度
      gl.glRotatef(xrotate, 1, 0, 0);
      gl.glRotatef(yrotate, 0, 1, 0);
      
      //计算点坐标
      float r = 0.5f ;//半径
      float x = 0f,y = 0f,z = -0.5f ;
      
      /******************** 锥面 ************************/
      //顶点坐标集合
      List<Float> coordsList = new ArrayList<Float>();
      //添加锥顶点
      coordsList.add(0f);
      coordsList.add(0f);
      coordsList.add(0.5f);
      
      //顶点颜色集合
      List<Float> colorList = new ArrayList<Float>();
      colorList.add(1f);//r
      colorList.add(0f);//g
      colorList.add(0f);//b
      colorList.add(1f);//a
      
      /******************** 锥底 ************************/
      //锥底坐标
      List<Float> coordsConeBottomList = new ArrayList<Float>();
      coordsConeBottomList.add(0f);
      coordsConeBottomList.add(0f);
      coordsConeBottomList.add(-0.5f);
      
      boolean flag = false ;
      //底面
      for(float alpha = 0f ; alpha < Math.PI * 6 ; alpha = (float) (alpha + Math.PI / 8)){
       //锥面
       x = (float) (r * Math.cos(alpha));
       y = (float) (r * Math.sin(alpha));
       coordsList.add(x);
       coordsList.add(y);
       coordsList.add(z);
       
       //锥底坐标
       coordsConeBottomList.add(x);
       coordsConeBottomList.add(y);
       coordsConeBottomList.add(z);
       
       //点颜色值
       if(flag = !flag){
        //黄色
        colorList.add(1f);
        colorList.add(1f);
        colorList.add(0f);
        colorList.add(1f);
       }
       else{
        //红色
        colorList.add(1f);
        colorList.add(0f);
        colorList.add(0f);
        colorList.add(1f);
       }
      }
      //点颜色值
      if(flag = !flag){
       //黄色
       colorList.add(1f);
       colorList.add(1f);
       colorList.add(0f);
       colorList.add(1f);
      }
      else{
       //红色
       colorList.add(1f);
       colorList.add(0f);
       colorList.add(0f);
       colorList.add(1f);
      }
      
      //颜色缓冲区
      ByteBuffer colorBuffer = BufferUtil.list2ByteBuffer(colorList);
      gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
      //绘制锥面
      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, BufferUtil.list2ByteBuffer(coordsList));
      gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, coordsList.size() / 3);
      
      //剔除正面
      gl.glCullFace(GL10.GL_FRONT);
      //绘制锥底
      colorBuffer.position(4);
      gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, BufferUtil.list2ByteBuffer(coordsConeBottomList));
      gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, coordsConeBottomList.size() / 3);
     }
    }

    //主界面

    public class MainActivity extends Activity {

         private AbstractMyRenderer render;  

    private MyGLSurfaceView view;

     public void onCreate(Bundle savedInstanceState) {

     super.onCreate(savedInstanceState);        

    view = new GLSurfaceView(this);        

    render = new MyTriangleConeRenderer();       

      view.setRenderer(render);        

    //GLSurfaceView.RENDERMODE_CONTINUOUSLY:持续渲染(默认)        

    //GLSurfaceView.RENDERMODE_WHEN_DIRTY:脏渲染,命令渲染        

    view.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);        

    setContentView(view);    

    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {

    float step = 5f ;    

     //up      

    if(keyCode == KeyEvent.KEYCODE_DPAD_UP){       

    render.xrotate = render.xrotate - step ;    

     }      else if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN){       

    render.xrotate = render.xrotate + step ;    

     }      else if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT){      

     render.yrotate = render.yrotate + step ;      

    }      else if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT){       

    render.yrotate = render.yrotate - step ;    

     }      

    //请求渲染,和脏渲染配合使用      

    view.requestRender();    

     return super.onKeyDown(keyCode, event);    

    }

    }

  • 相关阅读:
    高精度计算
    c++ sort
    算法分类小结
    二叉树层序遍历
    clion windows c++环境配置 mingw
    kafka,filebeat 配置
    centos7 源码安装mysql5.7
    如何优雅的生成及遍历python嵌套字典
    Java Swing 绝对布局管理方法,null布局【图】
    python3.4+pymssql 中文乱码问题解决
  • 原文地址:https://www.cnblogs.com/danmao/p/3817434.html
Copyright © 2011-2022 走看看