现在的位置: 首页 > 综合 > 正文

android opengl 画球 画圆

2013年02月20日 ⁄ 综合 ⁄ 共 4975字 ⁄ 字号 评论关闭

  

做了2个简单的类 一个是描述球的 一个是平面圆的

public class Ball
{
	private int slices = 36; //越大越圆滑
	private int stacks = 24; //同↑
	private FloatBuffer[] normalsBuffers;
	private FloatBuffer[] slicesBuffers;
	private float yAngle;
	private float zAngle;
	
	
	float radius = 1.3f;
	public Ball()
	{
		slicesBuffers = new FloatBuffer[slices];
		normalsBuffers = new FloatBuffer[slices];
        for (int i = 0; i < slices; i++) {
			
			float[] vertexCoords = new float[6 * (stacks + 1)];
			float[] normalCoords = new float[6 * (stacks + 1)];

			double alpha0 = i * (2 * Math.PI) / slices;
			double alpha1 = (i + 1) * (2 * Math.PI) / slices;
			
			float cosAlpha0 = (float) Math.cos(alpha0);
			float sinAlpha0 = (float) Math.sin(alpha0);
			float cosAlpha1 = (float) Math.cos(alpha1);
			float sinAlpha1 = (float) Math.sin(alpha1);

			for (int j = 0; j <= stacks; j++) 
			{	
				double beta = j * Math.PI / stacks - Math.PI / 2;
				
				float cosBeta = (float) Math.cos(beta);
				float sinBeta = (float) Math.sin(beta);
				
				
				setXYZ(vertexCoords, 6 * j,
						radius * cosBeta * cosAlpha1,
						radius * sinBeta,
						radius * cosBeta * sinAlpha1);
				setXYZ(vertexCoords, 6 * j + 3,
						radius * cosBeta * cosAlpha0,
						radius * sinBeta,
						radius * cosBeta * sinAlpha0);
				setXYZ(normalCoords, 6 * j,
						cosBeta * cosAlpha1,
						sinBeta,
						cosBeta * sinAlpha1);
				setXYZ(normalCoords, 6 * j + 3,
						cosBeta * cosAlpha0,
						sinBeta,
						cosBeta * sinAlpha0);
			}
			slicesBuffers[i] = FloatBuffer.wrap(vertexCoords);
			normalsBuffers[i] = FloatBuffer.wrap(normalCoords);
        }	
    }
	
	public void setXYZ(float[] vector, int offset, float x, float y, float z) {
		vector[offset] = x;
		vector[offset + 1] = y;
		vector[offset + 2] = z;
	}
	
	public void draw(GL10 gl)
	{
		gl.glLoadIdentity();
		gl.glTranslatef(0.0f, 0.0f, -7.0f);
		gl.glColor4f(1.0f, 0.2f, 0.3f, 1.0f);
		gl.glRotatef(yAngle, 1.0f, 0.0f, 0.0f);
		gl.glRotatef(zAngle, 0.0f, 1.0f, 0.0f);
		
		for (int i = 0; i < slices; i++) {
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, slicesBuffers[i]);
			gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 2 * (stacks + 1));

		}
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
	}

	public void setyAngle(float yAngle)
	{
		this.yAngle = yAngle;
	}

	public void setzAngle(float zAngle)
	{
		this.zAngle = zAngle;
	}
}
public class Oval
{
	private float[] vertices = new float[720];
	private FloatBuffer verBuffer ;
	private float yAngle;
	private float zAngle;
	public Oval()
	{
        //初始化圆形数据
    	for (int i = 0; i < 720; i += 2) {
    	    // x 坐标
    	    vertices[i]   =  (float) (Math.cos(DegToRad(i)) * 1);
    	    // y 坐标
    	    vertices[i+1] =  (float) (Math.sin(DegToRad(i)) * 1);
    	}	
        //设置圆形顶点数据
        ByteBuffer qbb = ByteBuffer.allocateDirect(vertices.length * 4);
        qbb.order(ByteOrder.nativeOrder());
    	verBuffer = qbb.asFloatBuffer();
    	verBuffer.put(vertices);
    	verBuffer.position(0); 
    }
	
    public float DegToRad(float deg)
    {
    	return (float) (3.14159265358979323846 * deg / 180.0);
    }
	
