zoukankan      html  css  js  c++  java
  • 实现生成星星,让星星自转和绕原点公转的简单demo。

    物体旋转都用到了gl.glRotatef,然而我们知道旋转函数是绕此时经过绘图原点的轴旋转的,即

                 gl.glLoadIdentity();
    //右移 1.5 单位,并移入屏幕 4.0
    gl.glTranslatef(0f, 0f, -4f);
    //旋转矩阵
    gl.glRotatef(rotateTri, 0.0f, 3.0f,0f);
    绕过点(0,0,-4)的向量(0,3,0)旋转的。星星的公转是绕屏幕中心原点旋转,而绘图和自转都是绕星星本身的中心旋转,因此为了让两个旋转不相互干扰,必须在设置绘图原点和自转之前就进行公转的设定:
           gl.glLoadIdentity();
    gl.glTranslatef(0f, 0.0f, -deep);//先将屏幕移到深层
    gl.glRotatef(start.angle, 0f , 0f, 1f);//函数本身的意思是将图形绕z轴旋转到angle角度,通过修改angle的值来实现公转,此时绘图原点还在屏幕中心
    gl.glTranslatef(start.dist*(float)Math.cos(start.angle),start.dist*(float)Math.sin(start.angle), 0);//由于星星初始角度不同,离原点距离不同就会导致其中心位置,即绘图原点的不同,通过角度和离屏幕中心点的距离计算出
    gl.glRotatef(rotateY , 1f , 0f, 0f);//绕y轴自转,此时绘图原点已经移到星星自身的中心
     
    下面是实现了多个星星在屏幕内旋转和自转的demo:
    start类:
    public class Start {
    float dist;
    int r , g , b;
    float angle;
    boolean IsBigging = true;//是否正在背离原点旋转
    float rotateSelf; //自转的角速度
    float rotateElse; //公转的角速度
     
    public Start (float dist , int r , int g , int b , float angle,float rotateSelf,float rotateElse)
    {
    this.dist = dist;
    this.r = r;
    this.g = g;
    this.b = b;
    this.angle = angle;
    this.rotateSelf = rotateSelf;
    this.rotateElse =rotateElse;
    }
    }
    Render类:
    package com.example.zp.rotatestartdemo;
     
    import android.opengl.GLSurfaceView;
     
    import java.nio.FloatBuffer;
    import java.nio.IntBuffer;
     
    import javax.microedition.khronos.egl.EGLConfig;
    import javax.microedition.khronos.opengles.GL10;
     
    /**
    * Created by lenovo on 2016/9/6.
    */
    public class GLRender implements GLSurfaceView.Renderer{
     
    private int numberStarts =50;
    private Start [] starts = new Start[numberStarts];
    private float deep = 6f;
    private float maxDist = 4f;//屏幕在deep层能显示的最大横坐标,这里表示的是离原点的最大值

     
    private void init()
    {
    //初始化星星
    for(int i = 0 ; i < numberStarts ; i++)
    {
    float dis = 0.2f*i;
    int r = (int)(Math.random()*256);
    int g = (int)(Math.random()*256);
    int b = (int)(Math.random()*256);
    float angle =(float)(Math.random())*2f*(float)Math.PI;
    float rotateSelf = (float)(Math.random())*2f*(float)Math.PI/8f;
    float rotateElse = (float)(Math.random())*2f*(float)Math.PI/16f;
    starts[i] = new Start(dis , r , g , b , angle,rotateSelf,rotateElse);
    }
    }
     
    //三角形
    FloatBuffer vertices = BufferUtil.floatToBuffer(new float[]{
    -0.025f,0.05f,0f,
    -0.1f,0.05f,0f,
    -0.05f,-0.025f,0f,
    -0.1f,-0.1f,0f,
    0f,-0.05f,0f,
    0.1f,-0.1f,0f,
    0.05f,-0.025f,0f,
    0.1f,0.05f,0f,
    0.025f,0.05f,0f,
    0f,0.1f,0f,
    -0.025f,0.05f,0f
     
    });
    //五边形
    FloatBuffer vertices2 = BufferUtil.floatToBuffer(new float[]{
    -0.025f,0.05f,0f,
    -0.05f,-0.025f,0f,
    0f,-0.05f,0f,
     
    -0.025f,0.05f,0f,
    0f,-0.05f,0f,
    0.025f,0.05f,0f,
     
    0f,-0.05f,0f,
    0.05f,-0.025f,0f,
    0.025f,0.05f,0f
    });
     
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    gl.glShadeModel(GL10.GL_SMOOTH);
    // 黑色背景
    gl.glClearColor(0, 0, 0, 0);
    // 设置深度缓存
    gl.glClearDepthf(1.0f);
    // gl.glEnable(GL10.GL_CULL_FACE);//启用这个后,当目前图片转到背面时候就看不到了,意思就是画一个面,只能从正面看到这个面,从背面就看不到,因此不能随便加
    // 启用阴影平滑
     
    // 启用深度测试
    gl.glEnable(GL10.GL_DEPTH_TEST);
    gl.glDepthFunc(GL10.GL_LEQUAL);
    // 告诉系统对透视进行修正
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
    init();
    }
     
     
    @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.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    for(int i = 0 ; i < numberStarts ; i++) {
    drawStart(gl, starts[i]);
    }
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
     
    }
     
    // float rotateSpeed = 0.3f ;
    float rotateY = 0;
    public void drawStart(GL10 gl , Start start)
    {
    gl.glLoadIdentity();
    gl.glTranslatef(0f, 0.0f, -deep);
    gl.glRotatef(start.angle, 0f , 0f, 1f);//rotateZ
    gl.glTranslatef(start.dist*(float)Math.cos(start.angle),start.dist*(float)Math.sin(start.angle), 0);
    gl.glRotatef(rotateY , 1f , 0f, 0f);
     
    float r = (float)(start.r)/255f;
    float g = (float)start.g/255f;
    float b = (float)start.b/255f;
    gl.glColor4f(r,g,b,1f);
     
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertices);
     
    for(int i = 0 ; i <5 ; i ++)
    {
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,i*2,3);
    }
    gl.glFinish();
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertices2);
    for(int i = 0 ; i <3 ; i ++)
    {
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,i*3,3);
    }
    gl.glFinish();
     
     
    if(start.dist>=maxDist)
    start.IsBigging = false;
    if(start.dist<=0)
    start.IsBigging = true;
    //此处的0.01f代表的是星星公转时候离心和向心运动的速度,即dist的变化速率 
    if(start.IsBigging)
    start.dist=start.dist + 0.01f;
    else
    start.dist=start.dist - 0.01f;
     
    rotateY = rotateY + start.rotateSelf;
     
    start.angle = start.angle +start.rotateElse;
     
    }
     
     
     
    }

     

  • 相关阅读:
    C# if else 使物体在X轴循环移动
    Jmeter之csv、用户自定义变量以及Query Type分析
    jmeter实战之笔记整理
    Badboy参数化
    Jmeter之Badboy录制脚本及简化脚本http请求
    jmeter之jdbc请求
    性能测试
    接口自动化学习--testNG
    接口自动化学习--mock
    Git工具使用小结
  • 原文地址:https://www.cnblogs.com/bokeofzp/p/5967587.html
Copyright © 2011-2022 走看看