Android OpenGL ES 简明开发教程_3D坐标变换

该系列文章均转载自

http://blog.csdn.net/mapdigit/article/details/7526556

由于原文好像无法打开,正好自己有记录,所以正好分享出来,其中也对一些API作了解释。


Coordinate System坐标系

OpenGL使用了右手坐标系统,右手坐标系判断方法:让右手大拇指指向x轴的正方向,食指指向y轴的正方向,如果中指能指向z轴的正方向,则称这个坐标系为右手直角坐标系。

这里写图片描述


Translate平移变换

方法public abstract void glTranslatef (float x, float y, float z) 用于坐标平移变换。在上个例子中我们把需要显示的正方形后移了4个单位,就是使用的坐标的平移变换,可以进行多次平移变换,其结果为多个平移矩阵的累计结果,矩阵的顺序不重要,可以互换。
这里写图片描述


Rotate旋转

方法public abstract void glRotatef(float angle, float x, float y, float z)用来实现选择坐标变换,单位为角度。 (x,y,z)定义旋转的参照矢量方向。多次旋转的顺序非常重要。
这里写图片描述

比如你选择一个骰子,首先按下列顺序选择3次:

gl.glRotatef(90f, 1.0f, 0.0f, 0.0f);
gl.glRotatef(90f, 0.0f, 1.0f, 0.0f);
gl.glRotatef(90f, 0.0f, 0.0f, 1.0f);

这里写图片描述

然后打算逆向旋转回原先的初始状态,需要有如下旋转:

gl.glRotatef(90f, -1.0f, 0.0f, 0.0f);
gl.glRotatef(90f, 0.0f, -1.0f, 0.0f);
gl.glRotatef(90f, 0.0f, 0.0f, -1.0f);

这里写图片描述

或者如下旋转:

gl.glRotatef(90f, 0.0f, 0.0f, -1.0f);
gl.glRotatef(90f, 0.0f, -1.0f, 0.0f);
gl.glRotatef(90f, -1.0f, 0.0f, 0.0f);

旋转变换glRotatef(angle, -x, -y, -z) 和glRotatef(-angle, x, y, z)是等价的,但选择变换的顺序直接影响最终坐标变换的结果。 角度为正时表示逆时针方向。


Translate & Rotate (平移和旋转组合变换)

在对Mesh(网格,构成三维形体的基本单位)同时进行平移和选择变换时,坐标变换的顺序也直接影响最终的结果。

比如:先平移后旋转, 旋转的中心为平移后的坐标
这里写图片描述

先旋转后平移: 平移在则相对于旋转后的坐标系:
这里写图片描述

一个基本的原则是:坐标变换都是相对于变换的Mesh本身的坐标系进行的。


Scale(缩放)

方法public abstract void glScalef (float x, float y, float z)用于缩放变换。

下图为使用gl.glScalef(2f, 2f, 2f) 变换后的基本,相当于把每个坐标值都乘以2.
这里写图片描述


Translate & Scale(平移和缩放组合变换)

同样当需要平移和缩放时,变换的顺序也会影响最终结果。
比如先平移后缩放:

gl.glTranslatef(2, 0, 0);
gl.glScalef(0.5f, 0.5f, 0.5f);

这里写图片描述

如果调换一下顺序:

gl.glScalef(0.5f, 0.5f, 0.5f);
gl.glTranslatef(2, 0, 0);

这里写图片描述


矩阵操作,单位矩阵

在进行平移,旋转和缩放的时候,所有的变换都是针对当前矩阵(与当前矩形相乘),如果需要将当前矩阵恢复到最初的矩阵,就可以使用单位矩阵(无平移,旋转和缩放)。
public abstract void glLoadIdentity()。

在栈中保存当前矩阵和栈中回复所存矩阵,可以使用
public abstract void glPushMatrix()

public abstract void glPopMatrix()。

在使用坐标变换的一个好习惯是在变换前用glPushMatrix()保存当前矩阵,完成坐标操作后,再用glPopMatrix()恢复原先的矩阵设置。

最后利用上面介绍的坐标变换知识,来绘制3个正方形A,B,C。进行缩放变换,使的B比A小50%,C比B小50%。 然后以屏幕中心逆时针旋转A,B以A为中心顺时针旋转,C以B为中心顺时针旋转同时以自己中心高速逆时针旋转。

onDrawFrame()方法变成如下:

public void onDrawFrame(GL10 gl10) {

    gl10.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    gl10.glLoadIdentity();
    gl10.glTranslatef(0,0,-10);

    // SQUARE A
    // Save the current matrix.
    gl10.glPushMatrix();
    // Rotate square A counter-clockwise.
    gl10.glRotatef(angle, 0, 0, 1);
    // Draw square A.
    mSquare.draw(gl10);
    // Restore the last matrix.
    gl10.glPopMatrix();

    // SQUARE B
    // Save the current matrix
    gl10.glPushMatrix();
    // Rotate square B before moving it, making it rotate around A.
    gl10.glRotatef(-angle, 0, 0, 1);
    // Move square B.
    gl10.glTranslatef(2, 0, 0);
    // Scale it to 50% of square A
    gl10.glScalef(.5f, .5f, .5f);
    // Draw square B.
    mSquare.draw(gl10);

    // SQUARE C
    // Save the current matrix
    gl10.glPushMatrix();
    // Make the rotation around B
    gl10.glRotatef(-angle, 0, 0, 1);
    gl10.glTranslatef(2, 0, 0);
    // Scale it to 50% of square B
    gl10.glScalef(.5f, .5f, .5f);
    // Rotate around it's own center.
    gl10.glRotatef(angle*10, 0, 0, 1);
    // Draw square C.
    mSquare.draw(gl10);

    // Restore to the matrix as it was before C.
    gl10.glPopMatrix();
    // Restore to the matrix as it was before B.
    gl10.glPopMatrix();

    // Increse the angle.
    angle++;
}

完整代码下载:

https://github.com/upperLucky/OpenGLDemo_Polygon_

效果图为:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值