    public void draw(GL10 gl)
	{
        //重置投影矩阵
        gl.glLoadIdentity();
        // 移动操作,移入屏幕(Z轴)5个像素, x, y , z
        gl.glTranslatef(0.0f, 0.0f, -5.0f);
        
        //旋转, angle, x, y , z
        gl.glRotatef(yAngle, 0.0f, 1.0f, 0.0f);
        gl.glRotatef(zAngle, 1.0f, 0.0f, 0.0f);
        
        // 设置当前色为红色, R, G, B, Alpha
        gl.glColor4f(1.0f, 0.1f, 0.1f, 1.0f);
    	
    	//设置顶点类型为浮点坐标  
    	gl.glVertexPointer(2, GL10.GL_FLOAT, 0, verBuffer);

        //打开顶点数组
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        
    	//向OGL发送实际画图指令
    	gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 360);

        //画图结束
        gl.glFinish();
	}

	public void setyAngle(float yAngle)
	{
		this.yAngle = yAngle;
	}

	public void setzAngle(float zAngle)
	{
		this.zAngle = zAngle;
	}
}

这个是renderer类 声明了Ball 和 Oval 变量

public class GLRender implements Renderer{

	Oval o = new Oval();
	Ball b = new Ball();
	//度到弧度的转换

    @Override
    public void onDrawFrame(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();		
		gl.glEnable(GL10.GL_CULL_FACE);
		gl.glLightModelx(GL10.GL_LIGHT_MODEL_TWO_SIDE, GL10.GL_FALSE);
        //o.draw(gl);                 //------画圆
    	 b.draw(gl);		 //------画球
    }
     
    public void setyAngle(float yAngle)
	{
    	b.setyAngle(yAngle);
		o.setyAngle(yAngle);
	}

	public void setzAngle(float zAngle)
	{
		b.setzAngle(zAngle);
		o.setzAngle(zAngle);
	}

	@Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
 		if (height == 0) height = 1;
		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();
		GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 1.0f, 100.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_DEPTH_TEST);
		gl.glDepthFunc(GL10.GL_LEQUAL);
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);	
		gl.glCullFace(GL10.GL_BACK);
		gl.glEnable(GL10.GL_LIGHT0);
	}
}

最后是GLSurfaceView类

public class MyGLSurfaceView extends GLSurfaceView
{
	GLRender myRenderer;// 自定义的渲染器
	private final float TOUCH_SCALE_FACTOR = 180.0f / 320;// 角度缩放比例
	private float mPreviousY;// 上次的触控位置Y坐标
	private float mPreviousX;// 上次的触控位置X坐标
	float yAngle = 0;// 绕y轴旋转的角度
	float zAngle = 0;// 绕z轴旋转的角度

	public MyGLSurfaceView(Context context)
	{
		super(context);
		myRenderer = new GLRender();// 创建渲染器
		this.setRenderer(myRenderer);// 设置渲染器
		this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);// 设置渲染模式
	}

	@Override
	public boolean onTouchEvent(MotionEvent e)
	{	// 触摸事件的回调方法
		float x = e.getX();// 得到x坐标
		float y = e.getY();// 得到y坐标
		switch (e.getAction())
		{
		case MotionEvent.ACTION_MOVE:// 触控笔移动
			float dy = y - mPreviousY;// 计算触控笔Y位移
			float dx = x - mPreviousX;// 计算触控笔X位移
			yAngle += dx * TOUCH_SCALE_FACTOR;// 设置沿y轴旋转角度
			zAngle += dy * TOUCH_SCALE_FACTOR;// 设置沿z轴旋转角度
			myRenderer.setyAngle(yAngle);
			myRenderer.setzAngle(zAngle);	
			requestRender();// 重绘画面
		}
		mPreviousY = y;// 记录触控笔位置
		mPreviousX = x;// 记录触控笔位置
		return true;// 返回true
	}
}

重写了ontouch 事件  通过x y 计算出变化的角度 可以让图形做简单的转动 改一改就可以平动了
不过球因为没有做处理 只是用单一颜色绘制的 所以看起来和圆差不多 可以加上颜色数组 就比较明显了

 

【上篇】
【下篇】

抱歉!评论已关闭.